Initial commit: ERP system with advance verification fixes

This commit is contained in:
System Administrator
2026-03-25 23:55:36 +07:00
commit 563ca12d76
5920 changed files with 828689 additions and 0 deletions
@@ -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;