去掉无用组件以及修改准入评审列表接口,增加token 验证白名单
This commit is contained in:
10
src/app.ts
10
src/app.ts
@ -1,10 +1,10 @@
|
||||
import { history } from 'umi';
|
||||
|
||||
export function onRouteChange({ location }: any) {
|
||||
// const token = localStorage.getItem('token');
|
||||
// const whiteList = ['/login', '/user/register', '/403', '/404'];
|
||||
// if (!token && !whiteList.includes(location.pathname)) {
|
||||
// history.replace('/login');
|
||||
// }
|
||||
const token = sessionStorage.getItem('token');
|
||||
const whiteList = ['/login', '/user/register', '/403', '/404'];
|
||||
if (!token && !whiteList.includes(location.pathname)) {
|
||||
history.replace('/login');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,26 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
//导入logo图片
|
||||
import LogoImg from '@/assets/img/logo.png';
|
||||
//导入菜单组件
|
||||
import Language from './Language';
|
||||
import User from './User';
|
||||
import './layout.less';
|
||||
|
||||
|
||||
const HeaderComponent: React.FC = () => {
|
||||
// 用 state 保存 userId
|
||||
const [userId, setUserId] = useState(() => sessionStorage.getItem('userId'));
|
||||
|
||||
useEffect(() => {
|
||||
// 定义一个方法用于手动刷新 userId
|
||||
const refreshUserId = () => setUserId(sessionStorage.getItem('userId'));
|
||||
// 登录后你可以手动调用 refreshUserId
|
||||
// 或者监听页面 storage 事件(多窗口/多tab同步)
|
||||
window.addEventListener('storage', refreshUserId);
|
||||
// 页面内操作,比如登录成功后,也可以在登录回调里调用 setUserId
|
||||
return () => window.removeEventListener('storage', refreshUserId);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="headerComponent">
|
||||
<img className="logo" src={LogoImg} alt="logo" />
|
||||
|
@ -102,12 +102,14 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
|
||||
};
|
||||
//初始化
|
||||
useEffect(() => {
|
||||
categoryTree().then((res) => {
|
||||
const { code, data } = res;
|
||||
if (code == 200) {
|
||||
setCategoriesTreeData(data)
|
||||
}
|
||||
})
|
||||
if(visible) {
|
||||
categoryTree().then((res) => {
|
||||
const { code, data } = res;
|
||||
if (code == 200) {
|
||||
setCategoriesTreeData(data)
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [visible, form]);
|
||||
return (
|
||||
<Modal
|
||||
|
@ -226,14 +226,16 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
|
||||
};
|
||||
//初始化
|
||||
useEffect(() => {
|
||||
categoryTree().then((res) => {
|
||||
const { code, data } = res;
|
||||
if (code == 200) {
|
||||
setCategoriesTreeData(data)
|
||||
}
|
||||
|
||||
})
|
||||
form.setFieldsValue({ method: 'online' });
|
||||
if(visible) {
|
||||
categoryTree().then((res) => {
|
||||
const { code, data } = res;
|
||||
if (code == 200) {
|
||||
setCategoriesTreeData(data)
|
||||
}
|
||||
|
||||
})
|
||||
form.setFieldsValue({ method: 'online' });
|
||||
}
|
||||
}, [visible, form]);
|
||||
return (
|
||||
<Modal
|
||||
|
@ -8,7 +8,7 @@ interface getPageData {
|
||||
pageSize: number;
|
||||
accessWorkName?: string;
|
||||
}
|
||||
export const getPage = (data: getPageData) => request.post('/coscoAccessWork/getPage', { data});
|
||||
export const getPage = (data: getPageData) => request.post('/coscoAccessWork/getReviewPage', { data});
|
||||
/**
|
||||
* 评审修改时用的详情页
|
||||
*/
|
||||
|
@ -1,213 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Modal, Table, Button, Checkbox, Popconfirm, message, Descriptions, Spin } from 'antd';
|
||||
import { getSupplierPage, detail, apply } from "../services";
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
// 供应商类型
|
||||
interface Supplier {
|
||||
id: string;
|
||||
name: string;
|
||||
region?: string;
|
||||
creditCode?: string;
|
||||
type?: string;
|
||||
inStore?: boolean; // 已入库
|
||||
}
|
||||
|
||||
// 基本信息类型
|
||||
interface CategoryInfo {
|
||||
name?: string;
|
||||
validDate?: string;
|
||||
manager?: string;
|
||||
structure?: string;
|
||||
}
|
||||
|
||||
const SupplierAddModal: React.FC<{
|
||||
visible: boolean;
|
||||
storeId: string;
|
||||
onCancel: () => void;
|
||||
onSuccess: () => void;
|
||||
}> = ({ visible, storeId, onCancel, onSuccess }) => {
|
||||
// 供应商数据
|
||||
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
||||
// 已勾选的供应商 id
|
||||
const [selectedIds, setSelectedIds] = useState<string[]>([]);
|
||||
// 品类库基本信息
|
||||
const [categoryInfo, setCategoryInfo] = useState<CategoryInfo>({});
|
||||
// loading
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// 分页
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 拉数据
|
||||
const fetchSuppliers = async (page = 1, pageSize = 10) => {
|
||||
setLoading(true);
|
||||
const res = await getSupplierPage({ basePageRequest: { pageNo: page, pageSize } });
|
||||
setLoading(false);
|
||||
if (res.code === 200 && res.data) {
|
||||
setSuppliers((res.data.records || []).map((s: any) => ({
|
||||
...s,
|
||||
inStore: s.inStore ?? false, // 若接口无此字段,可自己加逻辑判断
|
||||
})));
|
||||
setPagination(p => ({
|
||||
...p,
|
||||
total: res.data.total || 0,
|
||||
current: res.data.current || page,
|
||||
pageSize: res.data.size || pageSize,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
// 拉取基本信息
|
||||
const fetchCategoryInfo = async () => {
|
||||
if (!storeId) return;
|
||||
const res = await detail({ id: storeId });
|
||||
if (res.code === 200 && res.data) setCategoryInfo(res.data);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
fetchSuppliers(pagination.current, pagination.pageSize);
|
||||
fetchCategoryInfo();
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [visible, storeId]);
|
||||
|
||||
// 分页变更
|
||||
const handleTableChange = (pag: any) => {
|
||||
setPagination({ ...pagination, current: pag.current, pageSize: pag.pageSize });
|
||||
fetchSuppliers(pag.current, pag.pageSize);
|
||||
};
|
||||
|
||||
// 选择供应商 checkbox 变化
|
||||
const handleSelect = (checked: boolean, id: string) => {
|
||||
setSelectedIds(checked
|
||||
? [...selectedIds, id]
|
||||
: selectedIds.filter(i => i !== id)
|
||||
);
|
||||
};
|
||||
|
||||
// “移除”操作
|
||||
const handleRemove = (id: string) => {
|
||||
setSuppliers(suppliers.map(s =>
|
||||
s.id === id ? { ...s, inStore: false } : s
|
||||
));
|
||||
message.success('移除成功');
|
||||
};
|
||||
|
||||
// 确认入库
|
||||
const handleOk = () => {
|
||||
apply({ categoryLibraryId: storeId ,supplierIds: selectedIds })
|
||||
setSelectedIds([]);
|
||||
onSuccess && onSuccess();
|
||||
};
|
||||
|
||||
// 列表列
|
||||
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' },
|
||||
{ title: '境内/境外', dataIndex: 'region', align: 'center' },
|
||||
{ title: '统一社会信用代码', dataIndex: 'creditCode', align: 'center' },
|
||||
{ title: '供应商分类', dataIndex: 'type', align: 'center' },
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
render: (text: any, record: Supplier) => {
|
||||
if (record.inStore) {
|
||||
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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(record.id)}
|
||||
onChange={e => handleSelect(e.target.checked, record.id)}
|
||||
>
|
||||
选择
|
||||
</Checkbox>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="添加供应商"
|
||||
visible={visible}
|
||||
onCancel={onCancel}
|
||||
footer={[
|
||||
<Button key="ok" type="primary" onClick={handleOk}>确认入库</Button>,
|
||||
<Button key="cancel" onClick={onCancel}>取消</Button>,
|
||||
]}
|
||||
width={820}
|
||||
bodyStyle={{ padding: 24 }}
|
||||
destroyOnClose
|
||||
>
|
||||
{/* 基本信息区 */}
|
||||
<div style={{ marginBottom: 18 }}>
|
||||
<Descriptions
|
||||
title="品类库基本信息"
|
||||
bordered
|
||||
column={2}
|
||||
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?.validDate || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="负责人">
|
||||
{categoryInfo?.manager || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="品类结构">
|
||||
{categoryInfo?.structure || '-'}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
{/* 供应商表格 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '8px 0 8px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
}}>
|
||||
<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 }),
|
||||
}}
|
||||
bordered
|
||||
/>
|
||||
</Spin>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default SupplierAddModal;
|
@ -20,7 +20,7 @@ interface LockNode extends DataNode {
|
||||
lockType: string;
|
||||
children?: LockNode[];
|
||||
}
|
||||
const SupplierAddModal: React.FC<{
|
||||
const ViewModal: React.FC<{
|
||||
visible: boolean;
|
||||
storeId: string;
|
||||
onCancel: () => void;
|
||||
@ -128,4 +128,4 @@ const SupplierAddModal: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
export default SupplierAddModal;
|
||||
export default ViewModal;
|
||||
|
@ -1,167 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Modal, Form, Input, DatePicker, Button, Tree, Select, message } from 'antd';
|
||||
|
||||
const treeData = [
|
||||
{
|
||||
title: '货物',
|
||||
key: 'goods',
|
||||
children: [
|
||||
{ title: '燃油', key: 'fuel' },
|
||||
{ title: '润滑油', key: 'oil' },
|
||||
{ title: '船用物料', key: 'marine' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '工程',
|
||||
key: 'project',
|
||||
children: [
|
||||
{ title: '土建', key: 'civil' },
|
||||
{ title: '机电', key: 'me' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '服务',
|
||||
key: 'service',
|
||||
children: [
|
||||
{ title: '运输', key: 'transport' },
|
||||
{ title: '维修', key: 'maintenance' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const regionOptions = [
|
||||
{ label: '全球', value: 'global' },
|
||||
{ label: '新加坡', value: 'singapore' },
|
||||
{ label: '香港', value: 'hongkong' },
|
||||
];
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
onCancel: () => void;
|
||||
onSuccess?: () => void;
|
||||
}
|
||||
const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) => {
|
||||
const [form] = Form.useForm();
|
||||
// 受控 checkedKeys
|
||||
const [checkedKeys, setCheckedKeys] = useState<string[]>([]);
|
||||
// 切换“选择品类”时,自动清除“区域选择”
|
||||
useEffect(() => {
|
||||
if (!visible) {
|
||||
setCheckedKeys([]);
|
||||
form.resetFields();
|
||||
}
|
||||
}, [visible]);
|
||||
// 只能同一级单选
|
||||
const handleTreeCheck = (checkedKeysValue: any, info: any) => {
|
||||
console.log(checkedKeysValue);
|
||||
|
||||
let checked = Array.isArray(checkedKeysValue) ? checkedKeysValue : checkedKeysValue.checked;
|
||||
// 记录每个一级key的选中(只保留同级最后一次点击)
|
||||
const map: Record<string, string> = {};
|
||||
checked.forEach(k => {
|
||||
const parent = treeData.find(node =>
|
||||
node.key === k || node.children?.some(c => c.key === k)
|
||||
);
|
||||
if (parent) map[parent.key] = k;
|
||||
});
|
||||
const onlyOneEachLevel = Object.values(map);
|
||||
console.log(onlyOneEachLevel,'onlyOneEachLevel');
|
||||
|
||||
|
||||
setCheckedKeys(onlyOneEachLevel); // 实时刷新
|
||||
form.setFieldsValue({ categoryKeys: onlyOneEachLevel });
|
||||
};
|
||||
|
||||
// 提交校验
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
await form.validateFields();
|
||||
message.success('提交成功(模拟)');
|
||||
onSuccess && onSuccess();
|
||||
onCancel();
|
||||
form.resetFields();
|
||||
} catch { }
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
title="新增品类库"
|
||||
onCancel={onCancel}
|
||||
footer={null}
|
||||
width={700}
|
||||
destroyOnClose
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
layout="horizontal"
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
colon={false}
|
||||
style={{ marginTop: 10 }}
|
||||
>
|
||||
<Form.Item
|
||||
label={<span>品类库名称</span>}
|
||||
name="storeName"
|
||||
rules={[{ required: true, message: '请输入品类库名称' }]}
|
||||
>
|
||||
<Input placeholder="请输入品类库名称" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={<span>有效期至</span>}
|
||||
name="validTo"
|
||||
rules={[{ required: true, message: '请选择有效期' }]}
|
||||
>
|
||||
<DatePicker style={{ width: '100%' }} placeholder="年/月/日" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={<span>负责部门</span>}
|
||||
name="ownerDept"
|
||||
rules={[{ required: true, message: '请输入品类库负责人' }]}
|
||||
>
|
||||
<Input placeholder="请输入品类库负责人" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={<span>选择品类 </span>}
|
||||
name="categoryKeys"
|
||||
required
|
||||
rules={[ { required: true, message: '请选择品类' },
|
||||
]}
|
||||
>
|
||||
<Tree
|
||||
checkable
|
||||
selectable={false}
|
||||
treeData={treeData}
|
||||
checkedKeys={checkedKeys}
|
||||
onCheck={handleTreeCheck}
|
||||
/>
|
||||
<span style={{ color: '#888', marginLeft: 4, fontWeight: 400, fontSize: 12 }}>
|
||||
(注:同一级品类不可多选)
|
||||
</span>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={<span>区域选择(仅燃油品)</span>}
|
||||
name="region"
|
||||
rules={[{ required: true, message: '请选择区域' }]}
|
||||
required
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择区域"
|
||||
style={{ width: 260 }}
|
||||
options={regionOptions}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: 'center', marginTop: 30 }}>
|
||||
<Button type="primary" style={{ width: 160 }} onClick={handleOk}>
|
||||
提交审批
|
||||
</Button>
|
||||
<Button style={{ width: 120, marginLeft: 32 }} onClick={onCancel}>
|
||||
取消
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CategoryAddModal;
|
@ -1,161 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Modal, Table, Button, Checkbox, Popconfirm, message, Descriptions } from 'antd';
|
||||
|
||||
// 示例供应商数据
|
||||
const mockSuppliers = [
|
||||
{
|
||||
id: 1,
|
||||
name: '中山市合创展包装材料有限公司',
|
||||
region: '境内',
|
||||
creditCode: '910000000000000000',
|
||||
type: '中央企业',
|
||||
inStore: false, // 还没入库
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '深圳市欧阳华斯电源有限公司',
|
||||
region: '境内',
|
||||
creditCode: '910000000000000000',
|
||||
type: '地方国有企业',
|
||||
inStore: true, // 已入库
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '广东振兴塑胶机械有限公司',
|
||||
region: '境内',
|
||||
creditCode: '910000000000000000',
|
||||
type: '民营企业',
|
||||
inStore: false, // 还没入库
|
||||
},
|
||||
];
|
||||
|
||||
const SupplierAddModal = ({ visible, onCancel, onOk, categoryInfo }) => {
|
||||
// 供应商数据(受控)
|
||||
const [suppliers, setSuppliers] = useState(mockSuppliers);
|
||||
// 已勾选的供应商 id
|
||||
const [selectedIds, setSelectedIds] = useState([]);
|
||||
|
||||
// 选择供应商 checkbox 变化
|
||||
const handleSelect = (checked, id) => {
|
||||
setSelectedIds(checked
|
||||
? [...selectedIds, id]
|
||||
: selectedIds.filter(i => i !== id)
|
||||
);
|
||||
};
|
||||
|
||||
// “移除”操作
|
||||
const handleRemove = (id) => {
|
||||
setSuppliers(suppliers.map(s =>
|
||||
s.id === id ? { ...s, inStore: false } : s
|
||||
));
|
||||
message.success('移除成功');
|
||||
};
|
||||
|
||||
// 确认入库
|
||||
const handleOk = () => {
|
||||
// 这里可调接口,演示只做提示
|
||||
message.success(`成功入库供应商ID: ${selectedIds.join(', ')}`);
|
||||
setSelectedIds([]);
|
||||
onOk && onOk();
|
||||
};
|
||||
|
||||
// 列表列
|
||||
const columns = [
|
||||
{ title: '序号', dataIndex: 'id', align: 'center', width: 60, render: (t, r, i) => i + 1 },
|
||||
{ title: '供应商名称', dataIndex: 'name', align: 'center' },
|
||||
{ title: '境内/境外', dataIndex: 'region', align: 'center' },
|
||||
{ title: '统一社会信用代码', dataIndex: 'creditCode', align: 'center' },
|
||||
{ title: '供应商分类', dataIndex: 'type', align: 'center' },
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
render: (text, record) => {
|
||||
if (record.inStore) {
|
||||
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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(record.id)}
|
||||
onChange={e => handleSelect(e.target.checked, record.id)}
|
||||
>
|
||||
选择
|
||||
</Checkbox>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="添加供应商"
|
||||
visible={visible}
|
||||
onCancel={onCancel}
|
||||
footer={[
|
||||
<Button key="ok" type="primary" onClick={handleOk}>确认入库</Button>,
|
||||
<Button key="cancel" onClick={onCancel}>取消</Button>,
|
||||
]}
|
||||
width={820}
|
||||
bodyStyle={{ padding: 24 }}
|
||||
destroyOnClose
|
||||
>
|
||||
{/* 基本信息区 */}
|
||||
<div style={{ marginBottom: 18 }}>
|
||||
<Descriptions
|
||||
title="品类库基本信息"
|
||||
bordered
|
||||
column={2}
|
||||
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?.validDate || '2028-03-31'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="负责人">
|
||||
{categoryInfo?.manager || '李四'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="品类结构">
|
||||
{categoryInfo?.structure || '货物 燃料'}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 供应商表格 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '8px 0 8px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
}}>
|
||||
<span>选择供应商</span>
|
||||
|
||||
</div>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={suppliers}
|
||||
rowKey="id"
|
||||
pagination={false}
|
||||
bordered
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default SupplierAddModal;
|
@ -1,105 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Modal, Table, Button, Checkbox, Popconfirm, message, Descriptions } from 'antd';
|
||||
|
||||
// 示例供应商数据
|
||||
const mockSuppliers = [
|
||||
{
|
||||
id: 1,
|
||||
name: '中山市合创展包装材料有限公司',
|
||||
region: '境内',
|
||||
creditCode: '910000000000000000',
|
||||
type: '中央企业',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '深圳市欧阳华斯电源有限公司',
|
||||
region: '境内',
|
||||
creditCode: '910000000000000000',
|
||||
type: '地方国有企业',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '广东振兴塑胶机械有限公司',
|
||||
region: '境内',
|
||||
creditCode: '910000000000000000',
|
||||
type: '民营企业',
|
||||
},
|
||||
];
|
||||
|
||||
const SupplierListModal = ({ visible, onCancel, onOk, categoryInfo }) => {
|
||||
// 供应商数据(受控)
|
||||
const [suppliers, setSuppliers] = useState(mockSuppliers);
|
||||
|
||||
|
||||
|
||||
// 列表列
|
||||
const columns = [
|
||||
{ title: '序号', dataIndex: 'id', align: 'center', width: 60, render: (t, r, i) => i + 1 },
|
||||
{ title: '供应商名称', dataIndex: 'name', align: 'center' },
|
||||
{ title: '境内/境外', dataIndex: 'region', align: 'center' },
|
||||
{ title: '统一社会信用代码', dataIndex: 'creditCode', align: 'center' },
|
||||
{ title: '供应商分类', dataIndex: 'type', align: 'center' },
|
||||
|
||||
];
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="供应商"
|
||||
visible={visible}
|
||||
onCancel={onCancel}
|
||||
footer={[
|
||||
<Button key="cancel" onClick={onCancel}>关闭</Button>,
|
||||
]}
|
||||
width={820}
|
||||
bodyStyle={{ padding: 24 }}
|
||||
destroyOnClose
|
||||
>
|
||||
{/* 基本信息区 */}
|
||||
<div style={{ marginBottom: 18 }}>
|
||||
<Descriptions
|
||||
title="品类库基本信息"
|
||||
bordered
|
||||
column={2}
|
||||
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?.validDate || '2028-03-31'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="负责人">
|
||||
{categoryInfo?.manager || '李四'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="品类结构">
|
||||
{categoryInfo?.structure || '货物 燃料'}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 供应商表格 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '8px 0 8px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
}}>
|
||||
<span>选择供应商</span>
|
||||
|
||||
</div>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={suppliers}
|
||||
rowKey="id"
|
||||
pagination={false}
|
||||
bordered
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default SupplierListModal;
|
@ -1,213 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Modal, Table, Button, Checkbox, Popconfirm, message, Descriptions, Spin } from 'antd';
|
||||
import { getSupplierPage, detail, apply } from "../services";
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
// 供应商类型
|
||||
interface Supplier {
|
||||
id: string;
|
||||
name: string;
|
||||
region?: string;
|
||||
creditCode?: string;
|
||||
type?: string;
|
||||
inStore?: boolean; // 已入库
|
||||
}
|
||||
|
||||
// 基本信息类型
|
||||
interface CategoryInfo {
|
||||
name?: string;
|
||||
validDate?: string;
|
||||
manager?: string;
|
||||
structure?: string;
|
||||
}
|
||||
|
||||
const SupplierAddModal: React.FC<{
|
||||
visible: boolean;
|
||||
storeId: string;
|
||||
onCancel: () => void;
|
||||
onSuccess: () => void;
|
||||
}> = ({ visible, storeId, onCancel, onSuccess }) => {
|
||||
// 供应商数据
|
||||
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
||||
// 已勾选的供应商 id
|
||||
const [selectedIds, setSelectedIds] = useState<string[]>([]);
|
||||
// 品类库基本信息
|
||||
const [categoryInfo, setCategoryInfo] = useState<CategoryInfo>({});
|
||||
// loading
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// 分页
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 拉数据
|
||||
const fetchSuppliers = async (page = 1, pageSize = 10) => {
|
||||
setLoading(true);
|
||||
const res = await getSupplierPage({ basePageRequest: { pageNo: page, pageSize } });
|
||||
setLoading(false);
|
||||
if (res.code === 200 && res.data) {
|
||||
setSuppliers((res.data.records || []).map((s: any) => ({
|
||||
...s,
|
||||
inStore: s.inStore ?? false, // 若接口无此字段,可自己加逻辑判断
|
||||
})));
|
||||
setPagination(p => ({
|
||||
...p,
|
||||
total: res.data.total || 0,
|
||||
current: res.data.current || page,
|
||||
pageSize: res.data.size || pageSize,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
// 拉取基本信息
|
||||
const fetchCategoryInfo = async () => {
|
||||
if (!storeId) return;
|
||||
const res = await detail({ id: storeId });
|
||||
if (res.code === 200 && res.data) setCategoryInfo(res.data);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
fetchSuppliers(pagination.current, pagination.pageSize);
|
||||
fetchCategoryInfo();
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [visible, storeId]);
|
||||
|
||||
// 分页变更
|
||||
const handleTableChange = (pag: any) => {
|
||||
setPagination({ ...pagination, current: pag.current, pageSize: pag.pageSize });
|
||||
fetchSuppliers(pag.current, pag.pageSize);
|
||||
};
|
||||
|
||||
// 选择供应商 checkbox 变化
|
||||
const handleSelect = (checked: boolean, id: string) => {
|
||||
setSelectedIds(checked
|
||||
? [...selectedIds, id]
|
||||
: selectedIds.filter(i => i !== id)
|
||||
);
|
||||
};
|
||||
|
||||
// “移除”操作
|
||||
const handleRemove = (id: string) => {
|
||||
setSuppliers(suppliers.map(s =>
|
||||
s.id === id ? { ...s, inStore: false } : s
|
||||
));
|
||||
message.success('移除成功');
|
||||
};
|
||||
|
||||
// 确认入库
|
||||
const handleOk = () => {
|
||||
apply({ categoryLibraryId: storeId ,supplierIds: selectedIds })
|
||||
setSelectedIds([]);
|
||||
onSuccess && onSuccess();
|
||||
};
|
||||
|
||||
// 列表列
|
||||
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' },
|
||||
{ title: '境内/境外', dataIndex: 'region', align: 'center' },
|
||||
{ title: '统一社会信用代码', dataIndex: 'creditCode', align: 'center' },
|
||||
{ title: '供应商分类', dataIndex: 'type', align: 'center' },
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
render: (text: any, record: Supplier) => {
|
||||
if (record.inStore) {
|
||||
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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(record.id)}
|
||||
onChange={e => handleSelect(e.target.checked, record.id)}
|
||||
>
|
||||
选择
|
||||
</Checkbox>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="添加供应商"
|
||||
visible={visible}
|
||||
onCancel={onCancel}
|
||||
footer={[
|
||||
<Button key="ok" type="primary" onClick={handleOk}>确认入库</Button>,
|
||||
<Button key="cancel" onClick={onCancel}>取消</Button>,
|
||||
]}
|
||||
width={820}
|
||||
bodyStyle={{ padding: 24 }}
|
||||
destroyOnClose
|
||||
>
|
||||
{/* 基本信息区 */}
|
||||
<div style={{ marginBottom: 18 }}>
|
||||
<Descriptions
|
||||
title="品类库基本信息"
|
||||
bordered
|
||||
column={2}
|
||||
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?.validDate || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="负责人">
|
||||
{categoryInfo?.manager || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="品类结构">
|
||||
{categoryInfo?.structure || '-'}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
{/* 供应商表格 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '8px 0 8px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
}}>
|
||||
<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 }),
|
||||
}}
|
||||
bordered
|
||||
/>
|
||||
</Spin>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default SupplierAddModal;
|
@ -40,7 +40,7 @@ interface columns {
|
||||
supplierCategory: string;
|
||||
}
|
||||
|
||||
const SupplierAddModal: React.FC<{
|
||||
const ViewModal: React.FC<{
|
||||
visible: boolean;
|
||||
storeId: string;
|
||||
onCancel: () => void;
|
||||
@ -148,4 +148,4 @@ const SupplierAddModal: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
export default SupplierAddModal;
|
||||
export default ViewModal;
|
||||
|
@ -1,22 +1,14 @@
|
||||
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 statusColorMap = {
|
||||
'未开始': 'default',
|
||||
'进行中': 'processing',
|
||||
'已结束': 'success',
|
||||
};
|
||||
|
||||
const resultColorMap = {
|
||||
'通过': 'success',
|
||||
'驳回': 'error',
|
||||
};
|
||||
|
||||
const regionOptions = [
|
||||
{ label: '请选择', value: '' },
|
||||
{ label: '境内', value: '境内' },
|
||||
@ -34,9 +26,21 @@ const resultOptions = [
|
||||
{ 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<any[]>([]);
|
||||
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);
|
||||
@ -78,7 +82,7 @@ const SupplierChangeManage: React.FC = () => {
|
||||
fetchData();
|
||||
};
|
||||
|
||||
const columns = [
|
||||
const columns: ColumnsType<Columns> = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
@ -94,7 +98,7 @@ const SupplierChangeManage: React.FC = () => {
|
||||
},
|
||||
{
|
||||
title: '境内/境外',
|
||||
dataIndex: 'region',
|
||||
dataIndex: 'supplierTypeCn',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
|
@ -144,7 +144,7 @@ const SupplierChangeReviewManage: React.FC<Props> = ({ dispatch }) => {
|
||||
},
|
||||
{
|
||||
title: '境内/境外',
|
||||
dataIndex: 'supplierType',
|
||||
dataIndex: 'supplierTypeCn',
|
||||
align: 'center',
|
||||
width: 160,
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useRef, useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Table, Form, Input, Button, Row, Col, DatePicker, Tabs, Space, message } from 'antd';
|
||||
import { SearchOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { SearchOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
//组件
|
||||
import SupplierViewModal from './components/SupplierViewModal';
|
||||
|
@ -22,11 +22,6 @@ interface CreateBlacklistModalProps {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const DEPT_OPTIONS = [
|
||||
{ value: "0", label: "黑名单" },
|
||||
{ value: "1", label: "灰名单" },
|
||||
];
|
||||
|
||||
const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
||||
visible,
|
||||
onOk,
|
||||
|
Reference in New Issue
Block a user