This commit is contained in:
linxd
2025-07-15 10:22:31 +08:00
24 changed files with 183 additions and 98 deletions

View File

@ -1,10 +1,16 @@
export default {
dev: {
'/api/v1': {
target: 'http://10.0.0.14:18030',// 李
// target: 'http://10.0.0.46:18030',// 袁
changeOrigin: true,
pathRewrite: { '^/api/v1': '/v1' },
},
'/api': {
// target: 'http://10.242.37.148:18022',//
// 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.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,

View File

@ -237,6 +237,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
{
title: intl.formatMessage({ id: 'supplierTaskManage.column.supplierName' }),
dataIndex: 'supplierName',
width: 120,
ellipsis: true,
render: (supplierName: string) => (
<Tooltip placement="topLeft" title={supplierName}>
@ -247,6 +248,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
{
title: intl.formatMessage({ id: 'supplierTaskManage.column.socialCreditCode' }),
dataIndex: 'socialCreditCode',
width: 120,
ellipsis: true,
render: (socialCreditCode: string) => (
<Tooltip placement="topLeft" title={socialCreditCode}>
@ -257,6 +259,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
{
title: intl.formatMessage({ id: 'supplierTaskManage.column.categoryName' }),
dataIndex: 'categoryName',
width: 120,
ellipsis: true,
render: (categoryName: string) => (
<Tooltip placement="topLeft" title={categoryName}>

View File

@ -1,5 +1,5 @@
// src/layouts/BasicLayout.tsx
import React from 'react';
import React, { useEffect, useState } from 'react';
import ProLayout, { PageContainer } from '@ant-design/pro-layout';
import { Link, useLocation, useIntl, useHistory } from 'umi';
import { connect } from 'dva';
@ -34,6 +34,28 @@ 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, history: any, dynamicBreadcrumbName: string | null) => {
const breadcrumbRoutes = routeBreadcrumb?.routes;
return (
@ -74,11 +96,28 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
const location = useLocation();
const intl = useIntl();
const history = useHistory();
const [menuRoutes, setMenuRoutes] = useState<any[]>([]);
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);
}
}, []);
return (
<ConfigProvider>
<ProLayout
{...defaultSettings}
route={{ routes }}
// route={{ routes: menuRoutes }}
subMenuItemRender={(menuItemProps, defaultDom) => {
return MenuRender(menuItemProps, true);
}}

View File

@ -3,7 +3,7 @@ import { Form, Input, Button, Checkbox, Tabs, message } from 'antd';
import { UserOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone, HomeOutlined } from '@ant-design/icons';
import { history, useIntl } from 'umi';
import './login.less';
import { getCaptcha, supplierLogin, expertLogin, accountLogin } from '@/servers/api/login';
import { getCaptcha, supplierLogin, expertLogin, accountLogin, getUserinfo, findMenuList } from '@/servers/api/login';
import { encryptWithRsa } from '@/utils/encryptWithRsa'
import Password from 'antd/lib/input/Password';
@ -51,6 +51,20 @@ const LoginPage: React.FC = () => {
// sessionStorage.setItem('userId', loginRes.data.supplierUser.userId);
}
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');
const menuList = await findMenuList({ roleIdList });
sessionStorage.setItem('menuList', JSON.stringify(menuList.data));
// }
})
message.success('登录成功');
history.push('/index');
} else {

View File

@ -71,7 +71,7 @@ const SupplierSelector: React.FC<{ visible: boolean; onCancel: () => void; onSel
}, [visible])
//供应商名称
const columns = [
{ title: '供应商名称', dataIndex: 'name', ellipsis: true, render: (name: string) => (
{ title: '供应商名称', dataIndex: 'name', ellipsis: true, width: 160, render: (name: string) => (
<Tooltip placement="topLeft" title={name}>
{name}
</Tooltip>

View File

@ -88,12 +88,12 @@ const SupplierCategoryEntry: React.FC = () => {
width: 60,
render: (_: any, __: any, idx: number) => (((pagination.current ?? 1) - 1) * (pagination.pageSize ?? 10)) + idx + 1,
},
{ title: '准入工作', ellipsis: true, dataIndex: 'accessWorkName' },
{ title: '准入单位', ellipsis: true, dataIndex: 'deptId' },
{ title: '准入部门', ellipsis: true, dataIndex: 'deptId' },
{ title: '准入方式', ellipsis: true, dataIndex: 'accessTypeText' },
{ title: '准入工作', ellipsis: true, width: 120, dataIndex: 'accessWorkName' },
{ title: '准入单位', ellipsis: true, width: 120, dataIndex: 'deptId' },
{ title: '准入部门', ellipsis: true, width: 120, dataIndex: 'deptId' },
{ title: '准入方式', ellipsis: true, width: 120, dataIndex: 'accessTypeText' },
{ title: '申请时间', dataIndex: 'createTime', width: 180 },
{ title: '状态', ellipsis: true, dataIndex: 'approveStatusText' },
{ title: '状态', ellipsis: true, width: 120, dataIndex: 'approveStatusText' },
{
title: '操作',
width: 140,

View File

@ -120,21 +120,25 @@ const SupplierEntryReview: React.FC = () => {
dataIndex: 'accessWorkName',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '准入部门',
dataIndex: 'deptId',
align: 'center',
width: 120,
},
{
title: '准入方式',
dataIndex: 'accessTypeText',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '准入品类',
dataIndex: 'categoryNameList',
width: 120,
align: 'center',
render: (_: any, record: any) => {
return (
@ -164,15 +168,18 @@ const SupplierEntryReview: React.FC = () => {
title: '流程状态',
dataIndex: 'reviewStatusText',
align: 'center',
width: 120,
},
{
title: '审核',
dataIndex: 'approveStatusText',
align: 'center',
width: 120,
},
{
title: '操作',
width: 120,
fixed: 'right',
render: (_: any, record: any) => {
return (
<Space>

View File

@ -497,7 +497,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
</Button>
</Form.Item>
</Form>
{/* 供应商选择 */}
<SupplierSelector
visible={supplierModalVisible}
onCancel={() => setSupplierModalVisible(false)}
@ -507,7 +507,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
setSupplierModalVisible(false);
}}
/>
{/* 评审人员选择 */}
<ReviewerSelector
visible={reviewerModalVisible}
onCancel={() => setReviewerModalVisible(false)}
@ -519,7 +519,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
setReviewerModalVisible(false);
}}
/>
{/* 评审分工选择 */}
<DivisionModal
reviewerSelector={selectedReviewers}
visible={divisionModalVisible}

View File

@ -40,9 +40,10 @@ const DivisionModal: React.FC<{
// 过滤出组长
const nonLeaderReviewers = useMemo(
() => (reviewerSelector?.selected || []).filter(
r => reviewerSelector.leader && r.id !== reviewerSelector.leader.id
r => reviewerSelector.leader && r.userId !== reviewerSelector.leader.userId
), [reviewerSelector]
);
//列表数据渲染 -默认第一条
const [data, setData] = useState<DivisionRow[]>([
{ key: '1', itemName: '合规检查', reviewerChecks: {} },

View File

@ -2,6 +2,8 @@ import React, { useState, useEffect, useMemo } from 'react';
import { Modal, Table, Radio, Button, message } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { getUserPage } from '../services'
// 评审人数据结构
interface Reviewer {
id: string;
@ -23,31 +25,6 @@ interface ReviewerSelectorProps {
leader?: string; // 回显组长userId
}
// 模拟分页接口
const fetchReviewers = async ({
pageNum,
pageSize,
}: {
pageNum: number;
pageSize: number;
}): Promise<{ list: Reviewer[]; total: number }> => {
return new Promise((resolve) => {
setTimeout(() => {
const all: Reviewer[] = Array.from({ length: 36 }, (_, i) => ({
id: `u-${i + 1}`,
name: `评审人${i + 1}`,
userId: `E000${i + 1}`,
deptId: `部门${(i % 3) + 1}`,
isLeader: 0,
}));
resolve({
list: all.slice((pageNum - 1) * pageSize, pageNum * pageSize),
total: all.length,
});
}, 300);
});
};
const ReviewerSelector: React.FC<ReviewerSelectorProps> = ({
visible,
onCancel,
@ -82,19 +59,22 @@ const ReviewerSelector: React.FC<ReviewerSelectorProps> = ({
useEffect(() => {
if (!visible) return;
setLoading(true);
fetchReviewers({ pageNum: page, pageSize })
getUserPage({ basePageRequest: { pageNo: page, pageSize } })
.then((res) => {
setData(res.list);
setTotal(res.total);
const { code, data } = res;
if(code == 200) {
setData(data.records);
setTotal(data.total);
}
})
.finally(() => setLoading(false));
}, [visible, page, pageSize]);
// 当前已选项(全局选中的都能做组长)
const selectedReviewerObjs = useMemo(
() => data.filter((item) => selectedRowKeys.includes(item.userId)),
[data, selectedRowKeys]
);
// const selectedReviewerObjs = useMemo(
// () => data.filter((item) => selectedRowKeys.includes(item.userId)),
// [data, selectedRowKeys]
// );
// 列
const columns: ColumnsType<Reviewer> = [
@ -134,7 +114,8 @@ const ReviewerSelector: React.FC<ReviewerSelectorProps> = ({
...item,
isLeader: item.userId === leaderUserId ? 1 : 0,
}));
console.log(selected);
// 完整数据传回
onSelect?.({
selected,

View File

@ -70,7 +70,7 @@ const SupplierSelector: React.FC<{ visible: boolean; onCancel: () => void; onSel
}, [visible])
//供应商名称
const columns = [
{ title: '供应商名称', dataIndex: 'name', ellipsis: true, render: (name: string) => (
{ title: '供应商名称', dataIndex: 'name', ellipsis: true, width: 160, render: (name: string) => (
<Tooltip placement="topLeft" title={name}>
{name}
</Tooltip>

View File

@ -91,15 +91,16 @@ const AccessManagement: React.FC = () => {
width: 80,
render: (_: any, __: any, idx: number) => (((pagination.current ?? 1) - 1) * (pagination.pageSize ?? 10)) + idx + 1,
},
{ title: '准入工作', ellipsis: true, dataIndex: 'accessWorkName' },
{ title: '准入单位', ellipsis: true, dataIndex: 'deptId' },
{ title: '准入部门', ellipsis: true, dataIndex: 'deptId' },
{ title: '准入方式', ellipsis: true, dataIndex: 'accessTypeText' },
{ title: '申请时间', ellipsis: true, dataIndex: 'createTime' },
{ title: '状态', dataIndex: 'reviewStatusText' },
{ title: '准入工作', ellipsis: true, width: 120, dataIndex: 'accessWorkName' },
{ title: '准入单位', ellipsis: true, width: 120, dataIndex: 'deptId' },
{ title: '准入部门', ellipsis: true, width: 120, dataIndex: 'deptId' },
{ title: '准入方式', ellipsis: true, width: 120, dataIndex: 'accessTypeText' },
{ title: '申请时间', ellipsis: true, width: 180, dataIndex: 'createTime' },
{ title: '状态', dataIndex: 'reviewStatusText', width: 80, },
{
title: '操作',
width: 200,
fixed: 'right',
render: (_: any, record: any) => (
<Space>
<a onClick={() => openModal('view', record)}></a>

View File

@ -68,6 +68,17 @@ interface CoscoAccessWork {
}
export const add = (data: addInterface) => request.post('/coscoAccessWork/add', { data });
interface getUserPage {
basePageRequest: basePageRequest;
}
interface basePageRequest {
pageNo: number;
pageSize: number;
}
export const getUserPage = (data: getUserPage) => request.post('/user/getUserPage', { data });
/**
* 品类选择查询树
*/

View File

@ -94,6 +94,7 @@ const CooperateEnterprise: React.FC = () => {
title: '准入工作',
dataIndex: 'accessWorkName',
key: 'accessWorkName',
width: 120,
ellipsis: true,
},
{
@ -101,14 +102,14 @@ const CooperateEnterprise: React.FC = () => {
dataIndex: 'deptId',
key: 'deptId',
ellipsis: true,
width: 180,
width: 120,
},
{
title: '准入部门',
dataIndex: 'deptId',
key: 'deptId',
ellipsis: true,
width: 180,
width: 120,
},
{
title: '准入品类',
@ -130,7 +131,7 @@ const CooperateEnterprise: React.FC = () => {
dataIndex: 'accessTypeText',
key: 'accessTypeText',
ellipsis: true,
width: 160,
width: 120,
},
{
title: '评审时间',
@ -148,6 +149,7 @@ const CooperateEnterprise: React.FC = () => {
{
title: '操作',
width: 140,
fixed: 'right',
render: (_: any, record: any) => {
// 已完成 3 、结果汇总中 2 、进行中1 、 未开始0
// 显示评审 按钮

View File

@ -2,16 +2,7 @@ import React, { useEffect, useState } from 'react';
import { Modal, Table, Spin, Descriptions } from 'antd';
import { supplierChangeApplyById } from '../services';
interface Qualification {
type: string;
name: string;
level: string;
number: string;
org: string;
issueDate: string;
validDate: string;
file?: string;
}
interface InfoItem {
fieldAnnotation?: string;
newValue?: string;
@ -23,9 +14,14 @@ interface InfoItem {
coscoSupplierChangeHistoryList?: [];
}
interface DetailData {
coscoSupplierChangeApply: InfoItem;
fieldAnnotation?: string;
newValue?: string;
oldValue?: string;
title?: string;
changeDesc?: string;
supplierName?: string;
approveStatusText?: string;
coscoSupplierChangeHistoryList: InfoItem[];
qualifications: Qualification[];
}
interface DetailViewProps {
visible: boolean;
@ -87,11 +83,11 @@ const DetailView: React.FC<DetailViewProps> = ({ visible, onClose, detailId }) =
<div>
{/* 基本信息 */}
<Descriptions bordered column={1}>
<Descriptions.Item label="变更标题" labelStyle={{width: '140px'}}>{detailData.coscoSupplierChangeApply?.title}</Descriptions.Item>
<Descriptions.Item label="变更说明">{detailData.coscoSupplierChangeApply?.changeDesc}</Descriptions.Item>
{detailData.coscoSupplierChangeApply?.coscoSupplierChangeHistoryList && (
<Descriptions.Item label="附件">{detailData.coscoSupplierChangeApply?.changeDesc}</Descriptions.Item>
) }
<Descriptions.Item label="变更标题" labelStyle={{width: '140px'}}>{detailData?.title}</Descriptions.Item>
<Descriptions.Item label="变更说明">{detailData?.changeDesc}</Descriptions.Item>
{/* {detailData?.coscoSupplierChangeHistoryList && (
<Descriptions.Item label="附件">{detailData?.changeDesc}</Descriptions.Item>
) } */}
</Descriptions>
{/* 变更内容 */}
<div style={{ padding: '16px 0 10px 2px', color: '#333', fontSize: '14px' }}></div>

View File

@ -54,9 +54,9 @@ const CooperateEnterprise: React.FC = () => {
render: (_: any, __: any, idx: number) => (((pagination.current ?? 1) - 1) * (pagination.pageSize ?? 10)) + idx + 1,
},
{
title: '变更内容',
dataIndex: 'changeDesc',
key: 'changeDesc',
title: '变更标题',
dataIndex: 'title',
key: 'title',
},
{
title: '提交时间',
@ -70,8 +70,8 @@ const CooperateEnterprise: React.FC = () => {
},
{
title: '审批状态',
dataIndex: 'enterpriseType',
key: 'enterpriseType',
dataIndex: 'approveStatusText',
key: 'approveStatusText',
},
{
title: '审批时间',

View File

@ -115,6 +115,7 @@ const CooperateEnterprise: React.FC = () => {
dataIndex: 'exitReason',
key: 'exitReason',
ellipsis: true,
width: 120,
},
];
return (

View File

@ -80,6 +80,7 @@ const supplierNews: React.FC = () => {
dataIndex: 'content',
key: 'content',
ellipsis: true,
},
{
title: '业务类型',

View File

@ -2,16 +2,7 @@ import React, { useEffect, useState } from 'react';
import { Modal, Table, Spin, Descriptions } from 'antd';
import { supplierChangeApplyById } from '../services';
interface Qualification {
type: string;
name: string;
level: string;
number: string;
org: string;
issueDate: string;
validDate: string;
file?: string;
}
interface InfoItem {
fieldAnnotation?: string;
newValue?: string;
@ -23,9 +14,12 @@ interface InfoItem {
coscoSupplierChangeHistoryList?: [];
}
interface DetailData {
coscoSupplierChangeApply: InfoItem;
fieldAnnotation?: string;
title?: string;
changeDesc?: string;
supplierName?: string;
approveStatusText?: string;
coscoSupplierChangeHistoryList: InfoItem[];
qualifications: Qualification[];
}
interface DetailViewProps {
visible: boolean;
@ -87,11 +81,11 @@ const DetailView: React.FC<DetailViewProps> = ({ visible, onClose, detailId }) =
<div>
{/* 基本信息 */}
<Descriptions bordered column={1}>
<Descriptions.Item label="变更标题" labelStyle={{width: '140px'}}>{detailData.coscoSupplierChangeApply?.title}</Descriptions.Item>
<Descriptions.Item label="变更说明">{detailData.coscoSupplierChangeApply?.changeDesc}</Descriptions.Item>
{detailData.coscoSupplierChangeApply?.coscoSupplierChangeHistoryList && (
<Descriptions.Item label="附件">{detailData.coscoSupplierChangeApply?.changeDesc}</Descriptions.Item>
) }
<Descriptions.Item label="变更标题" labelStyle={{width: '140px'}}>{detailData?.title}</Descriptions.Item>
<Descriptions.Item label="变更说明">{detailData?.changeDesc}</Descriptions.Item>
{/* {detailData?.coscoSupplierChangeHistoryList && (
<Descriptions.Item label="附件">{detailData?.changeDesc}</Descriptions.Item>
) } */}
</Descriptions>
{/* 变更内容 */}
<div style={{ padding: '16px 0 10px 2px', color: '#333', fontSize: '14px' }}></div>

View File

@ -125,6 +125,7 @@ const SupplierChangeReviewManage: React.FC<Props> = ({ dispatch }) => {
title: '供应商名称',
dataIndex: 'supplierName',
align: 'left',
width: 160,
ellipsis: true,
render: (dom, record) =>
<Tooltip title={record.supplierName}>

View File

@ -156,7 +156,8 @@ const groupQualifiedSupplierQuery: React.FC<Props> = ({ dispatch }) => {
dataIndex: 'name',
key: 'name',
align: 'left',
ellipsis: true,
ellipsis: true,
width: 160,
render: (dom, record) =>
<Tooltip title={record.name}>
<a

View File

@ -116,6 +116,7 @@ const mySupplierInquiry: React.FC<mySupplierInquiryProps> = ({ dispatch }) => {
title: '供应商名称',
dataIndex: 'name',
key: 'name',
width: 160,
ellipsis: true,
render: (dom, record) =>
<Tooltip title={record.name}>

View File

@ -117,6 +117,7 @@ const RegistrationQuery: React.FC<RegistrationQueryProps> = ({ dispatch }) => {
dataIndex: 'name',
key: 'name',
align: 'left',
width: 160,
ellipsis: true,
render: (dom, record) =>
<Tooltip title={record.name}>

View File

@ -37,5 +37,29 @@ export async function supplierLogin (data: API.LoginSupplier) {
data
});
}
/**
* 用户信息
*/
export async function getUserinfo() {
return request('/v1/userinfo/get', {
method: 'GET'
});
}
/**
* 退出
*/
export async function Logout() {
return request('/v1/login/logout', {
method: 'GET'
});
}
/**
* 路由
*/
export async function findMenuList(data: any) {
return request('/v1/menu/findMenuList', {
method: 'POST',
data
});
}