搜索弄成全局

This commit is contained in:
孙景学
2025-07-16 14:51:36 +08:00
parent af2bd823b6
commit 05f46a8dee
17 changed files with 106 additions and 628 deletions

View File

@ -1,104 +0,0 @@
import { Request, Response } from 'express';
// 代码中会兼容本地 service mock 以及部署站点的静态数据
export default {
'GET /api/supplier/getSupplierChangeList': (req: Request, res: Response) => {
res.send({
code: 200,
msg: 'success',
data: [
{
id: 1,
name: '中山市合创展包装材料有限公司',
region: '境内',
supplierType: '中央企业',
accessTime: '2025-03-03 09:30',
changeTime: '2025-03-03 09:30',
status: '未开始',
result: '',
},
],
total: 10
});
},
'GET /api/supplier/list': (req: Request, res: Response) => {
res.send({
code: 200,
msg: 'success',
data: [
{
id: 1,
name: '中山市合创展包装材料有限公司',
region: '境内',
supplierType: '中央企业',
accessTime: '2025-03-03 09:30',
changeTime: '2025-03-03 09:30',
status: '未开始',
result: '',
},
],
total: 10
});
},
'GET /api/system/getPage': (req: Request, res: Response) => {
res.json({
code: 200,
data: [
{
deptName: '供应商名称变更',
categoryName: '2024-05-20 13:22:11',
createTime: '集团采购部',
exitTime: '已通过',
exitReason: '2024-05-21 09:10:31',
},
{
deptName: '法人代表变更',
categoryName: '2024-05-18 08:30:55',
createTime: '分公司审核部',
exitTime: '审核中',
exitReason: '',
},
],
total: 2,
msg: '操作成功'
});
},
'GET /api/system/getSupplierChangeDetail': (req: Request, res: Response) => {
res.json({
"code": 200,
"msg": "success",
"data": {
baseInfo: [
{ label: '供应商名称', value: 'xxx' },
{ label: '境内/境外', value: '境内' },
{ label: '准入单位', value: 'xxxx' },
{ label: '准入部门', value: '采购部' },
],
changeInfo: [
{ label: '供应商名称-变更前', value: 'xxxx' },
{ label: '供应商名称-变更后', value: 'xxxx' },
],
"supplierName": "中山市合创展包装材料有限公司",
"accessUnit": "中远海运(青岛)有限公司",
"region": "境内",
"accessDept": "采购部",
"beforeName": "中山市合创展包装材料有限公司",
"afterName": "中山市合创展包装有限公司",
"qualifications": [
{
"type": "CMMI资质",
"name": "CMMI资质",
"level": "高级",
"number": "546464",
"org": "XX机构",
"issueDate": "2024-09-08",
"validDate": "2028-09-10",
"file": "https://dummyimage.com/40x30/1890ff/fff.png&text=附件"
}
]
}
}
);
},
};

View File

