diff --git a/config/routes.ts b/config/routes.ts index 3e99f63..b7e65ad 100644 --- a/config/routes.ts +++ b/config/routes.ts @@ -27,12 +27,13 @@ export default [ }, { path: '/admin', - name: '管理页', + name: '后台管理', icon: 'crown', - access: 'canAdmin', + // access: 'canAdmin', routes: [ { path: '/admin', redirect: '/admin/sub-page' }, - { path: '/admin/sub-page', name: '二级管理页', component: './Admin' }, + { path: '/admin/sub-page', name: '论坛管理', component: './Admin' }, + { path: '/admin/user-manage', name: '用户管理', component: './Admin_UserManage' }, ], }, { path: '/', redirect: '/welcome' }, diff --git a/src/pages/Admin.tsx b/src/pages/Admin.tsx index 905c6f6..6381976 100644 --- a/src/pages/Admin.tsx +++ b/src/pages/Admin.tsx @@ -1,44 +1,191 @@ -import { HeartTwoTone, SmileTwoTone } from '@ant-design/icons'; +import React, { useEffect, useState } from 'react'; import { PageContainer } from '@ant-design/pro-components'; -import '@umijs/max'; -import { Alert, Card, Typography } from 'antd'; -import React from 'react'; -const Admin: React.FC = () => { +import { Table, Button, Modal, Form, Input, Tag, Space, Popconfirm, message, Avatar } from 'antd'; +import { listAllPostsUsingGet, updatePostUsingPost, deletePostUsingPost, addPostUsingPost } from '@/services/hebi/postController'; + +const ForumAdmin: React.FC = () => { + const [posts, setPosts] = useState([]); + const [loading, setLoading] = useState(false); + const [editingPost, setEditingPost] = useState(null); + const [modalVisible, setModalVisible] = useState(false); + const [form] = Form.useForm(); + const [search, setSearch] = useState(''); + + // 获取帖子列表 + const fetchPosts = async () => { + setLoading(true); + const res = await listAllPostsUsingGet(); + if (res && res.code === 0 && Array.isArray(res.data)) { + setPosts(res.data); + } + setLoading(false); + }; + + useEffect(() => { + fetchPosts(); + }, []); + + // 编辑 + const handleEdit = (record: any) => { + setEditingPost(record); + setModalVisible(true); + form.setFieldsValue({ + ...record, + tags: record.tagList?.join(','), + }); + }; + + // 新增 + const handleAdd = () => { + setEditingPost(null); + setModalVisible(true); + form.resetFields(); + }; + + // 删除 + const handleDelete = async (id: number) => { + const res = await deletePostUsingPost({ id }); + if (res && res.code === 0) { + message.success('删除成功'); + fetchPosts(); + } else { + message.error(res?.message || '删除失败'); + } + }; + + // 提交表单 + const handleOk = async () => { + const values = await form.validateFields(); + const tags = values.tags ? values.tags.split(',').map((t: string) => t.trim()) : []; + if (editingPost) { + // 编辑 + const res = await updatePostUsingPost({ ...editingPost, ...values, tags }); + if (res && res.code === 0) { + message.success('更新成功'); + setModalVisible(false); + fetchPosts(); + } else { + message.error(res?.message || '更新失败'); + } + } else { + // 新增 + const res = await addPostUsingPost({ ...values, tags }); + if (res && res.code === 0) { + message.success('新增成功'); + setModalVisible(false); + fetchPosts(); + } else { + message.error(res?.message || '新增失败'); + } + } + }; + + const columns = [ + { + title: 'ID', + dataIndex: 'id', + width: 60, + }, + { + title: '标题', + dataIndex: 'title', + width: 200, + }, + { + title: '标签', + dataIndex: 'tagList', + render: (tags: string[]) => ( + <> + {tags?.map(tag => ( + {tag} + ))} + + ), + }, + { + title: '作者', + dataIndex: ['user', 'userName'], + width: 100, + render: (_: any, record: any) => ( + + {record.user?.userName} + + ), + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 180, + }, + { + title: '操作', + key: 'action', + width: 160, + render: (_: any, record: any) => ( + + + handleDelete(record.id)}> + + + + ), + }, + ]; + + // 前端搜索过滤 + const filteredPosts = posts.filter(post => { + const keyword = search.trim().toLowerCase(); + if (!keyword) return true; + const titleMatch = post.title?.toLowerCase().includes(keyword); + const tagsMatch = (post.tagList || []).some((tag: string) => + tag.toLowerCase().includes(keyword) + ); + return titleMatch || tagsMatch; + }); + return ( - - - +
+ + setSearch(e.target.value)} /> - - 基于AIGC的智能数据分析系统 - - -

+ + setModalVisible(false)} + destroyOnClose > - Want to add more pages? Please refer to{' '} - - use block - - 。 -

