第三方评价页面

This commit is contained in:
孙景学
2025-08-12 14:52:14 +08:00
parent 69a90c7d7f
commit 3804a1c9ef
15 changed files with 939 additions and 132 deletions

View File

@ -1,7 +1,6 @@
import React, { useState, useEffect } from 'react';
import { Descriptions, Button, message } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { IntlShape } from 'react-intl';
import { getQuery, getQueryAndUpdate } from '../services';
import { useIntl } from 'umi';

View File

@ -0,0 +1,145 @@
import React, { useEffect, useState } from "react";
import { Table, Descriptions, Spin, message, Tooltip } from "antd";
import { viewBlacklist } from "../services";
import type { ColumnsType } from 'antd/es/table';
import { getDictList } from '@/servers/api/dicts';
import GlobalModal from '../GlobalModal/index'
interface Supplier {
id: number; // 作为 rowKey 用于唯一标识
supplierName: string; // 供应商名称
unit: string; // 准入部门
accessTime: string; // 准入时间
categoryName: string; // 准入品类
lastEval: string; // 最近一次评价
lastEvalDate: string; // 评价时间
supplierId: string;
categoryId: string;
}
interface DetailData {
deptName: string;
timelimitType: string;
blacklistReason: string;
}
interface ViewBlacklistModalProps {
visible: boolean;
record: any; // 用于查询详情数据
}
const ViewBlacklistModal: React.FC<ViewBlacklistModalProps> = ({
visible,
record = {},
}) => {
const [loading, setLoading] = useState(false);
const [detail, setDetail] = useState<DetailData | null>(null);
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
const [timelimitMap, setTimelimitMap] = useState<{ [code: string]: string }>({});
const [visibleGlobalModal, setVisibleGlobalModal] = useState(false);
const [id, setId] = useState('');
const fetchData = async () => {
setLoading(true);
try {
const { code, data } = await viewBlacklist(record.id)
if (code == 200) {
setDetail(data);
} else {
message.error("获取详情失败");
}
if (code == 200) {
setSuppliers(data.supplierList || []);
} else {
message.error("获取供应商列表失败");
}
} catch (error) {
message.error("获取数据异常");
} finally {
setLoading(false);
}
};
useEffect(() => {
if (visible && record) {
getDictList('blacklist_deadline').then((res) => {
const { code, data } = res;
if (code == 200) {
const map: { [code: string]: string } = {};
data.forEach((item: { code: string, dicName: string }) => {
map[item.code] = item.dicName;
});
setTimelimitMap(map);
}
})
fetchData();
}
}, [visible, record]);
const columns: ColumnsType<Supplier> = [
{
title: "供应商名称", dataIndex: "supplierName", align: "left",
width: 200,
ellipsis: true,
render: (dom, record) => {
return (
<Tooltip title={record.supplierName} overlayStyle={{ zIndex: 1200 }}>
<a
onClick={() => {
setId(record.supplierId)
setVisibleGlobalModal(true)
}}
>
{record.supplierName}
</a>
</Tooltip>
)
}
},
// { title: "准入部门", dataIndex: "deptName", align: "center" },
// { title: "准入时间", dataIndex: "evaluateTime", align: "center" },
{ title: "统一社会信用代码/税号", dataIndex: "unifiedCode", align: "center" },
{
title: "准入品类", dataIndex: "categoryName", align: "center", width: 180,
ellipsis: true,
render: (dom, record) => {
return (
<Tooltip title={record.categoryName} overlayStyle={{ zIndex: 1200 }}>
{record.categoryName}
</Tooltip>
)
}
},
];
return (
<div >
<Spin spinning={loading}>
<Table
columns={columns}
dataSource={suppliers}
rowKey="id"
bordered
pagination={false}
/>
{detail && (
<Descriptions
column={1}
labelStyle={{ width: 160 }}
bordered
style={{ marginTop: 24 }}
>
<Descriptions.Item label="时限类型" >{timelimitMap[detail.timelimitType] || '' }</Descriptions.Item>
<Descriptions.Item label="退出黑名单原因" >{detail.blacklistReason}</Descriptions.Item>
</Descriptions>
)}
</Spin>
<GlobalModal visible={visibleGlobalModal} id={id} onCancel={() => setVisibleGlobalModal(false)} />
</div>
);
};
export default ViewBlacklistModal;

View File