@ -1,144 +0,0 @@
import React, { useEffect, useState } from 'react';
import { Modal, Table, Spin } from 'antd';
import { getSupplierChangeDetail } from '../services';
interface Qualification {
type: string;
name: string;
level: string;
number: string;
org: string;
issueDate: string;
validDate: string;
file?: string;
}
interface InfoItem {
label: string;
value: string;
}
interface DetailData {
baseInfo: InfoItem[];
changeInfo: InfoItem[];
qualifications: Qualification[];
}
interface DetailViewProps {
visible: boolean;
onClose: () => void;
detailId?: string | number;
}
const DetailView: React.FC<DetailViewProps> = ({ visible, onClose, detailId }) => {
const [loading, setLoading] = useState(false);
const [detailData, setDetailData] = useState<DetailData | null>(null);
useEffect(() => {
if (visible && detailId) {
setLoading(true);
getSupplierChangeDetail(detailId)
.then(res => {
if (res.code === 200) {
setDetailData(res.data);
}
})
.finally(() => setLoading(false));
}
if (!visible) setDetailData(null);
}, [visible, detailId]);
const columns = [
{ title: '资质证书类型', dataIndex: 'type', width: 120 },
{ title: '资质名称', dataIndex: 'name', width: 120 },
{ title: '资质类别和等级', dataIndex: 'level', width: 120 },
{ title: '资质证书编号', dataIndex: 'number', width: 120 },
{ title: '发证机构', dataIndex: 'org', width: 120 },
{ title: '发证日期', dataIndex: 'issueDate', width: 120 },
{ title: '资质有效期至', dataIndex: 'validDate', width: 120 },
{
title: '附件',
dataIndex: 'file',
width: 120,
render: (file: string) =>
file ? (
<span>
<img src={file} alt="附件" style={{ width: 30, verticalAlign: 'middle', marginRight: 8 }} />
<a></a>
</span>
) : (
'-'
),
},
];
// 把info数组两两合并成一行显示
function renderInfoTable(infoArr: InfoItem[]) {
const rows = [];
for (let i = 0; i < infoArr.length; i++) {
const left = infoArr[i];
const right = infoArr[i + 1] || { label: '', value: '' };
rows.push(
<tr key={i}>
<td style={tdStyleTitle}>{left.label}</td>
<td style={tdStyle}>{left.value}</td>
<td style={tdStyleTitle}>{right.label}</td>
<td style={tdStyle}>{right.value}</td>
</tr>
);
}
return (
<table style={{ width: '100%', borderCollapse: 'collapse', background: '#fff', marginBottom: 8 }}>
<tbody>{rows}</tbody>
</table>
);
}
return (
<Modal
title="供应商信息变更审批"
visible={visible}
onCancel={onClose}
footer={null}
width={1000}
bodyStyle={{ padding: 24 }}
destroyOnClose
>
<Spin spinning={loading}>
{detailData && (
<div>
{/* 基本信息 */}
{renderInfoTable(detailData.baseInfo)}
{/* 变更内容 */}
<div style={{ padding: '16px 0 0 2px', fontWeight: 700 }}></div>
{renderInfoTable(detailData.changeInfo)}
{/* 新增资质 */}
<div style={{ padding: '0 0 6px 2px', fontWeight: 700 }}>1</div>
<Table
columns={columns}
dataSource={detailData.qualifications}
rowKey="number"
size="small"
pagination={false}
bordered
style={{ margin: '0 0 16px 0' }}
/>
</div>
)}
</Spin>
</Modal>
);
};
const tdStyleTitle: React.CSSProperties = {
background: '#fafafa',
fontWeight: 700,
width: 130,
padding: 8,
border: '1px solid #f0f0f0',
};
const tdStyle: React.CSSProperties = {
background: '#fff',
padding: 8,
border: '1px solid #f0f0f0',
};
export default DetailView;

View File