+
+ + + + + + + + + + +
); }; -export default Admin; + +export default ForumAdmin; diff --git a/src/pages/Admin_UserManage.tsx b/src/pages/Admin_UserManage.tsx new file mode 100644 index 0000000..b8f2d8d --- /dev/null +++ b/src/pages/Admin_UserManage.tsx @@ -0,0 +1,255 @@ +import React, { useEffect, useState } from 'react'; +import { PageContainer } from '@ant-design/pro-components'; +import { Table, Button, Modal, Form, Input, Space, Popconfirm, message, Avatar, Select } from 'antd'; +import { listUserByPageUsingPost, updateUserUsingPost, deleteUserUsingPost, addUserUsingPost } from '@/services/hebi/userController'; + +const { Option } = Select; + +const UserManage: React.FC = () => { + const [allUsers, setAllUsers] = useState([]); + const [users, setUsers] = useState([]); + const [loading, setLoading] = useState(false); + const [editingUser, setEditingUser] = useState(null); + const [modalVisible, setModalVisible] = useState(false); + const [form] = Form.useForm(); + const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 }); + const [search, setSearch] = useState(''); + const [isAdd, setIsAdd] = useState(false); // 新增/编辑标志 + + // 拉取所有用户 + const fetchAllUsers = async () => { + setLoading(true); + const res = await listUserByPageUsingPost({ + userQueryRequest: { + current: 1, + pageSize: 10000, // 假设不会超过1万用户 + }, + }); + if (res && res.code === 0 && res.data) { + setAllUsers(res.data.records || []); + } + setLoading(false); + }; + + // 前端过滤和分页 + const filterAndPaginate = (all: any[], keyword: string, page: number, pageSize: number) => { + let filtered = all; + if (keyword.trim()) { + filtered = all.filter(user => + (user.userName || '').toLowerCase().includes(keyword.trim().toLowerCase()) + ); + } + const total = filtered.length; + const start = (page - 1) * pageSize; + const end = start + pageSize; + return { + users: filtered.slice(start, end), + total, + }; + }; + + // 初始化和数据变动时处理 + useEffect(() => { + fetchAllUsers(); + }, []); + + useEffect(() => { + const { users, total } = filterAndPaginate(allUsers, search, pagination.current, pagination.pageSize); + setUsers(users); + setPagination(prev => ({ ...prev, total })); + }, [allUsers, search, pagination.current, pagination.pageSize]); + + // 搜索时重置到第一页 + const handleSearch = (value: string) => { + setSearch(value); + setPagination(prev => ({ ...prev, current: 1 })); + }; + + // 新增 + const handleAdd = () => { + setIsAdd(true); + setEditingUser(null); + setModalVisible(true); + form.resetFields(); + }; + + // 编辑 + const handleEdit = (record: any) => { + setIsAdd(false); + setEditingUser(record); + setModalVisible(true); + form.setFieldsValue({ + ...record, + }); + }; + + // 提交表单 + const handleOk = async () => { + const values = await form.validateFields(); + if (isAdd) { + const res = await addUserUsingPost({ ...values }); + if (res && res.code === 0) { + message.success('新增成功'); + setModalVisible(false); + fetchAllUsers(); + } else { + message.error(res?.message || '新增失败'); + } + } else { + const res = await updateUserUsingPost({ ...editingUser, ...values }); + if (res && res.code === 0) { + message.success('更新成功'); + setModalVisible(false); + fetchAllUsers(); + } else { + message.error(res?.message || '更新失败'); + } + } + }; + + // 删除 + const handleDelete = async (id: number) => { + const res = await deleteUserUsingPost({ id }); + if (res && res.code === 0) { + message.success('删除成功'); + fetchAllUsers(); + } else { + message.error(res?.message || '删除失败'); + } + }; + + const columns = [ + { + title: 'ID', + dataIndex: 'id', + width: 60, + align: 'center', + }, + { + title: '头像', + dataIndex: 'userAvatar', + width: 80, + align: 'center', + render: (avatar: string) => , + }, + { + title: '用户名', + dataIndex: 'userName', + width: 160, + align: 'center', + }, + { + title: '账号', + dataIndex: 'userAccount', + width: 160, + align: 'center', + }, + { + title: '角色', + dataIndex: 'userRole', + width: 100, + align: 'center', + render: (role: string) => { + if (role === 'admin') return 管理员; + if (role === 'ban') return 禁用; + return 普通用户; + }, + }, + { + title: '简介', + dataIndex: 'userProfile', + width: 200, + align: 'center', + ellipsis: true, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 180, + align: 'center', + }, + { + title: '操作', + key: 'action', + width: 160, + align: 'center', + render: (_: any, record: any) => ( + + + handleDelete(record.id)}> + + + + ), + }, + ]; + + return ( + +
+ + handleSearch(e.target.value)} + onSearch={handleSearch} + /> +
+
setPagination(prev => ({ ...prev, current: page, pageSize })), + }} + scroll={{ x: 1000 }} + /> + setModalVisible(false)} + destroyOnClose + width={480} + bodyStyle={{ padding: 24 }} + > +
+ + + + + + + + + + + + + + + + {isAdd && ( + + + + )} + +
+ + ); +}; + +export default UserManage;