Initial commit: ERP system with advance verification fixes
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Card, Typography, Table, Button, Space, Modal, Form, Select, Input, message, Tag, Steps, Divider, Switch, Badge } from 'antd';
|
||||
import { EditOutlined, PlusOutlined, SettingOutlined, CheckCircleOutlined, ClockCircleOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
|
||||
const { Title, Paragraph, Text } = Typography;
|
||||
const { Option } = Select;
|
||||
|
||||
interface ProcessNode {
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
roleName: string;
|
||||
order: number;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
const ProcessManagement: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [editingNode, setEditingNode] = useState<ProcessNode | null>(null);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
// 流程节点数据
|
||||
const [nodes, setNodes] = useState<ProcessNode[]>([
|
||||
{ id: '1', name: '发起申请', role: 'applicant', roleName: '申请人(任意角色)', order: 1, enabled: true },
|
||||
{ id: '2', name: '审批', role: 'admin', roleName: '管理员', order: 2, enabled: true },
|
||||
{ id: '3', name: '执行付款', role: 'admin', roleName: '管理员', order: 3, enabled: true },
|
||||
]);
|
||||
|
||||
// 角色选项
|
||||
const roleOptions = [
|
||||
{ value: 'applicant', label: '申请人(任意角色)' },
|
||||
{ value: 'admin', label: '管理员' },
|
||||
{ value: 'finance', label: '财务专员' },
|
||||
{ value: 'manager', label: '项目经理' },
|
||||
];
|
||||
|
||||
// 流程类型
|
||||
const processTypes = [
|
||||
{ key: 'advance', name: '预支申请', description: '员工预支款项申请流程' },
|
||||
{ key: 'reimbursement', name: '报销申请', description: '费用报销申请流程' },
|
||||
{ key: 'payment', name: '付款申请', description: '供应商付款申请流程' },
|
||||
{ key: 'verification', name: '核销申请', description: '单据核销申请流程' },
|
||||
];
|
||||
|
||||
const handleEdit = (node: ProcessNode) => {
|
||||
setEditingNode(node);
|
||||
form.setFieldsValue({
|
||||
role: node.role
|
||||
});
|
||||
setModalVisible(true);
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
form.validateFields().then(values => {
|
||||
if (editingNode) {
|
||||
const updatedNodes = nodes.map(n => {
|
||||
if (n.id === editingNode.id) {
|
||||
const roleOption = roleOptions.find(r => r.value === values.role);
|
||||
return { ...n, role: values.role, roleName: roleOption?.label || values.role };
|
||||
}
|
||||
return n;
|
||||
});
|
||||
setNodes(updatedNodes);
|
||||
message.success('节点配置已保存');
|
||||
}
|
||||
setModalVisible(false);
|
||||
});
|
||||
};
|
||||
|
||||
const getStatusTag = (enabled: boolean) => {
|
||||
return enabled ? <Tag color="success">已启用</Tag> : <Tag color="default">已禁用</Tag>;
|
||||
};
|
||||
|
||||
const getStepStatus = (order: number) => {
|
||||
if (order === 1) return 'finish';
|
||||
if (order === 2) return 'process';
|
||||
return 'wait';
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '顺序',
|
||||
dataIndex: 'order',
|
||||
key: 'order',
|
||||
width: 80,
|
||||
render: (v: number) => <Badge count={v} style={{ backgroundColor: '#1890ff' }} />
|
||||
},
|
||||
{ title: '节点名称', dataIndex: 'name', key: 'name', width: 150 },
|
||||
{
|
||||
title: '执行角色',
|
||||
dataIndex: 'roleName',
|
||||
key: 'roleName',
|
||||
render: (v: string, r: ProcessNode) => (
|
||||
<Space>
|
||||
<Tag color={r.role === 'admin' ? 'blue' : r.role === 'finance' ? 'green' : 'default'}>
|
||||
{v}
|
||||
</Tag>
|
||||
</Space>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'enabled',
|
||||
key: 'enabled',
|
||||
width: 100,
|
||||
render: (v: boolean) => getStatusTag(v)
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 120,
|
||||
render: (_: any, record: ProcessNode) => (
|
||||
<Space>
|
||||
<Button size="small" icon={<EditOutlined />} onClick={() => handleEdit(record)}>
|
||||
编辑
|
||||
</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ padding: 24 }}>
|
||||
<div style={{ marginBottom: 24 }}>
|
||||
<Title level={3} style={{ marginBottom: 8 }}>流程管理</Title>
|
||||
<Paragraph type="secondary">
|
||||
配置财务申请的审批流程节点,支持自定义执行角色
|
||||
</Paragraph>
|
||||
</div>
|
||||
|
||||
{/* 流程图示 */}
|
||||
<Card title="当前流程图" style={{ marginBottom: 24 }}>
|
||||
<Steps current={1} style={{ marginTop: 16 }}>
|
||||
{nodes.filter(n => n.enabled).map((node, index) => (
|
||||
<Steps.Step
|
||||
key={node.id}
|
||||
title={node.name}
|
||||
description={node.roleName}
|
||||
status={getStepStatus(node.order)}
|
||||
icon={
|
||||
node.order === 1 ? <PlusOutlined /> :
|
||||
node.order === 2 ? <CheckCircleOutlined /> :
|
||||
<SyncOutlined />
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</Steps>
|
||||
<Divider />
|
||||
<Paragraph type="secondary" style={{ marginBottom: 0 }}>
|
||||
<Text strong>说明:</Text>
|
||||
当前流程为「申请人 → 管理员审批 → 管理员执行」,后续可在下方修改执行角色为财务专员。
|
||||
</Paragraph>
|
||||
</Card>
|
||||
|
||||
{/* 节点配置表 */}
|
||||
<Card title="节点配置">
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={nodes}
|
||||
rowKey="id"
|
||||
pagination={false}
|
||||
size="middle"
|
||||
/>
|
||||
</Card>
|
||||
|
||||
{/* 流程类型说明 */}
|
||||
<Card title="适用流程" style={{ marginTop: 24 }}>
|
||||
<Table
|
||||
columns={[
|
||||
{ title: '流程类型', dataIndex: 'name', key: 'name', width: 150 },
|
||||
{ title: '说明', dataIndex: 'description', key: 'description' },
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
width: 100,
|
||||
render: () => <Tag color="success">已启用</Tag>
|
||||
}
|
||||
]}
|
||||
dataSource={processTypes}
|
||||
rowKey="key"
|
||||
pagination={false}
|
||||
size="middle"
|
||||
/>
|
||||
</Card>
|
||||
|
||||
{/* 编辑节点弹窗 */}
|
||||
<Modal
|
||||
title={`编辑节点:${editingNode?.name}`}
|
||||
open={modalVisible}
|
||||
onCancel={() => setModalVisible(false)}
|
||||
onOk={handleSave}
|
||||
width={500}
|
||||
>
|
||||
<Form form={form} layout="vertical">
|
||||
<Form.Item label="节点名称">
|
||||
<Input value={editingNode?.name} disabled />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="role"
|
||||
label="执行角色"
|
||||
rules={[{ required: true, message: '请选择执行角色' }]}
|
||||
>
|
||||
<Select placeholder="选择执行角色">
|
||||
{roleOptions.map(opt => (
|
||||
<Option key={opt.value} value={opt.value}>{opt.label}</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<div style={{ padding: 12, background: '#fffbe6', borderRadius: 6, marginTop: 16 }}>
|
||||
<Text type="warning">
|
||||
⚠️ 修改执行角色会影响所有使用此流程的申请。建议在公司有财务专员后再将执行节点改为财务角色。
|
||||
</Text>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProcessManagement;
|
||||
Reference in New Issue
Block a user