11
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled

This commit is contained in:
francis-fh
2026-07-24 16:19:41 +08:00
parent 970cbffe00
commit 0b90547ceb

View File

@@ -1,14 +1,81 @@
import React, { useEffect, useRef, useState } from 'react';
import { Form, Input, Modal, Switch, Tag, message } from 'antd';
import { Form, Input, Modal, Switch, Tag, Button, message } from 'antd';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { useAccess } from '@umijs/max';
import {
DeleteOutlined,
FormOutlined,
AlignLeftOutlined,
AuditOutlined,
PlusOutlined,
} from '@ant-design/icons';
import EditCompanyListRow, { CompanyDetailView } from '@/pages/Company/List/edit';
import {
addCmsCompanyList,
delCmsCompanyList,
getCmsCompanyDetail,
parseCmsCompanyDetailResponse,
putCmsCompanyList,
} from '@/services/company/list';
import { postCompanyApproval } from '@/services/company/review';
import { changeLcCompanyStatus, getAdminCompanyList, resetLcPsw } from '@/services/cms/company';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
import { getCmsIndustryTreeList } from '@/services/classify/industry';
import DictTag, { DictValueEnumObj } from '@/components/DictTag';
/** 将行业树数据展平为 DictValueEnumObj */
const flattenIndustryTree = (tree: { id: number; label: string; children?: any[] }[]): DictValueEnumObj => {
const map: DictValueEnumObj = {};
const walk = (nodes: { id: number; label: string; children?: any[] }[]) => {
nodes?.forEach((node) => {
map[node.id] = {
text: node.label,
label: node.label,
value: node.id,
};
if (node.children?.length) {
walk(node.children);
}
});
};
walk(tree);
return map;
};
const loadCompanyDetail = async (record: API.CmsCompany.CompanyUser) => {
const resp = await getCmsCompanyDetail(record.companyId);
const detail = parseCmsCompanyDetailResponse(resp);
if (!detail) {
return { ...record } as any;
}
return { ...record, ...detail } as any;
};
function CompanyUserList() {
const access = useAccess();
const actionRef = useRef<ActionType>();
// ---- 字典数据 ----
const [scaleEnum, setScaleEnum] = useState<Record<string, any>>({});
const [natureEnum, setNatureEnum] = useState<Record<string, any>>({});
const [companyNatureEnum, setCompanyNatureEnum] = useState<DictValueEnumObj>({});
const [industryEnum, setIndustryEnum] = useState<DictValueEnumObj>({});
// ---- 编辑弹窗 ----
const [currentRow, setCurrentRow] = useState<API.CompanyList.Company>();
const [modalVisible, setModalVisible] = useState<boolean>(false);
// ---- 详情弹窗 ----
const [detailVisible, setDetailVisible] = useState<boolean>(false);
const [detailLoading, setDetailLoading] = useState<boolean>(false);
const [detailData, setDetailData] = useState<API.CompanyList.Company | undefined>();
// ---- 审核弹窗 ----
const [approvalVisible, setApprovalVisible] = useState<boolean>(false);
const [approvalStatus, setApprovalStatus] = useState<1 | 2>(1);
const [approvalReason, setApprovalReason] = useState<string>('');
// ---- 密码修改弹窗 ----
const [passwordModalOpen, setPasswordModalOpen] = useState(false);
const [currentRecord, setCurrentRecord] = useState<API.CmsCompany.CompanyUser | null>(null);
const [passwordForm] = Form.useForm();
@@ -16,8 +83,34 @@ function CompanyUserList() {
useEffect(() => {
getDictValueEnum('scale', true, true).then(setScaleEnum);
getDictValueEnum('company_nature', true, true).then(setNatureEnum);
getDictValueEnum('company_nature', false, true).then(setCompanyNatureEnum);
getCmsIndustryTreeList().then((res) => {
if (res?.data) {
setIndustryEnum(flattenIndustryTree(res.data));
}
});
}, []);
// ---- 删除处理 ----
const handleRemoveOne = async (companyId: string) => {
const hide = message.loading('正在删除');
if (!companyId) return true;
try {
const resp = await delCmsCompanyList(companyId);
hide();
if (resp.code === 200) {
message.success('删除成功,即将刷新');
} else {
message.error(resp.msg);
}
return true;
} catch (error) {
hide();
message.error('删除失败,请重试');
return false;
}
};
const columns: ProColumns<API.CmsCompany.CompanyUser>[] = [
{
title: '企业名称',
@@ -49,7 +142,7 @@ function CompanyUserList() {
align: 'center',
width: 100,
valueEnum: scaleEnum,
render: (_, record) => <DictTag enums={scaleEnum} value={record.scale} />,
render: (_, record) => <DictTag enums={scaleEnum} value={record.scale ?? undefined} />,
},
{
title: '注册地址',
@@ -148,11 +241,96 @@ function CompanyUserList() {
{
title: '操作',
align: 'center',
width: 120,
width: 320,
fixed: 'right',
hideInSearch: true,
render: (_, record) => (
<a
render: (_, record) => [
<Button
type="link"
size="small"
key="detail"
icon={<AlignLeftOutlined />}
hidden={!access.hasPerms('cms:company:query')}
onClick={async () => {
setDetailData({ ...record } as any);
setDetailVisible(true);
setDetailLoading(true);
try {
const merged = await loadCompanyDetail(record);
setDetailData(merged);
} catch (e) {
message.error('获取详情失败');
} finally {
setDetailLoading(false);
}
}}
>
</Button>,
<Button
type="link"
size="small"
key="edit"
icon={<FormOutlined />}
hidden={!access.hasPerms('cms:company:edit')}
onClick={async () => {
const hide = message.loading('正在加载详情');
try {
const merged = await loadCompanyDetail(record);
setCurrentRow(merged);
setModalVisible(true);
} catch (e) {
message.error('获取详情失败');
} finally {
hide();
}
}}
>
</Button>,
<Button
type="link"
size="small"
key="approval"
hidden={!access.hasPerms('sys:company:approval')}
icon={<AuditOutlined />}
onClick={() => {
setCurrentRow(record as any);
setApprovalStatus(1);
setApprovalReason('');
setApprovalVisible(true);
}}
>
</Button>,
<Button
type="link"
size="small"
danger
key="batchRemove"
icon={<DeleteOutlined />}
hidden={!access.hasPerms('cms:company:remove')}
onClick={async () => {
Modal.confirm({
title: '删除',
content: '确定删除该项吗?',
okText: '确认',
cancelText: '取消',
onOk: async () => {
const success = await handleRemoveOne(String(record.companyId));
if (success) {
actionRef.current?.reload();
}
},
});
}}
>
</Button>,
<Button
type="link"
size="small"
key="resetPwd"
onClick={() => {
setCurrentRecord(record);
passwordForm.resetFields();
@@ -160,8 +338,8 @@ function CompanyUserList() {
}}
>
</a>
),
</Button>,
],
},
];
@@ -182,7 +360,155 @@ function CompanyUserList() {
scroll={{ x: 'max-content' }}
pagination={{ defaultPageSize: 10, showSizeChanger: true }}
headerTitle="企业用户管理"
toolBarRender={() => [
<Button
type="primary"
key="add"
hidden={!access.hasPerms('cms:company:add')}
onClick={async () => {
setCurrentRow(undefined);
setModalVisible(true);
}}
>
<PlusOutlined />
</Button>,
]}
/>
{/* 编辑/新增弹窗 */}
<EditCompanyListRow
open={modalVisible}
onSubmit={async (values) => {
let resData;
if (values.companyId) {
resData = await putCmsCompanyList({
...values,
companyNature: values.companyNature || '',
});
} else {
resData = await addCmsCompanyList({
...values,
companyNature: values.companyNature || '',
});
}
if (resData.code === 200) {
setModalVisible(false);
setCurrentRow(undefined);
message.success(values.companyId ? '修改成功' : '新增成功');
actionRef.current?.reload();
}
}}
onCancel={() => {
setModalVisible(false);
setCurrentRow(undefined);
}}
values={currentRow}
scaleEnum={scaleEnum}
companyNatureEnum={companyNatureEnum}
/>
{/* 详情弹窗 */}
<CompanyDetailView
open={detailVisible}
loading={detailLoading}
onCancel={() => {
setDetailVisible(false);
setDetailData(undefined);
}}
record={detailData}
scaleEnum={scaleEnum}
companyNatureEnum={companyNatureEnum}
industryEnum={industryEnum}
/>
{/* 审核弹窗 */}
<Modal
title="企业资质审核"
open={approvalVisible}
width={520}
onCancel={() => {
setApprovalVisible(false);
setApprovalReason('');
}}
footer={null}
>
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
<div>
<span style={{ marginRight: 12 }}></span>
<label style={{ marginRight: 16 }}>
<input
type="radio"
name="approvalStatus"
checked={approvalStatus === 1}
onChange={() => setApprovalStatus(1)}
/>
<span style={{ marginLeft: 6 }}></span>
</label>
<label>
<input
type="radio"
name="approvalStatus"
checked={approvalStatus === 2}
onChange={() => setApprovalStatus(2)}
/>
<span style={{ marginLeft: 6 }}></span>
</label>
</div>
{approvalStatus === 2 && (
<div>
<div style={{ marginBottom: 6 }}></div>
<textarea
style={{ width: '100%', minHeight: 100 }}
placeholder="请输入驳回原因"
value={approvalReason}
onChange={(e) => setApprovalReason(e.target.value)}
/>
</div>
)}
<div style={{ textAlign: 'right', marginTop: 8 }}>
<Button onClick={() => setApprovalVisible(false)} style={{ marginRight: 8 }}>
</Button>
<Button
type="primary"
onClick={async () => {
if (!currentRow?.companyId) {
message.error('缺少企业ID');
return;
}
if (approvalStatus === 2 && !approvalReason.trim()) {
message.warning('请填写驳回原因');
return;
}
const hide = message.loading('正在提交审核');
try {
const resp = await postCompanyApproval({
companyId: currentRow.companyId,
status: approvalStatus,
notPassReason: approvalStatus === 2 ? approvalReason.trim() : undefined,
});
hide();
if (resp?.code === 200) {
message.success('提交成功');
setApprovalVisible(false);
setApprovalReason('');
actionRef.current?.reload();
} else {
message.error(resp?.msg || '提交失败');
}
} catch (e) {
hide();
message.error('提交失败');
}
}}
>
</Button>
</div>
</div>
</Modal>
{/* 修改密码弹窗 */}
<Modal
title="修改密码"
open={passwordModalOpen}