safety-eval-service-frontend/src/pages/Container/QualificationReview/QualReviewForm/ReviewModal.js

240 lines
6.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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