import React, { useEffect, useMemo, useState } from 'react';
import { Button, Form, Input, InputNumber, Modal, Popconfirm, Select, Space, Switch, Table, Tag, Typography, message } from 'antd';
import { DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined, AppstoreOutlined } from '@ant-design/icons';
import { SycmCard } from '../../components/Common';
import {
createDepartment,
deleteDepartment,
getDepartmentPagePermissions,
getDepartments,
updateDepartment,
updateDepartmentPagePermissions,
} from '../../api/admin';
const { Text } = Typography;
const DEPARTMENT_SOURCE_META = {
dingtalk: { color: 'blue', label: '钉钉同步' },
hr: { color: 'cyan', label: 'HR同步' },
local: { color: 'default', label: '本地' },
};
const DepartmentManagement = () => {
const [departments, setDepartments] = useState([]);
const [loading, setLoading] = useState(false);
const [saving, setSaving] = useState(false);
const [permissionSaving, setPermissionSaving] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const [permissionVisible, setPermissionVisible] = useState(false);
const [editingDepartment, setEditingDepartment] = useState(null);
const [permissionDepartment, setPermissionDepartment] = useState(null);
const [pagePermissions, setPagePermissions] = useState([]);
const [form] = Form.useForm();
const departmentMap = useMemo(() => {
return departments.reduce((acc, item) => {
acc[item.id] = item;
return acc;
}, {});
}, [departments]);
const fetchDepartments = async () => {
try {
setLoading(true);
const data = await getDepartments();
setDepartments(Array.isArray(data) ? data : []);
} catch (error) {
message.error(error.response?.data?.error || '获取部门列表失败');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchDepartments();
}, []);
const openCreateModal = () => {
setEditingDepartment(null);
form.resetFields();
form.setFieldsValue({
sort: 0,
status: 'active',
});
setModalVisible(true);
};
const openEditModal = (record) => {
setEditingDepartment(record);
form.setFieldsValue({
name: record.name,
code: record.code,
parentId: record.parentId || undefined,
sort: record.sort,
status: record.status,
});
setModalVisible(true);
};
const handleSave = async () => {
try {
const values = await form.validateFields();
setSaving(true);
if (editingDepartment) {
await updateDepartment(editingDepartment.id, values);
message.success('部门信息已更新');
} else {
await createDepartment(values);
message.success('部门已创建');
}
setModalVisible(false);
fetchDepartments();
} catch (error) {
if (!error?.errorFields) {
message.error(error.response?.data?.error || '保存部门失败');
}
} finally {
setSaving(false);
}
};
const handleDelete = async (id) => {
try {
await deleteDepartment(id);
message.success('部门已删除');
fetchDepartments();
} catch (error) {
message.error(error.response?.data?.error || '删除部门失败');
}
};
const openPermissionModal = async (record) => {
try {
setPermissionDepartment(record);
const data = await getDepartmentPagePermissions(record.id);
setPagePermissions(Array.isArray(data.permissions) ? data.permissions : []);
setPermissionVisible(true);
} catch (error) {
message.error(error.response?.data?.error || '获取部门功能页面失败');
}
};
const handlePermissionToggle = (pageKey, allowed) => {
setPagePermissions((prev) =>
prev.map((item) => (item.pageKey === pageKey ? { ...item, allowed } : item))
);
};
const handleSavePermissions = async () => {
if (!permissionDepartment) {
return;
}
try {
setPermissionSaving(true);
await updateDepartmentPagePermissions(permissionDepartment.id, {
permissions: pagePermissions.map((item) => ({
pageKey: item.pageKey,
allowed: item.allowed,
})),
});
message.success('部门功能页面权限已更新');
setPermissionVisible(false);
} catch (error) {
message.error(error.response?.data?.error || '更新部门功能页面失败');
} finally {
setPermissionSaving(false);
}
};
const columns = [
{
title: '部门名称',
dataIndex: 'name',
width: 220,
},
{
title: '编码',
dataIndex: 'code',
width: 160,
},
{
title: '上级部门',
dataIndex: 'parentId',
width: 180,
render: (value) => (value && departmentMap[value] ? departmentMap[value].name : '顶级部门'),
},
{
title: '来源',
dataIndex: 'source',
width: 120,
render: (value) => {
const sourceMeta = DEPARTMENT_SOURCE_META[value] || { color: 'default', label: value || '未知' };
return