feat
parent
160be8ae9c
commit
2d3f1895f3
|
|
@ -5,3 +5,9 @@ export const queryReviewList = declareRequest(
|
||||||
"Get > /safety-eval/qual-filing/page",
|
"Get > /safety-eval/qual-filing/page",
|
||||||
'qualReviewList: [] | res.data || [] & qualReviewTotal: 0 | res.total || 0'
|
'qualReviewList: [] | res.data || [] & qualReviewTotal: 0 | res.total || 0'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const queryComplianceCheck = declareRequest(
|
||||||
|
"qualReviewLoading",
|
||||||
|
"Get > /safety-eval/qual-filing/compliance-check > id",
|
||||||
|
'complianceCheckItems: [] | res.data || []',
|
||||||
|
);
|
||||||
|
|
@ -29,12 +29,14 @@ export default function AttachmentUpload({ name, label, disabled = false }) {
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
getValueFromEvent={({ fileList }) => {
|
getValueFromEvent={({ fileList }) => {
|
||||||
|
console.log(fileList, 'fileList')
|
||||||
return (
|
return (
|
||||||
fileList?.map((file) => ({
|
fileList?.map((file) => ({
|
||||||
url: file.response?.data?.url || file.url,
|
url: file.response?.data?.url || file.url,
|
||||||
uid: file.uid,
|
uid: file.uid,
|
||||||
status: "done",
|
status: "done",
|
||||||
name: file.name,
|
name: file.name,
|
||||||
|
percent: file.percent,
|
||||||
})) || []
|
})) || []
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ export default function CommitmentStep({
|
||||||
personnelOptions = [],
|
personnelOptions = [],
|
||||||
onSignatureChange,
|
onSignatureChange,
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
const legalRepName = Form.useWatch("legalRepName", form);
|
const legalRepName = Form.useWatch("legalRepName", form);
|
||||||
const filingUnitName = Form.useWatch("filingUnitName", form);
|
const filingUnitName = Form.useWatch("filingUnitName", form);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Button, Space, Table } from "antd";
|
import { Button, Image, Space, Table, Upload } from "antd";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { resolveUploadFileId } from "~/utils/mockUpload";
|
|
||||||
import OrgEquipmentSelectModal from "./OrgEquipmentSelectModal";
|
import OrgEquipmentSelectModal from "./OrgEquipmentSelectModal";
|
||||||
|
|
||||||
export default function EquipmentStep({
|
export default function EquipmentStep({
|
||||||
|
|
@ -11,8 +11,11 @@ export default function EquipmentStep({
|
||||||
onUploadCalibration,
|
onUploadCalibration,
|
||||||
}) {
|
}) {
|
||||||
const [selectOpen, setSelectOpen] = useState(false);
|
const [selectOpen, setSelectOpen] = useState(false);
|
||||||
|
const [previewImage, setPreviewImage] = useState("");
|
||||||
const existingIds = equipmentList.map((item) => String(item.sourceEquipmentId || ""));
|
const existingIds = equipmentList.map((item) => String(item.sourceEquipmentId || ""));
|
||||||
|
|
||||||
|
const isImage = (url) => /\.(png|jpe?g|gif|bmp|webp|svg)(\?.*)?$/i.test(url || "");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ display: "flex", justifyContent: "space-between", marginBottom: 12 }}>
|
<div style={{ display: "flex", justifyContent: "space-between", marginBottom: 12 }}>
|
||||||
|
|
@ -33,17 +36,42 @@ export default function EquipmentStep({
|
||||||
{ title: "生产厂家", dataIndex: "manufacturer" },
|
{ title: "生产厂家", dataIndex: "manufacturer" },
|
||||||
{
|
{
|
||||||
title: "计量检定情况",
|
title: "计量检定情况",
|
||||||
width: 120,
|
width: 180,
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
!disabled ? (
|
<Space size="small">
|
||||||
<Button
|
{record.calibrationReportUrl ? (
|
||||||
type="link"
|
<Button
|
||||||
size="small"
|
type="link"
|
||||||
onClick={() => onUploadCalibration?.(record, resolveUploadFileId([]))}
|
size="small"
|
||||||
>
|
onClick={() => {
|
||||||
上传报告
|
if (isImage(record.calibrationReportUrl)) {
|
||||||
</Button>
|
setPreviewImage(record.calibrationReportUrl);
|
||||||
) : (record.calibrationReportUrl ? "已上传" : "-")
|
} else {
|
||||||
|
window.open(record.calibrationReportUrl);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
预览
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
!disabled && (
|
||||||
|
<Upload
|
||||||
|
showUploadList={false}
|
||||||
|
action={`${window.process.env.app.API_HOST}/safety-eval/file/upload`}
|
||||||
|
onChange={(info) => {
|
||||||
|
if (info.file.status === "done") {
|
||||||
|
const data = info.file.response?.data;
|
||||||
|
if (data) {
|
||||||
|
onUploadCalibration?.(record, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="link" size="small">上传报告</Button>
|
||||||
|
</Upload>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -66,6 +94,16 @@ export default function EquipmentStep({
|
||||||
setSelectOpen(false);
|
setSelectOpen(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Image
|
||||||
|
style={{ display: "none" }}
|
||||||
|
preview={{
|
||||||
|
visible: !!previewImage,
|
||||||
|
src: previewImage,
|
||||||
|
onVisibleChange: (visible) => {
|
||||||
|
if (!visible) setPreviewImage("");
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,9 @@ export default function MaterialStep({
|
||||||
action={`${window.process.env.app.API_HOST}/safety-eval/file/upload`}
|
action={`${window.process.env.app.API_HOST}/safety-eval/file/upload`}
|
||||||
onChange={(info) => {
|
onChange={(info) => {
|
||||||
if (info.file.status === "done") {
|
if (info.file.status === "done") {
|
||||||
const url = info.file.response?.data?.url;
|
const data = info.file.response?.data;
|
||||||
if (url) {
|
if (data) {
|
||||||
onUpload?.(record, url);
|
onUpload?.(record, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ function FilingFormPage(props) {
|
||||||
: mode === FILING_FORM_MODE.CHANGE
|
: mode === FILING_FORM_MODE.CHANGE
|
||||||
? "change"
|
? "change"
|
||||||
: "application";
|
: "application";
|
||||||
const goBackList = useCallback(() => goFilingList(listMode), [listMode]);
|
|
||||||
const saveActionHint =
|
const saveActionHint =
|
||||||
mode === FILING_FORM_MODE.FILED
|
mode === FILING_FORM_MODE.FILED
|
||||||
? "请点击提交后保存"
|
? "请点击提交后保存"
|
||||||
|
|
@ -66,6 +66,7 @@ function FilingFormPage(props) {
|
||||||
return personnelOptions;
|
return personnelOptions;
|
||||||
}
|
}
|
||||||
const options = await fetchOrgPersonnelOptions().catch(() => []);
|
const options = await fetchOrgPersonnelOptions().catch(() => []);
|
||||||
|
|
||||||
setPersonnelOptions(options);
|
setPersonnelOptions(options);
|
||||||
return options;
|
return options;
|
||||||
}, [personnelOptions.length]);
|
}, [personnelOptions.length]);
|
||||||
|
|
@ -167,23 +168,24 @@ function FilingFormPage(props) {
|
||||||
|
|
||||||
if (result?.success) {
|
if (result?.success) {
|
||||||
setVerifyOpen(false);
|
setVerifyOpen(false);
|
||||||
message.success(isSaveDraft ? "暂存成功" : "提交成功");
|
message.success(config.isSaveDraft ? "暂存成功" : "提交成功");
|
||||||
props.history.push("filingApplication/list");
|
props.history.push("filingApplication/list");
|
||||||
} else {
|
} else {
|
||||||
message.error(result?.message || (isSaveDraft ? "暂存失败" : "提交失败"));
|
message.error(result?.message || (config.isSaveDraft ? "暂存失败" : "提交失败"));
|
||||||
}
|
}
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMaterialUpload = (record, url) => {
|
const handleMaterialUpload = (record, {url, ext}) => {
|
||||||
const attachmentUrl = url || resolveUploadFileId([]);
|
const attachmentUrl = url ;
|
||||||
setDetail((prev) => ({
|
setDetail((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
materials: (prev.materials || []).map((item) => {
|
materials: (prev.materials || []).map((item) => {
|
||||||
return item.materialType === record.materialType
|
return item.id === record.id
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
attachmentUrl,
|
attachmentUrl,
|
||||||
|
materialFormat: ext,
|
||||||
uploadStatusCode: 2,
|
uploadStatusCode: 2,
|
||||||
uploadStatusName: "已上传",
|
uploadStatusName: "已上传",
|
||||||
}
|
}
|
||||||
|
|
@ -193,20 +195,8 @@ function FilingFormPage(props) {
|
||||||
message.success(`材料已选择,${saveActionHint}`);
|
message.success(`材料已选择,${saveActionHint}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSignatureChange = (url, files) => {
|
|
||||||
commitmentForm.setFieldsValue({
|
|
||||||
signatureFiles: files,
|
|
||||||
legalRepSignatureUrl: url,
|
|
||||||
});
|
|
||||||
setDetail((prev) => ({
|
|
||||||
...prev,
|
|
||||||
commitment: {
|
|
||||||
...prev.commitment,
|
|
||||||
legalRepSignatureUrl: url,
|
|
||||||
signatureFiles: files,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePersonnelAdd = (sourcePersonnelIds, rows = []) => {
|
const handlePersonnelAdd = (sourcePersonnelIds, rows = []) => {
|
||||||
const existing = new Set(
|
const existing = new Set(
|
||||||
|
|
@ -290,8 +280,8 @@ function FilingFormPage(props) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEquipmentCalibration = (record, url) => {
|
const handleEquipmentCalibration = (record, { url }) => {
|
||||||
updateDetail((prev) => ({
|
setDetail((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
equipmentList: (prev.equipmentList || []).map((item) =>
|
equipmentList: (prev.equipmentList || []).map((item) =>
|
||||||
item.id === record.id ? { ...item, calibrationReportUrl: url } : item,
|
item.id === record.id ? { ...item, calibrationReportUrl: url } : item,
|
||||||
|
|
@ -320,7 +310,7 @@ function FilingFormPage(props) {
|
||||||
{
|
{
|
||||||
key: "commitment",
|
key: "commitment",
|
||||||
label: "3. 法定代表人承诺书",
|
label: "3. 法定代表人承诺书",
|
||||||
children: <CommitmentStep form={commitmentForm} disabled={readOnly} />,
|
children: <CommitmentStep form={commitmentForm} disabled={readOnly} personnelOptions={personnelOptions} />,
|
||||||
forceRender: true,
|
forceRender: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -344,7 +334,7 @@ function FilingFormPage(props) {
|
||||||
disabled={readOnly}
|
disabled={readOnly}
|
||||||
onAdd={handleEquipmentAdd}
|
onAdd={handleEquipmentAdd}
|
||||||
onRemove={handleEquipmentRemove}
|
onRemove={handleEquipmentRemove}
|
||||||
onCalibration={handleEquipmentCalibration}
|
onUploadCalibration={handleEquipmentCalibration}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
@ -399,21 +389,7 @@ function FilingFormPage(props) {
|
||||||
borderTop: "1px solid #f0f0f0",
|
borderTop: "1px solid #f0f0f0",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Space>
|
|
||||||
<Button
|
|
||||||
onClick={() =>
|
|
||||||
goFilingList(
|
|
||||||
mode === FILING_FORM_MODE.FILED
|
|
||||||
? "filed"
|
|
||||||
: mode === FILING_FORM_MODE.CHANGE
|
|
||||||
? "change"
|
|
||||||
: "application",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
<Space>
|
<Space>
|
||||||
{stepIndex > 0 && (
|
{stepIndex > 0 && (
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ export default function FilingListTable({
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: "备案属地", dataIndex: "filingTerritoryName", width: 120, ellipsis: true },
|
{ title: "备案属地", dataIndex: "filingTerritoryName", width: 120, ellipsis: true },
|
||||||
{ title: "备案单位", dataIndex: "filingUnitName", ellipsis: true },
|
{ title: "备案单位", dataIndex: "filingUnitName", ellipsis: true },
|
||||||
{ title: "备案编号", dataIndex: "filingNo", width: 180, render: (val, record) => val || record.id || "-" },
|
{ title: "备案编号", dataIndex: "filingNo", width: 200, render: (val, record) => val || record.id || "-" },
|
||||||
{ title: "安全评价业务范围", dataIndex: "businessScope", ellipsis: true },
|
{ title: "安全评价业务范围", dataIndex: "businessScope", ellipsis: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
/** 备案材料通用模板(对齐后端 QualFilingMaterialTemplateProvider / 原型 10 项) */
|
/** 备案材料通用模板(对齐后端 QualFilingMaterialTemplateProvider / 原型 10 项) */
|
||||||
|
|
||||||
export const FILING_MATERIAL_TEMPLATE = [
|
export const FILING_MATERIAL_TEMPLATE = [
|
||||||
{ materialType: 1, materialContent: "申请材料目录(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
|
{id: 1, materialType: 1, materialContent: "申请材料目录(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
|
||||||
{ materialType: 2, materialContent: "申请书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 },
|
{id: 2, materialType: 2, materialContent: "申请书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 },
|
||||||
{ materialType: 3, materialContent: "法人证明(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "营业执照或事业单位法人证书等", requiredFlag: 1 },
|
{id: 3, materialType: 3, materialContent: "法人证明(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "营业执照或事业单位法人证书等", requiredFlag: 1 },
|
||||||
{ materialType: 4, materialContent: "三年内无重大违法失信记录查询证明(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 },
|
{id: 4, materialType: 4, materialContent: "三年内无重大违法失信记录查询证明(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名并加盖单位公章", requiredFlag: 1 },
|
||||||
{ materialType: 5, materialContent: "法定代表人承诺书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名", requiredFlag: 1 },
|
{id: 5, materialType: 5, materialContent: "法定代表人承诺书(原件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "法定代表人亲笔签名", requiredFlag: 1 },
|
||||||
{ materialType: 6, materialContent: "固定资产法定证明材料或书面承诺", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
|
{id: 6, materialType: 6, materialContent: "固定资产法定证明材料或书面承诺", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
|
||||||
{ materialType: 7, materialContent: "工作场所及档案室面积证明资料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "房产证、租赁协议等", requiredFlag: 1 },
|
{id: 7, materialType: 7, materialContent: "工作场所及档案室面积证明资料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "房产证、租赁协议等", requiredFlag: 1 },
|
||||||
{ materialType: 8, materialContent: "安全评价师专业能力证明(彩色复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "学历证书、职称证及其他相关证明材料", requiredFlag: 1 },
|
{id: 8, materialType: 8, materialContent: "安全评价师专业能力证明(彩色复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "学历证书、职称证及其他相关证明材料", requiredFlag: 1 },
|
||||||
{ materialType: 9, materialContent: "相关负责人证明材料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "任命文件、简历、职称证等", requiredFlag: 1 },
|
{id: 9, materialType: 9, materialContent: "相关负责人证明材料(复印件)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: "任命文件、简历、职称证等", requiredFlag: 1 },
|
||||||
{ materialType: 10, materialContent: "机构内部管理制度(非受控版)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
|
{id: 10, materialType: 10, materialContent: "机构内部管理制度(非受控版)", materialFormat: "pdf", attachmentDesc: "纸质版扫描件", materialRemark: null, requiredFlag: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
export function createLocalMaterials() {
|
export function createLocalMaterials() {
|
||||||
|
|
|
||||||
|
|
@ -271,14 +271,14 @@ export function mergeDetailFromForms(detail, { basicValues, commitmentValues })
|
||||||
return {
|
return {
|
||||||
...detail,
|
...detail,
|
||||||
...basicValues,
|
...basicValues,
|
||||||
attachmentUrl: basicValues?.attachmentUrl?.map((file) => file.url).join(",") || undefined,
|
attachmentUrl: Array.isArray(basicValues?.attachmentUrl) ? basicValues?.attachmentUrl?.map((file) => file.url).join(",") : basicValues?.attachmentUrl,
|
||||||
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: commitmentValues?.legalRepSignatureUrl?.map((file) => file.url).join(",") || undefined,
|
legalRepSignatureUrl: Array.isArray(commitmentValues?.legalRepSignatureUrl) ? commitmentValues?.legalRepSignatureUrl?.map((file) => file.url).join(",") : commitmentValues?.legalRepSignatureUrl,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,37 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Button, Tag, Space, Modal, Select, Input, Form } from "antd";
|
import { Button, Tag, Space, Modal, Select, Input, Form, Spin } from "antd";
|
||||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
import { REVIEW_STATUS_MAP } from "~/enumerate/constant";
|
import { REVIEW_STATUS_MAP } from "~/enumerate/constant";
|
||||||
import { MOCK_DETAIL, MOCK_MATERIALS, LEGAL_CHECK_ITEMS, LEGAL_STATUS_STYLE } from "../mockData";
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
|
import {
|
||||||
|
MOCK_DETAIL,
|
||||||
|
MOCK_MATERIALS,
|
||||||
|
LEGAL_CHECK_ITEMS,
|
||||||
|
LEGAL_STATUS_STYLE,
|
||||||
|
} from "../mockData";
|
||||||
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
|
import { NS_QUAL_REVIEW } from "~/enumerate/namespace";
|
||||||
import FilingTabs from "../FilingTabs";
|
import FilingTabs from "../FilingTabs";
|
||||||
import "./indes.less";
|
import "./indes.less";
|
||||||
|
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
const {router}=tools;
|
||||||
|
|
||||||
const QualReviewForm = (props) => {
|
const QualReviewForm = (props) => {
|
||||||
|
const { queryComplianceCheck, qualReview } = props;
|
||||||
|
const { qualReviewLoading, complianceCheckItems } = qualReview;
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [compliance, setCompliance] = useState({});
|
const [compliance, setCompliance] = useState({});
|
||||||
const [reviewVisible, setReviewVisible] = useState(false);
|
const [reviewVisible, setReviewVisible] = useState(false);
|
||||||
const detail = MOCK_DETAIL;
|
const detail = MOCK_DETAIL;
|
||||||
const statusConfig = REVIEW_STATUS_MAP[detail.reviewStatus];
|
const statusConfig = REVIEW_STATUS_MAP[detail.reviewStatus];
|
||||||
|
|
||||||
const legalPassCount = LEGAL_CHECK_ITEMS.filter((i) => i.status === "pass").length;
|
const legalPassCount = LEGAL_CHECK_ITEMS.filter(
|
||||||
const legalFailCount = LEGAL_CHECK_ITEMS.filter((i) => i.status === "fail").length;
|
(i) => i.status === "pass",
|
||||||
|
).length;
|
||||||
|
const legalFailCount = LEGAL_CHECK_ITEMS.filter(
|
||||||
|
(i) => i.status === "fail",
|
||||||
|
).length;
|
||||||
|
|
||||||
const handleSubmit = (action) => {
|
const handleSubmit = (action) => {
|
||||||
form.validateFields().then((values) => {
|
form.validateFields().then((values) => {
|
||||||
|
|
@ -24,94 +39,199 @@ const QualReviewForm = (props) => {
|
||||||
setReviewVisible(false);
|
setReviewVisible(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
queryComplianceCheck({id: router.query.id});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout
|
<PageLayout
|
||||||
title={
|
title={
|
||||||
<Space>
|
<Space>
|
||||||
<span>资质备案审核</span>
|
<span>资质备案审核</span>
|
||||||
{statusConfig && <Tag color={statusConfig.color}>{statusConfig.label}</Tag>}
|
{statusConfig && (
|
||||||
|
<Tag color={statusConfig.color}>{statusConfig.label}</Tag>
|
||||||
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
history={props.history}
|
history={props.history}
|
||||||
previous
|
previous
|
||||||
footer={<Button type="primary" onClick={() => setReviewVisible(true)}>审核操作</Button>}
|
footer={
|
||||||
|
<Button type="primary" onClick={() => setReviewVisible(true)}>
|
||||||
|
审核操作
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className="qual-review-form">
|
<Spin spinning={qualReviewLoading}>
|
||||||
<div className="legal-check-bar">
|
<div className="qual-review-form">
|
||||||
<div className="legal-check-title">法律规定内容</div>
|
<div className="legal-check-bar">
|
||||||
<div className="legal-check-grid">
|
<div className="legal-check-title">法律规定内容</div>
|
||||||
{LEGAL_CHECK_ITEMS.map((item) => {
|
<div className="legal-check-grid">
|
||||||
const style = LEGAL_STATUS_STYLE[item.status];
|
{complianceCheckItems.map((item) => {
|
||||||
return (
|
const style = LEGAL_STATUS_STYLE[item.status];
|
||||||
<div key={item.key} className="legal-check-item" style={{ borderLeft: `3px solid ${style.borderColor}`, background: style.bg }}>
|
return (
|
||||||
<span>{style.icon}</span>
|
<div
|
||||||
<div>
|
key={item.key}
|
||||||
<div style={{ fontWeight: 500 }}>{item.title}</div>
|
className="legal-check-item"
|
||||||
<div className="legal-check-item-desc">{item.desc}</div>
|
style={{
|
||||||
|
borderLeft: `3px solid ${style.borderColor}`,
|
||||||
|
background: style.bg,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>{style.icon}</span>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontWeight: 500 }}>{item.title}</div>
|
||||||
|
<div className="legal-check-item-desc">{item.description}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FilingTabs
|
||||||
|
detail={detail}
|
||||||
|
isReview
|
||||||
|
compliance={compliance}
|
||||||
|
onComplianceChange={(id, v) =>
|
||||||
|
setCompliance((prev) => ({ ...prev, [id]: v }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title="审核操作"
|
||||||
|
open={reviewVisible}
|
||||||
|
onCancel={() => setReviewVisible(false)}
|
||||||
|
width={580}
|
||||||
|
footer={
|
||||||
|
<div
|
||||||
|
style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}
|
||||||
|
>
|
||||||
|
<Button onClick={() => setReviewVisible(false)}>取消</Button>
|
||||||
|
<Button type="primary" onClick={() => handleSubmit("submit")}>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
style={{ background: "#52c41a", borderColor: "#52c41a" }}
|
||||||
|
onClick={() => handleSubmit("pass")}
|
||||||
|
>
|
||||||
|
通过
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
background: "#f8fafc",
|
||||||
|
border: "1px solid #d9d9d9",
|
||||||
|
borderRadius: 6,
|
||||||
|
padding: "0.75rem",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "0.88rem",
|
||||||
|
fontWeight: 600,
|
||||||
|
marginBottom: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
评价分析
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "1fr 1fr 1fr 1fr",
|
||||||
|
gap: "0.4rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={statStyle}>
|
||||||
|
<div style={statLabelStyle}>已核验材料</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "1.1rem",
|
||||||
|
fontWeight: 700,
|
||||||
|
color: "#1677ff",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{legalPassCount + legalFailCount}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
<div style={statStyle}>
|
||||||
})}
|
<div style={statLabelStyle}>符合</div>
|
||||||
</div>
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "1.1rem",
|
||||||
|
fontWeight: 700,
|
||||||
|
color: "#059669",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{legalPassCount}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={statStyle}>
|
||||||
|
<div style={statLabelStyle}>不符合</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "1.1rem",
|
||||||
|
fontWeight: 700,
|
||||||
|
color: "#dc2626",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{legalFailCount}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Form form={form} layout="vertical" style={{ marginTop: "0.5rem" }}>
|
||||||
|
<Form.Item
|
||||||
|
label="审核结果"
|
||||||
|
name="reviewResult"
|
||||||
|
rules={[{ required: true, message: "请选择审核结果" }]}
|
||||||
|
>
|
||||||
|
<Select placeholder="请选择">
|
||||||
|
<Select.Option value="pass">通过</Select.Option>
|
||||||
|
<Select.Option value="pending">待定</Select.Option>
|
||||||
|
<Select.Option value="reject">不通过</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="指派专家"
|
||||||
|
name="expert"
|
||||||
|
rules={[{ required: true, message: "请选择专家" }]}
|
||||||
|
>
|
||||||
|
<Select placeholder="— 请选择 —">
|
||||||
|
<Select.Option value="chen">陈教授(化工安全)</Select.Option>
|
||||||
|
<Select.Option value="li">李教授(矿山安全)</Select.Option>
|
||||||
|
<Select.Option value="wang">王高工(建筑施工)</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="综合审核意见"
|
||||||
|
name="remark"
|
||||||
|
rules={[{ required: true, message: "请输入综合审核意见" }]}
|
||||||
|
>
|
||||||
|
<TextArea rows={3} placeholder="请输入综合审核意见..." />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
</Spin>
|
||||||
<FilingTabs
|
|
||||||
detail={detail}
|
|
||||||
isReview
|
|
||||||
compliance={compliance}
|
|
||||||
onComplianceChange={(id, v) => setCompliance((prev) => ({ ...prev, [id]: v }))}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
title="审核操作"
|
|
||||||
open={reviewVisible}
|
|
||||||
onCancel={() => setReviewVisible(false)}
|
|
||||||
width={580}
|
|
||||||
footer={
|
|
||||||
<div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
|
|
||||||
<Button onClick={() => setReviewVisible(false)}>取消</Button>
|
|
||||||
<Button type="primary" onClick={() => handleSubmit("submit")}>提交</Button>
|
|
||||||
<Button type="primary" style={{ background: "#52c41a", borderColor: "#52c41a" }} onClick={() => handleSubmit("pass")}>通过</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div style={{ background: "#f8fafc", border: "1px solid #d9d9d9", borderRadius: 6, padding: "0.75rem", marginBottom: "1rem" }}>
|
|
||||||
<div style={{ fontSize: "0.88rem", fontWeight: 600, marginBottom: "0.5rem" }}>评价分析</div>
|
|
||||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: "0.4rem" }}>
|
|
||||||
<div style={statStyle}><div style={statLabelStyle}>已核验材料</div><div style={{ fontSize: "1.1rem", fontWeight: 700, color: "#1677ff" }}>{legalPassCount+legalFailCount}</div></div>
|
|
||||||
<div style={statStyle}><div style={statLabelStyle}>符合</div><div style={{ fontSize: "1.1rem", fontWeight: 700, color: "#059669" }}>{legalPassCount}</div></div>
|
|
||||||
<div style={statStyle}><div style={statLabelStyle}>不符合</div><div style={{ fontSize: "1.1rem", fontWeight: 700, color: "#dc2626" }}>{legalFailCount}</div></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Form form={form} layout="vertical" style={{ marginTop: "0.5rem" }}>
|
|
||||||
<Form.Item label="审核结果" name="reviewResult" rules={[{ required: true, message: "请选择审核结果" }]}>
|
|
||||||
<Select placeholder="请选择">
|
|
||||||
<Select.Option value="pass">通过</Select.Option>
|
|
||||||
<Select.Option value="pending">待定</Select.Option>
|
|
||||||
<Select.Option value="reject">不通过</Select.Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="指派专家" name="expert" rules={[{ required: true, message: "请选择专家" }]}>
|
|
||||||
<Select placeholder="— 请选择 —">
|
|
||||||
<Select.Option value="chen">陈教授(化工安全)</Select.Option>
|
|
||||||
<Select.Option value="li">李教授(矿山安全)</Select.Option>
|
|
||||||
<Select.Option value="wang">王高工(建筑施工)</Select.Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="综合审核意见" name="remark" rules={[{ required: true, message: "请输入综合审核意见" }]}>
|
|
||||||
<TextArea rows={3} placeholder="请输入综合审核意见..." />
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const statStyle = { background: "#fff", border: "1px solid #d9d9d9", borderRadius: 6, padding: "0.4rem", textAlign: "center" };
|
const statStyle = {
|
||||||
|
background: "#fff",
|
||||||
|
border: "1px solid #d9d9d9",
|
||||||
|
borderRadius: 6,
|
||||||
|
padding: "0.4rem",
|
||||||
|
textAlign: "center",
|
||||||
|
};
|
||||||
const statLabelStyle = { fontSize: "0.7rem", color: "rgba(0,0,0,0.45)" };
|
const statLabelStyle = { fontSize: "0.7rem", color: "rgba(0,0,0,0.45)" };
|
||||||
|
|
||||||
export default QualReviewForm;
|
export default Connect(
|
||||||
|
[NS_QUAL_REVIEW],
|
||||||
|
true,
|
||||||
|
)(QualReviewForm);
|
||||||
|
|
|
||||||
|
|
@ -114,5 +114,5 @@ export const LEGAL_CHECK_ITEMS = [
|
||||||
export const LEGAL_STATUS_STYLE = {
|
export const LEGAL_STATUS_STYLE = {
|
||||||
pass: { icon: "✅", borderColor: "#059669", bg: "#f0fdf4" },
|
pass: { icon: "✅", borderColor: "#059669", bg: "#f0fdf4" },
|
||||||
warn: { icon: "⚠️", borderColor: "#d97706", bg: "#fffbeb" },
|
warn: { icon: "⚠️", borderColor: "#d97706", bg: "#fffbeb" },
|
||||||
fail: { icon: "❌", borderColor: "#dc2626", bg: "#fef2f2" },
|
NOT_PASS: { icon: "❌", borderColor: "#dc2626", bg: "#fef2f2" },
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue