Переглянути джерело

创建了3个新文件:

pages_dashboard.tsx (系统仪表盘功能)
pages_users.tsx (用户管理功能)
pages_file_library.tsx (文件库管理功能)
更新了所有引用:

修改了web_app.tsx中的导入语句
确保路由配置正确指向新文件
原pages_sys.tsx文件已不再使用,可以安全删除
yourname 6 місяців тому
батько
коміт
d0d88ab950

+ 44 - 0
client/admin/pages_dashboard.tsx

@@ -0,0 +1,44 @@
+import React from 'react';
+import { 
+  Card, Row, Col, Typography, Statistic
+} from 'antd';
+
+const { Title } = Typography;
+
+// 仪表盘页面
+export const DashboardPage = () => {
+  return (
+    <div>
+      <Title level={2}>仪表盘</Title>
+      <Row gutter={16}>
+        <Col span={8}>
+          <Card>
+            <Statistic
+              title="活跃用户"
+              value={112893}
+              loading={false}
+            />
+          </Card>
+        </Col>
+        <Col span={8}>
+          <Card>
+            <Statistic
+              title="系统消息"
+              value={93}
+              loading={false}
+            />
+          </Card>
+        </Col>
+        <Col span={8}>
+          <Card>
+            <Statistic
+              title="在线用户"
+              value={1128}
+              loading={false}
+            />
+          </Card>
+        </Col>
+      </Row>
+    </div>
+  );
+};

+ 9 - 331
client/admin/pages_sys.tsx → client/admin/pages_file_library.tsx

