供应商联系人
This commit is contained in:
@ -4,7 +4,7 @@ import { UploadOutlined } from '@ant-design/icons';
|
||||
import { categoryTree, uploadFile, superiorLockList, getSupplierPage, library, libraryData } from '../services';
|
||||
import type { UploadFile } from 'antd/es/upload/interface';
|
||||
import AccessDepartmentSelect from '@/components/AccessDepartmentSelect';
|
||||
import { getregionInternational } from '@/servers/api/register';
|
||||
import { getregionInternational, getAllAreaList } from '@/servers/api/register';
|
||||
const { Option } = Select;
|
||||
|
||||
const approveTypeOptions = [
|
||||
@ -136,7 +136,7 @@ const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) =>
|
||||
form.resetFields();
|
||||
}
|
||||
init(visible)
|
||||
getregionInternational().then(res => {
|
||||
getAllAreaList().then(res => {
|
||||
if (res.code === 200) {
|
||||
setRegionOptions(res.data);
|
||||
}
|
||||
@ -282,7 +282,7 @@ const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) =>
|
||||
<Select placeholder="请选择区域">
|
||||
{
|
||||
regionOptions.map((item) => {
|
||||
return <Option value={item.id}>{item.name}</Option>
|
||||
return <Option value={item.id}>{item.dicName}</Option>
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
@ -365,7 +365,7 @@ const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) =>
|
||||
</Form.Item>
|
||||
);
|
||||
}}
|
||||
</Form.Item> {/* ✅ 外层 Form.Item 正确闭合 */}
|
||||
</Form.Item>
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,18 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Modal, Table, Button, Checkbox, Popconfirm, message, Descriptions, Spin } from 'antd';
|
||||
import { getSupplierPage, detail, apply } from "../services";
|
||||
import { Modal, Table, Button, Checkbox, Form, Select, message, Descriptions, Tooltip, Upload } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import type { UploadFile } from 'antd/es/upload/interface';
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
//接口
|
||||
import { getSupplierPage, detail, apply, uploadFile } from "../services";
|
||||
//统一列表分页
|
||||
import tableProps from '@/utils/tableProps'
|
||||
import { useSupplierDetailModal } from '@/components/SupplierDetailModalContext/SupplierDetailModalContext';
|
||||
const approveTypeOptions = [
|
||||
{ label: '是', value: 'online' },
|
||||
{ label: '否', value: 'offline' },
|
||||
];
|
||||
|
||||
// 供应商类型
|
||||
interface Supplier {
|
||||
id: string;
|
||||
@ -31,6 +42,7 @@ const SupplierAddModal: React.FC<{
|
||||
onCancel: () => void;
|
||||
onSuccess: () => void;
|
||||
}> = ({ visible, storeId, onCancel, onSuccess }) => {
|
||||
const [form] = Form.useForm();
|
||||
// 供应商数据
|
||||
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
||||
// 已勾选的供应商 id
|
||||
@ -40,6 +52,9 @@ const SupplierAddModal: React.FC<{
|
||||
// loading
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const supplierDetailModal = useSupplierDetailModal();
|
||||
//供应商符合性审查
|
||||
const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
|
||||
// 分页
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
@ -54,11 +69,11 @@ const SupplierAddModal: React.FC<{
|
||||
setLoading(false);
|
||||
if (res.code === 200 && res.data) {
|
||||
const inStoreSupplierIds = Array.isArray(inStoreList)
|
||||
? inStoreList.map((s: any) => typeof s === 'string' ? s : s.id)
|
||||
: [];
|
||||
? inStoreList.map((s: any) => typeof s === 'string' ? s : s.id)
|
||||
: [];
|
||||
setSuppliers((res.data.records || []).map((s: any) => ({
|
||||
...s,
|
||||
inStore: inStoreSupplierIds.includes(s.id),
|
||||
inStore: inStoreSupplierIds.includes(s.id),
|
||||
})));
|
||||
setPagination(p => ({
|
||||
...p,
|
||||
@ -74,7 +89,7 @@ const SupplierAddModal: React.FC<{
|
||||
if (!storeId) return;
|
||||
const res = await detail({ id: storeId });
|
||||
if (res.code === 200 && res.data) setCategoryInfo(res.data);
|
||||
fetchSuppliers(pagination.current, pagination.pageSize, res.data.suppliers || []);
|
||||
fetchSuppliers(pagination.current, pagination.pageSize, res.data.suppliers || []);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -99,33 +114,91 @@ const SupplierAddModal: React.FC<{
|
||||
};
|
||||
|
||||
// “移除”操作
|
||||
const handleRemove = (id: string) => {
|
||||
setSuppliers(suppliers.map(s =>
|
||||
s.id === id ? { ...s, inStore: false } : s
|
||||
));
|
||||
message.success('移除成功');
|
||||
};
|
||||
// const handleRemove = (id: string) => {
|
||||
// setSuppliers(suppliers.map(s =>
|
||||
// s.id === id ? { ...s, inStore: false } : s
|
||||
// ));
|
||||
// message.success('移除成功');
|
||||
// };
|
||||
|
||||
// 确认入库
|
||||
const handleOk = () => {
|
||||
if(selectedIds.length === 0) {
|
||||
const handleOk = async () => {
|
||||
if (selectedIds.length === 0) {
|
||||
message.warning('请选择入库供应商');
|
||||
return
|
||||
}
|
||||
apply({ categoryLibraryId: storeId ,supplierIds: selectedIds })
|
||||
const values = await form.validateFields();
|
||||
if(values.approveType === 'offline') {
|
||||
if (values.attachments.length === 0) {
|
||||
message.warning('请上传附件');
|
||||
return
|
||||
}
|
||||
} else if(!values.approveType) {
|
||||
message.warning('请选择签报');
|
||||
return
|
||||
}
|
||||
//
|
||||
if(values.attachments && values.attachments.length > 0) {
|
||||
values.coscoCategoryLibrarAttachments = {
|
||||
...values.attachments[0].response,
|
||||
fileUrl: values.attachments[0].response.url,
|
||||
attachmentsType: 'accessory'
|
||||
}
|
||||
}
|
||||
|
||||
apply({ categoryLibraryId: storeId, supplierIds: selectedIds, ...values })
|
||||
setSelectedIds([]);
|
||||
onSuccess && onSuccess();
|
||||
};
|
||||
|
||||
// 自定义上传
|
||||
const handleCustomRequest = async (options: any) => {
|
||||
const { file, onSuccess, onError } = options;
|
||||
try {
|
||||
// 1. 调用你自己写的上传接口
|
||||
const res = await uploadFile(file);
|
||||
// 2. 可根据后端返回结构,给 fileList 项增加 url 或其他字段
|
||||
const uploadedFile: UploadFile = {
|
||||
...file,
|
||||
status: 'done',
|
||||
url: res?.data?.url || res?.url, // 按后端返回实际字段
|
||||
name: res?.data?.name || file.name,
|
||||
coscoAccessWorkAttachments: res
|
||||
};
|
||||
setFileList([uploadedFile]);
|
||||
// 同步到 Form
|
||||
form.setFieldsValue({ supplierCompliance: [uploadedFile] });
|
||||
|
||||
onSuccess && onSuccess(res, file);
|
||||
message.success('上传成功');
|
||||
} catch (e) {
|
||||
onError && onError(e);
|
||||
message.error('上传失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 列表列
|
||||
const columns: ColumnsType<Supplier> = [
|
||||
{ title: '序号', dataIndex: 'id', align: 'center', width: 60, render: (t: any, r: any, i: number) => (pagination.current - 1) * pagination.pageSize + i + 1 },
|
||||
{ title: '供应商名称', dataIndex: 'name', align: 'center', ellipsis: true },
|
||||
{ title: '境内/境外', dataIndex: 'supplierType', align: 'center',
|
||||
render: (ext: any, record: any) => (<span>{`${record.supplierCategory === 'dvs'? '境内企业':'境外企业'}`}</span>) },
|
||||
{ title: '统一社会信用代码', dataIndex: 'socialCreditCode', align: 'center', ellipsis: true },
|
||||
{ title: '企业类型', dataIndex: 'categoryName', align: 'center' , ellipsis: true },
|
||||
|
||||
{
|
||||
title: "供应商名称", dataIndex: "name", align: "left",
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
render: (dom, record) => {
|
||||
return (
|
||||
<Tooltip>
|
||||
<a onClick={() => supplierDetailModal?.(record.id)}>{record.name || ''}</a>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '境内/境外', dataIndex: 'supplierType', align: 'center',
|
||||
render: (ext: any, record: any) => (<span>{`${record.supplierCategory === 'dvs' ? '境内企业' : '境外企业'}`}</span>)
|
||||
},
|
||||
{ title: '统一社会信用代码', dataIndex: 'unifiedCode', align: 'center', ellipsis: true },
|
||||
{ title: '企业类型', dataIndex: 'categoryName', align: 'center', ellipsis: true },
|
||||
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
@ -134,14 +207,6 @@ const SupplierAddModal: React.FC<{
|
||||
return (
|
||||
<>
|
||||
<span style={{ color: '#aaa' }}>已入库</span>
|
||||
{/* <Popconfirm
|
||||
title="确认移除该供应商?"
|
||||
onConfirm={() => handleRemove(record.id)}
|
||||
okText="确认"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Button size="small" type="link" danger style={{ marginLeft: 6 }}>移除</Button>
|
||||
</Popconfirm> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -180,23 +245,117 @@ const SupplierAddModal: React.FC<{
|
||||
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?.deptName || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="区域选择">
|
||||
{categoryInfo?.area || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="品类结构">
|
||||
{categoryInfo?.categoryName || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="品类库名称">
|
||||
{categoryInfo?.name || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="有效期至">
|
||||
{categoryInfo?.termOfValidity || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="负责部门">
|
||||
{categoryInfo?.deptName || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="区域选择">
|
||||
{categoryInfo?.area || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="品类结构">
|
||||
{categoryInfo?.categoryName || '-'}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
{/* 供应商表格 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '8px 0 8px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
}}>
|
||||
<span>选择签报</span>
|
||||
</div>
|
||||
<Form
|
||||
form={form}
|
||||
layout="horizontal"
|
||||
colon={false}
|
||||
onValuesChange={(changedValues) => {
|
||||
if ('approveType' in changedValues) {
|
||||
form.validateFields(['attachments']); // 手动校验附件
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
label="是否已走OA签报"
|
||||
name="approveType"
|
||||
rules={[{ required: true, message: '请选择否已走OA签报' }]}
|
||||
required
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择否已走OA签报"
|
||||
style={{ width: 260 }}
|
||||
options={approveTypeOptions}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item shouldUpdate={(prev, curr) => prev.approveType !== curr.approveType}>
|
||||
{() => {
|
||||
const isAttachmentRequired = form.getFieldValue('approveType') === 'offline';
|
||||
|
||||
return (
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
{isAttachmentRequired && <span style={{ color: 'red' }}>*</span>}
|
||||
附件(OA签报证明文件)
|
||||
</span>
|
||||
}
|
||||
name="attachments"
|
||||
rules={[
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (isAttachmentRequired && (!value || value.length === 0)) {
|
||||
return Promise.reject('请上传OA签报附件');
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
]}
|
||||
valuePropName="fileList"
|
||||
getValueFromEvent={(e) => (Array.isArray(e) ? e : e?.fileList)}
|
||||
>
|
||||
<Upload
|
||||
fileList={fileList}
|
||||
customRequest={handleCustomRequest}
|
||||
beforeUpload={(file) => {
|
||||
if (fileList.length >= 1) {
|
||||
message.error('只能上传一个文件');
|
||||
return Upload.LIST_IGNORE;
|
||||
}
|
||||
return true;
|
||||
}}
|
||||
onChange={({ fileList: newFileList }) => {
|
||||
setFileList(newFileList);
|
||||
form.setFieldsValue({
|
||||
supplierCompliance: newFileList,
|
||||
attachments: newFileList,
|
||||
});
|
||||
}}
|
||||
onRemove={(file) => {
|
||||
const newList = fileList.filter(item => item.uid !== file.uid);
|
||||
setFileList(newList);
|
||||
form.setFieldsValue({
|
||||
supplierCompliance: newList,
|
||||
attachments: newList,
|
||||
});
|
||||
}}
|
||||
accept=".pdf,.doc,.docx"
|
||||
maxCount={1}
|
||||
>
|
||||
<Button icon={<UploadOutlined />}>点击上传文件</Button>
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
);
|
||||
}}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
{/* 供应商表格 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
@ -207,23 +366,18 @@ const SupplierAddModal: React.FC<{
|
||||
}}>
|
||||
<span>选择供应商</span>
|
||||
</div>
|
||||
<Spin spinning={loading}>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={suppliers}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
current: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
total: pagination.total,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
onChange: (page, pageSize) => handleTableChange({ current: page, pageSize }),
|
||||
}}
|
||||
style={{ flex: 1, minHeight: 0 }}
|
||||
scroll={{ y: 'calc(100vh - 650px)' }}
|
||||
/>
|
||||
</Spin>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={suppliers}
|
||||
loading={loading}
|
||||
rowKey="id"
|
||||
pagination={{ ...tableProps.pagination, total: pagination.total }}
|
||||
onChange={(pagination) => {
|
||||
handleTableChange({ current: pagination.current!, pageSize: pagination.pageSize! })
|
||||
}}
|
||||
style={{ flex: 1, minHeight: 0 }}
|
||||
scroll={{ y: 'calc(100vh - 650px)' }}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user