This commit is contained in:
linxd
2025-06-24 20:33:01 +08:00
14 changed files with 920 additions and 634 deletions

View File

@ -1,269 +1,204 @@
import React, { useRef } from 'react'; import React, { useEffect, useState } from 'react';
import ProTable from '@ant-design/pro-table'; import { Table, Form, Select, Button, Tag, message } from 'antd';
import type { ProColumns, ActionType } from '@ant-design/pro-table';
import { Form, Select, Button, Row, Col, Tag, Space, DatePicker, Input } from 'antd';
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons'; import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
;import { getApprovePage } from './services'
import type { ColumnsType } from 'antd/es/table';
const { RangePicker } = DatePicker;
// 示例数据 interface SupplierEntryReviewRecord {
const tableData = [ id: string;
{ accessWorkName: string; // 准入工作
id: 1, deptId: string; // 准入部门ID
name: '中山市合创展包装材料有限公司', accessTypeText: string; // 准入方式
region: '境内', reviewStatusText: string; // 流程状态
type: '民营企业', categoryName: string; // 品类名称
category: '船用物料,添加剂', startTime: string; // 申请时间
time: '2025-03-03 09:30', endTime: string;
status: '未开始', createTime: string; // 创建时间
result: '', updateTime: string; // 更新时间
}, [key: string]: any; // 允许有其它字段
{ }
id: 2,
name: '深圳市欧阳华斯电源有限公司',
region: '境内',
type: '民营企业',
category: '绳机物料',
time: '2025-03-03 09:30',
status: '未开始',
result: '',
},
{
id: 3,
name: '广东振兴塑胶机械有限公司',
region: '境内',
type: '民营企业',
category: '船用物料',
time: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 4,
name: '上海硕建建筑技术工程有限公司',
region: '境内',
type: '民营企业',
category: '绳机物料',
time: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 5,
name: '中山市合创展包装材料有限公司',
region: '境内',
type: '民营企业',
category: '船用物料',
time: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 6,
name: '深圳市欧阳华斯电源有限公司',
region: '境内',
type: '民营企业',
category: '绳机物料',
time: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 7,
name: '广东振兴塑胶机械有限公司',
region: '境内',
type: '民营企业',
category: '船用物料',
time: '2025-03-03 09:30',
status: '已结束',
result: '通过',
},
{
id: 8,
name: '上海硕建建筑技术工程有限公司',
region: '境内',
type: '民营企业',
category: '绳机物料',
time: '2025-03-03 09:30',
status: '已结束',
result: '驳回',
},
{
id: 9,
name: '广东振兴塑胶机械有限公司',
region: '境内',
type: '民营企业',
category: '船用物料',
time: '2025-03-03 09:30',
status: '已结束',
result: '驳回',
},
{
id: 10,
name: '上海硕建建筑技术工程有限公司',
region: '境内',
type: '民营企业',
category: '绳机物料',
time: '2025-03-03 09:30',
status: '已结束',
result: '驳回',
},
];
const statusColorMap: Record<string, string> = { const statusColorMap: Record<string, string> = {
'未开始': 'default', '未开始': 'default',
'进行中': 'processing', '进行中': 'processing',
'已结束': 'success', '已完成': 'success',
}; };
const resultColorMap: Record<string, string> = { const methodOptions = [
'通过': 'success', { label: '全部', value: '' },
'驳回': 'error', { label: '线上准入', value: '线上准入' },
}; { label: '线下准入', value: '线下准入' },
];
const columns: ProColumns<any>[] = [ const statusOptions = [
{ label: '全部', value: '' },
{ label: '未开始', value: '未开始' },
{ label: '进行中', value: '进行中' },
{ label: '已完成', value: '已完成' },
];
const deptOptions = [
{ label: '全部', value: '' },
{ label: '采购部', value: 'DEPT001' },
{ label: '业务部', value: 'DEPT002' },
];
const columns:ColumnsType<SupplierEntryReviewRecord> = [
{ {
title: '序号', title: '序号',
dataIndex: 'index', dataIndex: 'index',
valueType: 'index',
width: 48, width: 48,
align: 'center', align: 'center',
render: (_: any, __: any, idx: number) => idx + 1,
}, },
{ {
title: '供应商名称', title: '准入工作',
dataIndex: 'name', dataIndex: 'accessWorkName',
align: 'center', align: 'center',
ellipsis: true, ellipsis: true,
}, },
{ {
title: '境内/境外', title: '准入部门',
dataIndex: 'region', dataIndex: 'deptId',
align: 'center', align: 'center',
render: (deptId: string) => deptId === 'DEPT001' ? '采购部' : deptId === 'DEPT002' ? '业务部' : deptId,
}, },
{ {
title: '企业类型', title: '准入方式',
dataIndex: 'type', dataIndex: 'accessTypeText',
align: 'center', align: 'center',
}, },
{ {
title: '准入品类', title: '准入品类',
dataIndex: 'category', dataIndex: 'categoryName',
align: 'center', align: 'center',
ellipsis: true, ellipsis: true,
}, },
{ {
title: '提交时间', title: '开始时间',
dataIndex: 'time', dataIndex: 'startTime',
align: 'center',
},
{
title: '结束时间',
dataIndex: 'endTime',
align: 'center', align: 'center',
sorter: (a, b) => new Date(a.time).getTime() - new Date(b.time).getTime(),
}, },
{ {
title: '流程状态', title: '流程状态',
dataIndex: 'status', dataIndex: 'reviewStatusText',
align: 'center', align: 'center',
render: (_, record) => render: (text: string) => <Tag color={statusColorMap[text] || 'default'}>{text}</Tag>,
<Tag color={statusColorMap[record.status] || 'default'}>{record.status}</Tag>,
}, },
{
title: '审批结果',
dataIndex: 'result',
align: 'center',
render: (val: string) =>
val ? <Tag color={resultColorMap[val] || 'default'}>{val}</Tag> : null,
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
valueType: 'option',
render: (_, record) => (
<Space>
<a></a>
<a></a>
</Space>
),
},
];
// 查询项选项
const regionOptions = [
{ label: '请选择', value: '' },
{ label: '境内', value: '境内' },
{ label: '境外', value: '境外' },
];
const statusOptions = [
{ label: '请选择', value: '' },
{ label: '未开始', value: '未开始' },
{ label: '进行中', value: '进行中' },
{ label: '已结束', value: '已结束' },
];
const resultOptions = [
{ label: '请选择', value: '' },
{ label: '通过', value: '通过' },
{ label: '驳回', value: '驳回' },
]; ];
const SupplierCategoryEntry: React.FC = () => { const SupplierCategoryEntry: React.FC = () => {
const actionRef = useRef<ActionType>(); const [form] = Form.useForm();
const [data, setData] = useState<any[]>([]);
const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 });
const [loading, setLoading] = useState(false);
// 查询区渲染 // 查询数据
const searchFormRender = ( const fetchData = async (params = {}) => {
<Form layout="vertical"> setLoading(true);
<Row gutter={16}> try {
<Col span={5}> const res = await getApprovePage({
<Form.Item name="name" label="供应商名称"> pageNo: pagination.current,
<Input placeholder="请输入供应商名称关键字" allowClear /> pageSize: pagination.pageSize,
</Form.Item> ...form.getFieldsValue(),
</Col> ...params,
<Col span={3}> });
<Form.Item name="region" label="境内/境外"> if (res.code === 200) {
<Select options={regionOptions} allowClear /> setData(res.data.records);
</Form.Item> setPagination({
</Col> ...pagination,
<Col span={4}> current: res.data.current,
<Form.Item name="time" label="提交时间"> total: res.data.total,
<RangePicker style={{ width: '100%' }} /> pageSize: res.data.size,
</Form.Item> });
</Col> } else {
<Col span={3}> setData([]);
<Form.Item name="status" label="流程状态"> setPagination({ ...pagination, total: 0 });
<Select options={statusOptions} allowClear /> }
</Form.Item> } catch (err) {
</Col> message.error('获取数据失败');
<Col span={3}> } finally {
<Form.Item name="result" label="审批结果"> setLoading(false);
<Select options={resultOptions} allowClear /> }
</Form.Item> };
</Col>
<Col span={3} style={{ display: 'flex', alignItems: 'flex-end' }}> useEffect(() => {
<Space> fetchData({ pageNo: 1 });
<Button type="primary" icon={<SearchOutlined />}></Button> // eslint-disable-next-line
<Button icon={<ReloadOutlined />}></Button> }, []);
</Space>
</Col> // 表格分页切换
</Row> const handleTableChange = (pag: any) => {
</Form> setPagination({
); ...pagination,
current: pag.current,
pageSize: pag.pageSize,
});
fetchData({
pageNo: pag.current,
pageSize: pag.pageSize,
});
};
// 搜索
const handleSearch = () => {
setPagination({ ...pagination, current: 1 });
fetchData({ pageNo: 1 });
};
// 重置
const handleReset = () => {
form.resetFields();
setPagination({ ...pagination, current: 1 });
fetchData({ pageNo: 1 });
};
return ( return (
<div> <div>
{/* 查询表单 */} <Form
{searchFormRender} form={form}
{/* 表格 */} layout="inline"
<ProTable style={{ marginBottom: 16 }}
onFinish={handleSearch}
>
<Form.Item name="accessTypeText" label="准入方式">
<Select options={methodOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item name="deptId" label="准入部门">
<Select options={deptOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item name="reviewStatusText" label="流程状态">
<Select options={statusOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" icon={<SearchOutlined />} style={{ marginRight: 8 }}>
</Button>
<Button onClick={handleReset} icon={<ReloadOutlined />}>
</Button>
</Form.Item>
</Form>
<Table
columns={columns} columns={columns}
actionRef={actionRef} dataSource={data}
dataSource={tableData}
rowKey="id" rowKey="id"
search={false} loading={loading}
pagination={{ pagination={{
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
showQuickJumper: true, showQuickJumper: true,
showSizeChanger: true, showSizeChanger: true,
pageSize: 10,
total: 188,
current: 1,
}} }}
options={false} onChange={handleTableChange}
bordered bordered
/> />
</div> </div>

View File

@ -0,0 +1,16 @@
import request from '@/utils/request';
/**
* 品类准入审核列表
*/
interface getPageData {
accessType?: string;
approveStatus?: string;
categoryId?: string;
deptId?: string;
pageNo: string;
pageSize: string;
reviewStatus?: string;
[property: string]: any;
}
export const getApprovePage = (data: getPageData) => request.post('/coscoAccessWorkCategory/getPage', { data});

View File

@ -1,8 +1,9 @@
import React, { useRef } from 'react'; import React, { useState, useEffect } from 'react';
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
import type { ProColumns, ActionType } from '@ant-design/pro-table'; import type { ProColumns, ActionType } from '@ant-design/pro-table';
import { Form, Select, Button, Row, Col, Tag, Space, DatePicker, Input } from 'antd'; import { Form, Select, Button, Row, Col, Tag, Space, DatePicker, Input } from 'antd';
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons'; import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
import { getApprovePage } from './services'
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
@ -204,8 +205,18 @@ const resultOptions = [
]; ];
const SupplierCategoryEntry: React.FC = () => { const SupplierCategoryEntry: React.FC = () => {
const actionRef = useRef<ActionType>(); // const actionRef = useRef<ActionType>();
console.log(1);
useEffect(() => {
console.log(1);
getApprovePage({
pageNo: 1,
pageSize: 10,
});
}, [])
// 查询区渲染 // 查询区渲染
const searchFormRender = ( const searchFormRender = (
<Form layout="vertical"> <Form layout="vertical">
@ -250,7 +261,7 @@ const SupplierCategoryEntry: React.FC = () => {
{/* 查询表单 */} {/* 查询表单 */}
{searchFormRender} {searchFormRender}
{/* 表格 */} {/* 表格 */}
<ProTable {/* <ProTable
columns={columns} columns={columns}
actionRef={actionRef} actionRef={actionRef}
dataSource={tableData} dataSource={tableData}
@ -265,7 +276,7 @@ const SupplierCategoryEntry: React.FC = () => {
}} }}
options={false} options={false}
bordered bordered
/> /> */}
</div> </div>
); );
}; };

View File

@ -0,0 +1,12 @@
import request from '@/utils/request';
/**
* 列表
*/
interface getPageData {
pageNo: number;
pageSize: number;
parentCode?: string;
}
export const getApprovePage = (data: getPageData) => request.post('/coscoAccessWork/getApprovePage', { data});

View File

@ -1,288 +1,205 @@
// src/pages/SupplierEntryReview/index.tsx import React, { useEffect, useState } from 'react';
import { Table, Form, Select, Button, Tag, message } from 'antd';
import React, { useRef } from 'react';
import ProTable from '@ant-design/pro-table';
import type { ProColumns, ActionType } from '@ant-design/pro-table';
import { Form, Select, Button, Row, Col, Tag, Space, message } from 'antd';
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons'; import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
import { getApprovePage } from './services';
import type { ColumnsType } from 'antd/es/table';
// 示例数据
const tableData = [ interface SupplierEntryReviewRecord {
{ id: string;
id: 1, accessWorkName: string; // 准入工作
work: '燃料XXX有限公司', deptId: string; // 准入部门ID
unit: '散运', accessTypeText: string; // 准入方式
dept: '采购部', reviewStatusText: string; // 流程状态
method: '线上', categoryName: string; // 品类名称
applyTime: '2025-03-03 09:30', startTime: string; // 申请时间
status: '未开始', endTime: string;
result: '', createTime: string; // 创建时间
}, updateTime: string; // 更新时间
{ [key: string]: any; // 允许有其它字段
id: 2, }
work: '备件XXX有限公司',
unit: '散运二级单位',
dept: '业务部',
method: '线下',
applyTime: '2025-03-03 09:30',
status: '未开始',
result: '',
},
{
id: 3,
work: '电机XXX有限公司',
unit: '散运',
dept: '采购部',
method: '线上',
applyTime: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 4,
work: '钢板XXX有限公司',
unit: '散运',
dept: '业务部',
method: '线下',
applyTime: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 5,
work: '燃料XXX有限公司',
unit: '散运',
dept: '采购部',
method: '线上',
applyTime: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 6,
work: '备件XXX有限公司',
unit: '散运二级单位',
dept: '业务部',
method: '线下',
applyTime: '2025-03-03 09:30',
status: '进行中',
result: '',
},
{
id: 7,
work: '电机XXX有限公司',
unit: '散运',
dept: '采购部',
method: '线上',
applyTime: '2025-03-03 09:30',
status: '已结束',
result: '通过',
},
{
id: 8,
work: '钢板XXX有限公司',
unit: '散运二级单位',
dept: '业务部',
method: '线下',
applyTime: '2025-03-03 09:30',
status: '已结束',
result: '驳回',
},
{
id: 9,
work: '燃料XXX有限公司',
unit: '散运',
dept: '采购部',
method: '线上',
applyTime: '2025-03-03 09:30',
status: '已结束',
result: '驳回',
},
{
id: 10,
work: '钢板XXX有限公司',
unit: '散运二级单位',
dept: '业务部',
method: '线下',
applyTime: '2025-03-03 09:30',
status: '已结束',
result: '驳回',
},
];
const statusColorMap: Record<string, string> = { const statusColorMap: Record<string, string> = {
'未开始': 'default', '未开始': 'default',
'进行中': 'processing', '进行中': 'processing',
'已结束': 'success', '已完成': 'success',
}; };
const resultColorMap: Record<string, string> = { const methodOptions = [
'通过': 'success', { label: '全部', value: '' },
'驳回': 'error', { label: '线上准入', value: '线上准入' },
}; { label: '线下准入', value: '线下准入' },
];
const columns: ProColumns<any>[] = [ const statusOptions = [
{ label: '全部', value: '' },
{ label: '未开始', value: '未开始' },
{ label: '进行中', value: '进行中' },
{ label: '已完成', value: '已完成' },
];
const deptOptions = [
{ label: '全部', value: '' },
{ label: '采购部', value: 'DEPT001' },
{ label: '业务部', value: 'DEPT002' },
];
const columns:ColumnsType<SupplierEntryReviewRecord> = [
{ {
title: '序号', title: '序号',
dataIndex: 'index', dataIndex: 'index',
valueType: 'index',
width: 48, width: 48,
align: 'center', align: 'center',
render: (_: any, __: any, idx: number) => idx + 1,
}, },
{ {
title: '准入工作', title: '准入工作',
dataIndex: 'work', dataIndex: 'accessWorkName',
align: 'center', align: 'center',
ellipsis: true, ellipsis: true,
}, },
{
title: '准入单位',
dataIndex: 'unit',
align: 'center',
},
{ {
title: '准入部门', title: '准入部门',
dataIndex: 'dept', dataIndex: 'deptId',
align: 'center', align: 'center',
render: (deptId: string) => deptId === 'DEPT001' ? '采购部' : deptId === 'DEPT002' ? '业务部' : deptId,
}, },
{ {
title: '准入方式', title: '准入方式',
dataIndex: 'method', dataIndex: 'accessTypeText',
align: 'center', align: 'center',
}, },
{ {
title: '申请时间', title: '准入品类',
dataIndex: 'applyTime', dataIndex: 'categoryName',
align: 'center',
ellipsis: true,
},
{
title: '开始时间',
dataIndex: 'startTime',
align: 'center',
},
{
title: '结束时间',
dataIndex: 'endTime',
align: 'center', align: 'center',
sorter: (a, b) => new Date(a.applyTime).getTime() - new Date(b.applyTime).getTime(),
}, },
{ {
title: '流程状态', title: '流程状态',
dataIndex: 'status', dataIndex: 'reviewStatusText',
align: 'center', align: 'center',
render: (_, record) => render: (text: string) => <Tag color={statusColorMap[text] || 'default'}>{text}</Tag>,
<Tag color={statusColorMap[record.status] || 'default'}>{record.status}</Tag>,
}, },
{
title: '审批结果',
dataIndex: 'result',
align: 'center',
render: (val: string) =>
val ? <Tag color={resultColorMap[val] || 'default'}>{val}</Tag> : null,
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
valueType: 'option',
render: (_, record) => (
<Space>
<a></a>
<a></a>
</Space>
),
},
];
const statusOptions = [
{ label: '未开始', value: '未开始' },
{ label: '进行中', value: '进行中' },
{ label: '已结束', value: '已结束' },
];
const unitOptions = [
{ label: '散运', value: '散运' },
{ label: '散运二级单位', value: '散运二级单位' },
];
const deptOptions = [
{ label: '采购部', value: '采购部' },
{ label: '业务部', value: '业务部' },
];
const methodOptions = [
{ label: '线上', value: '线上' },
{ label: '线下', value: '线下' },
];
const categoryOptions = [
{ label: '全部', value: '' },
];
const reviewResultOptions = [
{ label: '全部', value: '' },
{ label: '通过', value: '通过' },
{ label: '驳回', value: '驳回' },
]; ];
const SupplierEntryReview: React.FC = () => { const SupplierEntryReview: React.FC = () => {
const actionRef = useRef<ActionType>(); const [form] = Form.useForm();
const [data, setData] = useState<any[]>([]);
const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 });
const [loading, setLoading] = useState(false);
// 自定义查询表单 // 查询数据
const searchFormRender = ( const fetchData = async (params = {}) => {
<Form layout="vertical"> setLoading(true);
<Row gutter={16}> try {
<Col span={4}> const res = await getApprovePage({
<Form.Item name="method" label="准入方式"> pageNo: pagination.current,
<Select options={[{ label: '请选择', value: '' }, ...methodOptions]} allowClear /> pageSize: pagination.pageSize,
</Form.Item> ...form.getFieldsValue(),
</Col> ...params,
<Col span={4}> });
<Form.Item name="unit" label="准入单位"> if (res.code === 200) {
<Select options={[{ label: '请选择', value: '' }, ...unitOptions]} allowClear /> setData(res.data.records);
</Form.Item> setPagination({
</Col> ...pagination,
<Col span={4}> current: res.data.current,
<Form.Item name="dept" label="准入部门"> total: res.data.total,
<Select options={[{ label: '请选择', value: '' }, ...deptOptions]} allowClear /> pageSize: res.data.size,
</Form.Item> });
</Col> } else {
<Col span={4}> setData([]);
<Form.Item name="category" label="准入品类"> setPagination({ ...pagination, total: 0 });
<Select options={[{ label: '请选择', value: '' }, ...categoryOptions]} allowClear /> }
</Form.Item> } catch (err) {
</Col> message.error('获取数据失败');
<Col span={4}> } finally {
<Form.Item name="status" label="流程状态"> setLoading(false);
<Select options={[{ label: '请选择', value: '' }, ...statusOptions]} allowClear /> }
</Form.Item> };
</Col>
<Col span={4}> useEffect(() => {
<Form.Item name="result" label="审批结果"> fetchData({ pageNo: 1 });
<Select options={[{ label: '请选择', value: '' }, ...reviewResultOptions]} allowClear /> // eslint-disable-next-line
</Form.Item> }, []);
</Col>
</Row> // 表格分页切换
<Row gutter={16} style={{ marginBottom: 16 }}> const handleTableChange = (pag: any) => {
<Col> setPagination({
<Button type="primary" icon={<SearchOutlined />} style={{ marginRight: 8 }}></Button> ...pagination,
<Button icon={<ReloadOutlined />}></Button> current: pag.current,
</Col> pageSize: pag.pageSize,
</Row> });
</Form> fetchData({
); pageNo: pag.current,
pageSize: pag.pageSize,
});
};
// 搜索
const handleSearch = () => {
setPagination({ ...pagination, current: 1 });
fetchData({ pageNo: 1 });
};
// 重置
const handleReset = () => {
form.resetFields();
setPagination({ ...pagination, current: 1 });
fetchData({ pageNo: 1 });
};
return ( return (
<div> <div>
{/* 查询表单 */} <Form
{searchFormRender} form={form}
layout="inline"
style={{ marginBottom: 16 }}
onFinish={handleSearch}
>
<Form.Item name="accessTypeText" label="准入方式">
<Select options={methodOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item name="deptId" label="准入部门">
<Select options={deptOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item name="reviewStatusText" label="流程状态">
<Select options={statusOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" icon={<SearchOutlined />} style={{ marginRight: 8 }}>
</Button>
<Button onClick={handleReset} icon={<ReloadOutlined />}>
</Button>
</Form.Item>
</Form>
{/* 表格 */} <Table
<ProTable
columns={columns} columns={columns}
actionRef={actionRef} dataSource={data}
dataSource={tableData}
rowKey="id" rowKey="id"
search={false} loading={loading}
pagination={{ pagination={{
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
showQuickJumper: true, showQuickJumper: true,
showSizeChanger: true, showSizeChanger: true,
pageSize: 10,
total: 188,
current: 1,
}} }}
options={false} onChange={handleTableChange}
bordered
/> />
</div> </div>
); );

View File

@ -0,0 +1,17 @@
import request from '@/utils/request';
/**
* 列表
*/
interface getPageData {
accessType?: string;
approveStatus?: string;
categoryId?: string;
deptId?: string;
pageNo: string;
pageSize: string;
reviewStatus?: string;
[property: string]: any;
}
export const getApprovePage = (data: getPageData) => request.post('/coscoAccessWork/getApprovePage', { data});

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Modal, Descriptions, Table, Button } from 'antd'; import { Modal, Descriptions, Table, Button } from 'antd';
import { startApprove } from '../services'
const ApproveModal: React.FC<{ const ApproveModal: React.FC<{
visible: boolean; visible: boolean;

View File

@ -3,12 +3,29 @@ import { Modal, Descriptions } from 'antd';
import { coscoAccessWork } from '../services' import { coscoAccessWork } from '../services'
//数据接口
interface Data { interface Data {
accessWorkName: string; coscoAccessWork: coscoAccessWorks;
coscoAccessSupplierList: coscoAccessSupplierLists[];
coscoAccessCategoryList: coscoAccessCategoryLists[];
coscoAccessUserls: coscoAccessUserl[];
}
interface coscoAccessUserl {
deptId: string; deptId: string;
accessTypeText: string; userId: string;
createTime: string; }
interface coscoAccessCategoryLists {
categoryName: string;
[property: string]: any;
}
interface coscoAccessSupplierLists {
supplierName: string;
[property: string]: any;
}
interface coscoAccessWorks {
deptId: string;
startTime: string;
endTime: string;
reviewStatusText: string; reviewStatusText: string;
} }
@ -17,35 +34,51 @@ const ViewModal: React.FC<{
record?: any; record?: any;
onCancel: () => void; onCancel: () => void;
}> = ({ visible, record = {}, onCancel }) => { }> = ({ visible, record = {}, onCancel }) => {
//渲染数据
const [data, setData] = useState<Data | null>(null); const [data, setData] = useState<Data | null>(null);
//初始化
useEffect(() => { useEffect(() => {
if(record.id) { if (record.id) {
coscoAccessWork(record.id).then((res) => { coscoAccessWork(record.id).then((res) => {
const { code, data } = res; const { code, data } = res;
if (code == 200) { if (code == 200) {
setData(data.coscoAccessWork) setData(data)
} }
}) })
} }
}, [record]) }, [record])
return ( return (
<Modal title="查看详情" visible={visible} footer={null} onCancel={onCancel}> <Modal title="查看详情" visible={visible} footer={null} onCancel={onCancel}>
{data && ( {data && (
<Descriptions bordered column={1}> <Descriptions bordered column={1}>
<Descriptions.Item label="准入工作">{data.accessWorkName}</Descriptions.Item> <Descriptions.Item label="准入部门">{data.coscoAccessWork.deptId}</Descriptions.Item>
<Descriptions.Item label="准入单位">{data.deptId}</Descriptions.Item> <Descriptions.Item label="准入供应商">
<Descriptions.Item label="准入部门">{data.deptId}</Descriptions.Item> {data.coscoAccessSupplierList.map((item) => {
<Descriptions.Item label="准入方式">{data.accessTypeText}</Descriptions.Item> return (
<Descriptions.Item label="申请时间">{data.createTime}</Descriptions.Item> <div style={{ margin: '5px' }}>{item.supplierName}</div>
<Descriptions.Item label="状态">{data.reviewStatusText}</Descriptions.Item> )
})}
</Descriptions.Item>
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
)
})}
</Descriptions.Item>
<Descriptions.Item label="评审开始时间">{data.coscoAccessWork.startTime}</Descriptions.Item>
<Descriptions.Item label="评审结束时间">{data.coscoAccessWork.endTime}</Descriptions.Item>
<Descriptions.Item label="评审专家">
{data.coscoAccessUserls.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.deptId} - {item.userId}</div>
)
})}
</Descriptions.Item>
<Descriptions.Item label="审批结果">{data.coscoAccessWork.reviewStatusText}</Descriptions.Item>
</Descriptions> </Descriptions>
)} )}
</Modal> </Modal>
); );
}; };

