This commit is contained in:
孙景学
2025-07-16 10:28:26 +08:00
25 changed files with 397 additions and 161 deletions

View File

@ -203,7 +203,7 @@ const FileUpload: React.FC<FileUploadProps> = ({
}
return (
<Button icon={<UploadOutlined />} disabled={disabled}>
<Button type="link" icon={<UploadOutlined />} disabled={disabled}>
{buttonText || defaultButtonText}
</Button>
);

View File

@ -1,12 +1,99 @@
import React, { useState, useEffect } from 'react';
import { Button, Space, Descriptions } from 'antd';
import SupplierRegisterInfo from '@/components/GlobalModal/components/SupplierRegisterInfo';
import AccessCategoryTable from '@/components/GlobalModal/components/AccessCategoryTable';
import TianyanchaInfo from '@/components/GlobalModal/components/TianyanchaInfo';
import RiskList from '@/components/GlobalModal/components/RiskList';
import { coscoSupplierBase } from '@/components/GlobalModal/services';
import { useIntl } from 'umi';
const SupplierDetail = ({ supplierId }: { supplierId: string | null }) => {
const [supplierDetail, setSupplierDetail] = useState(null);
interface SupplierDetailProps {
supplierId: string | null;
}
const SupplierDetail: React.FC<SupplierDetailProps> = ({ supplierId }) => {
const intl = useIntl();
const [modalType, setModalType] = useState<'register' | 'category' | 'tianyancha' | 'risk'>('register');
const [registerInfo, setRegisterInfo] = useState<any>(null);
// 获取供应商信息
const fetchRegisterInfo = () => {
if (!supplierId) return;
coscoSupplierBase(supplierId).then((res) => {
const { code, data } = res;
if (code === 200) {
setRegisterInfo(data);
}
});
};
// 切换 Tab
const handleSwitch = (type: typeof modalType) => {
setModalType(type);
};
// 渲染内容
const renderContent = () => {
if (modalType === 'register' && registerInfo?.coscoSupplierBase) {
return <SupplierRegisterInfo registerInfo={registerInfo} />;
}
if (modalType === 'category') {
return supplierId ? <AccessCategoryTable id={supplierId} /> : null;
}
if (modalType === 'tianyancha') {
return supplierId ? <TianyanchaInfo id={supplierId} /> : null;
}
if (modalType === 'risk') {
return supplierId ? <RiskList id={supplierId} /> : null;
}
return null;
};
useEffect(() => {
console.log(supplierId);
if (supplierId) {
setModalType('register');
fetchRegisterInfo();
} else {
setRegisterInfo(null);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [supplierId]);
return <div>SupplierDetail</div>;
if (!supplierId) return null;
return (
(registerInfo?.coscoSupplierBase?.supplierType !== 'pe' && registerInfo) ? (
<div>
<Space style={{ marginBottom: 16 }}>
<Button type={modalType === 'register' ? 'primary' : 'default'} onClick={() => handleSwitch('register')}>{intl.formatMessage({ id: 'component.globalModal.register' })}</Button>
<Button type={modalType === 'category' ? 'primary' : 'default'} onClick={() => handleSwitch('category')}>{intl.formatMessage({ id: 'component.globalModal.category' })}</Button>
<Button type={modalType === 'tianyancha' ? 'primary' : 'default'} onClick={() => handleSwitch('tianyancha')}>{intl.formatMessage({ id: 'component.globalModal.tianyancha' })}</Button>
<Button type={modalType === 'risk' ? 'primary' : 'default'} onClick={() => handleSwitch('risk')}>{intl.formatMessage({ id: 'component.globalModal.ComplianceRisk' })}</Button>
</Space>
<div style={{ height: '600px', overflowY: 'auto' }}>
{renderContent()}
</div>
</div>
) : (
<Descriptions bordered column={3} style={{ marginBottom: 24 }} title={intl.formatMessage({ id: 'component.globalModal.supplierRegisterInfo' })}>
<Descriptions.Item label="姓名" labelStyle={{ width: '140px' }}>
<span>{registerInfo?.coscoSupplierBase?.personName}</span>
</Descriptions.Item>
<Descriptions.Item label="身份证号" labelStyle={{ width: '140px' }}>
<span>{registerInfo?.coscoSupplierBase?.idCard}</span>
</Descriptions.Item>
<Descriptions.Item label="联系电话" labelStyle={{ width: '140px' }}>
<span>{registerInfo?.coscoSupplierBase?.personPhone}</span>
</Descriptions.Item>
<Descriptions.Item label="开户行">
<span>{registerInfo?.coscoSupplierBase?.personBank}</span>
</Descriptions.Item>
<Descriptions.Item label="银行账号">
<span>{registerInfo?.coscoSupplierBase?.personAccount}</span>
</Descriptions.Item>
</Descriptions>
)
);
};
export default SupplierDetail;

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Modal } from 'antd';
import { Modal, message } from 'antd';
import SupplierDetail from './SupplierDetail';
const SupplierDetailModalContext = React.createContext<((id: string) => void) | null>(null);
@ -10,6 +10,7 @@ export const SupplierDetailModalProvider = ({ children }: { children: React.Reac
const [supplierId, setSupplierId] = useState<string | null>(null);
const showSupplierDetail = (id: string) => {
if (!id) return message.error('此供应商信息缺失,请联系管理员');
setSupplierId(id);
setVisible(true);
};
@ -17,7 +18,7 @@ export const SupplierDetailModalProvider = ({ children }: { children: React.Reac
return (
<SupplierDetailModalContext.Provider value={showSupplierDetail}>
{children}
<Modal visible={visible} onCancel={() => setVisible(false)} footer={null}>
<Modal visible={visible} onCancel={() => setVisible(false)} footer={null} width="90%">
<SupplierDetail supplierId={supplierId} />
</Modal>
</SupplierDetailModalContext.Provider>

View File

@ -1,3 +1,10 @@
// 任何页面/组件
const showSupplierDetail = useSupplierDetailModal();
<span onClick={() => showSupplierDetail(supplier.id)}>{supplier.name}</span>
// 任何组件
import { useSupplierDetailModal } from '@/components/SupplierDetailModalContext/SupplierDetailModalContext';
const MyComponent = () => {
const showSupplierDetail = useSupplierDetailModal();
return (
<a onClick={() => showSupplierDetail('123')}>查看供应商</a>
);
};

View File

@ -5,6 +5,7 @@ import { getSupplierPage } from '@/servers/api/supplier';
import CategorySelector from '@/components/CategorySelector/CategorySelector';
import './SupplierSelector.less';
import { useIntl } from 'umi';
import { useSupplierDetailModal } from '@/components/SupplierDetailModalContext/SupplierDetailModalContext';
const { Option } = Select;
@ -83,9 +84,10 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
// 查询参数
const [queryParams, setQueryParams] = useState({
pageNo: 1,
pageSize: 10
pageSize: 10,
});
const supplierDetailModal = useSupplierDetailModal();
/**
* 监听初始已选供应商变化,更新内部状态
*/
@ -129,7 +131,9 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
*/
const moveToLeft = () => {
// 过滤掉右侧选中的供应商
const remaining = chosenSuppliers.filter((item: SupplierItem) => !rightSelected.includes(item.id));
const remaining = chosenSuppliers.filter(
(item: SupplierItem) => !rightSelected.includes(item.id),
);
// 更新已选列表
setChosenSuppliers(remaining);
// 清空右侧选择状态
@ -151,18 +155,23 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
if (response && response.code === 200) {
// 请求成功,更新数据和分页信息
setTableListData(response.data.records.map((item: any) => ({
...item,
supplierName: item.name,
})));
setTableListData(
response.data.records.map((item: any) => ({
...item,
supplierName: item.name,
})),
);
setPagination({
current: queryParams.pageNo,
pageSize: queryParams.pageSize,
total: response.data.total || 0
total: response.data.total || 0,
});
} else {
// 请求失败,显示错误信息
message.error(response?.message || intl.formatMessage({ id: 'supplierTaskManage.message.fetchSupplierListFailed' }));
message.error(
response?.message ||
intl.formatMessage({ id: 'supplierTaskManage.message.fetchSupplierListFailed' }),
);
setTableListData([]);
setPagination({ current: 1, pageSize: 10, total: 0 });
}
@ -189,10 +198,10 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
*/
useEffect(() => {
const values = form.getFieldsValue();
setQueryParams(prev => ({
setQueryParams((prev) => ({
...prev,
...values,
pageNo: 1
pageNo: 1,
}));
}, []); // 空依赖数组,只在组件挂载时执行一次
@ -201,10 +210,10 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
* @param {any} values - 表单值
*/
const handleSearch = (values: any) => {
setQueryParams(prev => ({
setQueryParams((prev) => ({
...prev,
...values,
pageNo: 1
pageNo: 1,
}));
};
@ -214,10 +223,10 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
const handleReset = () => {
form.resetFields();
const values = form.getFieldsValue();
setQueryParams(prev => ({
setQueryParams((prev) => ({
...prev,
...values,
pageNo: 1
pageNo: 1,
}));
};
@ -226,18 +235,13 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
* @param {any} paginationInfo - 分页信息
*/
const handleTableChange = (paginationInfo: any) => {
setQueryParams(prev => ({
setQueryParams((prev) => ({
...prev,
pageNo: paginationInfo.current,
pageSize: paginationInfo.pageSize
pageSize: paginationInfo.pageSize,
}));
};
// 显示供应商详情
const showSupplierDetail = (record: SupplierItem) => {
console.log(record);
};
// 表格列定义
const columns = [
{
@ -247,7 +251,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
ellipsis: true,
render: (supplierName: string, record: SupplierItem) => (
<Tooltip placement="topLeft" title={supplierName}>
<span onClick={()=>showSupplierDetail(record)}>{supplierName}</span>
<Button type="link" onClick={() => supplierDetailModal?.(record.id)}>{supplierName}</Button>
</Tooltip>
),
},
@ -273,34 +277,61 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
</Tooltip>
),
},
];
return (
<div className="supplier-selector">
{/* 查询表单 */}
<Form layout="inline" form={form} onFinish={handleSearch} style={{ marginBottom: 30 }}>
<Form.Item name="name" label={intl.formatMessage({ id: 'supplierTaskManage.form.supplierName' })}>
<Input placeholder={intl.formatMessage({ id: 'supplierTaskManage.placeholder.supplierName' })} allowClear />
<Form.Item
name="name"
label={intl.formatMessage({ id: 'supplierTaskManage.form.supplierName' })}
>
<Input
placeholder={intl.formatMessage({ id: 'supplierTaskManage.placeholder.supplierName' })}
allowClear
/>
</Form.Item>
<Form.Item name="deptId" label={intl.formatMessage({ id: 'supplierTaskManage.form.department' })}>
<Select placeholder={intl.formatMessage({ id: 'supplierTaskManage.placeholder.selectDepartment' })} allowClear style={{ width: 150 }}>
<Option value="1">{intl.formatMessage({ id: 'supplierTaskManage.department.purchase' })}</Option>
<Option value="2">{intl.formatMessage({ id: 'supplierTaskManage.department.technology' })}</Option>
<Option value="3">{intl.formatMessage({ id: 'supplierTaskManage.department.quality' })}</Option>
<Form.Item
name="deptId"
label={intl.formatMessage({ id: 'supplierTaskManage.form.department' })}
>
<Select
placeholder={intl.formatMessage({
id: 'supplierTaskManage.placeholder.selectDepartment',
})}
allowClear
style={{ width: 150 }}
>
<Option value="1">
{intl.formatMessage({ id: 'supplierTaskManage.department.purchase' })}
</Option>
<Option value="2">
{intl.formatMessage({ id: 'supplierTaskManage.department.technology' })}
</Option>
<Option value="3">
{intl.formatMessage({ id: 'supplierTaskManage.department.quality' })}
</Option>
</Select>
</Form.Item>
<Form.Item name="categoryId" label={intl.formatMessage({ id: 'supplierTaskManage.form.category' })}>
<Form.Item
name="categoryId"
label={intl.formatMessage({ id: 'supplierTaskManage.form.category' })}
>
<CategorySelector multiple={false} style={{ width: 150 }} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">{intl.formatMessage({ id: 'supplierTaskManage.button.search' })}</Button>
<Button type="primary" htmlType="submit">
{intl.formatMessage({ id: 'supplierTaskManage.button.search' })}
</Button>
</Form.Item>
<Form.Item>
<Button onClick={handleReset}>{intl.formatMessage({ id: 'supplierTaskManage.button.reset' })}</Button>
<Button onClick={handleReset}>
{intl.formatMessage({ id: 'supplierTaskManage.button.reset' })}
</Button>
</Form.Item>
</Form>
@ -310,13 +341,18 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
<Col span={10}>
<div className="list-title">
{intl.formatMessage({ id: 'supplierTaskManage.text.availableSuppliers' })}
<span className="search-count">{intl.formatMessage({ id: 'supplierTaskManage.text.itemCount' }, { count: pagination.total })}</span>
<span className="search-count">
{intl.formatMessage(
{ id: 'supplierTaskManage.text.itemCount' },
{ count: pagination.total },
)}
</span>
</div>
<Table
rowSelection={{
type: 'checkbox',
onChange: setLeftSelected,
selectedRowKeys: leftSelected
selectedRowKeys: leftSelected,
}}
rowKey="id"
dataSource={tableListData}
@ -346,13 +382,18 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
<Col span={10}>
<div className="list-title">
{intl.formatMessage({ id: 'supplierTaskManage.text.selectedSuppliers' })}
<span className="search-count">{intl.formatMessage({ id: 'supplierTaskManage.text.itemCount' }, { count: chosenSuppliers.length })}</span>
<span className="search-count">
{intl.formatMessage(
{ id: 'supplierTaskManage.text.itemCount' },
{ count: chosenSuppliers.length },
)}
</span>
</div>
<Table
rowSelection={{
type: 'checkbox',
onChange: setRightSelected,
selectedRowKeys: rightSelected
selectedRowKeys: rightSelected,
}}
columns={columns}
dataSource={chosenSuppliers}