隐患修改 12.4

master
LiuJiaNan 2025-12-05 14:32:10 +08:00
parent e75c601e73
commit d5c9321cd6
4 changed files with 70 additions and 166 deletions

View File

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

View File

@ -1,9 +1,12 @@
import HiddenInfo from "zy-react-library/components/HiddenInfo/gwj";
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
function HiddenView() {
const query = useGetUrlQuery();
return (
<div>
<HiddenInfo />
<HiddenInfo history={query.history === "1"} />
</div>
);
}

View File

@ -19,7 +19,7 @@ import useGetFile from "zy-react-library/hooks/useGetFile";
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
import useGetUserInfo from "zy-react-library/hooks/useGetUserInfo";
import useUploadFile from "zy-react-library/hooks/useUploadFile";
import { createGuid, getLabelName } from "zy-react-library/utils";
import { createGuid, getFileUrl, getLabelName } from "zy-react-library/utils";
import ai_recognize from "~/assets/images/ai_recognize.png";
import { NS_CONFIRM_USER, NS_LEDGER, NS_PART } from "~/enumerate/namespace";
@ -33,15 +33,15 @@ function Add(props) {
const isRelated = Form.useWatch("isRelated", form);
const defaultValues = { isRelated: 2, rectificationType: 2 };
const aiHiddenImageRecognizeFilePath = useRef("");
const [aiHiddens, setAiHiddens] = useState([]);
const [aiHiddenModalOpen, setAiHiddenModalOpen] = useState(false);
const [selectHiddens, setSelectHiddens] = useState([]);
const [currentProcessHiddenIndex, setCurrentProcessHiddenIndex] = useState(-1);
const [imageSelectModalOpen, setImageSelectModalOpen] = useState(false);
const processedImageUids = useRef([]);
const [uploadedImages, setUploadedImages] = useState([]);
const processedImages = useRef([]);
const [modalTitle, setModalTitle] = useState("选择图片进行AI识别");
const [isShowAiButton, setIsShowAiButton] = useState(true);
const [hiddenPartType, setHiddenPartType] = useState("select");
const [confirmUserList, setConfirmUserList] = useState([]);
@ -103,138 +103,62 @@ function Add(props) {
getConfirmUserList();
}, []);
/**
* AI识别图片处理函数
* @param {object} selectedImage - 要识别的图片如果为空则使用第一张图片
* @param {boolean} isReset - 是否为重新AI识别用户点击AI识别按钮
* @param {boolean} isSelectOther - 是否为选择其他图片识别
*/
const getAIHiddenImageRecognize = async (selectedImage = null, isReset = false, isSelectOther = false) => {
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles");
const clearHiddenRecognizeState = () => {
setSelectHiddens([]);
setCurrentProcessHiddenIndex(-1);
form.setFieldValue("isAi", "");
form.setFieldValue("hiddenDesc", "");
form.setFieldValue("legalBasis", "");
form.setFieldValue("rectificationDescr", "");
form.setFieldValue("aiBatch", "");
};
const imageToProcess = selectedImage || hiddenImageFiles[0];
// 如果是重新识别用户点击AI识别按钮重置所有状态包括已处理图片
// 这样用户可以重新开始完整的AI识别流程
if (isReset) {
processedImages.current = []; // 清空已处理图片
form.setFieldValue("isAi", ""); // 清空AI识别标记
}
// 如果是重新识别或选择其他图片重置AI相关状态
// 重新识别重置所有状态选择其他图片只重置AI相关状态保留已处理图片记录
if (isReset || isSelectOther) {
setAiHiddens([]); // 清空AI识别结果
setSelectHiddens([]); // 清空已选择的隐患
setCurrentProcessHiddenIndex(-1); // 重置当前处理的隐患索引
form.setFieldValue("hiddenDesc", ""); // 清空隐患描述
form.setFieldValue("legalBasis", ""); // 清空法律依据
form.setFieldValue("rectificationDescr", ""); // 清空整改描述
form.setFieldValue("aiBatch", ""); // 清空批次号
aiHiddenImageRecognizeFilePath.current = "";
}
if (!aiHiddenImageRecognizeFilePath.current) {
// const { filePath } = await uploadFile({ files: [imageToProcess], params: { type: UPLOAD_FILE_TYPE_ENUM["3"] } });
// aiHiddenImageRecognizeFilePath.current = filePath;
aiHiddenImageRecognizeFilePath.current = "https://pic.rmb.bdstatic.com/bjh/news/0a68c2681805fcaea506d922f024420c.png";
}
const { data } = await props["hiddenAiRecognize"]({ hiddenUrl: "https://pic.rmb.bdstatic.com/bjh/news/0a68c2681805fcaea506d922f024420c.png" });
// const { data } = await props["hiddenAiRecognize"]({ hiddenUrl: getFileUrl() + aiHiddenImageRecognizeFilePath.current });
const getAIHiddenImageRecognize = async (imageToProcess) => {
const { filePath } = await uploadFile({ files: [imageToProcess], params: { type: UPLOAD_FILE_TYPE_ENUM["3"] } });
// const { data } = await props["hiddenAiRecognize"]({ hiddenUrl: "https://pic.rmb.bdstatic.com/bjh/news/0a68c2681805fcaea506d922f024420c.png" });
const { data } = await props["hiddenAiRecognize"]({ hiddenUrl: getFileUrl() + filePath });
if (data?.aiHiddens) {
processedImageUids.current.push(imageToProcess.uid);
setAiHiddens(data?.aiHiddens.map(item => ({ ...JSON.parse(item), id: createGuid() })));
// 使用setTimeout确保状态更新在正确的时机
setTimeout(() => {
const isAlreadyProcessed = processedImages.current.some(processedImg =>
(processedImg.url && processedImg.url === imageToProcess.url)
|| (processedImg.name && processedImg.name === imageToProcess.name)
|| (processedImg.uid && processedImg.uid === imageToProcess.uid),
);
if (imageToProcess && !isAlreadyProcessed) {
processedImages.current = [...processedImages.current, imageToProcess];
}
}, 0);
setAiHiddenModalOpen(true);
// await deleteFile({ files: [{ filePath: aiHiddenImageRecognizeFilePath.current }] });
clearHiddenRecognizeState();
await deleteFile({ files: [{ filePath }] });
}
};
/**
* 处理AI识别按钮点击事件
* 重新开始AI识别流程重置所有状态
*/
const handleAiRecognizeClick = () => {
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles");
if (!hiddenImageFiles || hiddenImageFiles.length === 0) {
message.warning("请上传图片");
return;
}
if (hiddenImageFiles.length === 1) {
// 只有一张图片直接进行AI识别标记为重新识别以重置所有状态
getAIHiddenImageRecognize(hiddenImageFiles[0], true);
}
else {
// 多张图片,显示图片选择弹窗让用户选择
setUploadedImages(hiddenImageFiles);
setModalTitle("选择图片进行AI识别"); // 标题用于区分操作类型
setImageSelectModalOpen(true);
}
const getUnprocessedImages = () => {
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles") || [];
return hiddenImageFiles.filter(item => !processedImageUids.current.includes(item.uid));
};
const getUnprocessedImagesCount = () => {
return getUnprocessedImages().length;
};
/**
* 处理选择其他图片按钮点击事件
* 显示确认对话框确认后打开图片选择弹窗只显示未处理的图片
*/
const handleSelectOtherImage = () => {
Modal.confirm({
title: "确认切换图片",
content: "当前有未处理完的隐患信息确认后进入选择图片选择图片重新AI识别将丢弃之前没有处理完的隐患",
onOk: () => {
// 获取所有上传的图片
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles");
// 过滤出未处理的图片(排除已处理过的图片)
const unprocessedImages = hiddenImageFiles.filter((img) => {
const isProcessed = processedImages.current.some(processedImg =>
(processedImg.url && processedImg.url === img.url)
|| (processedImg.name && processedImg.name === img.name)
|| (processedImg.uid && processedImg.uid === img.uid),
);
return !isProcessed;
});
// 如果没有未处理的图片,提示用户
if (unprocessedImages.length === 0) {
message.info("所有图片都已处理完毕");
return;
}
// 设置要显示的图片(未处理图片)
setUploadedImages(unprocessedImages);
// 设置弹窗标题,用于区分是选择其他图片操作
setModalTitle("选择其他图片进行AI识别");
// 打开图片选择弹窗
setImageSelectModalOpen(true);
setUploadedImages(getUnprocessedImages());
},
});
};
const getUnprocessedImagesCount = () => {
const handleAiRecognizeClick = () => {
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles") || [];
// 使用图片URL或name进行比较而不是对象引用
const unprocessedCount = hiddenImageFiles.filter((img) => {
const isProcessed = processedImages.current.some(processedImg =>
(processedImg.url && processedImg.url === img.url)
|| (processedImg.name && processedImg.name === img.name)
|| (processedImg.uid && processedImg.uid === img.uid),
);
return !isProcessed;
}).length;
return unprocessedCount;
if (hiddenImageFiles.length === 0) {
message.error("请上传图片");
return;
}
if (hiddenImageFiles.length === 1) {
getAIHiddenImageRecognize(hiddenImageFiles[0]);
return;
}
setUploadedImages(hiddenImageFiles);
setImageSelectModalOpen(true);
};
const onMergeHidden = (selectedRowKeys) => {
@ -282,16 +206,26 @@ function Add(props) {
if (hiddenPartType === "input") {
await props["partAdd"]({ hiddenregion: values.hiddenPart });
}
const hiddenImageFiles = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["3"], eqForeignKey: id });
const { success } = await props[!query.id ? "hiddenAdd" : "hiddenEdit"]({
...values,
id: query.id,
hiddenId: id,
source: "1",
hiddenJson: {
confirm: 1, // 确认 0否1是
rectify: 1, // 整改 0否1是
check: 1, // 验收 0否1是
special: 1, // 特殊处置 0否1是
extension: 1, // 延期 0否1是
},
hiddenImgAddCmds: hiddenImageFiles.map(item => ({ url: item.url })),
});
if (success) {
message.success("操作成功");
if (isExistNextOneHidden()) {
setCurrentProcessHiddenIndex(currentProcessHiddenIndex + 1);
setIsShowAiButton(false);
const currentValues = form.getFieldsValue();
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles");
const resetValues = {};
@ -323,32 +257,9 @@ function Add(props) {
loading={deleteFileLoading || uploadFileLoading || getFileLoading || props.ledger.ledgerLoading}
values={defaultValues}
onFinish={onSubmit}
onFinishFailed={() => {
if (isExistNextOneHidden()) {
setCurrentProcessHiddenIndex(currentProcessHiddenIndex + 1);
const currentValues = form.getFieldsValue();
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles");
const resetValues = {};
Object.keys(currentValues).forEach((key) => {
resetValues[key] = undefined;
});
form.setFieldsValue({
...resetValues,
...defaultValues,
isAi: 1,
hiddenImageFiles,
hiddenDesc: selectHiddens[currentProcessHiddenIndex + 1].hiddenDescr,
legalBasis: selectHiddens[currentProcessHiddenIndex + 1].legalBasis,
rectificationDescr: selectHiddens[currentProcessHiddenIndex + 1].rectificationSuggestions,
});
}
else {
props.history.goBack();
}
}}
submitButtonText={isExistNextOneHidden() ? "提交并下一个" : "提交"}
extraActionButtons={[
isAi === 1 && getUnprocessedImagesCount() > 0
(!isShowAiButton && getUnprocessedImagesCount() > 0)
&& (
<Button key="selectOther" onClick={handleSelectOtherImage}>
选择其他图片 (
@ -363,19 +274,12 @@ function Add(props) {
label: "隐患图片",
render: (
<Upload
disabled={currentProcessHiddenIndex > 0}
disabled={!isShowAiButton}
listType="picture-card"
onRemove={() => {
if (isAi === 1) {
setAiHiddens([]);
setSelectHiddens([]);
setCurrentProcessHiddenIndex(-1);
form.setFieldValue("isAi", "");
form.setFieldValue("hiddenDesc", "");
form.setFieldValue("legalBasis", "");
form.setFieldValue("rectificationDescr", "");
form.setFieldValue("aiBatch", "");
aiHiddenImageRecognizeFilePath.current = "";
clearHiddenRecognizeState();
}
}}
onGetRemoveFile={(file) => {
@ -384,7 +288,7 @@ function Add(props) {
tipContent={(
<>
{
(!query.id && currentProcessHiddenIndex <= 0) && (
(!query.id && isShowAiButton) && (
<img
src={ai_recognize}
alt="ai_recognize"
@ -752,8 +656,8 @@ function Add(props) {
title={modalTitle}
images={uploadedImages}
onCancel={() => setImageSelectModalOpen(false)}
onConfirm={(selectedImage, isReset = false, isSelectOther) => {
getAIHiddenImageRecognize(selectedImage, isReset, isSelectOther);
onConfirm={(selectedImage) => {
getAIHiddenImageRecognize(selectedImage);
}}
/>
)
@ -832,27 +736,16 @@ const AiHiddenModal = (props) => {
);
};
/**
* 图片选择弹窗组件
* 用于AI识别和选择其他图片时的图片选择
*/
const ImageSelectModal = (props) => {
const [selectedImage, setSelectedImage] = useState(null);
/**
* 确认选择图片并开始AI识别
* 根据弹窗标题判断操作类型传递相应的参数
*/
const handleConfirm = () => {
if (!selectedImage) {
message.warning("请选择一张图片进行AI识别");
return;
}
// 根据标题判断操作类型,传递相应的参数给父组件
const isReset = props.title === "选择图片进行AI识别"; // 重新AI识别重置所有状态
const isSelectOther = props.title === "选择其他图片进行AI识别"; // 选择其他图片:保留已处理图片记录
props.onConfirm(selectedImage, isReset, isSelectOther);
props.onCancel(); // 关闭弹窗
props.onConfirm(selectedImage);
props.onCancel();
};
return (

View File

@ -223,7 +223,7 @@ function List(props) {
},
{
title: "操作",
width: 150,
width: 220,
fixed: "right",
render: (_, record) => (
<Space>
@ -248,6 +248,14 @@ function List(props) {
)
}
{record.state === 100 && <Button type="link" danger onClick={() => onDelete(record.id)}>删除</Button>}
<Button
type="link"
onClick={() => {
props.history.push(`../HiddenView?id=${record.id}&hiddenId=${record.hiddenId}&history=1`);
}}
>
过程记录
</Button>
</Space>
),
},