From b5cb08deb5ca1dde1d456170b67d1ca9df6d9d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=99=AF=E5=AD=A6?= <5412262+sun_jing_xue@user.noreply.gitee.com> Date: Mon, 4 Aug 2025 16:06:23 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E4=B8=8E=E5=93=81=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/proxy.ts | 4 +- .../CategorySelector/CategorySelector.tsx | 2 +- .../component/ContactsInfoFormModal.tsx | 32 ++- .../CompanyInfo/component/ContactsInfoTab.tsx | 14 +- .../GlobalModal/components/ContactsInfo.tsx | 22 +- src/layouts/BasicLayout.tsx | 169 +++++++++------ src/layouts/Header.tsx | 31 +-- src/layouts/User.tsx | 95 ++++++++- src/layouts/layout.less | 26 ++- src/locales/en-US/login.ts | 2 +- src/locales/zh-CN/login.ts | 2 +- src/models/tab.ts | 192 ++++++++++++++++++ src/models/user.ts | 90 ++++---- .../supplierAdmissionStatistics.tsx | 19 +- src/pages/login/login.tsx | 43 ++-- .../components/CreateModal.tsx | 41 ++-- .../components/ViewModal.tsx | 2 +- .../components/ViewModal.tsx | 2 +- .../components/ViewModal.tsx | 6 +- .../admission/SupplierEntryReview/index.tsx | 30 +-- .../components/CreateModal.tsx | 29 ++- .../components/ViewModal.tsx | 6 +- .../components/ViewModal.tsx | 6 +- .../admissionReviewManagement/index.tsx | 16 +- .../backend/cooperateEnterprise/index.tsx | 17 +- .../components/CategoryAddModal.tsx | 4 +- .../mySupplierInquiry/index.tsx | 20 +- .../components/CreateBlacklistModal.tsx | 11 +- .../components/SupplierSelectModal.tsx | 2 + 29 files changed, 665 insertions(+), 270 deletions(-) create mode 100644 src/models/tab.ts diff --git a/config/proxy.ts b/config/proxy.ts index b2210a3..97dba59 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -1,6 +1,7 @@ export default { dev: { '/api/v1': { + // target: 'http://10.0.0.10:18030',// target: 'http://10.0.0.14:18030',// 李 // target: 'http://10.0.0.46:18030',// 袁 changeOrigin: true, @@ -11,13 +12,12 @@ export default { // target: 'http://10.0.0.10:18012',// 茂 // target: 'http://10.0.0.125:18012',// 测试 target: 'http://10.0.0.14:18012',// 李 - // target: 'http://10.0.0.14:18030',// 李 // target: 'http://10.0.0.46:18030',// 袁 changeOrigin: true, pathRewrite: { '^/api': '' }, }, '/upload': { - target: 'http://10.0.0.14:18013',// + target: 'http://10.0.0.14:18012',// changeOrigin: true, pathRewrite: { '^/upload': '' }, }, diff --git a/src/components/CategorySelector/CategorySelector.tsx b/src/components/CategorySelector/CategorySelector.tsx index cab61df..809de75 100644 --- a/src/components/CategorySelector/CategorySelector.tsx +++ b/src/components/CategorySelector/CategorySelector.tsx @@ -165,7 +165,7 @@ const CategorySelector: React.FC = ({ treeNodeFilterProp="title" multiple={multiple} treeDefaultExpandAll={treeData.length < 30} // 当节点数较少时默认展开所有节点 - dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} + dropdownStyle={{ maxHeight: 400, overflow: 'auto', whiteSpace: 'nowrap', }} treeCheckable={multiple} // 多选模式下显示复选框 showCheckedStrategy={SHOW_CHILD} // 显示策略:显示子节点 filterTreeNode={(inputValue, node) => { diff --git a/src/components/CompanyInfo/component/ContactsInfoFormModal.tsx b/src/components/CompanyInfo/component/ContactsInfoFormModal.tsx index 6ce3ba2..d9514d6 100644 --- a/src/components/CompanyInfo/component/ContactsInfoFormModal.tsx +++ b/src/components/CompanyInfo/component/ContactsInfoFormModal.tsx @@ -22,6 +22,7 @@ interface viewDataData { interface coscoSupplierUserCategory { categoryName: string; categoryId: string; + categoryPathName?: string; supplierUserId: string; } interface SupplierUserCategory { @@ -32,19 +33,27 @@ interface SupplierUserCategory { interface CategoryNode { key: string; title: string; + pathName: string; + path: string; children?: CategoryNode[]; } -function flattenTree( +function getKeyTitlePathMap( tree: CategoryNode[], - map: Record = {} -): Record { + keyTitleMap: Record = {}, + keyPathMap: Record = {}, + keyIdMap: Record = {} + ) { 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 InvoiceFormModal: React.FC = ({ @@ -141,12 +150,15 @@ const InvoiceFormModal: React.FC = ({ 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 coscoSupplierUserCategoryList = onlyLeafChecked.map((id) => ({ categoryId: id, categoryName: keyTitleMap[id] || '', + categoryPathName: keyPathMap[id] || '', + categoryPathId: keyIdMap[id] || '', })); setCheckedKeys(keys); // UI 显示用,还是全量 @@ -208,7 +220,7 @@ const InvoiceFormModal: React.FC = ({ {viewData?.contactsEmail} {viewData?.coscoSupplierUserCategoryList && viewData.coscoSupplierUserCategoryList.map((item) => { - return
{item.categoryName}
+ return
{item.categoryPathName}
})}
diff --git a/src/components/CompanyInfo/component/ContactsInfoTab.tsx b/src/components/CompanyInfo/component/ContactsInfoTab.tsx index 1c8a227..d9b95ba 100644 --- a/src/components/CompanyInfo/component/ContactsInfoTab.tsx +++ b/src/components/CompanyInfo/component/ContactsInfoTab.tsx @@ -137,18 +137,18 @@ const OtherAttachmentsTab: React.FC = (props) => { key: 'coscoSupplierUserCategoryList', ellipsis: true, width: 160, - render: (value: { categoryName: string }[] = []) => { + render: (value: { categoryName: string; categoryPathName: string }[] = []) => { if (!value || value.length === 0) return '-'; - if (value.length === 1) { - return {value[0].categoryName}; - } + // 多于1条 - const allNames = value.map(item => item.categoryName).join('、'); + const allNames = value.map(item => item.categoryPathName).join('\n'); return ( - + {allNames}} overlayStyle={{ zIndex: 1200 }}> {value[0].categoryName} - + {value.length !== 1 && ( + + )} ); diff --git a/src/components/GlobalModal/components/ContactsInfo.tsx b/src/components/GlobalModal/components/ContactsInfo.tsx index 7f6929d..d758b82 100644 --- a/src/components/GlobalModal/components/ContactsInfo.tsx +++ b/src/components/GlobalModal/components/ContactsInfo.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { Table, Tooltip } from 'antd'; import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'; -import { getCoscoSupplierUserPage } from '../services'; +import { getCoscoSupplierUserPage } from '../services'; import { useIntl } from 'umi'; interface getCoscoSupplierUser { @@ -21,7 +21,7 @@ interface getCoscoSupplierUser { interface Props { id?: string; } -const OtherAttachmentsTab: React.FC = ({id}) => { +const OtherAttachmentsTab: React.FC = ({ id }) => { //语言切换 const intl = useIntl(); //列表渲染数据 @@ -81,24 +81,24 @@ const OtherAttachmentsTab: React.FC = ({id}) => { key: 'coscoSupplierUserCategoryList', ellipsis: true, width: 160, - render: (value: { categoryName: string }[] = []) => { + render: (value: { categoryName: string; categoryPathName: string }[] = []) => { if (!value || value.length === 0) return '-'; - if (value.length === 1) { - return {value[0].categoryName}; - } + // 多于1条 - const allNames = value.map(item => item.categoryName).join('、'); + const allNames = value.map(item => item.categoryPathName).join('\n'); return ( - + {allNames}} overlayStyle={{ zIndex: 1200 }}> {value[0].categoryName} - + {value.length !== 1 && ( + + )} ); }, }, - + ]; return (
@@ -114,7 +114,7 @@ const OtherAttachmentsTab: React.FC = ({id}) => { loading={loading} onChange={(pagination) => getList(pagination.current!, pagination.pageSize!)} /> - +
); }; diff --git a/src/layouts/BasicLayout.tsx b/src/layouts/BasicLayout.tsx index c25799d..33862cc 100644 --- a/src/layouts/BasicLayout.tsx +++ b/src/layouts/BasicLayout.tsx @@ -1,15 +1,15 @@ // src/layouts/BasicLayout.tsx -import React, { useEffect, useState } from 'react'; +import React, { useState, useEffect } from 'react'; import ProLayout, { PageContainer } from '@ant-design/pro-layout'; -import { Link, useLocation, useIntl, useHistory } from 'umi'; +import { Link, useLocation, useIntl } from 'umi'; import { connect } from 'dva'; import defaultSettings from '../../config/defaultSettings'; -import routes from '../../config/router.config'; // 引入你的自定义路由结构 +import routes from '../../config/router.config'; import { ConfigProvider, Breadcrumb } from 'antd'; import HeaderComponent from './Header'; import IconFont from '@/components/IconFont/IconFont'; import type { BreadcrumbState } from '@/models/breadcrumb'; -import { SupplierDetailModalProvider } from '@/components/SupplierDetailModalContext/SupplierDetailModalContext'; +import type { TabModelState } from '@/models/tab'; const MenuRender = (item: any, isSubMenu: boolean) => { const intl = useIntl(); @@ -19,14 +19,14 @@ const MenuRender = (item: any, isSubMenu: boolean) => { - {intl.formatMessage({ id: `menu.${item.name}` || '' })} + {intl.formatMessage({ id: `${item.name}` || '' })} ) : ( - {intl.formatMessage({ id: `menu.${item.name}` || '' })} + {intl.formatMessage({ id: `${item.name}` || '' })} )} @@ -34,28 +34,6 @@ const MenuRender = (item: any, isSubMenu: boolean) => { ); }; -// 递归交集过滤函数 -function filterMenuByRouter(routes: any, menuRoutes: any) { - return routes.reduce((result: any, route: any) => { - // 只看有 name 的节点 - const menu = menuRoutes.find((m) => m.name === route.name); - if (menu) { - // 匹配到后,递归处理 children - let children = []; - if (route.children && menu.children) { - children = filterMenuByRouter(route.children, menu.children); - } - // 构建新节点,保留原 router.config.ts 路径等信息(比如 path, icon, ...其它字段) - result.push({ - ...route, - // ...menu, // 可按需决定是否 menu 字段覆盖 route 字段(比如 path) - // children: children.length > 0 ? children : undefined - }); - } - return result; - }, []); -} - const BreadcrumbRender = ( routeBreadcrumb: any, intl: any, @@ -89,64 +67,123 @@ const BreadcrumbRender = ( interface BasicLayoutProps { children: React.ReactNode; breadcrumb: BreadcrumbState; + tab: TabModelState; + dispatch: any; } +function convertMenuData(menus: any[]): any[] { + return menus.map(item => { + // 保留 icon 字段,如果没有就给默认 + const icon = item.icon || undefined; + // 递归 children->routes + let routes; + if (item.children && item.children.length > 0) { + routes = convertMenuData(item.children); + } + // 国际化优先找 menu.name,否则直接显示 name + return { + ...item, + icon, + routes, // prolayout 只认 routes + name: item.name, // 不要转 menu.xxx,MenuRender 时才转 + }; + }); +} + + const BasicLayout: React.FC = (props) => { - const { children, breadcrumb } = props; + const { children, tab, dispatch } = props; const location = useLocation(); const intl = useIntl(); - const history = useHistory(); + + const handleTabChange = (key: string) => { + dispatch({ + type: 'tab/switchTab', + payload: { key }, + }); + }; + + const handleTabEdit = (targetKey: any, action: string) => { + if (action === 'remove') { + dispatch({ + type: 'tab/closeTab', + payload: { key: targetKey }, + }); + } + }; const [menuRoutes, setMenuRoutes] = useState([]); useEffect(() => { const menuStr = sessionStorage.getItem('menuList'); if (menuStr) { - const menusFromApi = JSON.parse(menuStr); - // routes是本地静态路由,menusFromApi是接口菜单 - const finalMenus = filterMenuByRouter(routes, menusFromApi); - console.log(finalMenus); - - setMenuRoutes(finalMenus); + const menus = JSON.parse(menuStr); + setMenuRoutes(convertMenuData(menus)); } }, []); + + if (menuRoutes.length === 0) return null; + + return ( - - { - return MenuRender(menuItemProps, true); + undefined} + subMenuItemRender={(menuItemProps, defaultDom) => { + return MenuRender(menuItemProps, true); + }} + menuItemRender={(item, dom) => { + return MenuRender(item, false); + }} + location={location} + fixSiderbar + layout="mix" + headerRender={() => { + return ; + }} + > + null, + // breadcrumbRender: ({ breadcrumb: routeBreadcrumb }) => + // BreadcrumbRender(routeBreadcrumb, intl, history, breadcrumb.breadcrumbName), }} - menuItemRender={(item, dom) => { - return MenuRender(item, false); - }} - location={location} - fixSiderbar - layout="mix" - headerRender={() => { - return ; + // 将tab.tabList转换为需要的格式,添加国际化处理 + tabList={tab.tabList.map((item) => ({ + ...item, + tab: + typeof item.tab === 'string' + ? intl.formatMessage({ id: `menu.${item.tab}` }) + : item.tab, + }))} + tabProps={{ + type: 'editable-card', + hideAdd: true, + activeKey: tab.activeKey, + onChange: handleTabChange, + onEdit: handleTabEdit, + size: 'small', + tabBarGutter: 6, + renderTabBar: (propsTab, DefaultTabBar) => ( + + ), }} > - - BreadcrumbRender(routeBreadcrumb, intl, history, breadcrumb.breadcrumbName), - }} - > - {children} - - - + {children} + + ); }; -export default connect(({ breadcrumb }: { breadcrumb: BreadcrumbState }) => ({ - breadcrumb, -}))(BasicLayout); +export default connect( + ({ breadcrumb, tab }: { breadcrumb: BreadcrumbState; tab: TabModelState }) => ({ + breadcrumb, + tab, + }), +)(BasicLayout); diff --git a/src/layouts/Header.tsx b/src/layouts/Header.tsx index b5ac2cb..3a5b84e 100644 --- a/src/layouts/Header.tsx +++ b/src/layouts/Header.tsx @@ -1,44 +1,17 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; //导入logo图片 import LogoImg from '@/assets/img/logo.png'; //导入菜单组件 import Language from './Language'; import User from './User'; -import { history } from 'umi'; import './layout.less'; -import { Logout } from '@/servers/api/login'; - const HeaderComponent: React.FC = () => { - // 用 state 保存 userId - const [userId, setUserId] = useState(() => sessionStorage.getItem('userId')); - - const handLogout = () => { - Logout() - sessionStorage.clear(); - history.replace('/login'); - } - - useEffect(() => { - // 定义一个方法用于手动刷新 userId - const refreshUserId = () => setUserId(sessionStorage.getItem('userId')); - // 登录后你可以手动调用 refreshUserId - // 或者监听页面 storage 事件(多窗口/多tab同步) - window.addEventListener('storage', refreshUserId); - // 页面内操作,比如登录成功后,也可以在登录回调里调用 setUserId - return () => window.removeEventListener('storage', refreshUserId); - }, []); - return (
logo
- {!userId ? ( - - ) : ( -
退出
- )} - +
); diff --git a/src/layouts/User.tsx b/src/layouts/User.tsx index f715e64..c190e62 100644 --- a/src/layouts/User.tsx +++ b/src/layouts/User.tsx @@ -1,13 +1,94 @@ -import React from 'react'; -import { Link, useIntl } from 'umi'; -const User: React.FC = (props) => { - const intl = useIntl(); - +import React, { useEffect, useState } from 'react'; +import { Link, useIntl, connect, history } from 'umi'; +import { Dropdown, Button, Modal } from 'antd'; +import { DownOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; +import type { ConnectProps, Dispatch } from 'umi'; +import type { UserModelState } from '@/models/user'; +import { message } from 'antd'; +interface PageProps extends ConnectProps { + user: UserModelState; // dva model状态 + dispatch: Dispatch; // dva dispatch方法 +} +const User: React.FC = ({ user, dispatch }) => { + + + const intl = useIntl(); + useEffect(() => { + if (!user.userInfo) { + const userinfoStr = sessionStorage.getItem('Userinfo'); + if (userinfoStr) { + try { + const userInfo = JSON.parse(userinfoStr); + dispatch({ + type: 'user/saveUserInfo', + payload: userInfo, + }); + } catch (e) { + // 解析失败时可以报错提示 + console.error('Userinfo 解析失败', e); + } + } + } else if (user.token) { + dispatch({ + type: 'user/fetchUserInfo', + }); + } + }, [user.token]); + const handleMenuClick = (e: any) => { + if (e.key === 'logout') { + Modal.confirm({ + title: '确定退出登录吗?', + icon: , + content: '退出登录后,您将需要重新登录', + onOk() { + dispatch({ + type: 'user/logout', + }).then(() => { + sessionStorage.clear(); + message.success('退出登录成功'); + history.push('/login'); + }); + }, + onCancel() { + return; + }, + }); + } else if(e.key === 'profile') { + console.log(111); + + // history.push('/profile'); + } + }; return (
- {intl.formatMessage({ id: '登录/注册' })} + {user.userInfo?.fullName ? ( + + + + ) : ( + {intl.formatMessage({ id: '登录' })} + )}
); }; -export default User; + +export default connect(({ user }: { user: UserModelState }) => ({ user }))(User); diff --git a/src/layouts/layout.less b/src/layouts/layout.less index 3b7abb9..ca4deab 100644 --- a/src/layouts/layout.less +++ b/src/layouts/layout.less @@ -20,8 +20,32 @@ align-items: center; } .layout-content { - background: rgb(245,246,250); + background: rgb(245, 246, 250); padding: 0 15px; height: calc(100vh - 64px); overflow: auto; } +.ant-page-header.has-footer{ + padding-top: 0 !important; +} +.custom-tab-bar { + margin-bottom: 10px !important; + .ant-tabs-tab { + border-radius: 5px !important; + font-size: 13px !important; + padding: 6px 10px !important; + .ant-tabs-tab-remove{ + margin-left: 0 !important; + font-size: 10px !important; + } + &.ant-tabs-tab-active{ + background-color: @main-color !important; + .ant-tabs-tab-btn{ + color: #fff !important; + } + .ant-tabs-tab-remove{ + color: #fff !important; + } + } + } +} diff --git a/src/locales/en-US/login.ts b/src/locales/en-US/login.ts index 34a7084..7f8528c 100644 --- a/src/locales/en-US/login.ts +++ b/src/locales/en-US/login.ts @@ -3,7 +3,7 @@ export default { "login.title": "E-Bidding Platform", "login.tab.supplier": "Supplier", "login.tab.expert": "Expert", - "login.tab.agent": "Bidding Agent", + "login.tab.agent": "Group user", "login.username.placeholder": "Please enter username", "login.password.placeholder": "Please enter password", "login.remember": "Remember me", diff --git a/src/locales/zh-CN/login.ts b/src/locales/zh-CN/login.ts index 6521f8a..077255a 100644 --- a/src/locales/zh-CN/login.ts +++ b/src/locales/zh-CN/login.ts @@ -3,7 +3,7 @@ export default { "login.title": "中远海运", "login.tab.supplier": "供应商", "login.tab.expert": "专家", - "login.tab.agent": "招标代理", + "login.tab.agent": "集团用户", "login.username.placeholder": "请输入用户名", "login.password.placeholder": "请输入密码", "login.remember": "记住密码", diff --git a/src/models/tab.ts b/src/models/tab.ts new file mode 100644 index 0000000..e64e989 --- /dev/null +++ b/src/models/tab.ts @@ -0,0 +1,192 @@ +import { Effect, Reducer, Subscription } from 'umi'; +import { history } from 'umi'; +import routes from '../../config/router.config'; + +export interface TabItem { + tab: string; + key: string; + path: string; + closable: boolean; +} + +export interface TabModelState { + tabList: TabItem[]; + activeKey: string; +} + +export interface TabModelType { + namespace: 'tab'; + state: TabModelState; + effects: { + addTab: Effect; + closeTab: Effect; + switchTab: Effect; + }; + reducers: { + updateState: Reducer; + }; + subscriptions: { + setup: Subscription; + }; +} + +// 递归查找路由 +const findRouteByPath = (path: string, routeData: any[]): any => { + let result = null; + for (const route of routeData) { + if (route.path === path) { + result = route; + break; + } + if (route.routes) { + const subResult = findRouteByPath(path, route.routes); + if (subResult) { + result = subResult; + break; + } + } + } + return result; +}; + +const TabModel: TabModelType = { + namespace: 'tab', + + state: { + tabList: [], + activeKey: '/', + }, + + effects: { + *addTab({ payload }, { call, put, select }) { + const { tabList } = yield select((state: any) => state.tab); + const { path, tab, key } = payload; + + // 检查tab是否已存在 + const isExist = tabList.find((item: TabItem) => item.key === key); + + if (!isExist) { + // 添加新tab + yield put({ + type: 'updateState', + payload: { + tabList: [...tabList, { tab, key, path, closable: true }], + activeKey: key, + }, + }); + } else { + // 切换到已有tab + yield put({ + type: 'updateState', + payload: { + activeKey: key, + }, + }); + } + }, + + *closeTab({ payload }, { call, put, select }) { + const { key } = payload; + const { tabList, activeKey } = yield select((state: any) => state.tab); + + // 过滤掉要关闭的tab + const newTabList = tabList.filter((item: TabItem) => item.key !== key); + + // 如果关闭的是当前激活的tab,则切换到前一个tab + let newActiveKey = activeKey; + if (key === activeKey) { + const index = tabList.findIndex((item: TabItem) => item.key === key); + + // 判断关闭后是否还有tab + if (newTabList.length === 0) { + // 没有剩余tab时,导航到首页 + history.push('/'); + newActiveKey = '/'; + } else { + // 有剩余tab时,选择适当的tab作为活动tab + newActiveKey = index === 0 ? newTabList[0].key : tabList[index - 1].key; + + // 切换路由 + const targetTab = newTabList.find((item: TabItem) => item.key === newActiveKey); + if (targetTab) { + history.push(targetTab.path); + } + } + } + + yield put({ + type: 'updateState', + payload: { + tabList: newTabList, + activeKey: newActiveKey, + }, + }); + }, + + *switchTab({ payload }, { call, put, select }) { + const { key } = payload; + const { tabList } = yield select((state: any) => state.tab); + + // 找到目标tab并跳转 + const targetTab = tabList.find((item: TabItem) => item.key === key); + if (targetTab) { + history.push(targetTab.path); + } + + yield put({ + type: 'updateState', + payload: { + activeKey: key, + }, + }); + } + }, + + reducers: { + updateState(state, { payload }) { + return { + ...state, + ...payload, + }; + }, + }, + + subscriptions: { + setup({ dispatch }) { + return history.listen((location) => { + const { pathname } = location; + // 需要排除的路由 + const excludeRoutes = ['/login', '/register']; + + // 首页特殊处理 + if (pathname === '/') { + dispatch({ + type: 'updateState', + payload: { + activeKey: '/', + }, + }); + return; + } + + // 查找当前路由对应的菜单项 + const currentRoute = findRouteByPath(pathname, routes); + + if (currentRoute && !excludeRoutes.includes(pathname)) { + // 如果找到对应路由,添加或激活对应的tab + dispatch({ + type: 'addTab', + payload: { + path: pathname, + key: pathname, + // 直接使用菜单名称作为国际化ID + tab: currentRoute.name || '未命名页面', + }, + }); + } + }); + }, + }, +}; + +export default TabModel; diff --git a/src/models/user.ts b/src/models/user.ts index 08322ad..a9c5b28 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -1,35 +1,39 @@ import type { Effect, Reducer } from 'umi'; -import { queryCurrent, query as queryUsers } from '@/servers/user'; +import { getUserinfo, Logout } from '@/servers/api/login'; -export type CurrentUser = { - avatar?: string; - name?: string; - title?: string; - group?: string; - signature?: string; - tags?: { - key: string; - label: string; - }[]; - userid?: string; - unreadCount?: number; + +export type User = { + userId: string; + userName: string; + userType: string; +}; + +export type UserInfo = { + userId: string; + fullName: string; + loginName: string; + userType: string; + authorityList: { roleId: string, roleName: string, roleCode: string, roleScope: string }[]; }; export type UserModelState = { - currentUser?: CurrentUser; + user?: User; + token?: string; + userInfo?: UserInfo; }; export type UserModelType = { namespace: 'user'; state: UserModelState; effects: { - fetch: Effect; - fetchCurrent: Effect; + fetchUserInfo: Effect; + logout: Effect; }; reducers: { - saveCurrentUser: Reducer; - changeNotifyCount: Reducer; + saveLoginUser: Reducer; + saveUserInfo: Reducer; + clearUserInfo: Reducer; }; }; @@ -37,49 +41,53 @@ const UserModel: UserModelType = { namespace: 'user', state: { - currentUser: {}, + user: undefined, // 登录返回的用户信息 + token: sessionStorage.getItem('token') || '', // 登录返回的token + userInfo: undefined, // 请求userInfo返回的用户信息 }, effects: { - *fetch(_, { call, put }) { - const response = yield call(queryUsers); + *fetchUserInfo(_, { call, put }): Generator { + const userinfo = JSON.parse(sessionStorage.getItem('Userinfo') ?? '{}'); + console.log(userinfo,'userinfo'); + yield put({ - type: 'save', - payload: response, + type: 'saveUserInfo', + payload: userinfo, }); }, - *fetchCurrent(_, { call, put }) { - const response = yield call(queryCurrent); + *logout(_, { call, put }): Generator { + yield call(Logout); yield put({ - type: 'saveCurrentUser', - payload: response, + type: 'clearUserInfo' }); }, }, + reducers: { - saveCurrentUser(state, action) { + clearUserInfo(state) { return { ...state, - currentUser: action.payload || {}, + userInfo: undefined, + token: '', + user: {}, }; }, - changeNotifyCount( - state = { - currentUser: {}, - }, - action, - ) { + saveLoginUser(state, action) { return { ...state, - currentUser: { - ...state.currentUser, - notifyCount: action.payload.totalCount, - unreadCount: action.payload.unreadCount, - }, + user: action.payload.user || {}, + token: action.payload.token || '', }; }, - }, + saveUserInfo(state, action) { + return { + ...state, + userInfo: action.payload || {}, + }; + }, + } }; export default UserModel; diff --git a/src/pages/dataStatistics/supplierAdmissionStatistics/supplierAdmissionStatistics.tsx b/src/pages/dataStatistics/supplierAdmissionStatistics/supplierAdmissionStatistics.tsx index 2042056..9027e66 100644 --- a/src/pages/dataStatistics/supplierAdmissionStatistics/supplierAdmissionStatistics.tsx +++ b/src/pages/dataStatistics/supplierAdmissionStatistics/supplierAdmissionStatistics.tsx @@ -130,9 +130,24 @@ const SupplierAnnualStatistics: React.FC = () => { { title: intl.formatMessage({ id: 'dataStatistics.common.category' }), dataIndex: 'categoryNameList', - key: 'categoryNameList', width: 120, - render: (text: string[]) => text.join(','), + 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 ( + {allNames}} overlayStyle={{ zIndex: 1200 }}> + + {value[0].categoryName} + {value.length !== 1 && ( + + )} + + + ); + }, }, { title: intl.formatMessage({ id: 'dataStatistics.common.accessUnit' }), diff --git a/src/pages/login/login.tsx b/src/pages/login/login.tsx index 6ec447a..59f36ff 100644 --- a/src/pages/login/login.tsx +++ b/src/pages/login/login.tsx @@ -3,7 +3,7 @@ import { Form, Input, Button, Checkbox, Tabs, message } from 'antd'; import { UserOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons'; import { history, useIntl } from 'umi'; import './login.less'; -import { getCaptcha, supplierLogin, expertLogin, accountLogin, getUserinfo, refreshDictCache } from '@/servers/api/login'; +import { getCaptcha, supplierLogin, expertLogin, accountLogin, getUserinfo, refreshDictCache, findMenuList } from '@/servers/api/login'; import { encryptWithRsa } from '@/utils/encryptWithRsa' @@ -26,18 +26,20 @@ const LoginPage: React.FC = () => { useEffect(() => { fetchCaptcha(); - if(!sessionStorage.getItem('dict')) { + if (!sessionStorage.getItem('dict')) { refreshDictCache().then((res) => { - if(res.code == 200) { + if (res.code == 200) { sessionStorage.setItem('dict', JSON.stringify(res.data)) } }) } - + + form.setFieldsValue( { password: 'cosco2025', identifying: '1' } ) + }, [activeKey]); - // 组件挂载时,检查是否有记住的用户名 + // 组件挂载时,检查是否有记住的用户名 useEffect(() => { // const savedUser = localStorage.getItem('remember_user'); // if (savedUser) { @@ -88,25 +90,14 @@ const LoginPage: React.FC = () => { // }) } sessionStorage.setItem('currentUser', JSON.stringify(loginRes.data)); - - - getUserinfo().then(async (res) => { - // if(res.code == 200) { - const roleIdList = res.authorityList.map((item: any) => { - return item.roleId - }) - console.log(roleIdList, 'roleIdList'); + await getUserinfo().then(async (res) => { + const roleIdList = res.authorityList.map((item: any) => item.roleId); sessionStorage.setItem('Userinfo', JSON.stringify(res)); - // const menuList = await findMenuList({ roleIdList }); - // sessionStorage.setItem('menuList', JSON.stringify(menuList.data)); - // } - }) - - - - - message.success('登录成功'); - history.push('/index'); + const menuList: any = await findMenuList({ roleIdList }); + sessionStorage.setItem('menuList', JSON.stringify(menuList.data)); + message.success('登录成功'); + history.push('/index'); + }); } else { message.error(loginRes.message || '登录失败'); } @@ -162,7 +153,7 @@ const LoginPage: React.FC = () => { // 忘记密码点击 const onForgot = () => { - history.push('/forgot?type='+activeKey); + history.push('/forgot?type=' + activeKey); } return ( @@ -179,7 +170,7 @@ const LoginPage: React.FC = () => {
- + {/* */}
@@ -239,7 +230,7 @@ const LoginPage: React.FC = () => { {intl.formatMessage({ id: 'login.remember' })} - diff --git a/src/pages/supplier/admission/SupplierCategoryEntry/components/CreateModal.tsx b/src/pages/supplier/admission/SupplierCategoryEntry/components/CreateModal.tsx index 30a851f..57260db 100644 --- a/src/pages/supplier/admission/SupplierCategoryEntry/components/CreateModal.tsx +++ b/src/pages/supplier/admission/SupplierCategoryEntry/components/CreateModal.tsx @@ -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 = {} -): Record { + keyTitleMap: Record = {}, + keyPathMap: Record = {}, + keyIdMap: Record = {} + ) { 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 }); // 只存叶子到表单 diff --git a/src/pages/supplier/admission/SupplierCategoryEntry/components/ViewModal.tsx b/src/pages/supplier/admission/SupplierCategoryEntry/components/ViewModal.tsx index 04ec023..a434fb6 100644 --- a/src/pages/supplier/admission/SupplierCategoryEntry/components/ViewModal.tsx +++ b/src/pages/supplier/admission/SupplierCategoryEntry/components/ViewModal.tsx @@ -67,7 +67,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
diff --git a/src/pages/supplier/admission/SupplierCategoryEntryReview/components/ViewModal.tsx b/src/pages/supplier/admission/SupplierCategoryEntryReview/components/ViewModal.tsx index 6ee71ad..f7b3298 100644 --- a/src/pages/supplier/admission/SupplierCategoryEntryReview/components/ViewModal.tsx +++ b/src/pages/supplier/admission/SupplierCategoryEntryReview/components/ViewModal.tsx @@ -67,7 +67,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
diff --git a/src/pages/supplier/admission/SupplierEntryReview/components/ViewModal.tsx b/src/pages/supplier/admission/SupplierEntryReview/components/ViewModal.tsx index 03f24be..b2c205a 100644 --- a/src/pages/supplier/admission/SupplierEntryReview/components/ViewModal.tsx +++ b/src/pages/supplier/admission/SupplierEntryReview/components/ViewModal.tsx @@ -86,7 +86,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
@@ -101,7 +101,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
@@ -117,7 +117,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
diff --git a/src/pages/supplier/admission/SupplierEntryReview/index.tsx b/src/pages/supplier/admission/SupplierEntryReview/index.tsx index 6f40a3a..932816a 100644 --- a/src/pages/supplier/admission/SupplierEntryReview/index.tsx +++ b/src/pages/supplier/admission/SupplierEntryReview/index.tsx @@ -43,7 +43,7 @@ const SupplierEntryReview: React.FC = () => { const [loading, setLoading] = useState(false); const [modalInfo, setModalInfo] = useState({ visible: false, record: null }); // - const [enterpriseType, setEnterpriseType] = useState(); + const [enterpriseType, setEnterpriseType] = useState(); // 查询数据 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 {value[0]}; - } + // 多于1条 - const allNames = value.map(item => item).join('、'); + const allNames = value.map(item => item.categoryPathName).join('\n'); return ( - + {allNames}} overlayStyle={{ zIndex: 1200 }}> - {value[0]} - + {value[0].categoryName} + {value.length !== 1 && ( + + )} ); @@ -213,7 +213,7 @@ const SupplierEntryReview: React.FC = () => { onFinish={handleSearch} > - + diff --git a/src/pages/supplier/admission/admissionManagement/components/CreateModal.tsx b/src/pages/supplier/admission/admissionManagement/components/CreateModal.tsx index ee80d66..a65846b 100644 --- a/src/pages/supplier/admission/admissionManagement/components/CreateModal.tsx +++ b/src/pages/supplier/admission/admissionManagement/components/CreateModal.tsx @@ -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 = {} -): Record { + keyTitleMap: Record = {}, + keyPathMap: Record = {}, + keyIdMap: Record = {} + ) { 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 显示用,还是全量 diff --git a/src/pages/supplier/admission/admissionManagement/components/ViewModal.tsx b/src/pages/supplier/admission/admissionManagement/components/ViewModal.tsx index 06d47d7..cfa4d97 100644 --- a/src/pages/supplier/admission/admissionManagement/components/ViewModal.tsx +++ b/src/pages/supplier/admission/admissionManagement/components/ViewModal.tsx @@ -89,7 +89,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
@@ -104,7 +104,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
@@ -120,7 +120,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
diff --git a/src/pages/supplier/admission/admissionReviewManagement/components/ViewModal.tsx b/src/pages/supplier/admission/admissionReviewManagement/components/ViewModal.tsx index eeb3c21..f529227 100644 --- a/src/pages/supplier/admission/admissionReviewManagement/components/ViewModal.tsx +++ b/src/pages/supplier/admission/admissionReviewManagement/components/ViewModal.tsx @@ -90,7 +90,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
@@ -105,7 +105,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
@@ -120,7 +120,7 @@ const ViewModal: React.FC<{ {data.coscoAccessCategoryList.map((item) => { return ( -
{item.categoryName}
+
{item.categoryPathName}
) })}
diff --git a/src/pages/supplier/admission/admissionReviewManagement/index.tsx b/src/pages/supplier/admission/admissionReviewManagement/index.tsx index 5381510..6433964 100644 --- a/src/pages/supplier/admission/admissionReviewManagement/index.tsx +++ b/src/pages/supplier/admission/admissionReviewManagement/index.tsx @@ -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 {value[0]}; - } + // 多于1条 - const allNames = value.map(item => item).join('、'); + const allNames = value.map(item => item.categoryPathName).join('\n'); return ( - + {allNames}} overlayStyle={{ zIndex: 1200 }}> - {value[0]} - + {value[0].categoryName} + {value.length !== 1 && ( + + )} ); diff --git a/src/pages/supplier/backend/cooperateEnterprise/index.tsx b/src/pages/supplier/backend/cooperateEnterprise/index.tsx index 978da78..18ea293 100644 --- a/src/pages/supplier/backend/cooperateEnterprise/index.tsx +++ b/src/pages/supplier/backend/cooperateEnterprise/index.tsx @@ -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 ( + {item.categoryPathName}} overlayStyle={{ zIndex: 1200 }}> + + {item.categoryName} + + + ); + }, }, { title: '准入时间', diff --git a/src/pages/supplier/category/CategoryLibraryManage/components/CategoryAddModal.tsx b/src/pages/supplier/category/CategoryLibraryManage/components/CategoryAddModal.tsx index 3b662bd..61092cc 100644 --- a/src/pages/supplier/category/CategoryLibraryManage/components/CategoryAddModal.tsx +++ b/src/pages/supplier/category/CategoryLibraryManage/components/CategoryAddModal.tsx @@ -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', }); diff --git a/src/pages/supplier/informationRetrieval/mySupplierInquiry/index.tsx b/src/pages/supplier/informationRetrieval/mySupplierInquiry/index.tsx index 257edf9..b1f45dd 100644 --- a/src/pages/supplier/informationRetrieval/mySupplierInquiry/index.tsx +++ b/src/pages/supplier/informationRetrieval/mySupplierInquiry/index.tsx @@ -142,13 +142,29 @@ const mySupplierInquiry: React.FC = ({ 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 ( + {allNames}} overlayStyle={{ zIndex: 1200 }}> + + {value[0].categoryName} + {value.length !== 1 && ( + + )} + + + ); + }, }, { title: '准入时间', diff --git a/src/pages/supplier/supplierExit/supplierExitManage/components/CreateBlacklistModal.tsx b/src/pages/supplier/supplierExit/supplierExitManage/components/CreateBlacklistModal.tsx index 46723d5..0613200 100644 --- a/src/pages/supplier/supplierExit/supplierExitManage/components/CreateBlacklistModal.tsx +++ b/src/pages/supplier/supplierExit/supplierExitManage/components/CreateBlacklistModal.tsx @@ -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 = ({ } = { 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("提交成功"); diff --git a/src/pages/supplier/supplierExit/supplierExitManage/components/SupplierSelectModal.tsx b/src/pages/supplier/supplierExit/supplierExitManage/components/SupplierSelectModal.tsx index aa80a81..59fe9bd 100644 --- a/src/pages/supplier/supplierExit/supplierExitManage/components/SupplierSelectModal.tsx +++ b/src/pages/supplier/supplierExit/supplierExitManage/components/SupplierSelectModal.tsx @@ -21,6 +21,8 @@ interface Supplier { lastEvalDate: string; // 评价时间 supplierId: string; categoryId: string; + categoryPathName: string; + categoryPathId: string; } interface SupplierSelectModalProps {