2026-07-02 18:46:33 +08:00
|
|
|
|
import React, { useEffect, useMemo } from "react";
|
|
|
|
|
|
import { Button, Form, Input, message, Modal, Select } from "antd";
|
|
|
|
|
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
2026-07-03 10:35:36 +08:00
|
|
|
|
import { NS_QUAL_EXPERT, NS_QUAL_REVIEW } from "~/enumerate/namespace";
|
2026-08-10 14:16:49 +08:00
|
|
|
|
import { REVIEW_RESULT_OPTIONS } from "../reviewPageQuery";
|
2026-07-02 18:46:33 +08:00
|
|
|
|
|
|
|
|
|
|
const { TextArea } = Input;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-08-10 14:16:49 +08:00
|
|
|
|
* 审核操作弹窗(原型 modal-review-action)
|
|
|
|
|
|
* - 评价分析:已核验材料 / 符合 / 不符合 / 条件未满足 四卡
|
|
|
|
|
|
* - 表单:审核结果(通过/待定/不通过)、指派专家、综合审核意见
|
|
|
|
|
|
* - 底部:取消 / 📤 提交 / ✅ 通过
|
2026-07-02 18:46:33 +08:00
|
|
|
|
* @param {boolean} open
|
|
|
|
|
|
* @param {string|number} filingId - 备案申请ID
|
|
|
|
|
|
* @param {function} onCancel
|
|
|
|
|
|
* @param {function} onSuccess - 审核成功后回调(刷新列表等)
|
|
|
|
|
|
*/
|
2026-08-10 14:16:49 +08:00
|
|
|
|
const statStyle = {
|
|
|
|
|
|
background: "#fff",
|
|
|
|
|
|
border: "1px solid #e2e8f0",
|
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
|
padding: "0.4rem",
|
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
|
};
|
|
|
|
|
|
const statLabelStyle = { fontSize: "0.7rem", color: "#64748b" };
|
2026-07-02 18:46:33 +08:00
|
|
|
|
|
|
|
|
|
|
const ReviewModal = (props) => {
|
2026-08-10 14:16:49 +08:00
|
|
|
|
const {
|
|
|
|
|
|
open,
|
|
|
|
|
|
filingId,
|
|
|
|
|
|
isChange = false,
|
|
|
|
|
|
legalPassCount = 0,
|
|
|
|
|
|
legalFailCount = 0,
|
|
|
|
|
|
legalWarnCount = 0,
|
|
|
|
|
|
onCancel,
|
|
|
|
|
|
onSuccess,
|
|
|
|
|
|
} = props;
|
2026-08-12 11:07:14 +08:00
|
|
|
|
const {
|
|
|
|
|
|
qualExpert,
|
|
|
|
|
|
qualReview,
|
|
|
|
|
|
queryExpertPage,
|
|
|
|
|
|
reviewSubmit,
|
|
|
|
|
|
changeReviewSubmit,
|
|
|
|
|
|
} = props;
|
2026-07-03 10:35:36 +08:00
|
|
|
|
const { qualExpertList } = qualExpert || {};
|
|
|
|
|
|
const { qualReviewSubmitLoading } = qualReview || {};
|
2026-07-02 18:46:33 +08:00
|
|
|
|
|
|
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (open) {
|
|
|
|
|
|
form.resetFields();
|
2026-08-10 17:45:12 +08:00
|
|
|
|
queryExpertPage({ current: 1, size: 100 });
|
2026-07-02 18:46:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
}, [open]);
|
|
|
|
|
|
|
|
|
|
|
|
const expertOptions = useMemo(
|
|
|
|
|
|
() =>
|
|
|
|
|
|
(qualExpertList || []).map((item) => ({
|
2026-07-07 18:03:48 +08:00
|
|
|
|
label: item.userName,
|
2026-07-02 18:46:33 +08:00
|
|
|
|
value: item.id,
|
|
|
|
|
|
expert: item,
|
|
|
|
|
|
})),
|
|
|
|
|
|
[qualExpertList],
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2026-08-10 14:16:49 +08:00
|
|
|
|
const doSubmit = async (values, passQuick) => {
|
2026-08-12 11:07:14 +08:00
|
|
|
|
const selected = expertOptions.find(
|
|
|
|
|
|
(o) => o.value === values.filingExpertId,
|
|
|
|
|
|
);
|
2026-08-10 14:16:49 +08:00
|
|
|
|
const result = passQuick ? 1 : values.reviewResult;
|
|
|
|
|
|
const resultLabel =
|
|
|
|
|
|
REVIEW_RESULT_OPTIONS.find((r) => r.value === result)?.label || "通过";
|
2026-07-03 10:35:36 +08:00
|
|
|
|
const submitAction = isChange ? changeReviewSubmit : reviewSubmit;
|
2026-07-02 18:46:33 +08:00
|
|
|
|
const params = {
|
|
|
|
|
|
filingId,
|
2026-08-10 14:16:49 +08:00
|
|
|
|
reviewResult: result,
|
|
|
|
|
|
reviewResultRemark: passQuick ? "审核通过" : resultLabel,
|
2026-07-02 18:46:33 +08:00
|
|
|
|
filingExpertId: values.filingExpertId,
|
|
|
|
|
|
filingExpertName: selected?.expert?.userName,
|
2026-08-10 14:16:49 +08:00
|
|
|
|
reviewOpinion: values.reviewOpinion || (passQuick ? "审核通过" : ""),
|
2026-07-02 18:46:33 +08:00
|
|
|
|
};
|
2026-08-10 14:16:49 +08:00
|
|
|
|
if (isChange) {
|
|
|
|
|
|
params.id = params.filingId;
|
2026-07-03 16:17:39 +08:00
|
|
|
|
delete params.filingId;
|
|
|
|
|
|
}
|
2026-07-03 10:35:36 +08:00
|
|
|
|
const res = await submitAction(params);
|
2026-07-02 18:46:33 +08:00
|
|
|
|
if (res?.success !== false) {
|
2026-08-10 14:16:49 +08:00
|
|
|
|
message.success(passQuick ? "审核通过!" : "审核提交成功");
|
2026-07-02 18:46:33 +08:00
|
|
|
|
onCancel();
|
|
|
|
|
|
onSuccess?.();
|
2026-08-10 14:16:49 +08:00
|
|
|
|
return true;
|
2026-07-02 18:46:33 +08:00
|
|
|
|
}
|
2026-08-10 14:16:49 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleSubmit = async () => {
|
|
|
|
|
|
const values = await form.validateFields();
|
|
|
|
|
|
await doSubmit(values, false);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handlePass = async () => {
|
|
|
|
|
|
const values = form.getFieldsValue();
|
|
|
|
|
|
await doSubmit(values, true);
|
2026-07-02 18:46:33 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-08-10 14:16:49 +08:00
|
|
|
|
const totalChecked = legalPassCount + legalFailCount + legalWarnCount;
|
|
|
|
|
|
|
2026-07-02 18:46:33 +08:00
|
|
|
|
return (
|
|
|
|
|
|
<Modal
|
2026-08-10 14:16:49 +08:00
|
|
|
|
title="📋 审核操作"
|
2026-07-02 18:46:33 +08:00
|
|
|
|
open={open}
|
|
|
|
|
|
onCancel={onCancel}
|
2026-08-10 14:16:49 +08:00
|
|
|
|
width={620}
|
2026-07-02 18:46:33 +08:00
|
|
|
|
footer={
|
|
|
|
|
|
<div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
|
|
|
|
|
|
<Button onClick={onCancel}>取消</Button>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<Button loading={qualReviewSubmitLoading} onClick={handlePass}>
|
|
|
|
|
|
通过
|
2026-08-10 14:16:49 +08:00
|
|
|
|
</Button>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
loading={qualReviewSubmitLoading}
|
2026-08-12 11:07:14 +08:00
|
|
|
|
onClick={handleSubmit}
|
|
|
|
|
|
type="primary"
|
2026-08-10 14:16:49 +08:00
|
|
|
|
>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
提交
|
2026-07-02 18:46:33 +08:00
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div
|
|
|
|
|
|
style={{
|
|
|
|
|
|
background: "#f8fafc",
|
2026-08-10 14:16:49 +08:00
|
|
|
|
border: "1px solid #e2e8f0",
|
|
|
|
|
|
borderRadius: 8,
|
2026-07-02 18:46:33 +08:00
|
|
|
|
padding: "0.75rem",
|
|
|
|
|
|
marginBottom: "1rem",
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<div
|
|
|
|
|
|
style={{
|
|
|
|
|
|
fontSize: "0.88rem",
|
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
|
marginBottom: "0.5rem",
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
2026-08-10 14:16:49 +08:00
|
|
|
|
📊 评价分析
|
|
|
|
|
|
</div>
|
2026-07-02 18:46:33 +08:00
|
|
|
|
<div
|
|
|
|
|
|
style={{
|
2026-08-10 14:16:49 +08:00
|
|
|
|
display: "grid",
|
|
|
|
|
|
gridTemplateColumns: "1fr 1fr 1fr 1fr",
|
|
|
|
|
|
gap: "0.4rem",
|
2026-07-02 18:46:33 +08:00
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div style={statStyle}>
|
|
|
|
|
|
<div style={statLabelStyle}>已核验材料</div>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<div
|
|
|
|
|
|
style={{ fontSize: "1.1rem", fontWeight: 700, color: "#059669" }}
|
|
|
|
|
|
>
|
2026-08-10 14:16:49 +08:00
|
|
|
|
{totalChecked}
|
2026-07-02 18:46:33 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={statStyle}>
|
|
|
|
|
|
<div style={statLabelStyle}>符合</div>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<div
|
|
|
|
|
|
style={{ fontSize: "1.1rem", fontWeight: 700, color: "#059669" }}
|
|
|
|
|
|
>
|
2026-07-02 18:46:33 +08:00
|
|
|
|
{legalPassCount}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={statStyle}>
|
|
|
|
|
|
<div style={statLabelStyle}>不符合</div>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<div
|
|
|
|
|
|
style={{ fontSize: "1.1rem", fontWeight: 700, color: "#dc2626" }}
|
|
|
|
|
|
>
|
2026-07-02 18:46:33 +08:00
|
|
|
|
{legalFailCount}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-08-10 14:16:49 +08:00
|
|
|
|
<div style={statStyle}>
|
2026-08-11 17:52:43 +08:00
|
|
|
|
<div style={statLabelStyle}>风险提醒</div>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<div
|
|
|
|
|
|
style={{ fontSize: "1.1rem", fontWeight: 700, color: "#d97706" }}
|
|
|
|
|
|
>
|
2026-08-10 14:16:49 +08:00
|
|
|
|
{legalWarnCount}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-07-02 18:46:33 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<Form
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
layout="vertical"
|
|
|
|
|
|
style={{ marginTop: "0.5rem" }}
|
|
|
|
|
|
scrollToFirstError
|
|
|
|
|
|
>
|
2026-07-02 18:46:33 +08:00
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="审核结果"
|
|
|
|
|
|
name="reviewResult"
|
|
|
|
|
|
rules={[{ required: true, message: "请选择审核结果" }]}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Select placeholder="请选择">
|
|
|
|
|
|
{REVIEW_RESULT_OPTIONS.map((item) => (
|
|
|
|
|
|
<Select.Option key={item.value} value={item.value}>
|
|
|
|
|
|
{item.label}
|
|
|
|
|
|
</Select.Option>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
2026-08-05 10:09:57 +08:00
|
|
|
|
{!isChange && (
|
2026-08-10 14:16:49 +08:00
|
|
|
|
<Form.Item label="指派专家" name="filingExpertId">
|
2026-08-05 10:09:57 +08:00
|
|
|
|
<Select
|
|
|
|
|
|
placeholder="请选择"
|
|
|
|
|
|
showSearch
|
|
|
|
|
|
optionFilterProp="label"
|
|
|
|
|
|
options={expertOptions}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
)}
|
2026-07-02 18:46:33 +08:00
|
|
|
|
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="综合审核意见"
|
|
|
|
|
|
name="reviewOpinion"
|
|
|
|
|
|
rules={[{ required: true, message: "请输入综合审核意见" }]}
|
|
|
|
|
|
>
|
2026-08-12 11:07:14 +08:00
|
|
|
|
<TextArea
|
|
|
|
|
|
rows={3}
|
|
|
|
|
|
placeholder="请输入综合审核意见..."
|
|
|
|
|
|
maxLength={200}
|
|
|
|
|
|
/>
|
2026-07-02 18:46:33 +08:00
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Form>
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-08-10 14:16:49 +08:00
|
|
|
|
export default Connect([NS_QUAL_EXPERT, NS_QUAL_REVIEW], true)(ReviewModal);
|