@ -0,0 +1,90 @@
import React, { useEffect, useState } from 'react';
import { Descriptions } from 'antd';
import { detail } from "../services";
import { getDictList } from '@/servers/api/dicts'
// 基本信息类型
interface CategoryInfo {
name?: string;
validDate?: string;
manager?: string;
structure?: string;
termOfValidity?: string;
deptId?: string;
applyOrgName?: string;
orgName?: string;
deptName?: string;
categoryName?: string;
area?: string;
}
const ViewModal: React.FC<{
visible: boolean;
record: any;
}> = ({ visible, record={} }) => {
// 已勾选的供应商 id
// 品类库基本信息
const [categoryInfo, setCategoryInfo] = useState<CategoryInfo>({});
const [areaMap, setAreaMap] = useState<{ [code: string]: string }>({});
// 拉取基本信息
const fetchCategoryInfo = async () => {
if (!record) return;
const res = await detail({ id: record.id });
if (res.code === 200 && res.data) setCategoryInfo(res.data);
};
useEffect(() => {
if (visible) {
getDictList('area').then(res => {
if (res.code === 200) {
const map: { [code: string]: string } = {};
res.data.forEach((item: { code: string, dicName: string }) => {
map[item.code] = item.dicName;
});
setAreaMap(map);
}
});
fetchCategoryInfo();
}
}, [visible, record]);
return (
<div>
{/* 基本信息区 */}
<div style={{ marginBottom: 18 }}>
<Descriptions
bordered
column={1}
size="small"
style={{ marginBottom: 18, background: '#fff', borderRadius: 4 }}
labelStyle={{ width: 110, fontWeight: 500 }}
>
<Descriptions.Item label="品类库名称">
{categoryInfo?.name || '-'}
</Descriptions.Item>
<Descriptions.Item label="有效期至">
{categoryInfo?.termOfValidity || '-'}
</Descriptions.Item>
<Descriptions.Item label="创建单位">
{categoryInfo?.applyOrgName || '-'}
</Descriptions.Item>
<Descriptions.Item label="所属单位">
{categoryInfo?.orgName || '-'}
</Descriptions.Item>
<Descriptions.Item label="负责部门">
{categoryInfo?.deptName || '-'}
</Descriptions.Item>
<Descriptions.Item label="区域">
{categoryInfo?.area ? areaMap[categoryInfo.area] || categoryInfo?.area : '-'}
</Descriptions.Item>
<Descriptions.Item label="品类结构">
{categoryInfo?.categoryName || '-'}
</Descriptions.Item>
</Descriptions>
</div>
</div>
);
};
export default ViewModal;

View File

@ -0,0 +1,157 @@
import React, { useEffect, useState } from 'react';
import { Descriptions, Tooltip, Table } from 'antd';
import { applyDetail } from "../services";
import type { DataNode } from 'antd/es/tree';
import type { ColumnsType } from 'antd/es/table';
import { getDictList } from '@/servers/api/dicts'
import GlobalModal from '../GlobalModal/index'
// 基本信息类型
interface CategoryInfo {
name?: string;
validDate?: string;
manager?: string;
structure?: string;
termOfValidity?: string;
categoryName?: string;
deptName?: string;
deptId?: string;
area?: string;
applyTime?: string;
coscoCategoryLibrarySupplierVos?: coscoCategoryLibrarySupplierVos[];
}
interface coscoCategoryLibrarySupplierVos {
area: string;
id: string;
name: string;
selected: boolean;
supplierCategory: string;
unifiedSocialCreditCode: string;
}
interface LockNode extends DataNode {
key: string;
title: string;
categoryLibraryId: string;
categoryId: string;
lockType: string;
children?: LockNode[];
}
interface columns {
id: string;
name: string;
supplierCategory: string;
}
const ViewModal: React.FC<{
visible: boolean;
record: any;
}> = ({ visible, record={} }) => {
const [categoryInfo, setCategoryInfo] = useState<CategoryInfo>({});
const [areaMap, setAreaMap] = useState<{ [code: string]: string }>({});
const [visibleGlobalModal, setVisibleGlobalModal] = useState(false);
const [id, setId] = useState('');
// 拉取基本信息
const fetchCategoryInfo = async () => {
if (!record) return;
const res = await applyDetail({ id: record.id });
if (res.code === 200 && res.data) setCategoryInfo(res.data);
};
const formatData = (list: any[]): LockNode[] => {
return list.map(item => ({
key: item.categoryId,
title: item.categoryName,
categoryId: item.categoryId,
categoryLibraryId: item.categoryLibraryId,
lockType: item.lockType ? item.lockType : '0',
children: item.categoryList ? formatData(item.categoryList) : [],
}));
};
useEffect(() => {
if (visible) {
getDictList('area').then(res => {
if (res.code === 200) {
const map: { [code: string]: string } = {};
res.data.forEach((item: { code: string, dicName: string }) => {
map[item.code] = item.dicName;
});
setAreaMap(map);
}
});
fetchCategoryInfo();
}
}, [visible, record]);
const columns: ColumnsType<columns> = [
{
title: "供应商名称", dataIndex: "name", align: "left",
width: 360,
ellipsis: true,
render: (dom, record) => {
return (
<Tooltip title={record.name} overlayStyle={{ zIndex: 1200 }}>
<a
onClick={() => {
setId(record.id)
setVisibleGlobalModal(true)
}}
>
{record.name}
</a>
</Tooltip>
)
}
},
{
title: '境内/境外', dataIndex: 'supplierCategory', align: 'center',
render: (record: any) => {
const supplierCategoryType = record.supplierCategory === 'dvs' ? '境内企业' : record.supplierCategory === 'pe' ? '个人' : '境外企业'
return (
<span>{supplierCategoryType}</span>
)
}
},
{ title: '统一社会信用代码/税号', dataIndex: 'unifiedSocialCreditCode', align: 'center' },
]
return (
<div>
{/* 基本信息区 */}
<div style={{ marginBottom: 18 }}>
<Descriptions
bordered
column={1}
size="small"
style={{ marginBottom: 18, background: '#fff', borderRadius: 4 }}
labelStyle={{ width: 110, fontWeight: 500 }}
>
<Descriptions.Item label="品类库名称">
{categoryInfo?.name || '-'}
</Descriptions.Item>
<Descriptions.Item label="有效期至">
{categoryInfo?.applyTime || '-'}
</Descriptions.Item>
<Descriptions.Item label="区域">
{categoryInfo?.area ? areaMap[categoryInfo.area] || categoryInfo?.area : '-'}
</Descriptions.Item>
<Descriptions.Item label="品类结构">
{categoryInfo?.categoryName || '-'}
</Descriptions.Item>
</Descriptions>
</div>
{/*申请入库供应商 */}
<Table
columns={columns}
dataSource={categoryInfo.coscoCategoryLibrarySupplierVos}
rowKey="id"
pagination={false}
style={{ flex: 1, minHeight: 0 }}
scroll={{ y: 'calc(100vh - 650px)' }}
/>
<GlobalModal visible={visibleGlobalModal} id={id} onCancel={() => setVisibleGlobalModal(false)} />
</div>
);
};
export default ViewModal;

View File

@ -0,0 +1,145 @@
import React, { useEffect, useState } from "react";
import { Button, Table, Form, Input, Tooltip, DatePicker } from "antd";
import type { ColumnsType } from 'antd/es/table';
import { SearchOutlined, DeleteOutlined } from "@ant-design/icons";
//umi 相关
import { connect } from 'umi';
import moment from 'moment';
//接口
import { getExitInfoPage } from "../services";
import GlobalModal from '../GlobalModal/index'
//统一列表分页
import tableProps from '@/utils/tableProps'
interface Supplier {
id: string; // 作为 rowKey 用于唯一标识
supplierName: string; // 供应商名称
unit: string; // 准入部门
accessTime: string; // 准入时间
categoryName: string; // 准入品类
lastEval: string; // 最近一次评价
lastEvalDate: string; // 评价时间
supplierId: string;
categoryId: string;
}
interface ViewBlacklistModalProps {
visible: boolean;
record: any; // 用于查询详情数据
}
const ViewBlacklistModal: React.FC<ViewBlacklistModalProps> = ({
visible,
record={},
}) => {
const [loading, setLoading] = useState(false);
const [form] = Form.useForm();
const [data, setData] = useState<Supplier[]>([]);
const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 });
const [visibleGlobalModal, setVisibleGlobalModal] = useState(false);
const [id, setId] = useState('');
// 查询接口
const getList = async (pageNo = 1, pageSize = 10) => {
setLoading(true);
// 可传查询条件 form.getFieldsValue()
const values = form.getFieldsValue();
const { time } = values;
const startTime = time ? moment(time[0]).format('YYYY-MM-DD') : '';
const endTime = time ? moment(time[1]).format('YYYY-MM-DD') : '';
const { code, data } = await getExitInfoPage({ supplierexitId: record.id, pageNo, pageSize, ...values, startTime, endTime });
if (code === 200) {
setData(data.records);
setPagination(prev => ({ ...prev, current: pageNo, pageSize, total: data.total }));
}
setLoading(false);
};
// 查询
const handleSearch = () => {
setPagination({ ...pagination, current: 1 });
getList(1, pagination.pageSize);
};
// 重置
const handleReset = () => {
form.resetFields();
setPagination({ ...pagination, current: 1 });
getList(1, pagination.pageSize);
};
useEffect(() => {
if (visible && record) {
getList();
}
}, [visible, record]);
const columns: ColumnsType<Supplier> = [
{
title: "供应商名称", dataIndex: "supplierName", align: "left",
width: 360,
ellipsis: true,
render: (dom, record) => {
return (
<Tooltip title={record.supplierName} overlayStyle={{ zIndex: 1200 }}>
<a
onClick={() => {
setId(record.supplierId)
setVisibleGlobalModal(true)
}}
>
{record.supplierName}
</a>
</Tooltip>
)
}
},
{ title: "发起单位", dataIndex: "orgName", align: "center", ellipsis: true, width: 160 },
{ title: "发起部门", dataIndex: "deptName", align: "center", ellipsis: true, width: 160 },
{ title: "退出品类", dataIndex: "categoryName", align: "center", ellipsis: true, width: 160 },
{ title: "退出时间", dataIndex: "createTime", align: "center", width: 180 },
];
return (
<div>
<div className="filter-action-row">
<Form form={form} layout="inline" className="filter-form" >
<Form.Item name="exitTheme" label="供应商名称">
<Input placeholder="请输入" style={{ width: 150 }} allowClear maxLength={100} />
</Form.Item>
<Form.Item name="time" label="退出时间">
<DatePicker.RangePicker style={{ width: 220 }} allowClear />
</Form.Item>
<Form.Item>
<Button className="buttonSubmit" type="primary" htmlType="submit" icon={<SearchOutlined />} onClick={handleSearch} >
</Button>
</Form.Item>
<Form.Item>
<Button className="buttonReset" icon={<DeleteOutlined />} onClick={handleReset} ></Button>
</Form.Item>
</Form>
</div>
<Table
columns={columns}
dataSource={data}
loading={loading}
rowKey="id"
pagination={{ ...tableProps.pagination, total: pagination.total }}
onChange={(pagination) => {
getList(pagination.current, pagination.pageSize);
}}
style={{ flex: 1, minHeight: 'calc(100vh - 350px)' }}
scroll={{ y: 'calc(100vh - 350px)' }}
/>
<GlobalModal visible={visibleGlobalModal} id={id} onCancel={() => setVisibleGlobalModal(false)} />
</div>
);
};
export default connect()(ViewBlacklistModal);

View File

@ -7,7 +7,6 @@ import GlobalModal from '../GlobalModal/index'
interface ResultModalProps {
visible: boolean;
record?: { id?: string;[key: string]: any } | null;
onCancel: () => void;
dispatch: any;
}
@ -44,8 +43,6 @@ const RemarkViewModal: React.FC<{
const ResultModal: React.FC<ResultModalProps> = ({
visible,
record,
onCancel,
dispatch
}) => {
const [loading, setLoading] = useState(false);
const [suppliers, setSuppliers] = useState<any[]>([]);
@ -227,7 +224,7 @@ const ResultModal: React.FC<ResultModalProps> = ({
return (
<Table.Summary.Cell index={index} key={sup.supplierId} colSpan={colSpan} align="center">
<span style={{ color: groupSummaryResult[sup.supplierId] === '0' ? '#52c41a' : '#f5222d' }}>
{groupSummaryResult[sup.supplierId] === '0' ? '合格' : '不合格'}
{groupSummaryResult[sup.supplierId] === '0' ? '合格' : groupSummaryResult[sup.supplierId] === '1'? '不合格': ''}
</span>
</Table.Summary.Cell>
)
@ -237,7 +234,6 @@ const ResultModal: React.FC<ResultModalProps> = ({
return (
<div>
<h2 style={{ margin: '20px 0' }}></h2>
<Spin spinning={loading}>
<Table
columns={columns}

View File

@ -0,0 +1,120 @@
import React, { useState, useEffect } from 'react';
import { Descriptions, Spin } from 'antd';
import GlobalModal from '../GlobalModal/index'
import { coscoAccessWork } from '../services'
//数据接口
interface Data {
coscoAccessWork: coscoAccessWorks;
coscoAccessSupplierList: coscoAccessSupplierLists[];
coscoAccessCategoryList: coscoAccessCategoryLists[];
coscoAccessUserls: coscoAccessUserl[];
coscoAccessWorkAttachments: coscoAccessWorkAttachments;
}
interface coscoAccessWorkAttachments {
fileName: string;
fileUrl: string;
}
interface coscoAccessUserl {
deptName: string;
deptId: string;
userName: string;
userId: string;
}
interface coscoAccessCategoryLists {
categoryName: string;
[property: string]: any;
}
interface coscoAccessSupplierLists {
supplierName: string;
[property: string]: any;
}
interface coscoAccessWorks {
deptId: string;
deptName: string;
orgName: string;
startTime: string;
endTime: string;
reviewStatusText: string;
accessType: string;
accessDesc: string;
approveStatusText: string;
}
const ViewModal: React.FC<{
visible: boolean;
record?: any;
}> = ({ visible, record = {} }) => {
//渲染数据
const [data, setData] = useState<Data | null>(null);
const [loading, setLoading] = useState(false);
const [visibleGlobalModal, setVisibleGlobalModal] = useState(false);
const [id, setId] = useState('');
//初始化
useEffect(() => {
console.log(record, visible);
if (visible && record?.id) {
setLoading(true);
coscoAccessWork(record.id)
.then((res) => {
const { code, data } = res;
if (code == 200) {
setData(data);
}
})
.finally(() => setLoading(false));
} else {
setData(null);
}
}, [visible, record]);
return (
<div>
<Spin spinning={loading}>
{data && (
<Descriptions bordered column={1} labelStyle={{ width: 160 }}>
<Descriptions.Item label="供应商名称">
{data.coscoAccessSupplierList.map((item) => {
return (
<a
onClick={() => {
setId(item.supplierId)
setVisibleGlobalModal(true)
}}
>
{item.supplierName}
</a>
)
})}
</Descriptions.Item>
<Descriptions.Item label="境内/境外">{data.coscoAccessWork.orgName}</Descriptions.Item>
<Descriptions.Item label="已准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
<Descriptions.Item label="此次准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
<Descriptions.Item label="单位">{data.coscoAccessWork.orgName}</Descriptions.Item>
<Descriptions.Item label="申请部门">{data.coscoAccessWork.deptName}</Descriptions.Item>
<Descriptions.Item label="申请人">{data.coscoAccessWork.deptName}</Descriptions.Item>
<Descriptions.Item label="申请时间">{data.coscoAccessWork.deptName}</Descriptions.Item>
</Descriptions>
)}
</Spin>
<GlobalModal visible={visibleGlobalModal} id={id} onCancel={() => setVisibleGlobalModal(false)} />
</div>
);
};
export default ViewModal;

View File

@ -0,0 +1,91 @@
import React, { useEffect, useState } from 'react';
import { Spin, Descriptions } from 'antd';
import { supplierChangeApplyById } from '../services';
interface InfoItem {
fieldAnnotation?: string;
newValue?: string;
oldValue?: string;
title?: string;
changeDesc?: string;
supplierName?: string;
approveStatusText?: string;
coscoSupplierChangeHistoryList?: [];
}
interface DetailData {
fieldAnnotation?: string;
title?: string;
changeDesc?: string;
supplierName?: string;
approveStatusText?: string;
coscoSupplierChangeHistoryList: InfoItem[];
}
interface DetailViewProps {
visible: boolean;
record: any;
}
const supplierInfoChangeApproval: React.FC<DetailViewProps> = ({ visible, record={} }) => {
const [loading, setLoading] = useState(false);
const [detailData, setDetailData] = useState<DetailData | null>(null);
useEffect(() => {
if (visible && record) {
setLoading(true);
supplierChangeApplyById(record.id)
.then(res => {
if (res.code === 200) {
setDetailData(res.data);
}
})
.finally(() => setLoading(false));
}
if (!visible) setDetailData(null);
}, [visible, record]);
// 把info数组两两合并成一行显示
function renderInfoTable(infoArr: InfoItem[]) {
const rows = [];
for (let i = 0; i < infoArr.length; i++) {
rows.push(
<>
<Descriptions.Item label={`变更前-${infoArr[i].fieldAnnotation}` }>{infoArr[i].oldValue}</Descriptions.Item>
<Descriptions.Item label={`变更后-${infoArr[i].fieldAnnotation}` }>{infoArr[i].newValue}</Descriptions.Item>
</>
);
}
return (
<Descriptions bordered column={2}>
{rows}
</Descriptions>
);
}
return (
<div>
<Spin spinning={loading}>
{detailData && (
<div>
{/* 基本信息 */}
<Descriptions bordered column={1}>
<Descriptions.Item label="变更标题" labelStyle={{width: '140px'}}>{detailData?.title}</Descriptions.Item>
<Descriptions.Item label="变更说明">{detailData?.changeDesc}</Descriptions.Item>
{/* {detailData?.coscoSupplierChangeHistoryList && (
<Descriptions.Item label="附件">{detailData?.changeDesc}</Descriptions.Item>
) } */}
</Descriptions>
{/* 变更内容 */}
<div style={{ padding: '16px 0 10px 2px', color: '#333', fontSize: '14px' }}></div>
{renderInfoTable(detailData.coscoSupplierChangeHistoryList)}
</div>
)}
</Spin>
</div>
);
};
export default supplierInfoChangeApproval;

View File

@ -1,6 +1,5 @@
import React, { useState, useEffect } from 'react';
import { Modal, Descriptions, Spin } from 'antd';
import { useSupplierDetailModal } from '@/components/SupplierDetailModalContext/SupplierDetailModalContext';
import { Descriptions, Spin } from 'antd';
import GlobalModal from '../GlobalModal/index'
import { coscoAccessWork } from '../services'
@ -46,18 +45,16 @@ interface coscoAccessWorks {
const ViewModal: React.FC<{
visible: boolean;
record?: any;
onCancel: () => void;
}> = ({ visible, record = {}, onCancel }) => {
}> = ({ visible, record = {} }) => {
//渲染数据
const [data, setData] = useState < Data | null > (null);
const supplierDetailModal = useSupplierDetailModal();
const [data, setData] = useState<Data | null>(null);
const [loading, setLoading] = useState(false);
const [visibleGlobalModal, setVisibleGlobalModal] = useState(false);
const [id, setId] = useState('');
//初始化
useEffect(() => {
console.log(record,visible);
console.log(record, visible);
if (visible && record?.id) {
setLoading(true);
@ -76,12 +73,11 @@ const ViewModal: React.FC<{
return (
<div>
<h2 style={{ margin: '20px 0' }}></h2>
<Spin spinning={loading}>
{data && (
<Descriptions bordered column={1} labelStyle={{ width: 160 }}>
<Descriptions.Item label="准入单位">{data.coscoAccessWork.orgName}</Descriptions.Item>
<Descriptions.Item label="准入部门">{data.coscoAccessWork.deptName}</Descriptions.Item>
{/* <Descriptions.Item label="准入单位">{data.coscoAccessWork.orgName}</Descriptions.Item>
<Descriptions.Item label="准入部门">{data.coscoAccessWork.deptName}</Descriptions.Item> */}
<Descriptions.Item label="准入供应商">
{data.coscoAccessSupplierList.map((item) => {
return (
@ -93,13 +89,17 @@ const ViewModal: React.FC<{
>
{item.supplierName}
</a>
// <div style={{ margin: '5px', color: '#004f8e', cursor: 'pointer' }} onClick={() => supplierDetailModal?.(item.supplierId)} >{item.supplierName}</div>
)
})}
</Descriptions.Item>
{data.coscoAccessWork.accessType === 'scattered' && (
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
{/* {data.coscoAccessWork.accessType === 'scattered' && (
<>
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
@ -113,8 +113,8 @@ const ViewModal: React.FC<{
<a href={data.coscoAccessWorkAttachments.fileUrl} target="_blank" rel="noreferrer">{data.coscoAccessWorkAttachments.fileName}</a>
</Descriptions.Item>
</>
)}
{data.coscoAccessWork.accessType === 'offline' && (
)} */}
{/* {data.coscoAccessWork.accessType === 'offline' && (
<>
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
@ -127,10 +127,10 @@ const ViewModal: React.FC<{
<a href={data.coscoAccessWorkAttachments.fileUrl} target="_blank" rel="noreferrer">{data.coscoAccessWorkAttachments.fileName}</a>
</Descriptions.Item>
</>
)}
)} */}
{data.coscoAccessWork.accessType === 'online' && (
{/* {data.coscoAccessWork.accessType === 'online' && (
<>
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
@ -150,7 +150,7 @@ const ViewModal: React.FC<{
</Descriptions.Item>
<Descriptions.Item label="审批结果">{data.coscoAccessWork.approveStatusText}</Descriptions.Item>
</>
)}
)} */}
</Descriptions>
)}

View File

@ -1,10 +1,16 @@
// ViewReviewPage.tsx
import React, { useState, useEffect } from 'react';
import ResultModal from './components/ResultModal';
import ViewModal from './components/ViewModal';
import BlacklistApproval from './components/BlacklistApproval';
import ExitApproval from './components/ExitApproval';
import CategoryLibraryApproval from './components/CategoryLibraryApproval';
import CategoryLibrarySupplierApproval from './components/CategoryLibrarySupplierApproval';
import SupplierCategoryAccessApproval from './components/SupplierCategoryAccessApproval';
import SupplierInfoChangeApproval from './components/SupplierInfoChangeApproval';
import { refreshDictCache } from '@/servers/api/login';
import { encryptWithRsa } from '@/utils/encryptWithRsa';
const ViewReviewPage: React.FC = () => {
const [modalVisible, setModalVisible] = useState<boolean>(false);
const [modalRecord, setModalRecord] = useState<{ id: string } | null>(null);
@ -14,20 +20,17 @@ const ViewReviewPage: React.FC = () => {
const params = new URLSearchParams(window.location.search);
const base64 = params.get('code');
if (!base64) return;
const b64 = base64.replace(/-/g, '+').replace(/_/g, '/');
try {
// 解码
const decodedStr = atob(base64);
const p2 = new URLSearchParams(decodedStr);
const decodedStr = atob(b64);
const query = /%[0-9A-F]{2}/i.test(decodedStr) ? decodeURIComponent(decodedStr) : decodedStr;
const p2 = new URLSearchParams(query);
const id = p2.get('id') ?? '';
const code = p2.get('code') ?? '';
const userId = p2.get('userId') ?? '';
if (!id) return;
setType(code); // code 现在一定是 string
// 初始化字典
if (!sessionStorage.getItem('dict')) {
refreshDictCache().then((res) => {
@ -36,12 +39,10 @@ const ViewReviewPage: React.FC = () => {
}
});
}
// 只有在 userId 存在时再加密保存
if (userId) {
sessionStorage.setItem('userId', encryptWithRsa(userId));
}
setModalRecord({ id });
setModalVisible(true);
} catch (err) {
@ -63,21 +64,85 @@ const ViewReviewPage: React.FC = () => {
return (
<div style={{ padding: '20px' }}>
{/* 供应商准入审批, 供应商品类准入审批 */}
{['supplierAccessApproval', 'supplierCategoryAccessApproval'].includes(type) && (
{/* 供应商准入审批 */}
{['supplierAccessApproval'].includes(type) && (
<>
<ViewModal
visible={modalVisible}
record={modalRecord ?? undefined}
onCancel={() => setModalVisible(false)}
/>
<ResultModal
visible={modalVisible}
record={modalRecord ?? undefined}
onCancel={() => setModalVisible(false)}
/>
</>
)}
{/* 供应商品类准入审批 */}
{['supplierCategoryAccessApproval'].includes(type) && (
<>
<SupplierCategoryAccessApproval
visible={modalVisible}
record={modalRecord ?? undefined}
/>
</>
)}
{/* 供应商信息变更审批*/}
{['supplierInfoChangeApproval'].includes(type) && (
<>
<SupplierInfoChangeApproval
visible={modalVisible}
record={modalRecord}
/>
</>
)}
{/* 黑名单审批*/}
{['blacklistApproval'].includes(type) && (
<>
<BlacklistApproval
visible={modalVisible}
record={modalRecord}
/>
</>
)}
{/* 退出审批 ----*/}
{['exitApproval'].includes(type) && (
<>
<ExitApproval
visible={modalVisible}
record={modalRecord}
/>
</>
)}
{/* 品类库审批 */}
{['categoryLibraryApproval'].includes(type) && (
<>
<CategoryLibraryApproval
visible={modalVisible}
record={modalRecord}
/>
</>
)}
{/* 品类库供应商入库审批 */}
{['categoryLibrarySupplierApproval'].includes(type) && (
<>
<CategoryLibrarySupplierApproval
visible={modalVisible}
record={modalRecord}
/>
</>
)}
{/* 评价审批 */}
{['evaluationApproval'].includes(type) && (
<>
{/* <EvaluationApproval
visible={modalVisible}
record={modalRecord}
/> */}
</>
)}
</div>
);
};

View File

@ -36,54 +36,50 @@ export const coscoSupplierBase = (data: coscoSupplierBaseData) => request.post('
/**
* 未准入的供应商分页列表查询
*/
interface addInterface {
categoryIds: string[];
coscoAccessItems: CoscoAccessItem[];
coscoAccessUserls: CoscoAccessUserl[];
coscoAccessWork: CoscoAccessWork;
supplierIds: string[];
[property: string]: any;
}
// interface addInterface {
// categoryIds: string[];
// coscoAccessItems: CoscoAccessItem[];
// coscoAccessUserls: CoscoAccessUserl[];
// coscoAccessWork: CoscoAccessWork;
// supplierIds: string[];
// [property: string]: any;
// }
interface CoscoAccessItem {
itemName: string;
reviewBy: string[];
[property: string]: any;
}
// interface CoscoAccessItem {
// itemName: string;
// reviewBy: string[];
// [property: string]: any;
// }
interface CoscoAccessUserl {
deptId: string;
isLeader: number;
userId: string;
[property: string]: any;
}
// interface CoscoAccessUserl {
// deptId: string;
// isLeader: number;
// userId: string;
// [property: string]: any;
// }
interface CoscoAccessWork {
accessType: string;
accessWorkName: string;
deptId: string;
endTime: string;
startTime: string;
[property: string]: any;
}
export const add = (data: addInterface) => request.post('/coscoAccessWork/add', { data });
// interface CoscoAccessWork {
// accessType: string;
// accessWorkName: string;
// deptId: string;
// endTime: string;
// startTime: string;
// [property: string]: any;
// }
// export const add = (data: addInterface) => request.post('/coscoAccessWork/add', { data });
// interface getUserPage {
// basePageRequest: basePageRequest;
// userId: string;
// }
// interface basePageRequest {
// pageNo: number;
// pageSize: number;
// }
interface getUserPage {
basePageRequest: basePageRequest;
userId: string;
}
interface basePageRequest {
pageNo: number;
pageSize: number;
}
export const getUserPage = (data: getUserPage) => request.post('/v1/sysuser/getPageByUserCompany', { data });
// export const getUserPage = (data: getUserPage) => request.post('/v1/sysuser/getPageByUserCompany', { data });
/**
* 品类选择查询树
@ -94,33 +90,49 @@ export const categoryTree = () => request.get('/cosco/category/categoryTree');
*/
export const coscoAccessWork = (id: string) => request.get(`/coscoAccessWork/${id}`);
/**
* 上传文件
* @param file 上传的文件对象
* @returns 上传结果
*/
export const uploadFile = async (file: File) => {
const formData = new FormData();
formData.append('file', file);
return request('/fileConfig/files/upload', {
method: 'POST',
data: formData,
});
};
/**
* 发起审批
*/
interface startApproveData {
id: string;
}
export const startApprove = (params: startApproveData) => request.get(`/coscoAccessWork/startApprove`, { params });
export const startApprove = (params: { id:string }) => request.get(`/coscoAccessWork/startApprove`, { params });
/**
* 查看评审结果
*/
export const reviewInfoData = (params: startApproveData) => request.get(`/coscoAccessWork/reviewInfoData`, { params });
export const reviewInfoData = (params: { id:string }) => request.get(`/coscoAccessWork/reviewInfoData`, { params });
/**
* 变更
*/
export const supplierChangeApplyById = (id: string) => request.get(`/coscoSupplierChangeApply/supplierChangeApplyById/${id}` );
/**
* 黑名单
*/
export const viewBlacklist = (id: string) => request.get(`/black/blacklist/${id}`);
/**
* 退出
*/
interface getExitInfoPageData {
pageNo: number;
pageSize: number;
supplierexitId?: string;
deptId?: string;
accessType?: string;
reviewStatus?: string;
approveStatus?: string;
categoryId?: string;
exitTheme?: string;
startTime?: string;
endTime?: string;
}
export const getExitInfoPage = (data: getExitInfoPageData) => request.post('/coscoSupplierexit/getExitInfoPage', { data });
/**
* 品类库审批
*/
export const detail = (params: { id:string }) => request.get(`/cosco/library/detail`, { params });
/**
* 品类库入库审批
*/
export const applyDetail = (params: { id:string }) => request.get(`/cosco/apply/${params.id}`);
export const supplierChangeApprove = (data: { id:string; approveStatus:string }) => request.post('/synchronous/receiveApprove', { data });

View File

@ -229,7 +229,7 @@ const ResultModal: React.FC<ResultModalProps> = ({
return (
<Table.Summary.Cell index={index} key={sup.supplierId} colSpan={colSpan} align="center">
<span style={{ color: groupSummaryResult[sup.supplierId] === '0' ? '#52c41a' : '#f5222d' }}>
{groupSummaryResult[sup.supplierId] === '0' ? '合格' : '不合格'}
{groupSummaryResult[sup.supplierId] === '0' ? '合格' : groupSummaryResult[sup.supplierId] === '1'? '不合格': ''}
</span>
</Table.Summary.Cell>
)

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Modal, Table, Spin, Descriptions } from 'antd';
import { Modal, Spin, Descriptions } from 'antd';
import { supplierChangeApplyById } from '../services';
@ -97,17 +97,4 @@ const DetailView: React.FC<DetailViewProps> = ({ visible, onClose, detailId }) =
);
};
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,10 +1,10 @@
import React, { useState, useEffect } from "react";
//第三方UI库/组件
import { Modal, Form, Input, Button, Table, message, Tooltip } from "antd";
import { Modal, Form, Input, Button, Table, Tooltip } from "antd";
//类型定义
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
//umi 相关
import { useIntl } from 'umi';
// import { useIntl } from 'umi';
//本地服务/接口
import { getCategoryPage } from '../services';
//本地组件
@ -28,7 +28,7 @@ interface SupplierAccessDetailModalProps {
//主体
const SupplierAccessDetailModal: React.FC<SupplierAccessDetailModalProps> = ({ visible, onCancel, record }) => {
//双语
const intl = useIntl();
// const intl = useIntl();
//查询表单
const [form] = Form.useForm();
//列表渲染数据
@ -38,7 +38,7 @@ const SupplierAccessDetailModal: React.FC<SupplierAccessDetailModalProps> = ({ v
//列表分页
const [pagination, setPagination] = useState<TablePaginationConfig>({ current: 1, pageSize: 10, total: 0, });
//品类弹窗状态
const [addModalVisible, setAddModalVisible] = useState(false);
// const [addModalVisible, setAddModalVisible] = useState(false);
// 搜索
const handleSearch = () => {
setPagination({ ...pagination, current: 1 });