dev_1.0.1
tangjie 2026-07-01 17:57:42 +08:00
parent 70c645f465
commit 9102384a71
10 changed files with 225 additions and 128 deletions

View File

@ -10,7 +10,7 @@ module.exports = {
javaGitBranch: "<branch-name>", javaGitBranch: "<branch-name>",
// 本地联调 safety-eval-servicecontext-path: /safety-eval默认端口 8095 // 本地联调 safety-eval-servicecontext-path: /safety-eval默认端口 8095
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
API_HOST: "http://192.168.0.204:8095", API_HOST: "http://192.168.0.149",
}, },
production: { production: {
// 应用后端分支名称,部署上线需要 // 应用后端分支名称,部署上线需要

View File

@ -0,0 +1,68 @@
import { Form, Image, Upload } from "antd";
import { useState } from "react";
const isImage = (url) => /\.(png|jpe?g|gif|bmp|webp|svg)(\?.*)?$/i.test(url || "");
export default function AttachmentUpload({ name, label, disabled }) {
const [previewImage, setPreviewImage] = useState("");
return (
<>
<Form.Item
name={name}
label={label}
valuePropName="fileList"
getValueProps={(value) => {
if (Array.isArray(value)) {
return { fileList: value };
}
return {
fileList: value
? value.split(",").map((item) => ({
url: item,
uid: item,
status: "done",
name: "附件",
}))
: [],
};
}}
getValueFromEvent={({ fileList }) => {
return (
fileList?.map((file) => ({
url: file.response?.data?.url || file.url,
uid: file.uid,
status: "done",
name: file.name,
})) || []
);
}}
>
<Upload
disabled={disabled}
listType="picture-card"
action={`${window.process.env.app.API_HOST}/safety-eval/file/upload`}
onPreview={(file) => {
if (isImage(file.url || file.thumbUrl)) {
setPreviewImage(file.url || file.thumbUrl);
} else {
window.open(file.url || file.thumbUrl);
}
}}
>
上传附件
</Upload>
</Form.Item>
<Image
style={{ display: "none" }}
preview={{
visible: !!previewImage,
src: previewImage,
onVisibleChange: (visible) => {
if (!visible) setPreviewImage("");
},
}}
/>
</>
);
}

View File

@ -1,21 +1,39 @@
import { Form, Input, InputNumber, Row, Col, Select } from "antd"; import { Form, Input, InputNumber, Row, Col, Select } from "antd";
import { CHONGQING_DISTRICTS, QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions"; import {
CHONGQING_DISTRICTS,
QUALIFICATION_INDUSTRY_OPTIONS,
} from "~/enumerate/enterpriseOptions";
import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions"; import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions";
import FilingUpload, { resolveFilingUploadUrl } from "./FilingUpload"; import AttachmentUpload from "~/components/AttachmentUpload";
export default function export default function BasicInfoStep({ form, disabled }) {
BasicInfoStep({ form, disabled, onAttachmentChange }) {
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 name="businessScope" label="申请的业务范围" rules={[{ required: !disabled, message: "请选择业务范围" }]}> <Form.Item
<Select options={QUALIFICATION_INDUSTRY_OPTIONS} placeholder="请选择证照类型" /> name="businessScope"
label="申请的业务范围"
rules={[{ required: !disabled, message: "请选择业务范围" }]}
>
<Select
options={QUALIFICATION_INDUSTRY_OPTIONS}
placeholder="请选择证照类型"
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="filingTerritoryName" label="备案属地" rules={[{ required: !disabled, message: "请选择备案属地" }]}> <Form.Item
<Select options={CHONGQING_DISTRICTS} placeholder="请选择" showSearch optionFilterProp="label" /> name="filingTerritoryName"
label="备案属地"
rules={[{ required: !disabled, message: "请选择备案属地" }]}
>
<Select
options={CHONGQING_DISTRICTS}
placeholder="请选择"
showSearch
optionFilterProp="label"
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
@ -79,12 +97,18 @@ BasicInfoStep({ form, disabled, onAttachmentChange }) {
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="fulltimeEvaluatorCount" label="专职安全评价师数量(人)"> <Form.Item
name="fulltimeEvaluatorCount"
label="专职安全评价师数量(人)"
>
<InputNumber style={{ width: "100%" }} min={0} placeholder="人" /> <InputNumber style={{ width: "100%" }} min={0} placeholder="人" />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="registeredEngineerCount" label="注册安全工程师数量(人)"> <Form.Item
name="registeredEngineerCount"
label="注册安全工程师数量(人)"
>
<InputNumber style={{ width: "100%" }} min={0} placeholder="人" /> <InputNumber style={{ width: "100%" }} min={0} placeholder="人" />
</Form.Item> </Form.Item>
</Col> </Col>
@ -94,18 +118,7 @@ BasicInfoStep({ form, disabled, onAttachmentChange }) {
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<Form.Item name="attachments" label="上传附件"> <AttachmentUpload name="attachmentUrl" label="上传附件" disabled={disabled} />
<FilingUpload
disabled={disabled}
onChange={async (files) => {
if (disabled) {
return;
}
const url = resolveFilingUploadUrl(files);
onAttachmentChange?.(url, files);
}}
/>
</Form.Item>
</Col> </Col>
</Row> </Row>
</Form> </Form>

View File

@ -1,6 +1,7 @@
import { DatePicker, Form, Input, Row, Col, Select } from "antd"; import { DatePicker, Form, Input, Row, Col, Select } from "antd";
import { COMMITMENT_PARAGRAPHS } from "../../filingCommitment"; import { COMMITMENT_PARAGRAPHS } from "../../filingCommitment";
import FilingUpload, { resolveFilingUploadUrl } from "./FilingUpload"; import FilingUpload, { resolveFilingUploadUrl } from "./FilingUpload";
import AttachmentUpload from "~/components/AttachmentUpload";
const BLANK_STYLE = { const BLANK_STYLE = {
display: "inline-block", display: "inline-block",
@ -13,9 +14,7 @@ const BLANK_STYLE = {
function renderBlank(value) { function renderBlank(value) {
const text = value?.trim() || ""; const text = value?.trim() || "";
return ( return <span style={BLANK_STYLE}>{text || "\u00A0".repeat(8)}</span>;
<span style={BLANK_STYLE}>{text || "\u00A0".repeat(8)}</span>
);
} }
function CommitmentBody({ legalRepName, filingUnitName }) { function CommitmentBody({ legalRepName, filingUnitName }) {
@ -23,10 +22,20 @@ function CommitmentBody({ legalRepName, filingUnitName }) {
return ( return (
<div style={{ fontSize: 14, lineHeight: 2, color: "rgba(0,0,0,0.85)" }}> <div style={{ fontSize: 14, lineHeight: 2, color: "rgba(0,0,0,0.85)" }}>
{COMMITMENT_PARAGRAPHS.map((paragraph) => ( {COMMITMENT_PARAGRAPHS.map((paragraph) => (
<p key={paragraph.key} style={{ margin: paragraph.key === "intro" ? "0 0 12px" : "0 0 10px", textIndent: paragraph.key === "intro" ? 0 : "2em" }}> <p
key={paragraph.key}
style={{
margin: paragraph.key === "intro" ? "0 0 12px" : "0 0 10px",
textIndent: paragraph.key === "intro" ? 0 : "2em",
}}
>
{paragraph.parts.map((part, index) => { {paragraph.parts.map((part, index) => {
if (part.type === "blank") { if (part.type === "blank") {
return <span key={`${paragraph.key}-${index}`}>{renderBlank(values[part.field])}</span>; return (
<span key={`${paragraph.key}-${index}`}>
{renderBlank(values[part.field])}
</span>
);
} }
return <span key={`${paragraph.key}-${index}`}>{part.value}</span>; return <span key={`${paragraph.key}-${index}`}>{part.value}</span>;
})} })}
@ -50,7 +59,9 @@ export default function CommitmentStep({
form.setFieldsValue({ legalRepPersonnelId: undefined, legalRepName: "" }); form.setFieldsValue({ legalRepPersonnelId: undefined, legalRepName: "" });
return; return;
} }
const selected = personnelOptions.find((item) => item.value === personnelId); const selected = personnelOptions.find(
(item) => item.value === personnelId,
);
form.setFieldsValue({ form.setFieldsValue({
legalRepPersonnelId: personnelId, legalRepPersonnelId: personnelId,
legalRepName: selected?.staffName || selected?.label || "", legalRepName: selected?.staffName || selected?.label || "",
@ -70,15 +81,19 @@ export default function CommitmentStep({
<Input /> <Input />
</Form.Item> </Form.Item>
<div style={{ <div
border: "1px solid #e8e8e8", style={{
borderRadius: 4, border: "1px solid #e8e8e8",
padding: "20px 24px", borderRadius: 4,
background: "#fafafa", padding: "20px 24px",
marginBottom: 24, background: "#fafafa",
}} marginBottom: 24,
}}
> >
<CommitmentBody legalRepName={legalRepName} filingUnitName={filingUnitName} /> <CommitmentBody
legalRepName={legalRepName}
filingUnitName={filingUnitName}
/>
</div> </div>
<Row gutter={24}> <Row gutter={24}>
@ -104,20 +119,11 @@ export default function CommitmentStep({
</Form.Item> </Form.Item>
</Col> </Col>
</Row> </Row>
<AttachmentUpload
<Form.Item name="signatureFiles" label="电子签名"> name="legalRepSignatureUrl"
<FilingUpload label="电子签名"
disabled={disabled} disabled={disabled}
accept="image/*" />
onChange={(files) => {
if (disabled) {
return;
}
const url = resolveFilingUploadUrl(files);
onSignatureChange?.(url, files);
}}
/>
</Form.Item>
</Form> </Form>
</div> </div>
); );

View File

@ -15,9 +15,10 @@ export default function FilingUpload({
<Upload <Upload
maxCount={maxCount} maxCount={maxCount}
accept={accept} accept={accept}
action={`${window.process.env.app.API_HOST}/safety-eval/file/upload`}
disabled={disabled} disabled={disabled}
fileList={fileList} fileList={fileList}
beforeUpload={() => false}
onChange={(info) => { onChange={(info) => {
if (disabled) return; if (disabled) return;
onChange?.(info.fileList); onChange?.(info.fileList);

View File

@ -1,7 +1,5 @@
import { Button, Space, Table, Tag } from "antd"; import { Button, Image, Space, Table, Tag, Upload } from "antd";
import { useState } from "react"; import { useState } from "react";
import { resolveUploadFileId } from "~/utils/mockUpload";
import FilePreviewModal from "~/components/FilePreviewModal";
export default function MaterialStep({ export default function MaterialStep({
materials = [], materials = [],
@ -9,8 +7,10 @@ export default function MaterialStep({
onUpload, onUpload,
loading, loading,
}) { }) {
const [preview, setPreview] = useState(null); const [previewImage, setPreviewImage] = useState("");
console.log(disabled)
const isImage = (url) => /\.(png|jpe?g|gif|bmp|webp|svg)(\?.*)?$/i.test(url || "");
return ( return (
<> <>
<Table <Table
@ -44,16 +44,35 @@ console.log(disabled)
render: (_, record) => ( render: (_, record) => (
<Space size="small"> <Space size="small">
{record.attachmentUrl ? ( {record.attachmentUrl ? (
<Button type="link" size="small" onClick={() => setPreview(record)}>预览</Button> <Button
type="link"
size="small"
onClick={() => {
if (isImage(record.attachmentUrl)) {
setPreviewImage(record.attachmentUrl);
} else {
window.open(record.attachmentUrl);
}
}}
>
预览
</Button>
) : ( ) : (
!disabled && ( !disabled && (
<Button <Upload
type="link" showUploadList={false}
size="small" action={`${window.process.env.app.API_HOST}/safety-eval/file/upload`}
onClick={() => onUpload?.(record, resolveUploadFileId([]))} onChange={(info) => {
if (info.file.status === "done") {
const url = info.file.response?.data?.url;
if (url) {
onUpload?.(record, url);
}
}
}}
> >
上传 <Button type="link" size="small">上传</Button>
</Button> </Upload>
) )
)} )}
</Space> </Space>
@ -62,12 +81,15 @@ console.log(disabled)
{ title: "注释", dataIndex: "materialRemark", ellipsis: true }, { title: "注释", dataIndex: "materialRemark", ellipsis: true },
]} ]}
/> />
<FilePreviewModal <Image
open={!!preview} style={{ display: "none" }}
title="材料预览" preview={{
fileName={preview?.materialContent} visible: !!previewImage,
url={preview?.attachmentUrl} src: previewImage,
onCancel={() => setPreview(null)} onVisibleChange: (visible) => {
if (!visible) setPreviewImage("");
},
}}
/> />
</> </>
); );

View File

@ -93,12 +93,14 @@ function FilingFormPage(props) {
useEffect(() => { useEffect(() => {
loadPersonnelOptions(); loadPersonnelOptions();
if(query.id){ if(query.id){
fetchQualFilingDetail({ id: query.id }).then((res) => { fetchQualFilingDetail(query.id).then((res) => {
updateDetail((prev) => ({ ...prev, ...res?.data || {} })); setDetail((prev) => ({ ...prev, ...res?.data || {} }));
console.log(res?.data, 'res.data');
basicForm.setFieldsValue(res?.data || {});
}); });
} }
else{ else{
updateDetail((prev) => ({ ...prev, materials: FILING_MATERIAL_TEMPLATE })); setDetail((prev) => ({ ...prev, materials: FILING_MATERIAL_TEMPLATE }));
} }
}, []); }, []);
@ -131,21 +133,6 @@ function FilingFormPage(props) {
}, [commitmentForm, personnelOptions]); }, [commitmentForm, personnelOptions]);
const updateDetail = useCallback(
(updater) => {
setDetail((prev) => {
const next =
typeof updater === "function"
? updater(prev)
: { ...prev, ...updater };
detailRef.current = next;
return next;
});
},
[ mode, readOnly],
);
const collectCurrentDetail = useCallback(() => { const collectCurrentDetail = useCallback(() => {
const current = detailRef.current || detail; const current = detailRef.current || detail;
return mergeDetailFromForms(current, { return mergeDetailFromForms(current, {
@ -171,7 +158,7 @@ function FilingFormPage(props) {
setSubmitting(false); setSubmitting(false);
} }
}; };
const handleSubmitRequest = () => { const handleSubmitRequest = () => {
if (readOnly) { if (readOnly) {
return; return;
@ -189,8 +176,9 @@ function FilingFormPage(props) {
setSubmitting(true); setSubmitting(true);
try { try {
const currentDetail = collectCurrentDetail(); const currentDetail = collectCurrentDetail();
debugger
const saved = await persistFilingToBackend(props, currentDetail, mode); const saved = await persistFilingToBackend(props, currentDetail, mode);
clearLocalDraft(mode);
if (mode === FILING_FORM_MODE.CHANGE) { if (mode === FILING_FORM_MODE.CHANGE) {
const res = await props.qualFilingChangeSubmit({ const res = await props.qualFilingChangeSubmit({
@ -219,32 +207,31 @@ function FilingFormPage(props) {
const handleMaterialUpload = (record, url) => { const handleMaterialUpload = (record, url) => {
const attachmentUrl = url || resolveUploadFileId([]); const attachmentUrl = url || resolveUploadFileId([]);
updateDetail((prev) => ({ setDetail((prev) => ({
...prev, ...prev,
materials: (prev.materials || []).map((item) => materials: (prev.materials || []).map((item) =>
item.id === record.id || item.sortOrder === record.sortOrder {
return item.id === record.id
? { ? {
...item, ...item,
attachmentUrl, attachmentUrl,
uploadStatusCode: 2, uploadStatusCode: 2,
uploadStatusName: "已上传", uploadStatusName: "已上传",
} }
: item, : item
}
), ),
})); }));
message.success(`材料已选择,${saveActionHint}`); message.success(`材料已选择,${saveActionHint}`);
}; };
const handleAttachmentChange = (url) => {
updateDetail((prev) => ({ ...prev, attachmentUrl: url }));
};
const handleSignatureChange = (url, files) => { const handleSignatureChange = (url, files) => {
commitmentForm.setFieldsValue({ commitmentForm.setFieldsValue({
signatureFiles: files, signatureFiles: files,
legalRepSignatureUrl: url, legalRepSignatureUrl: url,
}); });
updateDetail((prev) => ({ setDetail((prev) => ({
...prev, ...prev,
commitment: { commitment: {
...prev.commitment, ...prev.commitment,
@ -273,7 +260,7 @@ function FilingFormPage(props) {
? mapStaffRowToFilingPersonnel(row) ? mapStaffRowToFilingPersonnel(row)
: mapStaffRowToFilingPersonnel({ id }); : mapStaffRowToFilingPersonnel({ id });
}); });
updateDetail((prev) => ({ setDetail((prev) => ({
...prev, ...prev,
personnelList: [...(prev.personnelList || []), ...newRows], personnelList: [...(prev.personnelList || []), ...newRows],
})); }));
@ -285,7 +272,7 @@ function FilingFormPage(props) {
title: "提示", title: "提示",
content: `确认删除人员「${record.personName}」?`, content: `确认删除人员「${record.personName}」?`,
onOk: () => { onOk: () => {
updateDetail((prev) => ({ setDetail((prev) => ({
...prev, ...prev,
personnelList: (prev.personnelList || []).filter( personnelList: (prev.personnelList || []).filter(
(item) => item.id !== record.id, (item) => item.id !== record.id,
@ -314,7 +301,7 @@ function FilingFormPage(props) {
? mapEquipRowToFilingEquipment(row) ? mapEquipRowToFilingEquipment(row)
: mapEquipRowToFilingEquipment({ id }); : mapEquipRowToFilingEquipment({ id });
}); });
updateDetail((prev) => ({ setDetail((prev) => ({
...prev, ...prev,
equipmentList: [...(prev.equipmentList || []), ...newRows], equipmentList: [...(prev.equipmentList || []), ...newRows],
})); }));
@ -326,7 +313,7 @@ function FilingFormPage(props) {
title: "提示", title: "提示",
content: `确认移除装备「${record.deviceName}」?`, content: `确认移除装备「${record.deviceName}」?`,
onOk: () => { onOk: () => {
updateDetail((prev) => ({ setDetail((prev) => ({
...prev, ...prev,
equipmentList: (prev.equipmentList || []).filter( equipmentList: (prev.equipmentList || []).filter(
(item) => item.id !== record.id, (item) => item.id !== record.id,
@ -390,7 +377,6 @@ function FilingFormPage(props) {
<BasicInfoStep <BasicInfoStep
form={basicForm} form={basicForm}
disabled={readOnly} disabled={readOnly}
onAttachmentChange={handleAttachmentChange}
/> />
)} )}
{activeStep === "materials" && ( {activeStep === "materials" && (
@ -461,7 +447,10 @@ function FilingFormPage(props) {
{!isLastStep && ( {!isLastStep && (
<Button <Button
type="primary" type="primary"
onClick={() => setActiveStep(STEP_ITEMS[stepIndex + 1].key)} onClick={() => {
console.log(basicForm.getFieldsValue());
setActiveStep(STEP_ITEMS[stepIndex + 1].key)
}}
> >
下一步 下一步
</Button> </Button>

View File

@ -1,16 +1,16 @@
/** 备案材料通用模板(对齐后端 QualFilingMaterialTemplateProvider / 原型 10 项) */ /** 备案材料通用模板(对齐后端 QualFilingMaterialTemplateProvider / 原型 10 项) */
export const FILING_MATERIAL_TEMPLATE = [ export const FILING_MATERIAL_TEMPLATE = [
{ sortOrder: 1, materialContent: "申请材料目录(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 }, { id: 1, materialContent: "申请材料目录(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
{ sortOrder: 2, materialContent: "申请书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 }, { id: 2, materialContent: "申请书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 },
{ sortOrder: 3, materialContent: "法人证明(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "营业执照或事业单位法人证书等", requiredFlag: 1 }, { id: 3, materialContent: "法人证明(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "营业执照或事业单位法人证书等", requiredFlag: 1 },
{ sortOrder: 4, materialContent: "三年内无重大违法失信记录查询证明(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 }, { id: 4, materialContent: "三年内无重大违法失信记录查询证明(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 },
{ sortOrder: 5, materialContent: "法定代表人承诺书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名", requiredFlag: 1 }, { id: 5, materialContent: "法定代表人承诺书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名", requiredFlag: 1 },
{ sortOrder: 6, materialContent: "固定资产法定证明材料或书面承诺", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 }, { id: 6, materialContent: "固定资产法定证明材料或书面承诺", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
{ sortOrder: 7, materialContent: "工作场所及档案室面积证明资料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "房产证、租赁协议等", requiredFlag: 1 }, { id: 7, materialContent: "工作场所及档案室面积证明资料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "房产证、租赁协议等", requiredFlag: 1 },
{ sortOrder: 8, materialContent: "安全评价师专业能力证明(彩色复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "学历证书、职称证及其他相关证明材料", requiredFlag: 1 }, { id: 8, materialContent: "安全评价师专业能力证明(彩色复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "学历证书、职称证及其他相关证明材料", requiredFlag: 1 },
{ sortOrder: 9, materialContent: "相关负责人证明材料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "任命文件、简历、职称证等", requiredFlag: 1 }, { id: 9, materialContent: "相关负责人证明材料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "任命文件、简历、职称证等", requiredFlag: 1 },
{ sortOrder: 10, materialContent: "机构内部管理制度(非受控版)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 }, { id: 10, materialContent: "机构内部管理制度(非受控版)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
]; ];
export function createLocalMaterials() { export function createLocalMaterials() {

View File

@ -267,20 +267,18 @@ export async function persistFilingToBackend(props, detail, mode) {
} }
export function mergeDetailFromForms(detail, { basicValues, commitmentValues }) { export function mergeDetailFromForms(detail, { basicValues, commitmentValues }) {
const attachmentUrl = resolveUploadFileId(basicValues?.attachments) || detail.attachmentUrl;
return { return {
...detail, ...detail,
...basicValues, ...basicValues,
attachmentUrl, attachmentUrl: basicValues?.attachmentUrl?.map((file) => file.url).join(",") || undefined,
materials: detail.materials, materials: detail.materials,
personnelList: detail.personnelList, personnelList: detail.personnelList,
equipmentList: detail.equipmentList, equipmentList: detail.equipmentList,
commitment: { commitment: {
...detail.commitment, ...detail.commitment,
...commitmentValues, ...commitmentValues,
legalRepSignatureUrl: resolveUploadFileId(commitmentValues?.signatureFiles) legalRepSignatureUrl: basicValues?.legalRepSignatureUrl?.map((file) => file.url).join(",") || undefined,
|| commitmentValues?.legalRepSignatureUrl
|| detail.commitment?.legalRepSignatureUrl,
}, },
}; };
} }

View File

@ -84,16 +84,16 @@ export function verifyFilingPrerequisites(detail = {}) {
desc: "负责人、技术负责人、质量负责人具有高级职称,工作八年以上", desc: "负责人、技术负责人、质量负责人具有高级职称,工作八年以上",
passed: SKIP_PERSONNEL_VERIFY || keyOk, passed: SKIP_PERSONNEL_VERIFY || keyOk,
}); });
// const mgmtUploaded=detail.materials.every((m) => m.attachmentUrl);
const mgmtMaterial = (detail.materials || []).find((m) => Number(m.sortOrder) === 10); // items.push({
const mgmtUploaded = !!mgmtMaterial?.attachmentUrl; // key: "mgmtSystem",
// label: "管理体系",
items.push({ // desc: mgmtUploaded? "管理体系文件已上传" : "尚未上传管理体系文件",
key: "mgmtSystem", // passed: mgmtUploaded,
label: "管理体系", // });
desc: mgmtUploaded ? "管理体系文件已上传" : "尚未上传管理体系文件",
passed: mgmtUploaded,
});
return { return {
passed: items.every((item) => item.passed), passed: items.every((item) => item.passed),