@ -1,204 +0,0 @@
import React, { useEffect, useState } from 'react';
import { Table, Form, Input, Select, Button, DatePicker, Tag, Space, message } from 'antd';
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
// 类型定义
import type { ColumnsType } from 'antd/es/table';
import DetailView from './components/DetailView';
import { list } from './services';
const { RangePicker } = DatePicker;
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: '驳回' },
];
interface Columns {
name:string;
supplierTypeCn:string;
enterpriseTypeCn:string;
accessTime:string;
changeTime:string;
status:string;
result:string;
id:string;
}
const SupplierChangeManage: React.FC = () => {
const [form] = Form.useForm();
const [data, setData] = useState<Columns[]>([]);
const [loading, setLoading] = useState(false);
const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 });
const [detailVisible, setDetailVisible] = useState(false);
const [currentDetailId, setCurrentDetailId] = useState<number | null>(null);
// 获取表格数据
const fetchData = async (params = {}) => {
setLoading(true);
try {
const { code, data, total, msg } = await list({
page: pagination.current,
pageSize: pagination.pageSize,
...params,
});
if (code === 200) {
setData(data);
setPagination(p => ({ ...p, total: total || 0 }));
} else {
message.error(msg || '获取数据失败');
}
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
}, [pagination.current, pagination.pageSize]);
// 查询
const handleSearch = () => {
setPagination(p => ({ ...p, current: 1 }));
fetchData(form.getFieldsValue());
};
// 重置
const handleReset = () => {
form.resetFields();
setPagination(p => ({ ...p, current: 1 }));
fetchData();
};
const columns: ColumnsType<Columns> = [
{
title: '序号',
dataIndex: 'index',
width: 48,
align: 'center',
render: (_: any, __: any, idx: number) => (pagination.current - 1) * pagination.pageSize + idx + 1,
},
{
title: '供应商名称',
dataIndex: 'name',
align: 'center',
ellipsis: true,
},
{
title: '境内/境外',
dataIndex: 'supplierTypeCn',
align: 'center',
},
{
title: '供应商分类',
dataIndex: 'enterpriseTypeCn',
align: 'center',
},
{
title: '准入时间',
dataIndex: 'accessTime',
align: 'center',
},
{
title: '提交变更时间',
dataIndex: 'changeTime',
align: 'center',
},
{
title: '流程状态',
dataIndex: 'status',
align: 'center',
},
{
title: '审批结果',
dataIndex: 'result',
align: 'center',
},
{
title: '操作',
key: 'action',
align: 'center',
render: (_: any, record: any) => (
<Button type="link" onClick={() => handleDetail(record)}>
</Button>
),
},
];
// 弹窗操作
const handleDetail = (record: any) => {
setCurrentDetailId(record.id);
setDetailVisible(true);
};
const handleDetailClose = () => {
setDetailVisible(false);
setCurrentDetailId(null);
};
return (
<>
{/* 查询表单 */}
<Form
form={form}
layout="inline"
style={{ width: '100%', marginBottom: 16 }}
onFinish={handleSearch}
>
<Form.Item name="name" label="供应商名称">
<Input placeholder="请输入供应商名称关键字" allowClear />
</Form.Item>
<Form.Item name="region" label="境内/境外">
<Select options={regionOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item name="status" label="流程状态">
<Select options={statusOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item name="result" label="审批结果">
<Select options={resultOptions} allowClear style={{ width: 120 }} />
</Form.Item>
<Form.Item name="changeTime" label="提交变更时间">
<RangePicker style={{ width: 220 }} />
</Form.Item>
<Form.Item>
<Button type="primary" icon={<SearchOutlined />} htmlType="submit"></Button>
<Button icon={<ReloadOutlined />} style={{ marginLeft: 8 }} onClick={handleReset}></Button>
</Form.Item>
</Form>
{/* 数据表格 */}
<Table
columns={columns}
rowKey="id"
dataSource={data}
loading={loading}
bordered
pagination={{
...pagination,
showQuickJumper: true,
showSizeChanger: true,
onChange: (current, pageSize) => setPagination({ ...pagination, current }),
}}
/>
{/* 审批记录弹窗 */}
<DetailView
visible={detailVisible}
onClose={handleDetailClose}
detailId={currentDetailId || ''}
/>
</>
);
};
export default SupplierChangeManage;

View File

@ -1,22 +0,0 @@
import request from '@/utils/request';
export async function list(params:any) {
return request('/api/system/list', {
method: 'GET',
params
});
}
export async function getPage(params:any) {
return request('/api/system/getPage', {
method: 'GET',
params
});
}
export async function getSupplierChangeDetail(params:any) {
return request('/api/system/getSupplierChangeDetail', {
method: 'GET',
params
});
}

View File

@ -3,6 +3,7 @@ import { Table, Form, Input, Select, Button, DatePicker, Tooltip } from 'antd';
import { SearchOutlined, DeleteOutlined } from '@ant-design/icons';
//详情
import DetailView from './components/DetailView';
import RegionTypeSelect from '@/components/CommonSelect/RegionTypeSelect'
//接口
import { getPage } from './services';
import type { ColumnsType } from 'antd/es/table';
@ -16,12 +17,6 @@ import tableProps from '@/utils/tableProps'
const { RangePicker } = DatePicker;
const regionOptions = [
{ label: '境内企业', value: 'dvs' },
{ label: '境外企业', value: 'ovs' },
{ label: '个人', value: 'pe' },
];
interface Columns {
supplierName: string;
supplierType: string;
@ -202,8 +197,8 @@ const SupplierChangeReviewManage: React.FC<Props> = ({ dispatch }) => {
<Form.Item name="supplierName" label="供应商名称">
<Input placeholder="请输入供应商名称关键字" allowClear />
</Form.Item>
<Form.Item name="supplierType" label="境内/境外">
<Select options={regionOptions} allowClear style={{ width: 120 }} placeholder="请选择境内/境外" />
<Form.Item name="supplierType" label="企业类型">
<RegionTypeSelect />
</Form.Item>
<Form.Item name="approveStatus" label="审批状态">