View File

@ -73,14 +73,13 @@ const AccessManagement: React.FC = () => {
{ title: '准入部门', dataIndex: 'deptId' }, { title: '准入部门', dataIndex: 'deptId' },
{ title: '准入方式', dataIndex: 'accessTypeText' }, { title: '准入方式', dataIndex: 'accessTypeText' },
{ title: '申请时间', dataIndex: 'createTime' }, { title: '申请时间', dataIndex: 'createTime' },
{ title: '状态', dataIndex: 'approveStatus' }, { title: '状态', dataIndex: 'reviewStatusText' },
{ {
title: '操作', title: '操作',
render: (_: any, record: any) => ( render: (_: any, record: any) => (
<Space> <Space>
<a onClick={() => openModal('view', record)}></a> <a onClick={() => openModal('view', record)}></a>
<a onClick={() => openModal('approve', record)}></a> {/* <a onClick={() => openModal('approve', record)}>发起审批</a> */}
<a onClick={() => openModal('record', record)}></a>
<a onClick={() => openModal('result', record)}></a> <a onClick={() => openModal('result', record)}></a>
</Space> </Space>
), ),
@ -137,8 +136,8 @@ const AccessManagement: React.FC = () => {
/> />
{/* 弹窗区 */} {/* 弹窗区 */}
<ViewModal visible={modalInfo.type === 'view' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} /> <ViewModal visible={modalInfo.type === 'view' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} />
<ApproveModal visible={modalInfo.type === 'approve' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} /> {/* <ApproveModal visible={modalInfo.type === 'approve' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} /> */}
<RecordModal visible={modalInfo.type === 'record' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} /> {/* <RecordModal visible={modalInfo.type === 'record' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} /> */}
<ResultModal visible={modalInfo.type === 'result' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} /> <ResultModal visible={modalInfo.type === 'result' && modalInfo.visible} record={modalInfo.record} onCancel={closeModal} />
<CreateModal visible={modalInfo.type === 'create' && modalInfo.visible} onCancel={closeModal} /> <CreateModal visible={modalInfo.type === 'create' && modalInfo.visible} onCancel={closeModal} />
</> </>

View File

@ -82,6 +82,17 @@ export const uploadFile = async (file: File) => {
return request('/fileConfig/files/upload', { return request('/fileConfig/files/upload', {
method: 'POST', method: 'POST',
data: formData, data: formData,
}); });
}; };
/**
* 发起审批
*/
interface startApproveData {
id: string;
}
export const startApprove = (params: startApproveData) => request.get(`/coscoAccessWork/`, { params });

View File

@ -0,0 +1,270 @@
import React, { useEffect, useState } from 'react';
import { Modal, Table, Button, Select, Spin, message } from 'antd';
import { reviewInfo, update } from '../services';
interface ResultModalProps {
visible: boolean;
record?: { id?: string; [key: string]: any } | null;
onCancel: () => void;
onSubmit: () => void;
}
// 只读备注弹窗
const RemarkViewModal: React.FC<{
visible: boolean;
onCancel: () => void;
remark: string;
file?: any;
}> = ({ visible, onCancel, remark, file }) => (
<Modal
visible={visible}
title="备注信息"
footer={null}
onCancel={onCancel}
destroyOnClose
>
<div>
<div style={{ marginBottom: 12 }}>
<b></b>{remark || '无'}
</div>
{file && file.fileUrl && (
<div>
<b></b>
<a href={file.fileUrl} target="_blank" rel="noopener noreferrer">
{file.fileName}
</a>
</div>
)}
</div>
</Modal>
);
const GroupLeaderModal: React.FC<ResultModalProps> = ({
visible,
record,
onCancel,
onSubmit,
}) => {
const [loading, setLoading] = useState(false);
const [suppliers, setSuppliers] = useState<any[]>([]);
const [items, setItems] = useState<any[]>([]);
// groupSummaryResult: { [supplierId]: 0|1 }
const [groupSummaryResult, setGroupSummaryResult] = useState<{ [k: string]: 0 | 1 | undefined }>({});
// 查看备注弹窗
const [remarkModal, setRemarkModal] = useState({ open: false, remark: '', file: undefined as any });
// 拉取数据
useEffect(() => {
if (visible && record?.id) {
setLoading(true);
reviewInfo({ id: record.id })
.then((res: any) => {
const supplierList = res?.data || [];
setSuppliers(supplierList);
// 所有项,取第一家公司
const allItems = (supplierList[0]?.coscoAccessItemList || []);
// 非summary项
setItems(allItems.filter((item: any) => item.itemType !== 'summary'));
// summary 行初始化
const summaryMap: { [k: string]: 0 | 1 | undefined } = {};
supplierList.forEach((sup: any) => {
// summary 行
const summaryItem = (sup.coscoAccessItemList || []).find((i: any) => i.itemType === 'summary');
summaryMap[sup.supplierId] = summaryItem?.reviewResult;
});
setGroupSummaryResult(summaryMap);
})
.finally(() => setLoading(false));
} else if (!visible) {
setSuppliers([]);
setItems([]);
setGroupSummaryResult({});
}
}, [visible, record]);
// 处理summary下拉变更
const handleSummaryChange = (supplierId: string, value: 0 | 1) => {
setGroupSummaryResult(prev => ({
...prev,
[supplierId]: value,
}));
};
// 提交
const handleSubmit = () => {
// 只收集 summary 行参数
let summaryParams: any[] = [];
summaryParams = suppliers.map((sup: any) => {
// 找到summary项
const summaryItem = (sup.coscoAccessItemList || []).find((i: any) => i.itemType === 'summary');
if (!summaryItem) return null;
return {
id: summaryItem.id,
reviewResult: groupSummaryResult[sup.supplierId],
remark: '', // 可拓展
coscoAccessTtemAttachments: undefined,
accessWorkId: record?.id
}
}).filter(Boolean);
let accessWorkId = ''
if(record?.id) {
accessWorkId = record?.id
}
update({ coscoAccessUserItemList: summaryParams, accessWorkId }).then((res: any) => {
if (res.code === 200) {
message.success('提交成功');
onSubmit && onSubmit();
}
});
};
// 构造二级表头
const columns: any[] = [
{
title: '评审项',
dataIndex: 'itemName',
key: 'itemName',
width: 180,
fixed: 'left',
},
...suppliers.map(sup => {
// 当前公司所有人员所有非summary项取 coscoAccessUserItemList 多个)
const reviewerSet = new Set<string>();
(sup.coscoAccessItemList || []).forEach((item: any) => {
if (item.itemType !== 'summary' && Array.isArray(item.coscoAccessUserItemList)) {
item.coscoAccessUserItemList.forEach((u: any) => {
reviewerSet.add(u.reviewBy);
});
}
});
const reviewers = Array.from(reviewerSet);
return {
title: (
<div>
<div style={{ fontWeight: 600 }}>{sup.supplierName}</div>
</div>
),
children: reviewers.map((reviewBy: string) => ({
title: reviewBy,
dataIndex: `${sup.supplierId}_${reviewBy}`,
key: `${sup.supplierId}_${reviewBy}`,
width: 100,
align: 'center',
render: (_: any, row: any) => {
// 在sup.coscoAccessItemList里找该itemName下该人员
const item = (sup.coscoAccessItemList || []).find((it: any) => it.itemName === row.itemName && it.itemType !== 'summary');
if (!item) return null;
const userItem = (item.coscoAccessUserItemList || []).find((u: any) => u.reviewBy === reviewBy);
if (!userItem) return null;
return (
<div>
{userItem.reviewResult === '0'
? <span style={{ color: '#52c41a' }}></span>
: userItem.reviewResult === '1'
? <span style={{ color: '#f5222d' }}></span>
: ''}
{userItem.remark && (
<Button type="link" size="small" onClick={() =>
setRemarkModal({ open: true, remark: userItem.remark, file: userItem.coscoAccessTtemAttachments })
}></Button>
)}
</div>
);
}
}))
}
})
];
// 组装表格行数据
const tableData = items.map(item => {
const row: any = {
key: item.id,
itemName: item.itemName
};
suppliers.forEach(sup => {
// 每个人员一格
const reviewerSet = new Set<string>();
(sup.coscoAccessItemList || []).forEach((it: any) => {
if (it.itemType !== 'summary' && Array.isArray(it.coscoAccessUserItemList)) {
it.coscoAccessUserItemList.forEach((u: any) => {
reviewerSet.add(u.reviewBy);
});
}
});
const reviewers = Array.from(reviewerSet);
reviewers.forEach((reviewBy: string) => {
row[`${sup.supplierId}_${reviewBy}`] = null; // 具体显示用render
});
});
return row;
});
// summary 行
const summaryRow = (
<Table.Summary.Row>
<Table.Summary.Cell index={-1}></Table.Summary.Cell>
{suppliers.map((sup, index) => {
// 统计reviewer个数
const reviewerSet = new Set<string>();
(sup.coscoAccessItemList || []).forEach((item: any) => {
if (item.itemType !== 'summary' && Array.isArray(item.coscoAccessUserItemList)) {
item.coscoAccessUserItemList.forEach((u: any) => {
reviewerSet.add(u.reviewBy);
});
}
});
const colSpan = reviewerSet.size || 1;
return (
<Table.Summary.Cell index={index} key={sup.supplierId} colSpan={colSpan} align="center">
<Select
style={{ width: 120 }}
value={groupSummaryResult[sup.supplierId]}
placeholder="请选择"
onChange={val => handleSummaryChange(sup.supplierId, val)}
options={[
{ label: '合格', value: 0 },
{ label: '不合格', value: 1 }
]}
/>
</Table.Summary.Cell>
)
})}
</Table.Summary.Row>
);
return (
<Modal
title="评审结果(组长)"
visible={visible}
onCancel={onCancel}
footer={[
<Button key="cancel" onClick={onCancel}></Button>,
<Button key="submit" type="primary" onClick={handleSubmit}></Button>
]}
width={1000}
bodyStyle={{ maxHeight: '60vh', overflowY: 'auto' }}
centered
destroyOnClose
>
<Spin spinning={loading}>
<Table
columns={columns}
dataSource={tableData}
pagination={false}
bordered
summary={() => summaryRow}
scroll={{ x: 300 * suppliers.length + 200 }}
/>
</Spin>
<RemarkViewModal
visible={remarkModal.open}
onCancel={() => setRemarkModal({ open: false, remark: '', file: undefined })}
remark={remarkModal.remark}
file={remarkModal.file}
/>
</Modal>
);
};
export default GroupLeaderModal;

View File

@ -1,166 +1,200 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Modal, Table, Button, Radio, Input, Upload, message, Spin } from 'antd'; import { Modal, Table, Button, Radio, Input, Upload, message, Spin } from 'antd';
import { reviewInfo, uploadFile } from '../services'; // 你的接口 import { reviewInfo, uploadFile, update } from '../services';
import type { ColumnsType } from 'antd/es/table';
//主体参数接口
interface ResultModalProps { interface ResultModalProps {
visible: boolean; visible: boolean;
record?: { id?: string; [key: string]: any } | null; record?: { id?: string; [key: string]: any } | null;
onCancel: () => void; onCancel: () => void;
onSubmit: (payload: any) => void; onSubmit: () => void;
}
interface RowData {
key: string;
itemName: string;
// 其他如有
} }
// 单元格内容
type CellValue = { type CellValue = {
reviewResult?: 0 | 1; // 0合格 1不合格 reviewResult?: 0 | 1;
remark?: string; remark?: string;
file?: any; file?: any;
}; };
//主体
const ResultModal: React.FC<ResultModalProps> = ({ const ResultModal: React.FC<ResultModalProps> = ({
visible, visible,
record, record,
onCancel, onCancel,
onSubmit onSubmit
}) => { }) => {
// type: 'teamMembers' | 'groupLeader'
// 供应商、评审项、单元格数据
const [suppliers, setSuppliers] = useState<any[]>([]); const [suppliers, setSuppliers] = useState<any[]>([]);
const [items, setItems] = useState<any[]>([]); const [items, setItems] = useState<any[]>([]);
const [cellData, setCellData] = useState<{ const [userItemMatrix, setUserItemMatrix] = useState<any[][]>([]);
[itemId: string]: { [supplierId: string]: CellValue } // userItemId为唯一key
}>({}); const [cellData, setCellData] = useState<{ [userItemId: string]: CellValue }>({});
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
// 备注弹窗 // 备注弹窗
const [remarksModalVisible, setRemarksModalVisible] = useState(false); const [remarksModalVisible, setRemarksModalVisible] = useState(false);
const [remarks, setRemarks] = useState(''); const [remarks, setRemarks] = useState('');
const [fileList, setFileList] = useState<any[]>([]); const [fileList, setFileList] = useState<any[]>([]);
const [currentCell, setCurrentCell] = useState<{ itemId: string, supplierId: string } | null>(null); const [currentUserItemId, setCurrentUserItemId] = useState<string | null>(null);
// 拉取评审数据 // 拉取并整理表格数据
useEffect(() => { useEffect(() => {
if (visible && record?.id) { if (visible && record?.id) {
setLoading(true); setLoading(true);
reviewInfo({ id: record.id, userId: 'E0001' }) reviewInfo({ id: record.id })
.then((res: any) => { .then((res: any) => {
const data = res?.data || []; const supplierList = res?.data || [];
setSuppliers(data); setSuppliers(supplierList);
// 用第一家供应商的coscoAccessItemList生成所有评审项 // 用第一家供应商取所有“非summary”的评审项
const firstSupplier = data[0] || {}; const baseItems = (supplierList[0]?.coscoAccessItemList || []).filter(
const itemList = (firstSupplier.coscoAccessItemList || []).filter((i: { itemType:string } ) => i.itemType !== 'summary'); (item: any) => item.itemType !== 'summary'
setItems(itemList); );
setItems(baseItems);
// 初始化 cellData // 构建userItem二维矩阵[row][col]=userItem/null
const newCellData: any = {}; // userItemMatrix[row][col]为对应格的userItem
itemList.forEach((item: any) => { const matrix: any[][] = [];
newCellData[item.id] = {}; const newCellData: { [userItemId: string]: CellValue } = {};
data.forEach((sup: any) => { baseItems.forEach((item: any, rowIdx: number) => {
newCellData[item.id][sup.supplierId] = {}; matrix[rowIdx] = [];
supplierList.forEach((sup: any, colIdx: number) => {
const cur = (sup.coscoAccessItemList || []).find((it: any) => it.itemName === item.itemName && it.itemType !== 'summary');
const userItem =
cur?.coscoAccessUserItemList?.length > 0
? cur.coscoAccessUserItemList[0]
: null;
matrix[rowIdx][colIdx] = userItem;
// 初始化cellData
if (userItem) {
newCellData[userItem.id] = {
reviewResult: userItem.reviewResult,
remark: userItem.remark,
file: userItem.coscoAccessTtemAttachments
};
}
}); });
}); });
setUserItemMatrix(matrix);
setCellData(newCellData); setCellData(newCellData);
}) })
.finally(() => setLoading(false)); .finally(() => setLoading(false));
} else if (!visible) {
setSuppliers([]);
setItems([]);
setUserItemMatrix([]);
setCellData({});
} }
}, [visible, record]); }, [visible, record]);
// 单选 // 单选只用userItemId为唯一key
const handleRadioChange = (itemId: string, supplierId: string, value: string) => { const handleRadioChange = (userItemId: string, value: string) => {
setCellData(prev => ({ setCellData(prev => ({
...prev, ...prev,
[itemId]: { [userItemId]: {
...prev[itemId], ...prev[userItemId],
[supplierId]: { reviewResult: value === '合格' ? 0 : 1
...prev[itemId]?.[supplierId],
reviewResult: value === '合格' ? 0 : 1
}
} }
})); }));
}; };
// 打开备注弹窗 // 打开备注弹窗
const openRemarksModal = (itemId: string, supplierId: string) => { const openRemarksModal = (userItemId: string) => {
setCurrentCell({ itemId, supplierId }); setCurrentUserItemId(userItemId);
const cell = cellData[itemId]?.[supplierId] || {}; const cell = cellData[userItemId] || {};
setRemarks(cell.remark || ''); setRemarks(cell.remark || '');
setFileList(cell.file setFileList(
? [{ cell.file
uid: '-1', ? [
name: cell.file.fileName, {
status: 'done', uid: '-1',
url: cell.file.fileUrl, name: cell.file.fileName,
response: cell.file status: 'done',
}] url: cell.file.fileUrl,
: []); response: cell.file
}
]
: []
);
setRemarksModalVisible(true); setRemarksModalVisible(true);
}; };
// 上传 // 上传附件
const uploadProps = { const uploadProps = {
fileList, fileList,
maxCount: 1, maxCount: 1,
onRemove: () => setFileList([]), onRemove: () => setFileList([]),
customRequest: async (options: any) => { customRequest: async (options: any) => {
const res = await uploadFile(options.file);
const res = await uploadFile(options.file); setFileList([
const fileObj = res; {
setFileList([{ uid: options.file.uid,
uid: options.file.uid, name: res.fileName,
name: fileObj.fileName, status: 'done',
status: 'done', url: res.fileUrl,
url: fileObj.url, response: { ...res, fileUrl: res.url }
response: fileObj }
}]); ]);
message.success('文件上传成功'); message.success('文件上传成功');
options.onSuccess && options.onSuccess(res, options.file); options.onSuccess && options.onSuccess(res, options.file);
} }
}; };
// 备注提交 // 备注提交
const handleSubmitRemarks = () => { const handleSubmitRemarks = () => {
if (!currentCell) return; if (!currentUserItemId) return;
setCellData(prev => ({ setCellData(prev => ({
...prev, ...prev,
[currentCell.itemId]: { [currentUserItemId]: {
...prev[currentCell.itemId], ...prev[currentUserItemId],
[currentCell.supplierId]: { remark: remarks,
...prev[currentCell.itemId]?.[currentCell.supplierId], file: fileList[0]?.response || undefined
remark: remarks,
file: fileList[0]?.response || undefined
}
} }
})); }));
setRemarksModalVisible(false); setRemarksModalVisible(false);
}; };
// 提交 // 提交数据
const handleSubmit = () => { const handleSubmit = () => {
// 装参数 // 遍历userItemMatrix拼装参数
let result: any[] = []; let result: any[] = [];
items.forEach(item => { userItemMatrix.forEach(row => {
suppliers.forEach(sup => { row.forEach(userItem => {
const cell = cellData?.[item.id]?.[sup.supplierId]; if (userItem && cellData[userItem.id]?.reviewResult !== undefined) {
if (cell && cell.reviewResult !== undefined) {
result.push({ result.push({
id: item.id, id: userItem.id,
reviewResult: cell.reviewResult, reviewResult: cellData[userItem.id]?.reviewResult,
remark: cell.remark || '', remark: cellData[userItem.id]?.remark || '',
coscoAccessTtemAttachments: cell.file || undefined coscoAccessTtemAttachments: cellData[userItem.id]?.file
? {
...cellData[userItem.id]?.file,
accessWorkId: userItem.accessWorkId // 补充
}
: undefined
}); });
} }
}); });
}); });
let accessWorkId = ''
console.log(items,'items'); if(record?.id) {
console.log(result,'result'); accessWorkId = record?.id
}
// 提交审核
onSubmit && onSubmit({ coscoAccessUserItemList: result }); update( {coscoAccessUserItemList: result, accessWorkId }).then((res) => {
if(res.code == 200) {
message.success('提交成功');
onSubmit()
}
})
}; };
// 组装表头 // 组装表头
const columns = [ const columns: ColumnsType<RowData> = [
{ {
title: '评审项', title: '评审项',
dataIndex: 'itemName', dataIndex: 'itemName',
@ -168,15 +202,15 @@ const ResultModal: React.FC<ResultModalProps> = ({
width: 200, width: 200,
fixed: 'left' fixed: 'left'
}, },
...suppliers.map(sup => ({ ...suppliers.map((sup, colIdx) => ({
title: sup.supplierName, title: sup.supplierName,
dataIndex: sup.supplierId, dataIndex: sup.supplierId,
key: sup.supplierId, key: sup.supplierId,
width: 300, width: 300,
render: (_: any, row: any) => { render: (_: any, row: any, rowIdx: number) => {
const v = cellData?.[row.key]?.[sup.supplierId] || {}; const userItem = userItemMatrix[rowIdx]?.[colIdx];
console.log(sup,'sup'); if (!userItem) return null; // 无userItem不渲染
const v = cellData[userItem.id] || {};
return ( return (
<div> <div>
<Radio.Group <Radio.Group
@ -187,22 +221,30 @@ const ResultModal: React.FC<ResultModalProps> = ({
? '不合格' ? '不合格'
: undefined : undefined
} }
onChange={e => handleRadioChange(row.key, sup.supplierId, e.target.value)} onChange={e => handleRadioChange(userItem.id, e.target.value)}
> >
<Radio value="合格"></Radio> <Radio value="合格"></Radio>
<Radio value="不合格"></Radio> <Radio value="不合格"></Radio>
</Radio.Group> </Radio.Group>
<Button type="link" onClick={() => openRemarksModal(row.key, sup.supplierId)}></Button> <Button type="link" onClick={() => openRemarksModal(userItem.id)}>
{v.remark && <span style={{ color: '#aaa', fontSize: 12 }}></span>}
{v.file && <span style={{ color: '#52c41a', fontSize: 12, marginLeft: 8 }}></span>} </Button>
{v.remark && (
<span style={{ color: '#aaa', fontSize: 12 }}></span>
)}
{v.file && (
<span style={{ color: '#52c41a', fontSize: 12, marginLeft: 8 }}>
</span>
)}
</div> </div>
); );
} }
})) }))
]; ];
// 数据 // 表格数据
const tableData = items.map(item => ({ const tableData = items.map((item: any) => ({
key: item.id, key: item.id,
itemName: item.itemName itemName: item.itemName
})); }));
@ -213,8 +255,12 @@ const ResultModal: React.FC<ResultModalProps> = ({
visible={visible} visible={visible}
onCancel={onCancel} onCancel={onCancel}
footer={[ footer={[
<Button key="cancel" onClick={onCancel}></Button>, <Button key="cancel" onClick={onCancel}>
<Button key="submit" type="primary" onClick={handleSubmit}></Button>
</Button>,
<Button key="submit" type="primary" onClick={handleSubmit}>
</Button>
]} ]}
width={1000} width={1000}
bodyStyle={{ maxHeight: '60vh', overflowY: 'auto' }} bodyStyle={{ maxHeight: '60vh', overflowY: 'auto' }}
@ -235,8 +281,12 @@ const ResultModal: React.FC<ResultModalProps> = ({
visible={remarksModalVisible} visible={remarksModalVisible}
onCancel={() => setRemarksModalVisible(false)} onCancel={() => setRemarksModalVisible(false)}
footer={[ footer={[
<Button key="cancel" onClick={() => setRemarksModalVisible(false)}></Button>, <Button key="cancel" onClick={() => setRemarksModalVisible(false)}>
<Button key="submit" type="primary" onClick={handleSubmitRemarks}></Button>
</Button>,
<Button key="submit" type="primary" onClick={handleSubmitRemarks}>
</Button>
]} ]}
destroyOnClose destroyOnClose
> >

View File

@ -1,11 +1,12 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useIntl } from 'umi'; import { useIntl } from 'umi';
import { Form, Button, Table, Select, Space, Input } from 'antd'; import { Form, Button, Table, Space, Input } from 'antd';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'; import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import { SearchOutlined } from '@ant-design/icons'; import { SearchOutlined } from '@ant-design/icons';
import { getPage } from './services'; import { getPage } from './services';
//查看评审结果 弹窗 //查看评审结果 弹窗
import ResultModal from './components/ResultModal'; import ResultModal from './components/ResultModal';
import GroupLeaderModal from './components/GroupLeaderModal';
interface Data { interface Data {
deptName: string; deptName: string;
@ -16,7 +17,7 @@ interface Data {
} }
interface ModalInfo { interface ModalInfo {
type: 'view' | 'result' | null; type: 'teamMembers' | 'groupLeader' | null;
visible: boolean; visible: boolean;
record: Data | null; record: Data | null;
} }
@ -30,18 +31,24 @@ const CooperateEnterprise: React.FC = () => {
const [pagination, setPagination] = useState<TablePaginationConfig>({ current: 1, pageSize: 10, total: 0 }); const [pagination, setPagination] = useState<TablePaginationConfig>({ current: 1, pageSize: 10, total: 0 });
const [modalInfo, setModalInfo] = useState<ModalInfo>({ type: null, visible: false, record: null }); const [modalInfo, setModalInfo] = useState<ModalInfo>({ type: null, visible: false, record: null });
const openModal = (type: 'view' | 'result', record: Data) => { const openModal = (type: 'teamMembers' | 'groupLeader', record: Data) => {
setModalInfo({ type, visible: true, record }); setModalInfo({ type, visible: true, record });
}; };
//提交关闭审核
const closeModal = () => { const closeModal = () => {
setModalInfo({ type: null, visible: false, record: null }); setModalInfo({ type: null, visible: false, record: null });
}; };
//提交审核
const submitModal = () => {
closeModal();
handleReset();
};
// 列表数据 // 列表数据
const getList = async (params: { pageNo: number; pageSize: number; parentCode: string; }) => { const getList = async (params: { pageNo: number; pageSize: number; parentCode: string; }) => {
setLoading(true); setLoading(true);
try { try {
const { code, data } = await getPage(params); const { code, data } = await getPage({...params });
if (code === 200) { if (code === 200) {
setData(data.records); setData(data.records);
setPagination({ current: params.pageNo, pageSize: params.pageSize, total: data.total }); setPagination({ current: params.pageNo, pageSize: params.pageSize, total: data.total });
@ -97,8 +104,8 @@ const CooperateEnterprise: React.FC = () => {
}, },
{ {
title: '品类', title: '品类',
dataIndex: 'exitTime', dataIndex: 'categoryName',
key: 'exitTime', key: 'categoryName',
}, },
{ {
title: '准入方式', title: '准入方式',
@ -117,11 +124,19 @@ const CooperateEnterprise: React.FC = () => {
}, },
{ {
title: '操作', title: '操作',
render: (_: any, record: any) => ( render: (_: any, record: any) => {
const showAudit = (
(['未开始', '进行中'].includes(record.reviewStatusText) && record.isLeader === '0') ||
(['结果汇总中'].includes(record.reviewStatusText) && record.isLeader === '1')
);
const type = ['未开始', '进行中'].includes(record.reviewStatusText)? 'teamMembers': 'groupLeader';
return (
<Space> <Space>
<a onClick={() => openModal('result', record)}></a> {showAudit && <a onClick={() => openModal(type, record)}></a>}
</Space> </Space>
), )
},
}, },
]; ];
return ( return (
@ -153,12 +168,23 @@ const CooperateEnterprise: React.FC = () => {
loading={loading} loading={loading}
onChange={(pagination) => getList({ pageNo: pagination.current!, pageSize: pagination.pageSize!, parentCode: '', })} onChange={(pagination) => getList({ pageNo: pagination.current!, pageSize: pagination.pageSize!, parentCode: '', })}
/> />
{ modalInfo.type && modalInfo.type === 'teamMembers' && (
<ResultModal <ResultModal
visible={modalInfo.type === 'result' && modalInfo.visible} visible={modalInfo.visible}
record={modalInfo.record} record={modalInfo.record}
onCancel={closeModal} onCancel={closeModal}
/> onSubmit={submitModal}
/>
)}
{ modalInfo.type && modalInfo.type === 'groupLeader' && (
<GroupLeaderModal
visible={modalInfo.visible}
record={modalInfo.record}
onCancel={closeModal}
onSubmit={submitModal}
/>
)}
</> </>
); );
}; };

View File

@ -1,8 +1,5 @@
import request from '@/utils/request'; import request from '@/utils/request';
/** /**
* 准入列表 * 准入列表
*/ */
@ -11,7 +8,7 @@ interface getPageData {
pageSize: number; pageSize: number;
parentCode?: string; parentCode?: string;
} }
export const getPage = (data: getPageData) => request.post('/coscoAccessWork/getPage', { data }); export const getPage = (data: getPageData) => request.post('/coscoAccessWork/getPage', { data});
/** /**
* 评审修改时用的详情页 * 评审修改时用的详情页
*/ */
@ -37,42 +34,34 @@ export const uploadFile = async (file: File) => {
}); });
}; };
/**
* 组员评审
*/
export interface updateData {
export async function coscoSupplier(params:any) { accessWorkId: string;
console.log(params,'params'); coscoAccessUserItemList: CoscoAccessUserItemList[];
[property: string]: any;
return request('/api/system/coscoSupplier', {
method: 'GET',
params
});
} }
export async function library(params:any) { export interface CoscoAccessUserItemList {
return request('/api/system/library', { coscoAccessTtemAttachments: CoscoAccessTtemAttachments;
method: 'GET', id: number;
params remark: string;
}); reviewResult: number;
[property: string]: any;
} }
export async function qualifications(params:any) { export interface CoscoAccessTtemAttachments {
return request('/api/system/qualifications', { accessWorkId: string;
method: 'GET', fileName: string;
params filePath: string;
}); fileSize: string;
} fileType: string;
export async function invoice(params:any) { fileUrl: string;
return request('/api/system/invoice', { [property: string]: any;
method: 'GET',
params
});
}
export async function bank(params:any) {
return request('/api/system/bank', {
method: 'GET',
params
});
} }
export const update = (data: updateData) => request.post('/coscoAccessWork/update', { data });