增加隐患修改

master
LiuJiaNan 2025-12-12 15:19:00 +08:00
parent a8e3e03d98
commit 6fe79632c3
4 changed files with 309 additions and 194 deletions

View File

@ -32,7 +32,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-to-print": "^3.2.0", "react-to-print": "^3.2.0",
"zy-react-library": "^1.0.125" "zy-react-library": "^1.0.156"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^5.4.1", "@antfu/eslint-config": "^5.4.1",

View File

@ -32,6 +32,14 @@ export const hiddenAdd = declareRequest(
"inspectionLoading", "inspectionLoading",
`Post > @/hidden/hidden/save`, `Post > @/hidden/hidden/save`,
); );
export const hiddenEdit = declareRequest(
"ledgerLoading",
`Put > @/hidden/hidden/edit`,
);
export const hiddenView = declareRequest(
"ledgerLoading",
`Get > /hidden/hidden/{id}`,
);
export const partAdd = declareRequest( export const partAdd = declareRequest(
"inspectionLoading", "inspectionLoading",
`Post > @/hidden/hiddenRegion/save`, `Post > @/hidden/hiddenRegion/save`,

View File

@ -1,6 +1,6 @@
import { Button, Form, Input, Modal } from "antd"; import { Button, Form, Input, Modal } from "antd";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { useState } from "react"; import { useEffect, useState } from "react";
import FormBuilder from "zy-react-library/components/FormBuilder"; import FormBuilder from "zy-react-library/components/FormBuilder";
import Map from "zy-react-library/components/Map"; import Map from "zy-react-library/components/Map";
import DictionarySelectTree from "zy-react-library/components/SelectTree/Dictionary"; import DictionarySelectTree from "zy-react-library/components/SelectTree/Dictionary";
@ -13,8 +13,17 @@ function HiddenAddModal(props) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [hiddenPartType, setHiddenPartType] = useState("select"); const [hiddenPartType, setHiddenPartType] = useState("select");
useEffect(() => {
form.setFieldsValue(props.hiddenInfo);
}, []);
const onSubmit = (values) => { const onSubmit = (values) => {
props.onConfirm({ ...values, hiddenPartType, hiddenFindTime: dayjs().format("YYYY-MM-DD hh:mm:ss"), rectificationType: 2 }); props.onConfirm({
...values,
hiddenPartType,
hiddenFindTime: dayjs().format("YYYY-MM-DD hh:mm:ss"),
rectificationType: 2,
});
props.onCancel(); props.onCancel();
}; };
@ -106,16 +115,27 @@ function HiddenAddModal(props) {
{ {
name: "hiddenImageFiles", name: "hiddenImageFiles",
label: "隐患图片", label: "隐患图片",
render: (<Upload />), render: (
<Upload
onGetRemoveFile={file => form.setFieldValue("hiddenImageFiles", [...(form.getFieldValue("hiddenImageFiles") || []), file])}
/>
),
span: 24, span: 24,
}, },
{ name: "deleteHiddenImageFiles", label: "删除的隐患图片", onlyForLabel: true },
{ {
name: "hiddenVideoFiles", name: "hiddenVideoFiles",
label: "隐患视频", label: "隐患视频",
render: (<Upload fileType="video" />), render: (
<Upload
fileType="video"
onGetRemoveFile={file => form.setFieldValue("deleteHiddenVideoFiles", [...(form.getFieldValue("hiddenVideoFiles") || []), file])}
/>
),
span: 24, span: 24,
required: false, required: false,
}, },
{ name: "deleteHiddenVideoFiles", label: "删除的隐患视频", onlyForLabel: true },
{ {
name: "creatorId", name: "creatorId",
label: "隐患发现人", label: "隐患发现人",

View File

@ -1,5 +1,5 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Col, Form, Input, message, Modal, Row } from "antd"; import { Button, Form, message, Modal, Space } from "antd";
import { cloneDeep } from "lodash-es"; import { cloneDeep } from "lodash-es";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import FormBuilder from "zy-react-library/components/FormBuilder"; import FormBuilder from "zy-react-library/components/FormBuilder";
@ -37,11 +37,15 @@ function Add(props) {
const timeStart = Form.useWatch("timeStart", form); const timeStart = Form.useWatch("timeStart", form);
const [userInfo, setUserInfo] = useState({}); const [userInfo, setUserInfo] = useState({});
const [signatureFilePath, setSignatureFilePath] = useState("");
const [hiddenAddModalOpen, setHiddenAddModalOpen] = useState(false); const [hiddenAddModalOpen, setHiddenAddModalOpen] = useState(false);
const [hiddenDiscovererUserList, setHiddenDiscovererUserList] = useState([]); const [hiddenDiscovererUserList, setHiddenDiscovererUserList] = useState([]);
const [hiddenList, setHiddenList] = useState([]); const [hiddenList, setHiddenList] = useState([]);
const deleteHiddenIds = useRef([]); const deleteHiddenIds = useRef([]);
const [signatureFilePath, setSignatureFilePath] = useState(""); const [currentHiddenInfo, setCurrentHiddenInfo] = useState({});
const currentHiddenIndex = useRef(-1);
const getData = async () => { const getData = async () => {
const userInfo = await getUserInfo(); const userInfo = await getUserInfo();
@ -70,7 +74,11 @@ function Add(props) {
signatureTime: currentInspectorUser.signatureTime, signatureTime: currentInspectorUser.signatureTime,
}, },
}); });
const { data: hiddenList } = await props["hiddenList"]({ foreignKey: query.inspectionId, pageIndex: 1, pageSize: 999 }); const { data: hiddenList } = await props["hiddenList"]({
foreignKey: query.inspectionId,
pageIndex: 1,
pageSize: 999,
});
setHiddenList(hiddenList); setHiddenList(hiddenList);
} }
else { else {
@ -89,24 +97,52 @@ function Add(props) {
getData(); getData();
}, []); }, []);
const onSubmit = async (values, isDraft) => { const getHiddenDiscovererUserList = () => {
await isExistenceDuplicateSelection({ data: values.inspectorList, key: "userId" }); const inspectorList = form.getFieldValue("inspectorList");
// 删除旧的签字图片 const newHiddenDiscovererUserList = cloneDeep(inspectorList).filter(item => item && item.userId && item.departmentId);
if (!newHiddenDiscovererUserList.some(item => userInfo.id === item.userId)) {
newHiddenDiscovererUserList.unshift({
departmentId: userInfo.departmentId,
departmentName: userInfo.departmentName,
userId: userInfo.id,
userName: userInfo.name,
});
}
return newHiddenDiscovererUserList;
};
const getCurrentHiddenInfo = async (id, hiddenId) => {
const { data } = await props["hiddenView"]({ id });
const hiddenImageFiles = await getFile({
eqType: UPLOAD_FILE_TYPE_ENUM["3"],
eqForeignKey: hiddenId,
});
const hiddenVideoFiles = await getFile({
eqType: UPLOAD_FILE_TYPE_ENUM["102"],
eqForeignKey: hiddenId,
});
setCurrentHiddenInfo({ ...data, hiddenImageFiles, hiddenVideoFiles });
};
// 处理签名逻辑
const handleSignature = async (values) => {
await deleteFile({ single: false, files: [{ filePath: values.deleteSignature }] }); await deleteFile({ single: false, files: [{ filePath: values.deleteSignature }] });
let signatureFilePath = "";
// 签字图片
if (typeof values.initiator.signature !== "string") { if (typeof values.initiator.signature !== "string") {
const { filePath } = await uploadFile({ const { filePath } = await uploadFile({
files: [{ originFileObj: values.initiator.signature }], files: [{ originFileObj: values.initiator.signature }],
params: { type: UPLOAD_FILE_TYPE_ENUM["139"] }, params: { type: UPLOAD_FILE_TYPE_ENUM["139"] },
}); });
signatureFilePath = filePath; return filePath;
}
else {
signatureFilePath = values.initiator.signature;
} }
return values.initiator.signature;
};
// 处理检查情况图片
const handleSituationImages = async (values) => {
const situationList = cloneDeep(values.situationList.filter(Boolean)); const situationList = cloneDeep(values.situationList.filter(Boolean));
// 检查情况图片
for (let i = 0; i < situationList.length; i++) { for (let i = 0; i < situationList.length; i++) {
await deleteFile({ single: false, files: situationList[i].deleteFiles }); await deleteFile({ single: false, files: situationList[i].deleteFiles });
const { id } = await uploadFile({ const { id } = await uploadFile({
@ -115,10 +151,15 @@ function Add(props) {
params: { type: UPLOAD_FILE_TYPE_ENUM["140"], foreignKey: situationList[i].contentId }, params: { type: UPLOAD_FILE_TYPE_ENUM["140"], foreignKey: situationList[i].contentId },
}); });
situationList[i].imgId = id; situationList[i].imgId = id;
delete situationList[i].deleteFiles;
delete situationList[i].files;
} }
return situationList;
};
// 处理检查人员列表
const handleInspectorList = (values) => {
const inspectorList = cloneDeep(values.inspectorList.filter(Boolean)); const inspectorList = cloneDeep(values.inspectorList.filter(Boolean));
if (!inspectorList.some(item => userInfo.id === item.userId)) { if (!inspectorList.some(item => userInfo.id === item.userId)) {
inspectorList.push({ inspectorList.push({
departmentId: userInfo.departmentId, departmentId: userInfo.departmentId,
@ -127,12 +168,17 @@ function Add(props) {
userName: userInfo.name, userName: userInfo.name,
}); });
} }
// 发起新增请求
const { traceId } = await props[!query.id ? "inspectionAdd" : "inspectionUpdate"]({ return inspectorList;
};
// 提交主表单数据
const submitInspectionData = async (values, situationList, inspectorList, signaturePath, isDraft) => {
return await props[!query.id ? "inspectionAdd" : "inspectionUpdate"]({
...values, ...values,
situationList, situationList,
inspectorList, inspectorList,
initiator: { ...values.initiator, signature: signatureFilePath }, initiator: { ...values.initiator, signature: signaturePath },
isDraft, isDraft,
source: props.source || "5", source: props.source || "5",
deleteSignature: undefined, deleteSignature: undefined,
@ -140,47 +186,112 @@ function Add(props) {
inspectionId: query.id, inspectionId: query.id,
inspectionBusinessId: query.inspectionId, inspectionBusinessId: query.inspectionId,
}); });
// 删除隐患附件,删除隐患 };
for (let i = 0; i < deleteHiddenIds.current.length; i++) {
// 更新现有隐患
const handleHiddenSubmit = async (traceId, isDraft, index) => {
await deleteFile({
single: false,
files: hiddenList[index].deleteHiddenImageFiles,
});
await deleteFile({
single: false,
files: hiddenList[index].deleteHiddenVideoFiles,
});
const { id } = await uploadFile({
single: false,
files: hiddenList[index].hiddenImageFiles,
params: {
type: UPLOAD_FILE_TYPE_ENUM["3"],
foreignKey: hiddenList[index].hiddenId,
},
});
await uploadFile({
single: false,
files: hiddenList[index].hiddenVideoFiles,
params: {
type: UPLOAD_FILE_TYPE_ENUM["102"],
foreignKey: hiddenList[index].hiddenId,
},
});
if (hiddenList[index].hiddenPartType === "input") {
await props["partAdd"]({ hiddenregion: hiddenList[index].hiddenPart });
}
const hiddenImageFiles = await getFile({
eqType: UPLOAD_FILE_TYPE_ENUM["3"],
eqForeignKey: hiddenList[index].hiddenId,
});
await props["hiddenEdit"]({
...hiddenList[index],
source: 5,
hiddenId: id,
state: isDraft === 0 ? 102 : 98,
foreignKey: traceId,
hiddenJson: JSON.stringify({
confirm: 1,
rectify: 1,
check: 1,
special: 1,
extension: 1,
}),
hiddenImgAddCmds: hiddenImageFiles.map(item => ({ url: item.url })),
hiddenUserId: "",
});
};
// 处理隐患数据
const handleHiddenData = async (traceId, isDraft) => {
// 删除隐患
if (deleteHiddenIds.current.length > 0) {
props["hiddenDelete"]({ ids: deleteHiddenIds.current.join(",") }); props["hiddenDelete"]({ ids: deleteHiddenIds.current.join(",") });
}
// 删除隐患附件
for (let i = 0; i < deleteHiddenIds.current.length; i++) {
const hiddenImageFiles = await getFile({ const hiddenImageFiles = await getFile({
eqType: UPLOAD_FILE_TYPE_ENUM["3"], eqType: UPLOAD_FILE_TYPE_ENUM["3"],
eqForeignKey: deleteHiddenIds.current[i], eqForeignKey: deleteHiddenIds.current[i],
}); });
await deleteFile({ single: false, files: hiddenImageFiles }); await deleteFile({ single: false, files: hiddenImageFiles });
const hiddenVideoFiles = await getFile({ const hiddenVideoFiles = await getFile({
eqType: UPLOAD_FILE_TYPE_ENUM["102"], eqType: UPLOAD_FILE_TYPE_ENUM["102"],
eqForeignKey: deleteHiddenIds.current[i], eqForeignKey: deleteHiddenIds.current[i],
}); });
await deleteFile({ single: false, files: hiddenVideoFiles }); await deleteFile({ single: false, files: hiddenVideoFiles });
} }
// 上传隐患图片,新增隐患
// 新增/更新隐患
for (let i = 0; i < hiddenList.length; i++) { for (let i = 0; i < hiddenList.length; i++) {
if (!hiddenList[i].hiddenId) { await handleHiddenSubmit(traceId, isDraft, i);
const { id } = await uploadFile({
single: false,
files: hiddenList[i].hiddenImageFiles,
params: { type: UPLOAD_FILE_TYPE_ENUM["3"], foreignKey: hiddenList[i].hiddenId },
});
await uploadFile({
single: false,
files: hiddenList[i].hiddenVideoFiles,
params: { type: UPLOAD_FILE_TYPE_ENUM["102"], foreignKey: id },
});
delete hiddenList[i].hiddenImageFiles;
delete hiddenList[i].hiddenVideoFiles;
if (hiddenList[i].hiddenPartType === "input") {
await props["partAdd"]({ hiddenregion: hiddenList[i].hiddenPart });
}
await props["hiddenAdd"]({
...hiddenList[i],
source: 5,
hiddenId: id,
state: isDraft === 0 ? 102 : 98,
foreignKey: traceId,
});
}
} }
};
const onSubmit = async (values, isDraft) => {
// 检查重复选择
await isExistenceDuplicateSelection({ data: values.inspectorList, key: "userId" });
// 处理签名
const signatureResult = await handleSignature(values);
// 处理检查情况图片
const situationList = await handleSituationImages(values);
// 处理检查人员列表
const inspectorList = handleInspectorList(values);
// 提交主表单数据
const { traceId } = await submitInspectionData(values, situationList, inspectorList, signatureResult, isDraft);
// 处理隐患数据
await handleHiddenData(traceId, isDraft);
message.success("操作成功"); message.success("操作成功");
props.history.goBack(); props.history.goBack();
}; };
@ -272,123 +383,71 @@ function Add(props) {
}, },
{ label: "检查人员", render: FORM_ITEM_RENDER_ENUM.DIVIDER }, { label: "检查人员", render: FORM_ITEM_RENDER_ENUM.DIVIDER },
{ {
key: "inspectorList", name: "inspectorList",
customizeRender: true,
span: 24, span: 24,
render: ( render: FORM_ITEM_RENDER_ENUM.FORM_LIST,
<> formListUniqueProps: {
<Form.List name="inspectorList"> addButtonText: "添加检查人员",
{(fields, { add, remove }) => ( options: field => (
<> [
{fields.map((field, index) => ( {
<Row gutter={24} key={field.key}> name: [field.name, "departmentId"],
<Col span={12}> label: "检查人员部门",
<Form.Item render: (
label="检查人员部门" <DepartmentSelectTree
rules={[{ required: true, message: "请选择检查人员部门" }]} onChange={() => {
name={[field.name, "departmentId"]} form.setFieldValue(["inspectorList", field.name, "userId"], "");
> form.setFieldValue(["inspectorList", field.name, "userName"], "");
<DepartmentSelectTree }}
onChange={() => { onGetLabel={(label) => {
form.setFieldValue(["inspectorList", field.name, "userId"], ""); form.setFieldValue(["inspectorList", field.name, "departmentName"], label);
form.setFieldValue(["inspectorList", field.name, "userName"], ""); }}
}} />
onGetLabel={(label) => { ),
form.setFieldValue(["inspectorList", field.name, "departmentName"], label); },
}} { name: [field.name, "departmentName"], label: "检查人员部门名称", onlyForLabel: true },
/> { name: [field.name, "userName"], label: "检查人员名称", onlyForLabel: true },
</Form.Item> {
<Form.Item label="检查人员部门名称" noStyle name={[field.name, "departmentName"]}> name: [field.name, "userId"],
<input type="hidden" /> label: "检查人员",
</Form.Item> render: (
</Col> <PersonnelSelect
<Col span={12}> params={{ departmentId: inspectorList?.[field.name]?.departmentId || "" }}
<Form.Item label="检查人员" required> onGetLabel={label => form.setFieldValue(["inspectorList", field.name, "userName"], label)}
<div style={{ display: "flex", gap: 10 }}> />
<Form.Item ),
noStyle },
rules={[{ required: true, message: "请选择检查人员" }]} ]
name={[field.name, "userId"]} ),
> },
<PersonnelSelect
params={{ departmentId: inspectorList?.[field.name]?.departmentId || "" }}
onGetLabel={label => form.setFieldValue(["inspectorList", field.name, "userName"], label)}
/>
</Form.Item>
{
index >= 1
? <Button type="primary" danger onClick={() => remove(field.name)}>删除</Button>
: <Button type="primary" onClick={() => add()}>添加检查人员</Button>
}
</div>
</Form.Item>
<Form.Item label="检查人员名称" noStyle name={[field.name, "userName"]}>
<input type="hidden" />
</Form.Item>
</Col>
</Row>
))}
</>
)}
</Form.List>
</>
),
}, },
{ label: "检查情况", render: FORM_ITEM_RENDER_ENUM.DIVIDER }, { label: "检查情况", render: FORM_ITEM_RENDER_ENUM.DIVIDER },
{ {
key: "situationList", name: "situationList",
customizeRender: true,
span: 24, span: 24,
render: ( render: FORM_ITEM_RENDER_ENUM.FORM_LIST,
<> formListUniqueProps: {
<Form.List name="situationList"> addButtonText: "添加检查情况",
{(fields, { add, remove }) => ( options: field => ([
<> { name: [field.name, "content"], label: "检查情况", render: FORM_ITEM_RENDER_ENUM.TEXTAREA },
{fields.map((field, index) => ( { name: [field.name, "deleteFiles"], label: "删除的图片", onlyForLabel: true },
<Row gutter={24} key={field.key}> {
<Col span={12}> name: [field.name, "files"],
<Form.Item label: "图片",
label="检查情况" render: (
rules={[{ required: true, message: "请输入检查情况" }, { max: 500, message: "最多输入500字符" }]} <Upload
name={[field.name, "content"]} maxCount={1}
> onGetRemoveFile={(file) => {
<Input.TextArea placeholder="请输入检查情况" maxLength={500} showCount={true} rows={3} /> form.setFieldValue(
</Form.Item> ["situationList", field.name, "deleteFiles"],
</Col> [...(form.getFieldValue(["situationList", field.name, "deleteFiles"]) || []), file],
<Col span={12}> );
<Form.Item label="图片"> }}
<div style={{ display: "flex", gap: 10 }}> />
<div style={{ flex: 1 }}> ),
<Form.Item noStyle name={[field.name, "files"]}> },
<Upload ]),
maxCount={1} },
onGetRemoveFile={(file) => {
form.setFieldValue(
["situationList", field.name, "deleteFiles"],
[...(form.getFieldValue(["situationList", field.name, "deleteFiles"]) || []), file],
);
}}
/>
</Form.Item>
</div>
{
index >= 1
? <Button type="primary" danger onClick={() => remove(field.name)}>删除</Button>
: <Button type="primary" onClick={() => add()}>添加检查情况</Button>
}
</div>
</Form.Item>
<Form.Item name={[field.name, "deleteFiles"]} label="删除的图片" noStyle preserve={false}>
<input type="hidden" />
</Form.Item>
</Col>
</Row>
))}
</>
)}
</Form.List>
</>
),
}, },
{ label: "发现问题", render: FORM_ITEM_RENDER_ENUM.DIVIDER }, { label: "发现问题", render: FORM_ITEM_RENDER_ENUM.DIVIDER },
{ {
@ -405,18 +464,10 @@ function Add(props) {
<Button <Button
type="primary" type="primary"
onClick={() => { onClick={() => {
setHiddenDiscovererUserList(getHiddenDiscovererUserList());
setCurrentHiddenInfo({});
currentHiddenIndex.current = -1;
setHiddenAddModalOpen(true); setHiddenAddModalOpen(true);
const inspectorList = form.getFieldValue("inspectorList");
const newHiddenDiscovererUserList = cloneDeep(inspectorList).filter(item => item && item.userId && item.departmentId);
if (!newHiddenDiscovererUserList.some(item => userInfo.id === item.userId)) {
newHiddenDiscovererUserList.unshift({
departmentId: userInfo.departmentId,
departmentName: userInfo.departmentName,
userId: userInfo.id,
userName: userInfo.name,
});
}
setHiddenDiscovererUserList(newHiddenDiscovererUserList);
}} }}
> >
添加隐患 添加隐患
@ -427,26 +478,44 @@ function Add(props) {
{ title: "问题描述", dataIndex: "hiddenDesc" }, { title: "问题描述", dataIndex: "hiddenDesc" },
{ {
title: "操作", title: "操作",
width: 100, width: 120,
render: (_, record, index) => ( render: (_, record, index) => (
<Button <Space>
type="link" <Button
danger type="link"
onClick={() => { onClick={async () => {
Modal.confirm({ if (record.hiddenId) {
title: "提示", getCurrentHiddenInfo(record.id, record.hiddenId);
content: "确定删除该隐患吗?", }
onOk: async () => { else {
if (record.hiddenId) { setCurrentHiddenInfo({ ...record });
deleteHiddenIds.current.push(record.hiddenId); }
} setHiddenDiscovererUserList(getHiddenDiscovererUserList());
setHiddenList(hiddenList.filter((_, i) => i !== index)); currentHiddenIndex.current = index;
}, setHiddenAddModalOpen(true);
}); }}
}} >
> 编辑
删除 </Button>
</Button> <Button
type="link"
danger
onClick={() => {
Modal.confirm({
title: "提示",
content: "确定删除该隐患吗?",
onOk: async () => {
if (record.id) {
deleteHiddenIds.current.push(record.id);
}
setHiddenList(hiddenList.filter((_, i) => i !== index));
},
});
}}
>
删除
</Button>
</Space>
), ),
}, },
]} ]}
@ -483,8 +552,26 @@ function Add(props) {
hiddenAddModalOpen && ( hiddenAddModalOpen && (
<HiddenAddModal <HiddenAddModal
hiddenDiscovererUserList={hiddenDiscovererUserList} hiddenDiscovererUserList={hiddenDiscovererUserList}
onCancel={() => setHiddenAddModalOpen(false)} hiddenInfo={currentHiddenInfo}
onConfirm={values => setHiddenList([...hiddenList, values])} onCancel={() => {
setHiddenAddModalOpen(false);
setCurrentHiddenInfo({});
}}
onConfirm={(values) => {
if (currentHiddenIndex.current === -1) {
setHiddenList([...hiddenList, values]);
}
else {
setHiddenList(
hiddenList.map((item, index) => {
if (index === currentHiddenIndex.current)
return values;
return item;
}),
);
}
setCurrentHiddenInfo({});
}}
/> />
) )
} }