登录与品类

This commit is contained in:
孙景学
2025-08-04 16:06:23 +08:00
parent ad4efd8e46
commit b5cb08deb5
29 changed files with 665 additions and 270 deletions

View File

@ -5,22 +5,31 @@ import SupplierSelector from './SupplierSelector';
import AccessDepartmentSelect from '@/components/AccessDepartmentSelect';
// 请求
import { categoryTree, add } from '../services';
interface CategoryNode {
key: string;
pathName: string;
path: string;
title: string;
children?: CategoryNode[];
}
function flattenTree(
function getKeyTitlePathMap(
tree: CategoryNode[],
map: Record<string, string> = {}
): Record<string, string> {
keyTitleMap: Record<string, string> = {},
keyPathMap: Record<string, string> = {},
keyIdMap: Record<string, string> = {}
) {
tree.forEach((node) => {
map[node.key] = node.title;
if (node.children) flattenTree(node.children, map);
keyTitleMap[node.key] = node.title;
keyPathMap[node.key] = node.pathName;
keyIdMap[node.key] = node.path;
if (node.children && node.children.length > 0) {
getKeyTitlePathMap(node.children, keyTitleMap, keyPathMap, keyIdMap);
}
});
return map;
}
return { keyTitleMap, keyPathMap, keyIdMap };
}
// 主体
const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ visible, onCancel }) => {
@ -76,14 +85,16 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
const leafKeys = findLeafKeys(convertTreeData(categoriesTreeData));
const onlyLeafChecked = keys.filter(key => leafKeys.includes(String(key)));
// 平铺tree获取id=>title映射
const keyTitleMap = flattenTree(convertTreeData(categoriesTreeData));
// 拼 categoryItem 数组
const coscoAccessCategoryList = onlyLeafChecked.map((id) => ({
categoryId: id,
categoryName: keyTitleMap[id] || '',
}));
// 获取映射
const { keyTitleMap, keyPathMap, keyIdMap } = getKeyTitlePathMap(convertTreeData(categoriesTreeData));
// 拼 categoryItem 数组
const coscoAccessCategoryList = onlyLeafChecked.map((id) => ({
categoryId: id,
categoryName: keyTitleMap[id] || '',
categoryPathName: keyPathMap[id] || '',
categoryPathId: keyIdMap[id] || '',
}));
setCheckedKeys(keys); // UI 显示用,还是全量
form.setFieldsValue({ categoryIds: onlyLeafChecked, coscoAccessCategoryList }); // 只存叶子到表单

View File

@ -67,7 +67,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>

View File

@ -67,7 +67,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>

View File

@ -86,7 +86,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
@ -101,7 +101,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
@ -117,7 +117,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>

View File

@ -43,7 +43,7 @@ const SupplierEntryReview: React.FC = () => {
const [loading, setLoading] = useState(false);
const [modalInfo, setModalInfo] = useState<ModalInfo>({ visible: false, record: null });
//
const [enterpriseType, setEnterpriseType] = useState<Dict[]>();
const [enterpriseType, setEnterpriseType] = useState<Dict[]>();
// 查询数据
const fetchData = async (params = {}) => {
setLoading(true);
@ -75,11 +75,11 @@ const SupplierEntryReview: React.FC = () => {
useEffect(() => {
fetchData({ pageNo: 1 });
getDictList('approve_type').then((res) => {
if (res.code == 200) {
setEnterpriseType(res.data)
}
})
getDictList('approve_type').then((res) => {
if (res.code == 200) {
setEnterpriseType(res.data)
}
})
}, []);
// 表格分页切换
@ -146,18 +146,18 @@ const SupplierEntryReview: React.FC = () => {
dataIndex: 'categoryNameList',
width: 120,
align: 'center',
render: (value: { item: string }[] = []) => {
render: (value: { categoryName: string; categoryPathName: string }[] = []) => {
if (!value || value.length === 0) return '-';
if (value.length === 1) {
return <span>{value[0]}</span>;
}
// 多于1条
const allNames = value.map(item => item).join('');
const allNames = value.map(item => item.categoryPathName).join('\n');
return (
<Tooltip title={allNames} overlayStyle={{ zIndex: 1200 }}>
<Tooltip title={<pre style={{ margin: 0, fontSize: 12, fontFamily: '微软雅黑', whiteSpace: 'pre-wrap' }}>{allNames}</pre>} overlayStyle={{ zIndex: 1200 }}>
<span>
{value[0]}
<span></span>
{value[0].categoryName}
{value.length !== 1 && (
<span></span>
)}
</span>
</Tooltip>
);
@ -213,7 +213,7 @@ const SupplierEntryReview: React.FC = () => {
onFinish={handleSearch}
>
<Form.Item name="accessType" label="准入方式">
<AdmissionTypeSelect/>
<AdmissionTypeSelect />
</Form.Item>
<Form.Item name="deptId" label="准入部门">
<AccessDepartmentSelect orgCategory='' />

View File

@ -28,20 +28,28 @@ interface ReviewerSelectorData {
interface CategoryNode {
key: string;
pathName: string;
path: string;
title: string;
children?: CategoryNode[];
}
function flattenTree(
function getKeyTitlePathMap(
tree: CategoryNode[],
map: Record<string, string> = {}
): Record<string, string> {
keyTitleMap: Record<string, string> = {},
keyPathMap: Record<string, string> = {},
keyIdMap: Record<string, string> = {}
) {
tree.forEach((node) => {
map[node.key] = node.title;
if (node.children) flattenTree(node.children, map);
keyTitleMap[node.key] = node.title;
keyPathMap[node.key] = node.pathName;
keyIdMap[node.key] = node.path;
if (node.children && node.children.length > 0) {
getKeyTitlePathMap(node.children, keyTitleMap, keyPathMap, keyIdMap);
}
});
return map;
}
return { keyTitleMap, keyPathMap, keyIdMap };
}
// 主体
const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ visible, onCancel }) => {
@ -106,12 +114,15 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
const leafKeys = findLeafKeys(convertTreeData(categoriesTreeData));
const onlyLeafChecked = keys.filter(key => leafKeys.includes(String(key)));
// 平铺tree获取id=>title映射
const keyTitleMap = flattenTree(convertTreeData(categoriesTreeData));
// 获取映射
const { keyTitleMap, keyPathMap, keyIdMap } = getKeyTitlePathMap(convertTreeData(categoriesTreeData));
// 拼 categoryItem 数组
const coscoAccessCategoryList = onlyLeafChecked.map((id) => ({
categoryId: id,
categoryName: keyTitleMap[id] || '',
categoryPathName: keyPathMap[id] || '',
categoryPathId: keyIdMap[id] || '',
}));
setCheckedKeys(keys); // UI 显示用,还是全量

View File

@ -89,7 +89,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
@ -104,7 +104,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
@ -120,7 +120,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>

View File

@ -90,7 +90,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
@ -105,7 +105,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>
@ -120,7 +120,7 @@ const ViewModal: React.FC<{
<Descriptions.Item label="申请准入品类">
{data.coscoAccessCategoryList.map((item) => {
return (
<div style={{ margin: '5px' }}>{item.categoryName}</div>
<div style={{ margin: '5px' }}>{item.categoryPathName}</div>
)
})}
</Descriptions.Item>

View File

@ -117,18 +117,18 @@ const CooperateEnterprise: React.FC = () => {
dataIndex: 'categoryNameList',
align: 'center',
width: 160,
render: (value: { item: string }[] = []) => {
render: (value: { categoryName: string; categoryPathName: string }[] = []) => {
if (!value || value.length === 0) return '-';
if (value.length === 1) {
return <span>{value[0]}</span>;
}
// 多于1条
const allNames = value.map(item => item).join('');
const allNames = value.map(item => item.categoryPathName).join('\n');
return (
<Tooltip title={allNames} overlayStyle={{ zIndex: 1200 }}>
<Tooltip title={<pre style={{ margin: 0, fontSize: 12, fontFamily: '微软雅黑', whiteSpace: 'pre-wrap' }}>{allNames}</pre>} overlayStyle={{ zIndex: 1200 }}>
<span>
{value[0]}
<span></span>
{value[0].categoryName}
{value.length !== 1 && (
<span></span>
)}
</span>
</Tooltip>
);

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { useIntl } from 'umi';
import { Form, Button, Table, DatePicker } from 'antd';
import { Form, Button, Table, DatePicker, Tooltip } from 'antd';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import { SearchOutlined, DeleteOutlined } from '@ant-design/icons';
//接口
@ -20,6 +20,7 @@ interface Data {
createTime: string;
exitTime: string;
exitReason: string;
categoryPathName: string;
}
const CooperateEnterprise: React.FC = () => {
@ -91,11 +92,23 @@ const CooperateEnterprise: React.FC = () => {
key: 'deptName',
ellipsis: true
},
{
title: '准入品类',
dataIndex: 'categoryName',
key: 'categoryName',
ellipsis: true
ellipsis: true,
width: 120,
align: 'center',
render: (_:any, item:{ categoryName:string; categoryPathName:string; }) => {
return (
<Tooltip title={<pre style={{ margin: 0, fontSize: 12, fontFamily: '微软雅黑', whiteSpace: 'pre-wrap' }}>{item.categoryPathName}</pre>} overlayStyle={{ zIndex: 1200 }}>
<span>
{item.categoryName}
</span>
</Tooltip>
);
},
},
{
title: '准入时间',

View File

@ -35,13 +35,15 @@ function collectSelectedNodesWithParents(
): { id: string; categoryName: string; lockType: number; categoryType: string }[] {
const allKeysSet = collectCheckedWithParents(nodes, checkedKeys);
const result: { id: string; categoryName: string; lockType: number; categoryType: string }[] = [];
const result: { id: string; categoryName: string; lockType: number; categoryType: string; categoryPathName: string; categoryPathId: string }[] = [];
function dfs(list: TreeNodeType[]) {
list.forEach(node => {
if (allKeysSet.has(node.key)) {
result.push({
id: node.key,
categoryName: node.categoryName,
categoryPathName: node.pathName,
categoryPathId: node.path,
lockType: 0,
categoryType: node.children?.length === 0 ? '1' : '0',
});

View File

@ -142,13 +142,29 @@ const mySupplierInquiry: React.FC<mySupplierInquiryProps> = ({ dispatch }) => {
width: 120,
render: (code: string) => enterpriseTypeMap[code] || code
},
{
title: '准入品类',
dataIndex: 'categoryName',
key: 'categoryName',
dataIndex: 'categoryNameList',
align: 'center',
width: 120,
ellipsis: true,
render: (value: { categoryName: string; categoryPathName: string }[] = []) => {
if (!value || value.length === 0) return '-';
// 多于1条
const allNames = value.map(item => item.categoryPathName).join('\n');
return (
<Tooltip title={<pre style={{ margin: 0, fontSize: 12, fontFamily: '微软雅黑', whiteSpace: 'pre-wrap' }}>{allNames}</pre>} overlayStyle={{ zIndex: 1200 }}>
<span>
{value[0].categoryName}
{value.length !== 1 && (
<span></span>
)}
</span>
</Tooltip>
);
},
},
{
title: '准入时间',

View File

@ -17,6 +17,8 @@ interface Supplier {
lastEvalDate: string; // 评价时间
supplierId: string;
categoryId: string;
categoryPathId: string;
categoryPathName: string;
}
interface CreateBlacklistModalProps {
@ -73,9 +75,14 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
} = {
coscoSupplierexit: {...values},
supplierIdList: suppliers.map((item) => item.supplierId),
coscoSupplierexitSupplierCategoryList: suppliers.map((item) => ({ supplierId: item.supplierId, categoryId: item.categoryId, categoryName: item.categoryName }))
coscoSupplierexitSupplierCategoryList: suppliers.map((item) => ({
supplierId: item.supplierId,
categoryId: item.categoryId,
categoryName: item.categoryName,
categoryPathName: item.categoryPathName,
categoryPathId: item.categoryPathId,
}))
}
const res = await add(payload);
if (res?.success) {
message.success("提交成功");

View File

@ -21,6 +21,8 @@ interface Supplier {
lastEvalDate: string; // 评价时间
supplierId: string;
categoryId: string;
categoryPathName: string;
categoryPathId: string;
}
interface SupplierSelectModalProps {