Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	jjb.config.js
#	src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js
dev
huwei 2026-08-04 15:58:18 +08:00
commit b991405fc9
8 changed files with 169 additions and 119 deletions

View File

@ -10,10 +10,14 @@ module.exports = {
javaGitBranch: "dev", javaGitBranch: "dev",
// 本地联调 safetyEval-servicecontext-path: /safetyEval默认端口 8095 // 本地联调 safetyEval-servicecontext-path: /safetyEval默认端口 8095
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
// API_HOST: "https://gbs-gateway.qhdsafety.com", API_HOST: "https://gbs-gateway.qhdsafety.com",
// API_HOST: "http://192.168.0.134", // API_HOST: "http://192.168.0.134",
<<<<<<< HEAD
// API_HOST: "http://192.168.0.150", //太浅 // API_HOST: "http://192.168.0.150", //太浅
=======
//API_HOST: "http://192.168.0.150", //太浅
>>>>>>> origin/dev
// API_HOST: "http://192.168.0.152", // API_HOST: "http://192.168.0.152",
API_HOST: "http://192.168.0.103", //huwei API_HOST: "http://192.168.0.103", //huwei
}, },

View File

@ -185,13 +185,27 @@ export default function StaffViewModal({
<Descriptions.Item label="账号">{info.account}</Descriptions.Item> <Descriptions.Item label="账号">{info.account}</Descriptions.Item>
<Descriptions.Item label="部门">{info.deptName}</Descriptions.Item> <Descriptions.Item label="部门">{info.deptName}</Descriptions.Item>
<Descriptions.Item label="岗位">{info.postName}</Descriptions.Item> <Descriptions.Item label="岗位">{info.postName}</Descriptions.Item>
<Descriptions.Item label="身份证号">
{info.idCardNo}
</Descriptions.Item>
<Descriptions.Item label="现住地址" >
{info.currentAddress}
</Descriptions.Item>
<Descriptions.Item label="办公地址" >
{info.officeAddress}
</Descriptions.Item>
<Descriptions.Item label="学历类型"> <Descriptions.Item label="学历类型">
{info.educationTypeName || "-"} {info.educationTypeName || "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="毕业院校">
{info.graduateSchool}
</Descriptions.Item>
<Descriptions.Item label="学历层次"> <Descriptions.Item label="学历层次">
{info.educationLevelName || "-"} {info.educationLevelName || "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="基础学科专业">
{info.basicDisciplineMajorName || "-"}
</Descriptions.Item>
<Descriptions.Item label="是否注册安全工程师"> <Descriptions.Item label="是否注册安全工程师">
{REGISTER_ENGINEER_MAP[info.registerEngineerFlag] ?? "-"} {REGISTER_ENGINEER_MAP[info.registerEngineerFlag] ?? "-"}
@ -210,19 +224,7 @@ export default function StaffViewModal({
? "否" ? "否"
: "-"} : "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="身份证号">
{info.idCardNo}
</Descriptions.Item>
<Descriptions.Item label="现住地址" span={2}>
{info.currentAddress}
</Descriptions.Item>
<Descriptions.Item label="办公地址" span={2}>
{info.officeAddress}
</Descriptions.Item>
<Descriptions.Item label="毕业院校">
{info.graduateSchool}
</Descriptions.Item>
<Descriptions.Item <Descriptions.Item
label="出版学术专著、专利、获奖、发表学术论文等" label="出版学术专著、专利、获奖、发表学术论文等"

View File

@ -430,6 +430,17 @@ function CertModal({
disabled={professionalCapabilityOptions.length === 0} disabled={professionalCapabilityOptions.length === 0}
/> />
</Form.Item> </Form.Item>
<Form.Item
name="certTypeCode"
label="证书类型"
rules={[{ required: true, message: "请选择证书类型" }]}
>
<Select
placeholder="请选择证书类型"
options={CERT_TYPE_OPTIONS}
onChange={() => form.setFieldValue("cert_level", undefined)}
/>
</Form.Item>
<Form.Item <Form.Item
name="certName" name="certName"
label="证照名称" label="证照名称"
@ -470,17 +481,7 @@ function CertModal({
> >
<DatePicker.RangePicker style={{ width: "100%" }} /> <DatePicker.RangePicker style={{ width: "100%" }} />
</Form.Item> </Form.Item>
<Form.Item
name="certTypeCode"
label="证书类型"
rules={[{ required: true, message: "请选择证书类型" }]}
>
<Select
placeholder="请选择证书类型"
options={CERT_TYPE_OPTIONS}
onChange={() => form.setFieldValue("cert_level", undefined)}
/>
</Form.Item>
<Form.Item <Form.Item
name="certLevel" name="certLevel"
label="证书等级" label="证书等级"
@ -601,10 +602,11 @@ function ViewModal({ open, currentId, staffCertificateInfo, onCancel }) {
<Descriptions bordered column={1} labelStyle={{ width: 160 }}> <Descriptions bordered column={1} labelStyle={{ width: 160 }}>
<Descriptions.Item label="专业范围">{QUALIFICATION_INDUSTRY_OPTIONS_MAP[info.businessScope] }</Descriptions.Item> <Descriptions.Item label="专业范围">{QUALIFICATION_INDUSTRY_OPTIONS_MAP[info.businessScope] }</Descriptions.Item>
<Descriptions.Item label="专业能力">{info.professionalCapabilityName }</Descriptions.Item> <Descriptions.Item label="专业能力">{info.professionalCapabilityName }</Descriptions.Item>
<Descriptions.Item label="证照名称">{info.certName}</Descriptions.Item>
<Descriptions.Item label="证书类型"> <Descriptions.Item label="证书类型">
{CERT_TYPE_MAP[info.certTypeCode] || info.certTypeCode} {CERT_TYPE_MAP[info.certTypeCode] || info.certTypeCode}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="证照名称">{info.certName}</Descriptions.Item>
<Descriptions.Item label="证书等级"> <Descriptions.Item label="证书等级">
{CERT_LEVEL_LABEL_BY_TYPE[info.certTypeCode]?.[info.cert_level] || info.cert_level} {CERT_LEVEL_LABEL_BY_TYPE[info.certTypeCode]?.[info.cert_level] || info.cert_level}
</Descriptions.Item> </Descriptions.Item>

View File

@ -394,7 +394,7 @@ function StaffFormModal({
}; };
const loadBasicDisciplineMajors = async () => { const loadBasicDisciplineMajors = async () => {
await queryBasicDisciplineMajor({ pageSize: 999 }); await queryBasicDisciplineMajor({ pageSize: 999 });
}; };
@ -450,7 +450,7 @@ function StaffFormModal({
} }
form.setFieldsValue(setFields); form.setFieldsValue(setFields);
}) })
.finally(() => { .finally(() => {
if (!cancelled) setDetailLoading(false); if (!cancelled) setDetailLoading(false);
@ -645,7 +645,66 @@ function StaffFormModal({
<Input placeholder="请输入身份证号" maxLength={18} /> <Input placeholder="请输入身份证号" maxLength={18} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}>
<Form.Item
name="currentAddress"
label="现住地址"
rules={[{ max: 300, message: "现住地址不能超过300个字符" }]}
>
<Input placeholder="请输入现住地址" maxLength={300} showCount />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="officeAddress"
label="办公地址"
rules={[{ max: 300, message: "办公地址不能超过300个字符" }]}
>
<Input placeholder="请输入办公地址" maxLength={300} showCount />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item name="educationTypeCode" label="学历类型">
<Select
placeholder="请选择学历类型"
allowClear
options={EDUCATION_TYPE_OPTIONS}
onChange={(_val, option) => {
form.setFieldValue(
"educationTypeName",
option?.label || undefined,
);
}}
/>
</Form.Item>
<Form.Item name="educationTypeName" noStyle />
</Col>
<Col span={12}>
<Form.Item
name="graduateSchool"
label="毕业院校"
rules={[{ max: 200, message: "毕业院校不能超过200个字符" }]}
>
<Input placeholder="请输入毕业院校" maxLength={200} showCount />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item name="educationLevelCode" label="学历层次">
<Select
placeholder="请选择学历层次"
allowClear
options={EDUCATION_LEVEL_OPTIONS}
onChange={(val, option) => {
form.setFieldValue(
"educationLevelName",
option?.label || undefined,
);
}}
/>
</Form.Item>
<Form.Item name="educationLevelName" noStyle />
</Col>
<Col span={12}> <Col span={12}>
<Form.Item name="basicDisciplineMajorId" label="基础学科专业"> <Form.Item name="basicDisciplineMajorId" label="基础学科专业">
<Select <Select
@ -665,38 +724,6 @@ function StaffFormModal({
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}>
<Form.Item name="educationTypeCode" label="学历类型">
<Select
placeholder="请选择学历类型"
allowClear
options={EDUCATION_TYPE_OPTIONS}
onChange={(_val, option) => {
form.setFieldValue(
"educationTypeName",
option?.label || undefined,
);
}}
/>
</Form.Item>
<Form.Item name="educationTypeName" noStyle />
</Col>
<Col span={12}>
<Form.Item name="educationLevelCode" label="学历层次">
<Select
placeholder="请选择学历层次"
allowClear
options={EDUCATION_LEVEL_OPTIONS}
onChange={(val, option) => {
form.setFieldValue(
"educationLevelName",
option?.label || undefined,
);
}}
/>
</Form.Item>
<Form.Item name="educationLevelName" noStyle />
</Col>
<Col span={12}> <Col span={12}>
<AttachmentUpload <AttachmentUpload
name="proofMaterialUrl" name="proofMaterialUrl"
@ -883,34 +910,6 @@ function StaffFormModal({
/> />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}>
<Form.Item
name="currentAddress"
label="现住地址"
rules={[{ max: 300, message: "现住地址不能超过300个字符" }]}
>
<Input placeholder="请输入现住地址" maxLength={300} showCount />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="officeAddress"
label="办公地址"
rules={[{ max: 300, message: "办公地址不能超过300个字符" }]}
>
<Input placeholder="请输入办公地址" maxLength={300} showCount />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="graduateSchool"
label="毕业院校"
rules={[{ max: 200, message: "毕业院校不能超过200个字符" }]}
>
<Input placeholder="请输入毕业院校" maxLength={200} showCount />
</Form.Item>
</Col>
</Row> </Row>
</Form> </Form>
</Modal> </Modal>
@ -925,7 +924,7 @@ function StaffImportModal({ open, onCancel, onSuccess }) {
const handleDownloadTemplate = async () => { const handleDownloadTemplate = async () => {
try { try {
const res = await Get("/safetyEval/org-personnel/import/template"); const res = await Get("/safetyEval/org-personnel/import/template");
const url = res?.data ; const url = res?.data;
if (!url) { if (!url) {
message.warning("未获取到模板下载地址"); message.warning("未获取到模板下载地址");
return; return;
@ -961,10 +960,11 @@ function StaffImportModal({ open, onCancel, onSuccess }) {
const headers = { token: sessionStorage.getItem("token") || "" }; const headers = { token: sessionStorage.getItem("token") || "" };
const orgInfoId = sessionStorage.getItem("orgInfoId"); const orgInfoId = sessionStorage.getItem("orgInfoId");
if (orgInfoId) headers.orgInfoId = String(orgInfoId); if (orgInfoId) headers.orgInfoId = String(orgInfoId);
const resp = await fetch( const resp = await fetch(`${API_HOST}/safetyEval/org-personnel/import`, {
`${API_HOST}/safetyEval/org-personnel/import`, method: "POST",
{ method: "POST", headers, body: formData }, headers,
); body: formData,
});
const json = await resp.json(); const json = await resp.json();
if (json && json.success !== false) { if (json && json.success !== false) {
onDone(json.data, file); onDone(json.data, file);
@ -1004,8 +1004,7 @@ function StaffImportModal({ open, onCancel, onSuccess }) {
customRequest={customRequest} customRequest={customRequest}
disabled={uploading} disabled={uploading}
beforeUpload={(file) => { beforeUpload={(file) => {
const ext = const ext = "." + (file.name.split(".").pop() || "").toLowerCase();
"." + (file.name.split(".").pop() || "").toLowerCase();
if (![".xlsx", ".xls"].includes(ext)) { if (![".xlsx", ".xls"].includes(ext)) {
message.error("仅支持 .xlsx / .xls 格式文件"); message.error("仅支持 .xlsx / .xls 格式文件");
return Upload.LIST_IGNORE; return Upload.LIST_IGNORE;

View File

@ -6,14 +6,14 @@ import {
import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions"; import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions";
import AttachmentUpload from "~/components/AttachmentUpload"; import AttachmentUpload from "~/components/AttachmentUpload";
export default function BasicInfoStep({ form, disabled }) { export default function BasicInfoStep({ form, disabled, mode }) {
return ( return (
<Form form={form} layout="vertical" disabled={disabled}> <Form form={form} layout="vertical" disabled={disabled}>
<Row gutter={16}> <Row gutter={16}>
<Col span={24}> <Col span={24}>
<Form.Item <Form.Item
name="businessScope" name="businessScope"
label="申请的业务范围" label={mode === 'filed' ? "已有资质备案" : "申请的业务范围"}
rules={[{ required: !disabled, message: "请选择业务范围" }]} rules={[{ required: !disabled, message: "请选择业务范围" }]}
> >
<Select <Select
@ -38,32 +38,32 @@ export default function BasicInfoStep({ form, disabled }) {
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="filingUnitName" label="备案单位"> <Form.Item name="filingUnitName" label="备案单位" rules={[{ required: !disabled, message: "请输入备案单位" }]}>
<Input placeholder="备案单位" maxLength={64} /> <Input placeholder="备案单位" maxLength={64} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="filingUnitTypeName" label="备案单位类型"> <Form.Item name="filingUnitTypeName" label="备案单位类型" rules={[{ required: !disabled, message: "请选择备案单位类型" }]}>
<Select options={FILING_UNIT_TYPE_OPTIONS} placeholder="请选择" /> <Select options={FILING_UNIT_TYPE_OPTIONS} placeholder="请选择" />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="creditCode" label="统一社会信用代码"> <Form.Item name="creditCode" label="统一社会信用代码" rules={[{ required: !disabled, message: "请输入统一社会信用代码" }]}>
<Input placeholder="统一社会信用代码" maxLength={18} /> <Input placeholder="统一社会信用代码" maxLength={18} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<Form.Item name="officeAddress" label="办公地址"> <Form.Item name="officeAddress" label="办公地址" rules={[{ required: !disabled, message: "请输入办公地址" }]}>
<Input placeholder="办公地址" maxLength={128} /> <Input placeholder="办公地址" maxLength={128} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<Form.Item name="registerAddress" label="注册地址"> <Form.Item name="registerAddress" label="注册地址" rules={[{ required: !disabled, message: "请输入注册地址" }]}>
<Input placeholder="注册地址" maxLength={128} /> <Input placeholder="注册地址" maxLength={128} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="qualCertNo" label="资质证书编号"> <Form.Item name="qualCertNo" label="资质证书编号" rules={[{ required: !disabled, message: "请输入资质证书编号" }]}>
<Input placeholder="资质证书编号" maxLength={32} /> <Input placeholder="资质证书编号" maxLength={32} />
</Form.Item> </Form.Item>
</Col> </Col>
@ -72,6 +72,7 @@ export default function BasicInfoStep({ form, disabled }) {
name="infoDisclosureUrl" name="infoDisclosureUrl"
label="信息公开网址" label="信息公开网址"
rules={[ rules={[
{ required: !disabled, message: "请输入信息公开网址" },
{ {
pattern: /^https?:\/\/[^\s]+$/, pattern: /^https?:\/\/[^\s]+$/,
message: "请输入正确的网址,需以 http:// 或 https:// 开头", message: "请输入正确的网址,需以 http:// 或 https:// 开头",
@ -85,8 +86,8 @@ export default function BasicInfoStep({ form, disabled }) {
<Form.Item <Form.Item
name="legalPersonPhone" name="legalPersonPhone"
label="法人代表电话" label="法人代表电话"
rules={[ rules={[
{ required: !disabled, message: "请输入法人代表电话" },
{ {
pattern: /^(1\d{10}|0\d{2,3}-?\d{7,8})$/, pattern: /^(1\d{10}|0\d{2,3}-?\d{7,8})$/,
message: "请输入正确的手机号或座机号", message: "请输入正确的手机号或座机号",
@ -100,8 +101,8 @@ export default function BasicInfoStep({ form, disabled }) {
<Form.Item <Form.Item
name="contactPhone" name="contactPhone"
label="联系人电话" label="联系人电话"
rules={[ rules={[
{ required: !disabled, message: "请输入联系人电话" },
{ {
pattern: /^(1\d{10}|0\d{2,3}-?\d{7,8})$/, pattern: /^(1\d{10}|0\d{2,3}-?\d{7,8})$/,
message: "请输入正确的手机号或座机号", message: "请输入正确的手机号或座机号",
@ -151,7 +152,7 @@ export default function BasicInfoStep({ form, disabled }) {
<Form.Item <Form.Item
name="archiveRoomArea" name="archiveRoomArea"
label="档案室面积(㎡)" label="档案室面积(㎡)"
rules={[{ required: !disabled, message: "请输入档案室面积" }]}
> >
<InputNumber <InputNumber
style={{ width: "100%" }} style={{ width: "100%" }}
@ -166,7 +167,7 @@ export default function BasicInfoStep({ form, disabled }) {
<Form.Item <Form.Item
name="fulltimeEvaluatorCount" name="fulltimeEvaluatorCount"
label="专职安全评价师数量(人)" label="专职安全评价师数量(人)"
rules={[{ required: !disabled, message: "请输入专职安全评价师数量" }]}
> >
<InputNumber style={{ width: "100%" }} min={0} max={100000000} maxLength={9} placeholder="人" /> <InputNumber style={{ width: "100%" }} min={0} max={100000000} maxLength={9} placeholder="人" />
</Form.Item> </Form.Item>
@ -175,19 +176,20 @@ export default function BasicInfoStep({ form, disabled }) {
<Form.Item <Form.Item
name="registeredEngineerCount" name="registeredEngineerCount"
label="注册安全工程师数量(人)" label="注册安全工程师数量(人)"
rules={[{ required: !disabled, message: "请输入注册安全工程师数量" }]}
> >
<InputNumber style={{ width: "100%" }} min={0} max={100000000} maxLength={9} placeholder="人" /> <InputNumber style={{ width: "100%" }} min={0} max={100000000} maxLength={9} placeholder="人" />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<Form.Item name="unitIntro" label="单位基本情况介绍"> <Form.Item name="unitIntro" label="单位基本情况介绍" rules={[{ required: !disabled, message: "请输入单位基本情况介绍" }]}>
<Input.TextArea rows={3} placeholder="请输入单位基本情况介绍" maxLength={500} showCount /> <Input.TextArea rows={3} placeholder="请输入单位基本情况介绍" maxLength={500} showCount />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<AttachmentUpload <AttachmentUpload
name="attachmentUrl" name="attachmentUrl"
rules={[{ required: !disabled, message: "请上传附件" }]}
label="上传附件" label="上传附件"
disabled={disabled} disabled={disabled}
extra={'最多上传12个PDF、DOC、DOCX格式文件'} extra={'最多上传12个PDF、DOC、DOCX格式文件'}

View File

@ -23,7 +23,7 @@ export default function MaterialStep({
dataSource={materials} dataSource={materials}
columns={[ columns={[
{ title: "序号", width: 60, render: (_, record, index) => index + 1 }, { title: "序号", width: 60, render: (_, record, index) => index + 1 },
{ title: "内容", dataIndex: "materialContent", width: 200, ellipsis: true }, { title: "内容", dataIndex: "materialContent", width: 400, ellipsis: true },
{ title: "上传附件", dataIndex: "attachmentDesc", width: 100 }, { title: "上传附件", dataIndex: "attachmentDesc", width: 100 },
{ {
title: "格式", title: "格式",

View File

@ -36,7 +36,7 @@ const MODE_TITLE = {
function FilingFormPage(props) { function FilingFormPage(props) {
const query = router.query; const query = router.query;
const mode = query.mode; const mode = query.mode;
const [loading, setLoading] = useState(false);
const [submitting, setSubmitting] = useState(false); const [submitting, setSubmitting] = useState(false);
const [activeStep, setActiveStep] = useState("basic"); const [activeStep, setActiveStep] = useState("basic");
const [detail, setDetail] = useState(null); const [detail, setDetail] = useState(null);
@ -338,8 +338,8 @@ function FilingFormPage(props) {
const STEP_ITEMS = [ const STEP_ITEMS = [
{ {
key: "basic", key: "basic",
label: "1. 备案基本信息", label: "1. 基本信息备案",
children: <BasicInfoStep form={basicForm} disabled={readOnly} />, children: <BasicInfoStep form={basicForm} disabled={readOnly} mode={mode} />,
forceRender: true, forceRender: true,
}, },
{ {
@ -367,7 +367,7 @@ function FilingFormPage(props) {
}, },
{ {
key: "personnel", key: "personnel",
label: "4. 备案人员管理", label: "4. 专职人员备案",
children: ( children: (
<PersonnelStep <PersonnelStep
personnelList={detail?.personnelList || []} personnelList={detail?.personnelList || []}
@ -401,7 +401,7 @@ function FilingFormPage(props) {
history={props.history} history={props.history}
previous previous
> >
<Spin spinning={loading || submitting}> <Spin spinning={ submitting}>
<Tabs <Tabs
activeKey={activeStep} activeKey={activeStep}
items={STEP_ITEMS} items={STEP_ITEMS}

View File

@ -106,6 +106,38 @@ const ProjectDocLibrary = (props) => {
} }
}; };
const handleDownload = async (record) => {
const raw = record.project_doc_url || "";
if (!raw) {
message.warning("文件地址不存在");
return;
}
const fileUrl = /^https?:\/\//.test(raw) ? raw : (window.fileUrl || "") + raw;
const fileName = record.materialName || raw.split("/").pop() || "文件";
const hide = message.loading("正在下载...", 0);
try {
const response = await fetch(fileUrl, {
headers: { token: sessionStorage.getItem("token") || "" },
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const blob = await response.blob();
const blobUrl = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = blobUrl;
link.download = fileName;
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(blobUrl);
message.success("下载已开始");
} catch {
message.error("下载失败,请稍后重试");
} finally {
hide();
}
};
const columns = [ const columns = [
{ title: "项目编号", dataIndex: "projectNo", width: 130 }, { title: "项目编号", dataIndex: "projectNo", width: 130 },
{ {
@ -264,9 +296,18 @@ const ProjectDocLibrary = (props) => {
{ title: "文件名称", dataIndex: "materialName", ellipsis: true }, { title: "文件名称", dataIndex: "materialName", ellipsis: true },
{ {
title: "操作", title: "操作",
width: 100, width: 130,
render: (_, record) => ( render: (_, record) => (
<PreviewUrlButton url={record.project_doc_url} /> <Space size={8}>
<PreviewUrlButton url={record.project_doc_url} />
<Button
type="link"
size="small"
onClick={() => handleDownload(record)}
>
下载
</Button>
</Space>
), ),
}, },
]} ]}