| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- import React, { useState, useEffect } from 'react';
- import {
- Layout, Menu, Button, Table, Space,
- Form, Input, Select, TreeSelect, 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, Tree
- } from 'antd';
- import 'dayjs/locale/zh-cn';
- import {
- organizationAPI,
- } from './api.ts';
- import type { Organization } from '../share/types.ts';
-
- const { Title } = Typography;
- // 系统管理页面 - 机构管理
- export const OrganizationPage = () => {
- const [organizations, setOrganizations] = useState<Organization[]>([]);
- const [treeData, setTreeData] = useState<Organization[]>([]);
- const [loading, setLoading] = useState(false);
- const [modalVisible, setModalVisible] = useState(false);
- const [currentOrg, setCurrentOrg] = useState<Organization | null>(null);
- const [form] = Form.useForm();
- // 加载机构数据
- useEffect(() => {
- loadOrganizations();
- }, []);
- const loadOrganizations = async () => {
- setLoading(true);
- try {
- const res = await organizationAPI.getOrganizations();
- setTreeData(res.data);
- // 将树形数据转换为扁平列表
- const flattenOrganizations = flattenTree(res.data);
- setOrganizations(flattenOrganizations);
- } catch (err) {
- message.error('加载机构数据失败');
- console.error(err);
- } finally {
- setLoading(false);
- }
- };
- // 树形数据扁平化
- // 转换Organization为TreeSelect需要的格式
- const convertToTreeData = (orgs: Organization[]): Array<{value: string; title: string; children?: any}> => {
- return orgs.map(org => ({
- value: String(org.id),
- title: org.name,
- children: org.children ? convertToTreeData(org.children) : undefined,
- ...org
- }));
- };
- const flattenTree = (tree: Organization[]): Organization[] => {
- return tree.reduce((acc, node) => {
- acc.push({
- id: node.id,
- name: node.name,
- code: node.code,
- parentId: node.parentId,
- description: node.description
- });
- if (node.children) {
- acc.push(...flattenTree(node.children));
- }
- return acc;
- }, [] as Organization[]);
- };
- // 打开创建机构弹窗
- const handleCreate = () => {
- setCurrentOrg(null);
- setModalVisible(true);
- form.resetFields();
- };
- // 打开编辑机构弹窗
- const handleEdit = (record: Organization) => {
- setCurrentOrg(record);
- setModalVisible(true);
- form.setFieldsValue(record);
- };
- // 删除机构
- const handleDelete = async (id: number) => {
- Modal.confirm({
- title: '确认删除',
- content: '确定要删除该机构吗?',
- onOk: async () => {
- try {
- await organizationAPI.deleteOrganization(id);
- message.success('删除成功');
- loadOrganizations();
- } catch (err) {
- message.error('删除失败');
- }
- }
- });
- };
- // 提交表单
- const handleSubmit = async () => {
- try {
- const values = await form.validateFields();
- if (currentOrg?.id) {
- // 更新机构
- await organizationAPI.updateOrganization(currentOrg.id, values);
- message.success('更新成功');
- } else {
- // 创建机构
- await organizationAPI.createOrganization(values);
- message.success('创建成功');
- }
- setModalVisible(false);
- loadOrganizations();
- } catch (err) {
- console.error(err);
- }
- };
- const columns = [
- {
- title: '机构名称',
- dataIndex: 'name',
- key: 'name',
- },
- {
- title: '机构编码',
- dataIndex: 'code',
- key: 'code',
- },
- {
- title: '描述',
- dataIndex: 'description',
- key: 'description',
- },
- {
- title: '操作',
- key: 'action',
- render: (_: any, record: any) => (
- <Space size="middle">
- <Button size="small" onClick={() => handleEdit(record)}>
- 编辑
- </Button>
- <Button
- size="small"
- danger
- onClick={() => handleDelete(record.id)}
- >
- 删除
- </Button>
- </Space>
- ),
- },
- ];
- return (
- <div>
- <Title level={2}>机构管理</Title>
-
- <div className="bg-white rounded-lg shadow p-6">
- <div className="flex justify-between mb-4">
- <Button type="primary" onClick={handleCreate}>
- 新增机构
- </Button>
- </div>
- <Tabs defaultActiveKey="1">
- <Tabs.TabPane tab="树形展示" key="1">
- <TreeSelect
- treeData={treeData}
- placeholder="请选择机构"
- treeDefaultExpandAll
- className="w-full"
- dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
- fieldNames={{ label: 'name', value: 'id', children: 'children' }}
- onSelect={(value, node) => {
- const org = organizations.find(o => o.id === value);
- if (org) handleEdit(org);
- }}
- />
- </Tabs.TabPane>
- <Tabs.TabPane tab="表格展示" key="2">
- <Table
- dataSource={organizations}
- rowKey="id"
- loading={loading}
- pagination={false}
- columns={columns}
- />
- </Tabs.TabPane>
- </Tabs>
- </div>
- {/* 新增/编辑弹窗 */}
- <Modal
- title={currentOrg?.id ? '编辑机构' : '新增机构'}
- open={modalVisible}
- onOk={handleSubmit}
- onCancel={() => setModalVisible(false)}
- confirmLoading={loading}
- >
- <Form form={form} layout="vertical">
- <Form.Item
- name="name"
- label="机构名称"
- rules={[{ required: true, message: '请输入机构名称' }]}
- >
- <Input placeholder="请输入机构名称" />
- </Form.Item>
- <Form.Item
- name="code"
- label="机构编码"
- rules={[{ required: true, message: '请输入机构编码' }]}
- >
- <Input placeholder="请输入机构编码" />
- </Form.Item>
- <Form.Item
- name="parentId"
- label="上级机构"
- >
- <TreeSelect
- treeData={treeData}
- placeholder="请选择上级机构"
- allowClear
- treeDefaultExpandAll
- dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
- />
- </Form.Item>
- <Form.Item
- name="description"
- label="机构描述"
- >
- <Input.TextArea placeholder="请输入机构描述" rows={3} />
- </Form.Item>
- </Form>
- </Modal>
- </div>
- );
- };
|