# 管理后台前端页面开发流程规范 ## 适用场景 管理后台页面开发,包括列表页、详情页、表单页等后台功能页面的实现流程。 ## 开发流程 ### 1. **创建页面组件** - 位置: `src/client/admin/pages/[EntityName]List.tsx` 和 `src/client/admin/pages/[EntityName]Detail.tsx` - 列表页组件示例: ```tsx import React, { useEffect, useState } from 'react'; import { Table, Button, Space, Tag, message } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'; import { useNavigate } from 'react-router-dom'; import type { InferResponseType } from 'hono/client'; import { yourEntityClient } from '@/client/api'; // 类型定义 type EntityItem = InferResponseType; type EntityListResponse = InferResponseType; const YourEntityList: React.FC = () => { const navigate = useNavigate(); const [data, setData] = useState([]); const [loading, setLoading] = useState(true); const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 }); // 获取数据列表 const fetchData = async () => { try { setLoading(true); const res = await yourEntityClient.$get({ query: { page: pagination.current, pageSize: pagination.pageSize } }); if (!res.ok) throw new Error('获取数据失败'); const result: EntityListResponse = await res.json(); setData(result.data); setPagination({ ...pagination, total: result.pagination.total }); } catch (error) { message.error(error instanceof Error ? error.message : '获取数据失败'); } finally { setLoading(false); } }; useEffect(() => { fetchData(); }, [pagination.current, pagination.pageSize]); // 分页变化处理 const handleTableChange = (pagination: any) => { setPagination({ ...pagination, current: pagination.current, pageSize: pagination.pageSize }); }; // 操作按钮处理 const handleAdd = () => { navigate('/your-entities/new'); }; const handleEdit = (id: number) => { navigate(`/your-entities/${id}`); }; const handleDelete = async (id: number) => { try { const res = await yourEntityClient[':id'].$delete({ param: { id } }); if (!res.ok) throw new Error('删除失败'); message.success('删除成功'); fetchData(); } catch (error) { message.error(error instanceof Error ? error.message : '删除失败'); } }; // 表格列定义 const columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 80 }, { title: '名称', dataIndex: 'name', key: 'name' }, { title: '状态', dataIndex: 'status', key: 'status', render: (status: number) => ( {status === 1 ? '启用' : '禁用'} ) }, { title: '操作', key: 'action', render: (_: any, record: EntityItem) => ( ) } ]; return (

实体管理

({ ...item, key: item.id }))} loading={loading} pagination={{ current: pagination.current, pageSize: pagination.pageSize, total: pagination.total, showSizeChanger: true, showQuickJumper: true, showTotal: (total) => `共 ${total} 条记录` }} onChange={handleTableChange} bordered /> ); }; export default YourEntityList; ``` ### 2. **注册路由配置** - 位置: `src/client/admin/routes.tsx` - 添加路由配置示例: ```typescript import YourEntityList from './pages/YourEntityList'; import YourEntityDetail from './pages/YourEntityDetail'; export const routes = [ // ...其他路由 { path: '/your-entities', element: }, { path: '/your-entities/:id', element: }, { path: '/your-entities/new', element: } ]; ``` ### 3. **添加菜单配置** - 位置: `src/client/admin/menu.tsx` - 添加菜单配置示例: ```typescript import { TableOutlined } from '@ant-design/icons'; export const menuItems = [ // ...其他菜单项 { key: 'your-entities', icon: , label: '实体管理', path: '/your-entities' } ]; ``` ### 4. **创建表单组件** - 位置: `src/client/admin/components/[EntityName]Form.tsx` - 表单组件示例: ```tsx import React from 'react'; import { Form, Input, Select, message } from 'antd'; import type { CreateRequest, UpdateRequest } from '@/client/api/your-entity'; interface YourEntityFormProps { initialValues?: Partial; onFinish: (values: CreateRequest | UpdateRequest) => Promise; loading: boolean; } const { Option } = Select; const YourEntityForm: React.FC = ({ initialValues, onFinish, loading }) => { const [form] = Form.useForm(); // 初始化表单值 React.useEffect(() => { if (initialValues) { form.setFieldsValue(initialValues); } else { form.resetFields(); } }, [form, initialValues]); // 表单提交处理 const handleSubmit = async () => { try { const values = await form.validateFields(); await onFinish(values); } catch (error) { message.error('表单验证失败,请检查输入内容'); } }; return (
); }; export default YourEntityForm; ``` ### 5. **实现详情页** - 位置: `src/client/admin/pages/[EntityName]Detail.tsx` - 详情页组件示例: ```tsx import React, { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Card, Spin, message } from 'antd'; import type { InferResponseType, InferRequestType } from 'hono/client'; import { yourEntityClient } from '@/client/api'; import YourEntityForm from '../components/YourEntityForm'; // 类型定义 type EntityDetail = InferResponseType; type CreateRequest = InferRequestType['json']; type UpdateRequest = InferRequestType['json']; interface YourEntityDetailProps { isNew?: boolean; } const YourEntityDetail: React.FC = ({ isNew = false }) => { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const [loading, setLoading] = useState(!isNew); const [initialValues, setInitialValues] = useState>({}); // 获取详情数据 const fetchDetail = async () => { if (!id || isNew) return; try { setLoading(true); const res = await yourEntityClient[':id'].$get({ param: { id: Number(id) } }); if (!res.ok) throw new Error('获取详情失败'); const data: EntityDetail = await res.json(); setInitialValues(data); } catch (error) { message.error(error instanceof Error ? error.message : '获取详情失败'); } finally { setLoading(false); } }; useEffect(() => { fetchDetail(); }, [id, isNew]); // 表单提交处理 const handleFinish = async (values: CreateRequest | UpdateRequest) => { try { setLoading(true); if (isNew) { // 创建新实体 const res = await yourEntityClient.$post({ json: values as CreateRequest }); if (!res.ok) throw new Error('创建失败'); message.success('创建成功'); } else if (id) { // 更新实体 const res = await yourEntityClient[':id'].$put({ param: { id: Number(id) }, json: values as UpdateRequest }); if (!res.ok) throw new Error('更新失败'); message.success('更新成功'); } navigate('/your-entities'); } catch (error) { message.error(error instanceof Error ? error.message : '操作失败'); } finally { setLoading(false); } }; return (

{isNew ? '添加实体' : '编辑实体'}

); }; export default YourEntityDetail; ``` ### 6. **样式规范** - 使用CSS Modules或Styled Components进行样式隔离 - 页面容器样式: ```css .page-container { padding: 24px; } .page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; } ``` ### 7. **权限控制** - 使用ProtectedRoute组件包装需要权限控制的页面: ```tsx import { ProtectedRoute } from '@/client/admin/components/ProtectedRoute'; export const routes = [ // ...其他路由 { path: '/your-entities', element: ( ) } ];