diff --git a/src/pages/Container/BranchCompany/Average/Ledger/Add/index.js b/src/pages/Container/BranchCompany/Average/Ledger/Add/index.js
index f012fa2..b19311c 100644
--- a/src/pages/Container/BranchCompany/Average/Ledger/Add/index.js
+++ b/src/pages/Container/BranchCompany/Average/Ledger/Add/index.js
@@ -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={[
- ,
- ...(isAi === 1 && processedImages.length > 0 && getUnprocessedImagesCount() > 0
- ? [
- ,
- ]
- : []),
- ,
+ isAi === 1 && getUnprocessedImagesCount() > 0
+ && (
+
+ ),
]}
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 (