# 银龄智库管理后台代码实施指南 ## 1. 创建管理页面组件 ### 1.1 SilverKnowledges.tsx 列表页面 **文件路径**: `src/client/admin/pages/SilverKnowledges.tsx` ```tsx import React, { useState, useRef } from 'react'; import { Card, Button, Space, Tag, Modal, message, Switch, Popconfirm } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, StarOutlined } from '@ant-design/icons'; import type { ProColumns, ActionType } from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table'; import { useNavigate } from 'react-router'; import { useAuth } from '../hooks/AuthProvider'; import type { InferResponseType } from 'hono/client'; import { silverUsersClient } from '@/client/api'; import dayjs from 'dayjs'; type SilverKnowledge = InferResponseType['data'][0]; const SilverKnowledges: React.FC = () => { const navigate = useNavigate(); const { user } = useAuth(); const actionRef = useRef(); const [loading, setLoading] = useState(false); const handleAdd = () => { navigate('/admin/silver-knowledges/new'); }; const handleEdit = (record: SilverKnowledge) => { navigate(`/admin/silver-knowledges/${record.id}/edit`); }; const handleDelete = async (id: number) => { try { await silverUsersClient.knowledges[':id'].$delete({ param: { id: id.toString() } }); message.success('删除成功'); actionRef.current?.reload(); } catch (error) { message.error('删除失败'); } }; const handleToggleStatus = async (record: SilverKnowledge, newStatus: number) => { try { await silverUsersClient.knowledges[':id'].$put({ param: { id: record.id.toString() }, json: { status: newStatus } }); message.success('状态更新成功'); actionRef.current?.reload(); } catch (error) { message.error('状态更新失败'); } }; const handleToggleFeatured = async (record: SilverKnowledge, isFeatured: boolean) => { try { await silverUsersClient.knowledges[':id'].$put({ param: { id: record.id.toString() }, json: { isFeatured: isFeatured ? 1 : 0 } }); message.success(isFeatured ? '已设为推荐' : '已取消推荐'); actionRef.current?.reload(); } catch (error) { message.error('推荐设置失败'); } }; const columns: ProColumns[] = [ { title: 'ID', dataIndex: 'id', width: 80, hideInSearch: true, }, { title: '标题', dataIndex: 'title', ellipsis: true, width: 200, }, { title: '分类', dataIndex: 'category', render: (_, record) => record.category?.name || '-', width: 100, }, { title: '类型', dataIndex: 'type', valueEnum: { 1: { text: '文章', status: 'Processing' }, 2: { text: '视频', status: 'Success' }, 3: { text: '文档', status: 'Default' }, 4: { text: '课程', status: 'Warning' }, 5: { text: '经验分享', status: 'Success' }, 6: { text: '案例分享', status: 'Processing' }, 7: { text: '研究报告', status: 'Error' }, }, width: 100, }, { title: '状态', dataIndex: 'status', render: (_, record) => { const statusMap = { 0: 草稿, 1: 已发布, 2: 已隐藏, 3: 已删除, 4: 审核中, }; return statusMap[record.status] || '-'; }, valueEnum: { 0: { text: '草稿', status: 'Default' }, 1: { text: '已发布', status: 'Success' }, 2: { text: '已隐藏', status: 'Warning' }, 3: { text: '已删除', status: 'Error' }, 4: { text: '审核中', status: 'Processing' }, }, width: 100, }, { title: '作者', dataIndex: ['user', 'nickname'], width: 100, hideInSearch: true, }, { title: '浏览', dataIndex: 'viewCount', width: 80, hideInSearch: true, }, { title: '点赞', dataIndex: 'likeCount', width: 80, hideInSearch: true, }, { title: '收藏', dataIndex: 'favoriteCount', width: 80, hideInSearch: true, }, { title: '推荐', dataIndex: 'isFeatured', render: (_, record) => ( handleToggleFeatured(record, checked)} checkedChildren="是" unCheckedChildren="否" /> ), width: 80, hideInSearch: true, }, { title: '创建时间', dataIndex: 'createdAt', render: (_, record) => dayjs(record.createdAt).format('YYYY-MM-DD HH:mm'), width: 150, hideInSearch: true, }, { title: '操作', valueType: 'option', width: 200, render: (_, record) => ( handleDelete(record.id)} okText="确定" cancelText="取消" > ), }, ]; return ( headerTitle="银龄智库管理" actionRef={actionRef} rowKey="id" search={{ labelWidth: 120, }} toolBarRender={() => [ , ]} request={async (params) => { const response = await silverUsersClient.knowledges.$get({ query: { page: params.current || 1, pageSize: params.pageSize || 10, keyword: params.title, ...params, } }); const data = await response.json(); return { data: data.data, success: response.ok, total: data.pagination.total, }; }} columns={columns} pagination={{ showSizeChanger: true, showQuickJumper: true, }} /> ); }; export default SilverKnowledges; ``` ### 1.2 SilverKnowledgeForm.tsx 表单页面 **文件路径**: `src/client/admin/pages/SilverKnowledgeForm.tsx` ```tsx import React, { useEffect, useState } from 'react'; import { Card, Form, Input, Select, Button, Space, Upload, message, Row, Col } from 'antd'; import { InboxOutlined, ArrowLeftOutlined } from '@ant-design/icons'; import { useNavigate, useParams } from 'react-router'; import ReactQuill from 'react-quill'; import 'react-quill/dist/quill.snow.css'; import { useAuth } from '../hooks/AuthProvider'; import { silverUsersClient } from '@/client/api'; import type { InferResponseType, InferRequestType } from 'hono/client'; import dayjs from 'dayjs'; const { Option } = Select; const { TextArea } = Input; const { Dragger } = Upload; type SilverKnowledge = InferResponseType; type CreateKnowledge = InferRequestType['json']; type UpdateKnowledge = InferRequestType['json']; const knowledgeTypes = [ { value: 1, label: '文章' }, { value: 2, label: '视频' }, { value: 3, label: '文档' }, { value: 4, label: '课程' }, { value: 5, label: '经验分享' }, { value: 6, label: '案例分享' }, { value: 7, label: '研究报告' }, ]; const knowledgeStatus = [ { value: 0, label: '草稿' }, { value: 1, label: '已发布' }, { value: 2, label: '已隐藏' }, { value: 4, label: '审核中' }, ]; const SilverKnowledgeForm: React.FC = () => { const navigate = useNavigate(); const { id } = useParams(); const { user } = useAuth(); const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const [categories, setCategories] = useState([]); useEffect(() => { fetchCategories(); if (id) { fetchKnowledge(); } }, [id]); const fetchCategories = async () => { try { const response = await silverUsersClient['knowledge-categories'].$get(); const data = await response.json(); setCategories(data.data || []); } catch (error) { console.error('获取分类失败:', error); } }; const fetchKnowledge = async () => { if (!id) return; try { const response = await silverUsersClient.knowledges[':id'].$get({ param: { id } }); const data = await response.json(); form.setFieldsValue({ ...data, tags: data.tags ? JSON.parse(data.tags) : [], attachments: data.attachments ? JSON.parse(data.attachments) : [], }); } catch (error) { message.error('获取知识详情失败'); } }; const handleSubmit = async (values: any) => { setLoading(true); try { const submitData = { ...values, userId: user?.id, tags: values.tags ? JSON.stringify(values.tags) : undefined, attachments: values.attachments ? JSON.stringify(values.attachments) : undefined, }; if (id) { await silverUsersClient.knowledges[':id'].$put({ param: { id }, json: submitData }); message.success('更新成功'); } else { await silverUsersClient.knowledges.$post({ json: submitData }); message.success('创建成功'); } navigate('/admin/silver-knowledges'); } catch (error) { message.error(id ? '更新失败' : '创建失败'); } finally { setLoading(false); } }; const handleBack = () => { navigate('/admin/silver-knowledges'); }; const uploadProps = { name: 'file', multiple: true, action: '/api/v1/files/upload-policy', onChange(info: any) { const { status } = info.file; if (status === 'done') { message.success(`${info.file.name} 上传成功`); } else if (status === 'error') { message.error(`${info.file.name} 上传失败`); } }, }; return ( } onClick={handleBack}> 返回列表 } >