bug
parent
96a70d39c3
commit
8e35c0f289
1928
pnpm-lock.yaml
1928
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -76,12 +76,11 @@ const PROTO_THEME = {
|
||||||
token: { borderRadius: 8, borderRadiusLG: 12, borderRadiusSM: 6 },
|
token: { borderRadius: 8, borderRadiusLG: 12, borderRadiusSM: 6 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 原型通知类型筛选项 */
|
/** 通知类型与监管端监督检查告知一致 */
|
||||||
const MSG_TYPE_OPTIONS = [
|
const INSP_TYPE_OPTIONS = [
|
||||||
{ label: "整改通知", value: "整改通知" },
|
{ label: "项目过程检查", value: "PROJECT_PROCESS" },
|
||||||
{ label: "核查函", value: "核查函" },
|
{ label: "资质保持检查", value: "QUAL_KEEP" },
|
||||||
{ label: "补正通知", value: "补正通知" },
|
{ label: "专项检查", value: "SPECIAL" },
|
||||||
{ label: "办结通知", value: "办结通知" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const TAB_STATUS = {
|
const TAB_STATUS = {
|
||||||
|
|
@ -149,6 +148,53 @@ const formatDate = (val) => {
|
||||||
return d.isValid() ? d.format("YYYY-MM-DD") : val;
|
return d.isValid() ? d.format("YYYY-MM-DD") : val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveFileUrl = (raw) => {
|
||||||
|
if (!raw) return "";
|
||||||
|
const u = String(raw);
|
||||||
|
if (/^https?:\/\//i.test(u)) return u;
|
||||||
|
const base = window.fileUrl || "";
|
||||||
|
return base ? `${base}${u}` : u;
|
||||||
|
};
|
||||||
|
|
||||||
|
const parseUrlList = (val) => {
|
||||||
|
if (!val) return [];
|
||||||
|
if (Array.isArray(val)) return val.filter(Boolean);
|
||||||
|
if (typeof val === "string") {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(val);
|
||||||
|
if (Array.isArray(parsed)) return parsed.filter(Boolean);
|
||||||
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
.split(/[,;\n]/)
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const urlToFileItem = (url) => ({
|
||||||
|
fileUrl: url,
|
||||||
|
fileName: String(url).split("?")[0].split("/").pop() || "附件",
|
||||||
|
});
|
||||||
|
|
||||||
|
const collectViewFiles = (detail, materials = []) => {
|
||||||
|
const fromMaterials = (materials || []).filter((m) => m.fileUrl);
|
||||||
|
const fromNotice = parseUrlList(detail?.noticeUrls).map(urlToFileItem);
|
||||||
|
const fromResult = parseUrlList(detail?.resultUrls).map(urlToFileItem);
|
||||||
|
const seen = new Set();
|
||||||
|
return [...fromMaterials, ...fromNotice, ...fromResult].filter((item) => {
|
||||||
|
const key = resolveFileUrl(item.fileUrl);
|
||||||
|
if (!key || seen.has(key)) return false;
|
||||||
|
seen.add(key);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const materialFileName = (m) =>
|
||||||
|
m.fileName || m.materialName || m.name || String(m.fileUrl || "").split("?")[0].split("/").pop() || "附件";
|
||||||
|
|
||||||
const ModalSection = ({ title, desc, children }) => (
|
const ModalSection = ({ title, desc, children }) => (
|
||||||
<div className="inst-modal-section">
|
<div className="inst-modal-section">
|
||||||
<h4>{title}</h4>
|
<h4>{title}</h4>
|
||||||
|
|
@ -175,6 +221,7 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const [processOpen, setProcessOpen] = useState(false);
|
const [processOpen, setProcessOpen] = useState(false);
|
||||||
|
const [processViewOnly, setProcessViewOnly] = useState(false);
|
||||||
const [detail, setDetail] = useState(null);
|
const [detail, setDetail] = useState(null);
|
||||||
const [materials, setMaterials] = useState([]);
|
const [materials, setMaterials] = useState([]);
|
||||||
const [uploadUrls, setUploadUrls] = useState([]);
|
const [uploadUrls, setUploadUrls] = useState([]);
|
||||||
|
|
@ -192,9 +239,9 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
const buildQuery = (tab = activeTab) => {
|
const buildQuery = (tab = activeTab) => {
|
||||||
const values = searchForm.getFieldsValue();
|
const values = searchForm.getFieldsValue();
|
||||||
const tabStatus = TAB_STATUS[tab];
|
const tabStatus = TAB_STATUS[tab];
|
||||||
const keywordParts = [values.keyword, values.msgType].filter(Boolean);
|
|
||||||
return {
|
return {
|
||||||
keyword: keywordParts.length ? keywordParts.join(" ") : undefined,
|
keyword: values.keyword || undefined,
|
||||||
|
inspTypeCode: values.inspTypeCode || undefined,
|
||||||
statusCode: values.statusCode ?? tabStatus,
|
statusCode: values.statusCode ?? tabStatus,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -243,7 +290,8 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
fetchData(1, pageSize, key);
|
fetchData(1, pageSize, key);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openProcess = async (record) => {
|
const openProcess = async (record, viewOnly = false) => {
|
||||||
|
setProcessViewOnly(viewOnly);
|
||||||
setProcessOpen(true);
|
setProcessOpen(true);
|
||||||
setDetail(null);
|
setDetail(null);
|
||||||
setMaterials([]);
|
setMaterials([]);
|
||||||
|
|
@ -443,10 +491,15 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
width: 90,
|
width: 90,
|
||||||
align: "center",
|
align: "center",
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
render: (_, record) => (
|
render: (_, record) =>
|
||||||
|
record.statusCode === 1 ? (
|
||||||
<Button type="primary" size="small" onClick={() => openProcess(record)}>
|
<Button type="primary" size="small" onClick={() => openProcess(record)}>
|
||||||
处理
|
处理
|
||||||
</Button>
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button type="primary" size="small" onClick={() => openProcess(record, true)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -530,12 +583,12 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
allowClear
|
allowClear
|
||||||
/>
|
/>
|
||||||
</Form.Item>,
|
</Form.Item>,
|
||||||
<Form.Item key="msgType" name="msgType">
|
<Form.Item key="inspTypeCode" name="inspTypeCode">
|
||||||
<ControlWrapper.Select
|
<ControlWrapper.Select
|
||||||
label="通知类型"
|
label="通知类型"
|
||||||
placeholder="全部"
|
placeholder="全部"
|
||||||
allowClear
|
allowClear
|
||||||
options={MSG_TYPE_OPTIONS}
|
options={INSP_TYPE_OPTIONS}
|
||||||
/>
|
/>
|
||||||
</Form.Item>,
|
</Form.Item>,
|
||||||
<Form.Item key="statusCode" name="statusCode">
|
<Form.Item key="statusCode" name="statusCode">
|
||||||
|
|
@ -593,16 +646,26 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
|
|
||||||
{/* 处理 — 对齐原型 regMessageProcess */}
|
{/* 处理 — 对齐原型 regMessageProcess */}
|
||||||
<Modal
|
<Modal
|
||||||
title={detail ? `监管消息处理 - ${detail.noticeNo}` : "监管消息处理"}
|
title={
|
||||||
|
detail
|
||||||
|
? `${processViewOnly ? "监管消息查看" : "监管消息处理"} - ${detail.noticeNo}`
|
||||||
|
: processViewOnly
|
||||||
|
? "监管消息查看"
|
||||||
|
: "监管消息处理"
|
||||||
|
}
|
||||||
open={processOpen}
|
open={processOpen}
|
||||||
onCancel={() => setProcessOpen(false)}
|
onCancel={() => setProcessOpen(false)}
|
||||||
width={820}
|
width={820}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
className="inst-modal"
|
className="inst-modal"
|
||||||
footer={
|
footer={
|
||||||
|
processViewOnly ? (
|
||||||
|
<Button onClick={() => setProcessOpen(false)}>关闭</Button>
|
||||||
|
) : (
|
||||||
<Button type="primary" loading={submitting} onClick={handleSubmit}>
|
<Button type="primary" loading={submitting} onClick={handleSubmit}>
|
||||||
提交
|
提交
|
||||||
</Button>
|
</Button>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{institutionInspNoticeGetLoading || !detail ? (
|
{institutionInspNoticeGetLoading || !detail ? (
|
||||||
|
|
@ -613,26 +676,61 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
title="处理要求"
|
title="处理要求"
|
||||||
desc="机构收到消息后直接填写说明并上传证明材料,完成后提交监管复核。"
|
desc="机构收到消息后直接填写说明并上传证明材料,完成后提交监管复核。"
|
||||||
/>
|
/>
|
||||||
<Form form={processForm} layout="vertical" preserve={false} scrollToFirstError>
|
<Form
|
||||||
|
form={processForm}
|
||||||
|
layout="vertical"
|
||||||
|
preserve={false}
|
||||||
|
scrollToFirstError
|
||||||
|
>
|
||||||
<div className="inst-form-grid">
|
<div className="inst-form-grid">
|
||||||
<Form.Item name="noticeNo" label="关联消息编号">
|
<Form.Item name="noticeNo" label="关联消息编号">
|
||||||
<Input readOnly />
|
<Input readOnly />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="processType" label="处理方式">
|
<Form.Item name="processType" label="处理方式">
|
||||||
<Select options={PROCESS_TYPE_OPTIONS} />
|
<Select options={PROCESS_TYPE_OPTIONS} disabled={processViewOnly} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="processRemark"
|
name="processRemark"
|
||||||
label="处理说明"
|
label="处理说明"
|
||||||
className="inst-form-full"
|
className="inst-form-full"
|
||||||
>
|
>
|
||||||
<TextArea rows={3} />
|
<TextArea rows={3} disabled={processViewOnly} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="上传附件" className="inst-form-full">
|
<Form.Item
|
||||||
|
label={processViewOnly ? "附件" : "上传附件"}
|
||||||
|
className="inst-form-full"
|
||||||
|
>
|
||||||
|
{processViewOnly ? (
|
||||||
|
(() => {
|
||||||
|
const viewFiles = collectViewFiles(detail, materials);
|
||||||
|
return viewFiles.length ? (
|
||||||
|
viewFiles.map((m) => (
|
||||||
|
<a
|
||||||
|
key={m.id || m.fileUrl}
|
||||||
|
onClick={() =>
|
||||||
|
window.open(resolveFileUrl(m.fileUrl), "_blank")
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
display: "block",
|
||||||
|
color: "#1677ff",
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{materialFileName(m)}
|
||||||
|
</a>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<span>暂无附件</span>
|
||||||
|
);
|
||||||
|
})()
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
<Upload
|
<Upload
|
||||||
name="file"
|
name="file"
|
||||||
action={UPLOAD_ACTION}
|
action={UPLOAD_ACTION}
|
||||||
headers={{ token: sessionStorage.getItem("token") || "" }}
|
headers={{
|
||||||
|
token: sessionStorage.getItem("token") || "",
|
||||||
|
}}
|
||||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png"
|
accept=".pdf,.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png"
|
||||||
multiple
|
multiple
|
||||||
onChange={onFileUpload}
|
onChange={onFileUpload}
|
||||||
|
|
@ -642,6 +740,8 @@ const InstitutionInspectionNotice = (props) => {
|
||||||
<div className="inst-upload-tip">
|
<div className="inst-upload-tip">
|
||||||
支持 PDF、Word、Excel、图片,可选择多个文件。
|
支持 PDF、Word、Excel、图片,可选择多个文件。
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,13 @@ const RESULT_OPTIONS = [
|
||||||
{ label: "转入风险预警", value: 3 },
|
{ label: "转入风险预警", value: 3 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const PROCESS_TYPE_OPTIONS = [
|
||||||
|
{ label: "提交整改材料", value: "提交整改材料" },
|
||||||
|
{ label: "提交核查说明", value: "提交核查说明" },
|
||||||
|
{ label: "补充证明材料", value: "补充证明材料" },
|
||||||
|
{ label: "查看办结结果", value: "查看办结结果" },
|
||||||
|
];
|
||||||
|
|
||||||
const SOURCE_WARN_OPTIONS = [
|
const SOURCE_WARN_OPTIONS = [
|
||||||
{ label: "无", value: "" },
|
{ label: "无", value: "" },
|
||||||
{ label: "W-PROJ-2026-021", value: "W-PROJ-2026-021" },
|
{ label: "W-PROJ-2026-021", value: "W-PROJ-2026-021" },
|
||||||
|
|
@ -92,9 +99,25 @@ const formatDateTime = (val) => {
|
||||||
return d.isValid() ? d.format("YYYY-MM-DD HH:mm") : val;
|
return d.isValid() ? d.format("YYYY-MM-DD HH:mm") : val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveFileUrl = (raw) => {
|
||||||
|
if (!raw) return "";
|
||||||
|
const u = String(raw);
|
||||||
|
if (/^https?:\/\//i.test(u)) return u;
|
||||||
|
const base = window.fileUrl || "";
|
||||||
|
return base ? `${base}${u}` : u;
|
||||||
|
};
|
||||||
|
|
||||||
|
const materialFileName = (m) =>
|
||||||
|
m.fileName || m.materialName || m.name || String(m.fileUrl || "").split("/").pop() || "附件";
|
||||||
|
|
||||||
/** 雪花 ID 须保持字符串,避免 Number() 精度丢失 */
|
/** 雪花 ID 须保持字符串,避免 Number() 精度丢失 */
|
||||||
const toId = (id) => (id == null ? id : String(id));
|
const toId = (id) => (id == null ? id : String(id));
|
||||||
|
|
||||||
|
const urlToFileItem = (url) => ({
|
||||||
|
fileUrl: url,
|
||||||
|
fileName: String(url).split("?")[0].split("/").pop() || "附件",
|
||||||
|
});
|
||||||
|
|
||||||
const parseUrlList = (val) => {
|
const parseUrlList = (val) => {
|
||||||
if (!val) return [];
|
if (!val) return [];
|
||||||
if (Array.isArray(val)) return val.filter(Boolean);
|
if (Array.isArray(val)) return val.filter(Boolean);
|
||||||
|
|
@ -113,6 +136,19 @@ const parseUrlList = (val) => {
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const collectViewFiles = (detail, materials = []) => {
|
||||||
|
const fromMaterials = (materials || []).filter((m) => m.fileUrl);
|
||||||
|
const fromNotice = parseUrlList(detail?.noticeUrls).map(urlToFileItem);
|
||||||
|
const fromResult = parseUrlList(detail?.resultUrls).map(urlToFileItem);
|
||||||
|
const seen = new Set();
|
||||||
|
return [...fromMaterials, ...fromNotice, ...fromResult].filter((item) => {
|
||||||
|
const key = resolveFileUrl(item.fileUrl);
|
||||||
|
if (!key || seen.has(key)) return false;
|
||||||
|
seen.add(key);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const downloadBinary = async (method, path, bodyOrQuery, fallbackName) => {
|
const downloadBinary = async (method, path, bodyOrQuery, fallbackName) => {
|
||||||
const headers = { token: sessionStorage.getItem("token") || "" };
|
const headers = { token: sessionStorage.getItem("token") || "" };
|
||||||
let url = `${API_HOST}${path}`;
|
let url = `${API_HOST}${path}`;
|
||||||
|
|
@ -190,6 +226,7 @@ const InspectionNotice = (props) => {
|
||||||
const [resultForm] = Form.useForm();
|
const [resultForm] = Form.useForm();
|
||||||
const [remarkForm] = Form.useForm();
|
const [remarkForm] = Form.useForm();
|
||||||
const [exportForm] = Form.useForm();
|
const [exportForm] = Form.useForm();
|
||||||
|
const [processViewForm] = Form.useForm();
|
||||||
|
|
||||||
const [dataSource, setDataSource] = useState([]);
|
const [dataSource, setDataSource] = useState([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
|
|
@ -204,6 +241,9 @@ const InspectionNotice = (props) => {
|
||||||
|
|
||||||
const [detailOpen, setDetailOpen] = useState(false);
|
const [detailOpen, setDetailOpen] = useState(false);
|
||||||
const [detail, setDetail] = useState(null);
|
const [detail, setDetail] = useState(null);
|
||||||
|
const [processViewOpen, setProcessViewOpen] = useState(false);
|
||||||
|
const [processViewDetail, setProcessViewDetail] = useState(null);
|
||||||
|
const [processViewMaterials, setProcessViewMaterials] = useState([]);
|
||||||
|
|
||||||
const [resultOpen, setResultOpen] = useState(false);
|
const [resultOpen, setResultOpen] = useState(false);
|
||||||
const [resultRecord, setResultRecord] = useState(null);
|
const [resultRecord, setResultRecord] = useState(null);
|
||||||
|
|
@ -368,6 +408,34 @@ const InspectionNotice = (props) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openProcessView = async (record) => {
|
||||||
|
setProcessViewOpen(true);
|
||||||
|
setProcessViewDetail(null);
|
||||||
|
setProcessViewMaterials([]);
|
||||||
|
processViewForm.resetFields();
|
||||||
|
processViewForm.setFieldsValue({
|
||||||
|
noticeNo: record.noticeNo,
|
||||||
|
processType: "提交整改材料",
|
||||||
|
processRemark: "请根据监管要求填写问题原因、处理措施和完成情况。",
|
||||||
|
});
|
||||||
|
const [detailRes, matRes] = await Promise.all([
|
||||||
|
props.regulatorInspNoticeGet({ id: String(record.id) }),
|
||||||
|
props.regulatorInspNoticeMaterials({ noticeId: toId(record.id) }),
|
||||||
|
]);
|
||||||
|
if (detailRes?.success !== false) {
|
||||||
|
const data = detailRes?.data || null;
|
||||||
|
setProcessViewDetail(data);
|
||||||
|
processViewForm.setFieldsValue({
|
||||||
|
noticeNo: data?.noticeNo || record.noticeNo,
|
||||||
|
processType:
|
||||||
|
data?.statusCode === 4 ? "查看办结结果" : "提交整改材料",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (matRes?.success !== false) {
|
||||||
|
setProcessViewMaterials(matRes?.data || []);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const openDetail = async (record) => {
|
const openDetail = async (record) => {
|
||||||
setDetailOpen(true);
|
setDetailOpen(true);
|
||||||
setDetail(null);
|
setDetail(null);
|
||||||
|
|
@ -514,7 +582,6 @@ const InspectionNotice = (props) => {
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ title: "检查负责人", dataIndex: "leaderName", width: 100 },
|
|
||||||
{
|
{
|
||||||
title: "机构确认",
|
title: "机构确认",
|
||||||
dataIndex: "confirmFlag",
|
dataIndex: "confirmFlag",
|
||||||
|
|
@ -547,9 +614,15 @@ const InspectionNotice = (props) => {
|
||||||
title: "操作",
|
title: "操作",
|
||||||
key: "action",
|
key: "action",
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 180,
|
width: 240,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const code = record.statusCode;
|
const code = record.statusCode;
|
||||||
|
const processViewBtn =
|
||||||
|
record.confirmFlag === 1 ? (
|
||||||
|
<Button size="small" onClick={() => openProcessView(record)}>
|
||||||
|
处理查看
|
||||||
|
</Button>
|
||||||
|
) : null;
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
return (
|
return (
|
||||||
<span className="insp-actions">
|
<span className="insp-actions">
|
||||||
|
|
@ -559,6 +632,7 @@ const InspectionNotice = (props) => {
|
||||||
<Button size="small" onClick={() => handleIssueRow(record)}>
|
<Button size="small" onClick={() => handleIssueRow(record)}>
|
||||||
下发
|
下发
|
||||||
</Button>
|
</Button>
|
||||||
|
{processViewBtn}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -571,6 +645,7 @@ const InspectionNotice = (props) => {
|
||||||
<Button size="small" onClick={() => handleUrge(record)}>
|
<Button size="small" onClick={() => handleUrge(record)}>
|
||||||
提醒
|
提醒
|
||||||
</Button>
|
</Button>
|
||||||
|
{processViewBtn}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -583,6 +658,7 @@ const InspectionNotice = (props) => {
|
||||||
<Button size="small" onClick={() => openResult(record)}>
|
<Button size="small" onClick={() => openResult(record)}>
|
||||||
登记结果
|
登记结果
|
||||||
</Button>
|
</Button>
|
||||||
|
{processViewBtn}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -594,6 +670,7 @@ const InspectionNotice = (props) => {
|
||||||
<Button size="small" onClick={() => handleDownloadRecord(record)}>
|
<Button size="small" onClick={() => handleDownloadRecord(record)}>
|
||||||
下载记录
|
下载记录
|
||||||
</Button>
|
</Button>
|
||||||
|
{processViewBtn}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -885,6 +962,81 @@ const InspectionNotice = (props) => {
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
{/* 处理查看 — 与机构端监管消息查看一致 */}
|
||||||
|
<Modal
|
||||||
|
title={
|
||||||
|
processViewDetail
|
||||||
|
? `监管消息查看 - ${processViewDetail.noticeNo}`
|
||||||
|
: "监管消息查看"
|
||||||
|
}
|
||||||
|
open={processViewOpen}
|
||||||
|
onCancel={() => setProcessViewOpen(false)}
|
||||||
|
width={820}
|
||||||
|
destroyOnClose
|
||||||
|
className="insp-modal"
|
||||||
|
footer={<Button onClick={() => setProcessViewOpen(false)}>关闭</Button>}
|
||||||
|
>
|
||||||
|
{regulatorInspNoticeGetLoading || !processViewDetail ? (
|
||||||
|
<div className="insp-loading">加载中...</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<ModalSection
|
||||||
|
title="处理要求"
|
||||||
|
desc="机构收到消息后直接填写说明并上传证明材料,完成后提交监管复核。"
|
||||||
|
/>
|
||||||
|
<Form
|
||||||
|
form={processViewForm}
|
||||||
|
layout="vertical"
|
||||||
|
preserve={false}
|
||||||
|
scrollToFirstError
|
||||||
|
>
|
||||||
|
<div className="insp-form-grid">
|
||||||
|
<Form.Item name="noticeNo" label="关联消息编号">
|
||||||
|
<Input readOnly />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item name="processType" label="处理方式">
|
||||||
|
<Select options={PROCESS_TYPE_OPTIONS} disabled />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="processRemark"
|
||||||
|
label="处理说明"
|
||||||
|
className="insp-form-full"
|
||||||
|
>
|
||||||
|
<TextArea rows={3} disabled />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="附件" className="insp-form-full">
|
||||||
|
{(() => {
|
||||||
|
const viewFiles = collectViewFiles(
|
||||||
|
processViewDetail,
|
||||||
|
processViewMaterials,
|
||||||
|
);
|
||||||
|
return viewFiles.length ? (
|
||||||
|
viewFiles.map((m) => (
|
||||||
|
<a
|
||||||
|
key={m.id || m.fileUrl}
|
||||||
|
onClick={() =>
|
||||||
|
window.open(resolveFileUrl(m.fileUrl), "_blank")
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
display: "block",
|
||||||
|
color: "#1677ff",
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{materialFileName(m)}
|
||||||
|
</a>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<span>暂无附件</span>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
|
||||||
{/* 登记结果 — 对齐原型 inspectionResult */}
|
{/* 登记结果 — 对齐原型 inspectionResult */}
|
||||||
<Modal
|
<Modal
|
||||||
title={
|
title={
|
||||||
|
|
@ -924,10 +1076,20 @@ const InspectionNotice = (props) => {
|
||||||
<Select options={RESULT_OPTIONS} />
|
<Select options={RESULT_OPTIONS} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="resultSituation" label="检查情况" className="insp-form-full">
|
<Form.Item name="resultSituation" label="检查情况" className="insp-form-full">
|
||||||
<TextArea rows={3} placeholder="填写现场检查情况和发现问题" />
|
<TextArea
|
||||||
|
rows={3}
|
||||||
|
maxLength={500}
|
||||||
|
showCount
|
||||||
|
placeholder="填写现场检查情况和发现问题"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="rectifyRequire" label="整改要求" className="insp-form-full">
|
<Form.Item name="rectifyRequire" label="整改要求" className="insp-form-full">
|
||||||
<TextArea rows={2} placeholder="需要整改时填写整改事项和期限" />
|
<TextArea
|
||||||
|
rows={2}
|
||||||
|
maxLength={500}
|
||||||
|
showCount
|
||||||
|
placeholder="需要整改时填写整改事项和期限"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="rectifyDeadline" label="整改期限">
|
<Form.Item name="rectifyDeadline" label="整改期限">
|
||||||
<DatePicker style={{ width: "100%" }} />
|
<DatePicker style={{ width: "100%" }} />
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,12 @@
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.insp-upload-tip {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #64748b;
|
||||||
|
margin-top: 4.2px;
|
||||||
|
}
|
||||||
|
|
||||||
.insp-actions {
|
.insp-actions {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue