隐患修改 12.4

master
LiuJiaNan 2025-12-05 10:19:05 +08:00
parent 9b16bab9dd
commit 5da98bec37
1 changed files with 141 additions and 52 deletions

View File

@ -40,7 +40,7 @@ function Add(props) {
const [currentProcessHiddenIndex, setCurrentProcessHiddenIndex] = useState(-1);
const [imageSelectModalOpen, setImageSelectModalOpen] = useState(false);
const [uploadedImages, setUploadedImages] = useState([]);
const [processedImages, setProcessedImages] = useState([]);
const processedImages = useRef([]);
const [modalTitle, setModalTitle] = useState("选择图片进行AI识别");
const [hiddenPartType, setHiddenPartType] = useState("select");
@ -103,13 +103,34 @@ function Add(props) {
getConfirmUserList();
}, []);
const getAIHiddenImageRecognize = async (selectedImage = null) => {
/**
* 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 imageToProcess = selectedImage || hiddenImageFiles[0];
if (imageToProcess && !processedImages.includes(imageToProcess)) {
setProcessedImages([...processedImages, imageToProcess]);
// 如果是重新识别用户点击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) {
@ -119,10 +140,31 @@ function Add(props) {
}
const { data } = await props["hiddenAiRecognize"]({ hiddenUrl: "https://pic.rmb.bdstatic.com/bjh/news/0a68c2681805fcaea506d922f024420c.png" });
// const { data } = await props["hiddenAiRecognize"]({ hiddenUrl: getFileUrl() + aiHiddenImageRecognizeFilePath.current });
setAiHiddens((data?.aiHiddens || []).map(item => ({ ...JSON.parse(item), id: createGuid() })));
setAiHiddenModalOpen(true);
// await deleteFile({ files: [{ filePath: aiHiddenImageRecognizeFilePath.current }] });
if (data?.aiHiddens) {
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 }] });
}
};
/**
* 处理AI识别按钮点击事件
* 重新开始AI识别流程重置所有状态
*/
const handleAiRecognizeClick = () => {
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles");
if (!hiddenImageFiles || hiddenImageFiles.length === 0) {
@ -130,45 +172,50 @@ function Add(props) {
return;
}
setProcessedImages([]);
setAiHiddens([]);
setSelectHiddens([]);
setCurrentProcessHiddenIndex(-1);
form.setFieldValue("isAi", "");
form.setFieldValue("hiddenDesc", "");
form.setFieldValue("legalBasis", "");
form.setFieldValue("rectificationDescr", "");
if (hiddenImageFiles.length === 1) {
getAIHiddenImageRecognize(hiddenImageFiles[0]);
// 只有一张图片直接进行AI识别标记为重新识别以重置所有状态
getAIHiddenImageRecognize(hiddenImageFiles[0], true);
}
else {
// 多张图片,显示图片选择弹窗让用户选择
setUploadedImages(hiddenImageFiles);
setModalTitle("选择图片进行AI识别");
setModalTitle("选择图片进行AI识别"); // 标题用于区分操作类型
setImageSelectModalOpen(true);
}
};
/**
* 处理选择其他图片按钮点击事件
* 显示确认对话框确认后打开图片选择弹窗只显示未处理的图片
*/
const handleSelectOtherImage = () => {
Modal.confirm({
title: "确认切换图片",
content: "当前有未处理完的隐患信息确认后进入选择图片选择图片重新AI识别将丢弃之前没有处理完的隐患",
onOk: () => {
setAiHiddens([]);
setSelectHiddens([]);
setCurrentProcessHiddenIndex(-1);
form.setFieldValue("isAi", "");
form.setFieldValue("hiddenDesc", "");
form.setFieldValue("legalBasis", "");
form.setFieldValue("rectificationDescr", "");
// 获取所有上传的图片
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles");
const unprocessedImages = hiddenImageFiles.filter(img =>
!processedImages.includes(img),
);
// 过滤出未处理的图片(排除已处理过的图片)
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);
},
});
@ -176,9 +223,18 @@ function Add(props) {
const getUnprocessedImagesCount = () => {
const hiddenImageFiles = form.getFieldValue("hiddenImageFiles") || [];
return hiddenImageFiles.filter(img =>
!processedImages.includes(img),
).length;
// 使用图片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;
};
const onMergeHidden = (selectedRowKeys) => {
@ -267,20 +323,39 @@ function Add(props) {
loading={deleteFileLoading || uploadFileLoading || getFileLoading || props.ledger.ledgerLoading}
values={defaultValues}
onFinish={onSubmit}
showSubmitButton={false}
showCancelButton={false}
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={[
<Button key="submit" type="primary" onClick={form.submit}>{isExistNextOneHidden() ? "提交并下一个" : "提交"}</Button>,
...(isAi === 1 && processedImages.length > 0 && getUnprocessedImagesCount() > 0
? [
<Button key="selectOther" onClick={handleSelectOtherImage}>
选择其他图片 (
{getUnprocessedImagesCount()}
)
</Button>,
]
: []),
<Button key="back" onClick={() => props.history.goBack()}>取消</Button>,
isAi === 1 && getUnprocessedImagesCount() > 0
&& (
<Button key="selectOther" onClick={handleSelectOtherImage}>
选择其他图片 (
{getUnprocessedImagesCount()}
)
</Button>
),
]}
options={[
{
@ -292,14 +367,15 @@ function Add(props) {
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 = "";
setSelectHiddens([]);
setAiHiddens([]);
setCurrentProcessHiddenIndex(-1);
}
}}
onGetRemoveFile={(file) => {
@ -327,6 +403,7 @@ function Add(props) {
span: 24,
},
{ name: "isAi", label: "是否AI识别隐患", onlyForLabel: true },
{ name: "aiBatch", label: "AI识别隐患批次号", onlyForLabel: true },
{ name: "hiddenDesc", label: "隐患描述", render: FORM_ITEM_RENDER_ENUM.TEXTAREA, span: 24 },
{
name: "legalBasis",
@ -663,6 +740,7 @@ function Add(props) {
form.setFieldValue("hiddenDesc", selectedRows[0].hiddenDescr);
form.setFieldValue("legalBasis", selectedRows[0].legalBasis);
form.setFieldValue("rectificationDescr", selectedRows[0].rectificationSuggestions);
form.setFieldValue("aiBatch", createGuid());
}}
onMergeHidden={onMergeHidden}
/>
@ -674,8 +752,8 @@ function Add(props) {
title={modalTitle}
images={uploadedImages}
onCancel={() => setImageSelectModalOpen(false)}
onConfirm={(selectedImage) => {
getAIHiddenImageRecognize(selectedImage);
onConfirm={(selectedImage, isReset = false, isSelectOther) => {
getAIHiddenImageRecognize(selectedImage, isReset, isSelectOther);
}}
/>
)
@ -754,16 +832,27 @@ const AiHiddenModal = (props) => {
);
};
/**
* 图片选择弹窗组件
* 用于AI识别和选择其他图片时的图片选择
*/
const ImageSelectModal = (props) => {
const [selectedImage, setSelectedImage] = useState(null);
/**
* 确认选择图片并开始AI识别
* 根据弹窗标题判断操作类型传递相应的参数
*/
const handleConfirm = () => {
if (!selectedImage) {
message.warning("请选择一张图片进行AI识别");
return;
}
props.onConfirm(selectedImage);
props.onCancel();
// 根据标题判断操作类型,传递相应的参数给父组件
const isReset = props.title === "选择图片进行AI识别"; // 重新AI识别重置所有状态
const isSelectOther = props.title === "选择其他图片进行AI识别"; // 选择其他图片:保留已处理图片记录
props.onConfirm(selectedImage, isReset, isSelectOther);
props.onCancel(); // 关闭弹窗
};
return (