@@ -1,11 +1,8 @@
 import React, { useState, useEffect } from 'react';
 import React, { useState, useEffect } from 'react';
 import { 
 import { 
-  Layout, Menu, Button, Table, Space,
-  Form, Input, Select, message, Modal,
-  Card, Spin, Row, Col, Breadcrumb, Avatar,
-  Dropdown, ConfigProvider, theme, Typography,
-  Switch, Badge, Image, Upload, Divider, Descriptions,
-  Popconfirm, Tag, Statistic, DatePicker, Radio, Progress, Tabs, List, Alert, Collapse, Empty, Drawer
+  Button, Table, Space, Form, Input, Select, 
+  message, Modal, Card, Typography, Tag, Popconfirm,
+  Tabs, Image, Upload, Descriptions
 } from 'antd';
 } from 'antd';
 import {
 import {
   UploadOutlined,
   UploadOutlined,
@@ -14,336 +11,17 @@ import {
   FileWordOutlined,
   FileWordOutlined,
   FilePdfOutlined,
   FilePdfOutlined,
   FileOutlined,
   FileOutlined,
-} from '@ant-design/icons';   
-import { 
-  useQuery,
-} from '@tanstack/react-query';
+} from '@ant-design/icons';
+import { useQuery } from '@tanstack/react-query';
 import dayjs from 'dayjs';
 import dayjs from 'dayjs';
-import weekday from 'dayjs/plugin/weekday';
-import localeData from 'dayjs/plugin/localeData';
-import { uploadMinIOWithPolicy,uploadOSSWithPolicy } from '@d8d-appcontainer/api';
+import { uploadMinIOWithPolicy, uploadOSSWithPolicy } from '@d8d-appcontainer/api';
 import type { MinioUploadPolicy, OSSUploadPolicy } from '@d8d-appcontainer/types';
 import type { MinioUploadPolicy, OSSUploadPolicy } from '@d8d-appcontainer/types';
-import 'dayjs/locale/zh-cn';
-import type { 
-  FileLibrary, FileCategory
-} from '../share/types.ts';
-
-import {
-   OssType,
-} from '../share/types.ts';
-
-
-import { FileAPI , UserAPI } from './api/index.ts';
-
-
-// 配置 dayjs 插件
-dayjs.extend(weekday);
-dayjs.extend(localeData);
-
-// 设置 dayjs 语言
-dayjs.locale('zh-cn');
+import { FileAPI } from './api/index.ts';
+import type { FileLibrary, FileCategory } from '../share/types.ts';
+import { OssType } from '../share/types.ts';
 
 
 const { Title } = Typography;
 const { Title } = Typography;
 
 
-
-// 仪表盘页面
-export const DashboardPage = () => {
-  return (
-    <div>
-      <Title level={2}>仪表盘</Title>
-      <Row gutter={16}>
-        <Col span={8}>
-          <Card>
-            <Statistic
-              title="活跃用户"
-              value={112893}
-              loading={false}
-            />
-          </Card>
-        </Col>
-        <Col span={8}>
-          <Card>
-            <Statistic
-              title="系统消息"
-              value={93}
-              loading={false}
-            />
-          </Card>
-        </Col>
-        <Col span={8}>
-          <Card>
-            <Statistic
-              title="在线用户"
-              value={1128}
-              loading={false}
-            />
-          </Card>
-        </Col>
-      </Row>
-    </div>
-  );
-};
-
-// 用户管理页面
-export const UsersPage = () => {
-  const [searchParams, setSearchParams] = useState({
-    page: 1,
-    limit: 10,
-    search: ''
-  });
-  const [modalVisible, setModalVisible] = useState(false);
-  const [modalTitle, setModalTitle] = useState('');
-  const [editingUser, setEditingUser] = useState<any>(null);
-  const [form] = Form.useForm();
-
-  const { data: usersData, isLoading, refetch } = useQuery({
-    queryKey: ['users', searchParams],
-    queryFn: async () => {
-      return await UserAPI.getUsers(searchParams);
-    }
-  });
-
-  const users = usersData?.data || [];
-  const pagination = {
-    current: searchParams.page,
-    pageSize: searchParams.limit,
-    total: usersData?.pagination?.total || 0
-  };
-
-  // 处理搜索
-  const handleSearch = (values: any) => {
-    setSearchParams(prev => ({
-      ...prev,
-      search: values.search || '',
-      page: 1
-    }));
-  };
-
-  // 处理分页变化
-  const handleTableChange = (newPagination: any) => {
-    setSearchParams(prev => ({
-      ...prev,
-      page: newPagination.current,
-      limit: newPagination.pageSize
-    }));
-  };
-
-  // 打开创建用户模态框
-  const showCreateModal = () => {
-    setModalTitle('创建用户');
-    setEditingUser(null);
-    form.resetFields();
-    setModalVisible(true);
-  };
-
-  // 打开编辑用户模态框
-  const showEditModal = (user: any) => {
-    setModalTitle('编辑用户');
-    setEditingUser(user);
-    form.setFieldsValue(user);
-    setModalVisible(true);
-  };
-
-  // 处理模态框确认
-  const handleModalOk = async () => {
-    try {
-      const values = await form.validateFields();
-      
-      if (editingUser) {
-        // 编辑用户
-        await UserAPI.updateUser(editingUser.id, values);
-        message.success('用户更新成功');
-      } else {
-        // 创建用户
-        await UserAPI.createUser(values);
-        message.success('用户创建成功');
-      }
-      
-      setModalVisible(false);
-      form.resetFields();
-      refetch(); // 刷新用户列表
-    } catch (error) {
-      console.error('表单提交失败:', error);
-      message.error('操作失败,请重试');
-    }
-  };
-
-  // 处理删除用户
-  const handleDelete = async (id: number) => {
-    try {
-      await UserAPI.deleteUser(id);
-      message.success('用户删除成功');
-      refetch(); // 刷新用户列表
-    } catch (error) {
-      console.error('删除用户失败:', error);
-      message.error('删除失败,请重试');
-    }
-  };
-  
-  const columns = [
-    {
-      title: '用户名',
-      dataIndex: 'username',
-      key: 'username',
-    },
-    {
-      title: '昵称',
-      dataIndex: 'nickname',
-      key: 'nickname',
-    },
-    {
-      title: '邮箱',
-      dataIndex: 'email',
-      key: 'email',
-    },
-    {
-      title: '角色',
-      dataIndex: 'role',
-      key: 'role',
-      render: (role: string) => (
-        <Tag color={role === 'admin' ? 'red' : 'blue'}>
-          {role === 'admin' ? '管理员' : '普通用户'}
-        </Tag>
-      ),
-    },
-    {
-      title: '创建时间',
-      dataIndex: 'created_at',
-      key: 'created_at',
-      render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm:ss'),
-    },
-    {
-      title: '操作',
-      key: 'action',
-      render: (_: any, record: any) => (
-        <Space size="middle">
-          <Button type="link" onClick={() => showEditModal(record)}>
-            编辑
-          </Button>
-          <Popconfirm
-            title="确定要删除此用户吗?"
-            onConfirm={() => handleDelete(record.id)}
-            okText="确定"
-            cancelText="取消"
-          >
-            <Button type="link" danger>
-              删除
-            </Button>
-          </Popconfirm>
-        </Space>
-      ),
-    },
-  ];
-  
-  return (
-    <div>
-      <Title level={2}>用户管理</Title>
-      <Card>
-        <Form layout="inline" onFinish={handleSearch} style={{ marginBottom: 16 }}>
-          <Form.Item name="search" label="搜索">
-            <Input placeholder="用户名/昵称/邮箱" allowClear />
-          </Form.Item>
-          <Form.Item>
-            <Space>
-              <Button type="primary" htmlType="submit">
-                搜索
-              </Button>
-              <Button type="primary" onClick={showCreateModal}>
-                创建用户
-              </Button>
-            </Space>
-          </Form.Item>
-        </Form>
-
-        <Table
-          columns={columns}
-          dataSource={users}
-          loading={isLoading}
-          rowKey="id"
-          pagination={{
-            ...pagination,
-            showSizeChanger: true,
-            showQuickJumper: true,
-            showTotal: (total) => `共 ${total} 条记录`
-          }}
-          onChange={handleTableChange}
-        />
-      </Card>
-
-      {/* 创建/编辑用户模态框 */}
-      <Modal
-        title={modalTitle}
-        open={modalVisible}
-        onOk={handleModalOk}
-        onCancel={() => {
-          setModalVisible(false);
-          form.resetFields();
-        }}
-        width={600}
-      >
-        <Form
-          form={form}
-          layout="vertical"
-        >
-          <Form.Item
-            name="username"
-            label="用户名"
-            rules={[
-              { required: true, message: '请输入用户名' },
-              { min: 3, message: '用户名至少3个字符' }
-            ]}
-          >
-            <Input placeholder="请输入用户名" />
-          </Form.Item>
-
-          <Form.Item
-            name="nickname"
-            label="昵称"
-            rules={[{ required: true, message: '请输入昵称' }]}
-          >
-            <Input placeholder="请输入昵称" />
-          </Form.Item>
-
-          <Form.Item
-            name="email"
-            label="邮箱"
-            rules={[
-              { required: true, message: '请输入邮箱' },
-              { type: 'email', message: '请输入有效的邮箱地址' }
-            ]}
-          >
-            <Input placeholder="请输入邮箱" />
-          </Form.Item>
-
-          {!editingUser && (
-            <Form.Item
-              name="password"
-              label="密码"
-              rules={[
-                { required: true, message: '请输入密码' },
-                { min: 6, message: '密码至少6个字符' }
-              ]}
-            >
-              <Input.Password placeholder="请输入密码" />
-            </Form.Item>
-          )}
-
-          <Form.Item
-            name="role"
-            label="角色"
-            rules={[{ required: true, message: '请选择角色' }]}
-          >
-            <Select placeholder="请选择角色">
-              <Select.Option value="user">普通用户</Select.Option>
-              <Select.Option value="admin">管理员</Select.Option>
-            </Select>
-          </Form.Item>
-        </Form>
-      </Modal>
-    </div>
-  );
-};
-
 // 文件库管理页面
 // 文件库管理页面
 export const FileLibraryPage = () => {
 export const FileLibraryPage = () => {
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);

+ 270 - 0
client/admin/pages_users.tsx

@@ -0,0 +1,270 @@
+import React, { useState } from 'react';
+import { 
+  Button, Table, Space, Form, Input, Select, 
+  message, Modal, Card, Typography, Tag, Popconfirm 
+} from 'antd';
+import { useQuery } from '@tanstack/react-query';
+import dayjs from 'dayjs';
+import { UserAPI } from './api/index.ts';
+
+const { Title } = Typography;
+
+// 用户管理页面
+export const UsersPage = () => {
+  const [searchParams, setSearchParams] = useState({
+    page: 1,
+    limit: 10,
+    search: ''
+  });
+  const [modalVisible, setModalVisible] = useState(false);
+  const [modalTitle, setModalTitle] = useState('');
+  const [editingUser, setEditingUser] = useState<any>(null);
+  const [form] = Form.useForm();
+
+  const { data: usersData, isLoading, refetch } = useQuery({
+    queryKey: ['users', searchParams],
+    queryFn: async () => {
+      return await UserAPI.getUsers(searchParams);
+    }
+  });
+
+  const users = usersData?.data || [];
+  const pagination = {
+    current: searchParams.page,
+    pageSize: searchParams.limit,
+    total: usersData?.pagination?.total || 0
+  };
+
+  // 处理搜索
+  const handleSearch = (values: any) => {
+    setSearchParams(prev => ({
+      ...prev,
+      search: values.search || '',
+      page: 1
+    }));
+  };
+
+  // 处理分页变化
+  const handleTableChange = (newPagination: any) => {
+    setSearchParams(prev => ({
+      ...prev,
+      page: newPagination.current,
+      limit: newPagination.pageSize
+    }));
+  };
+
+  // 打开创建用户模态框
+  const showCreateModal = () => {
+    setModalTitle('创建用户');
+    setEditingUser(null);
+    form.resetFields();
+    setModalVisible(true);
+  };
+
+  // 打开编辑用户模态框
+  const showEditModal = (user: any) => {
+    setModalTitle('编辑用户');
+    setEditingUser(user);
+    form.setFieldsValue(user);
+    setModalVisible(true);
+  };
+
+  // 处理模态框确认
+  const handleModalOk = async () => {
+    try {
+      const values = await form.validateFields();
+      
+      if (editingUser) {
+        // 编辑用户
+        await UserAPI.updateUser(editingUser.id, values);
+        message.success('用户更新成功');
+      } else {
+        // 创建用户
+        await UserAPI.createUser(values);
+        message.success('用户创建成功');
+      }
+      
+      setModalVisible(false);
+      form.resetFields();
+      refetch(); // 刷新用户列表
+    } catch (error) {
+      console.error('表单提交失败:', error);
+      message.error('操作失败,请重试');
+    }
+  };
+
+  // 处理删除用户
+  const handleDelete = async (id: number) => {
+    try {
+      await UserAPI.deleteUser(id);
+      message.success('用户删除成功');
+      refetch(); // 刷新用户列表
+    } catch (error) {
+      console.error('删除用户失败:', error);
+      message.error('删除失败,请重试');
+    }
+  };
+  
+  const columns = [
+    {
+      title: '用户名',
+      dataIndex: 'username',
+      key: 'username',
+    },
+    {
+      title: '昵称',
+      dataIndex: 'nickname',
+      key: 'nickname',
+    },
+    {
+      title: '邮箱',
+      dataIndex: 'email',
+      key: 'email',
+    },
+    {
+      title: '角色',
+      dataIndex: 'role',
+      key: 'role',
+      render: (role: string) => (
+        <Tag color={role === 'admin' ? 'red' : 'blue'}>
+          {role === 'admin' ? '管理员' : '普通用户'}
+        </Tag>
+      ),
+    },
+    {
+      title: '创建时间',
+      dataIndex: 'created_at',
+      key: 'created_at',
+      render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm:ss'),
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (_: any, record: any) => (
+        <Space size="middle">
+          <Button type="link" onClick={() => showEditModal(record)}>
+            编辑
+          </Button>
+          <Popconfirm
+            title="确定要删除此用户吗?"
+            onConfirm={() => handleDelete(record.id)}
+            okText="确定"
+            cancelText="取消"
+          >
+            <Button type="link" danger>
+              删除
+            </Button>
+          </Popconfirm>
+        </Space>
+      ),
+    },
+  ];
+  
+  return (
+    <div>
+      <Title level={2}>用户管理</Title>
+      <Card>
+        <Form layout="inline" onFinish={handleSearch} style={{ marginBottom: 16 }}>
+          <Form.Item name="search" label="搜索">
+            <Input placeholder="用户名/昵称/邮箱" allowClear />
+          </Form.Item>
+          <Form.Item>
+            <Space>
+              <Button type="primary" htmlType="submit">
+                搜索
+              </Button>
+              <Button type="primary" onClick={showCreateModal}>
+                创建用户
+              </Button>
+            </Space>
+          </Form.Item>
+        </Form>
+
+        <Table
+          columns={columns}
+          dataSource={users}
+          loading={isLoading}
+          rowKey="id"
+          pagination={{
+            ...pagination,
+            showSizeChanger: true,
+            showQuickJumper: true,
+            showTotal: (total) => `共 ${total} 条记录`
+          }}
+          onChange={handleTableChange}
+        />
+      </Card>
+
+      {/* 创建/编辑用户模态框 */}
+      <Modal
+        title={modalTitle}
+        open={modalVisible}
+        onOk={handleModalOk}
+        onCancel={() => {
+          setModalVisible(false);
+          form.resetFields();
+        }}
+        width={600}
+      >
+        <Form
+          form={form}
+          layout="vertical"
+        >
+          <Form.Item
+            name="username"
+            label="用户名"
+            rules={[
+              { required: true, message: '请输入用户名' },
+              { min: 3, message: '用户名至少3个字符' }
+            ]}
+          >
+            <Input placeholder="请输入用户名" />
+          </Form.Item>
+
+          <Form.Item
+            name="nickname"
+            label="昵称"
+            rules={[{ required: true, message: '请输入昵称' }]}
+          >
+            <Input placeholder="请输入昵称" />
+          </Form.Item>
+
+          <Form.Item
+            name="email"
+            label="邮箱"
+            rules={[
+              { required: true, message: '请输入邮箱' },
+              { type: 'email', message: '请输入有效的邮箱地址' }
+            ]}
+          >
+            <Input placeholder="请输入邮箱" />
+          </Form.Item>
+
+          {!editingUser && (
+            <Form.Item
+              name="password"
+              label="密码"
+              rules={[
+                { required: true, message: '请输入密码' },
+                { min: 6, message: '密码至少6个字符' }
+              ]}
+            >
+              <Input.Password placeholder="请输入密码" />
+            </Form.Item>
+          )}
+
+          <Form.Item
+            name="role"
+            label="角色"
+            rules={[{ required: true, message: '请选择角色' }]}
+          >
+            <Select placeholder="请选择角色">
+              <Select.Option value="user">普通用户</Select.Option>
+              <Select.Option value="admin">管理员</Select.Option>
+            </Select>
+          </Form.Item>
+        </Form>
+      </Modal>
+    </div>
+  );
+};

+ 7 - 3
client/admin/web_app.tsx

@@ -55,10 +55,14 @@ import {
 } from './hooks_sys.tsx';
 } from './hooks_sys.tsx';
 
 
 import {
 import {
-  DashboardPage,
-  UsersPage,
+  DashboardPage
+} from './pages_dashboard.tsx';
+import {
+  UsersPage
+} from './pages_users.tsx';
+import {
   FileLibraryPage
   FileLibraryPage
-} from './pages_sys.tsx';
+} from './pages_file_library.tsx';
 import { KnowInfoPage } from './pages_know_info.tsx';
 import { KnowInfoPage } from './pages_know_info.tsx';
 import { MessagesPage } from './pages_messages.tsx';
 import { MessagesPage } from './pages_messages.tsx';
 import {SettingsPage } from './pages_settings.tsx';
 import {SettingsPage } from './pages_settings.tsx';