feat: 对接ai审核接口

This commit is contained in:
rd
2025-08-11 12:04:03 +08:00
parent f1f9338e58
commit 0b0caf6b64
10 changed files with 197 additions and 104 deletions

View File

@ -78,6 +78,17 @@ export const putWorkAuditsAuditPass = (params = {}) => {
return Http.put(`/v1/work-audits/${auditId}/audit-pass`, rest); return Http.put(`/v1/work-audits/${auditId}/audit-pass`, rest);
}; };
// 内容稿件审核-AI审查
export const postWorkAuditsAiReview = (params = {}) => {
const { id, ...rest } = params as { id: string; [key: string]: any };
return Http.post(`/v1/work-audits/${id}/ai-review`, rest);
};
// 内容稿件审核-获取AI审查结果
export const getWorkAuditsAiReviewResult = (id: string, ticket: string) => {
return Http.get(`/v1/work-audits/${id}/ai-review/${ticket}`);
};
// 内容稿件-列表(客户) // 内容稿件-列表(客户)
export const getShareWorksList = (shareCode: string) => { export const getShareWorksList = (shareCode: string) => {
return Http.get( return Http.get(
@ -120,3 +131,4 @@ export const deleteShareWorksComments = (id: string, commentId: string, shareCod
headers: { 'share-code': shareCode }, headers: { 'share-code': shareCode },
}); });
}; };

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="navbar-wrap"> <div class="navbar-wrap">
<div class="left-wrap"> <div class="left-wrap">
<a-space class="cursor-pointer" @click="router.push('/')"> <div class="h-full flex items-center cursor-pointer" @click="handleUserHome">
<img src="@/assets/LOGO.svg" alt="" /> <img src="@/assets/LOGO.svg" alt="" />
</a-space> </div>
</div> </div>
<div class="flex-1"> <div class="flex-1">
<NavbarMenu /> <NavbarMenu />
@ -16,6 +16,7 @@
import NavbarMenu from './components/navbar-menu'; import NavbarMenu from './components/navbar-menu';
import RightSide from './components/right-side'; import RightSide from './components/right-side';
import { handleUserHome } from '@/utils/user.ts';
import router from '@/router'; import router from '@/router';
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -28,7 +29,7 @@ import router from '@/router';
.left-wrap { .left-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
padding-left: 20px; padding-left: 24px;
} }
.arco-dropdown-option-suffix { .arco-dropdown-option-suffix {
display: none; display: none;

View File

@ -0,0 +1,54 @@
import { postWorkAuditsAiReview, getWorkAuditsAiReviewResult } from '@/api/all/generationWorkshop';
export default function useGetAiReviewResult({ cardInfo, updateAiReview }: { cardInfo: any; updateAiReview: (ai_review: any) => void }) {
const statusPollingTimer = ref<number | null>(null);
const ticket = ref('');
const checkLoading = ref(false);
const checkResult = ref<any>({});
const handleStartCheck = async () => {
checkLoading.value = true;
const { id, platform, content } = cardInfo.value;
const { code, data } = await postWorkAuditsAiReview({ id, platform, content });
if (code === 200) {
ticket.value = data.ticket;
startStatusPolling();
}
};
const handleAgainCheck = async () => {
checkResult.value = {};
ticket.value = '';
clearStatusPollingTimer();
handleStartCheck();
};
const startStatusPolling = () => {
clearStatusPollingTimer();
statusPollingTimer.value = setInterval(async () => {
const { code, data } = await getWorkAuditsAiReviewResult(cardInfo.value.id, ticket.value);
if (code === 200 && data.status === 1) {
checkResult.value = data.ai_review;
updateAiReview?.(data.ai_review);
checkLoading.value = false;
clearStatusPollingTimer();
}
}, 3000);
};
const clearStatusPollingTimer = () => {
if (statusPollingTimer.value) {
clearInterval(statusPollingTimer.value);
statusPollingTimer.value = null;
}
};
onUnmounted(() => {
clearStatusPollingTimer();
});
return {
handleStartCheck,
handleAgainCheck,
checkResult,
checkLoading,
ticket,
};
}

View File

@ -6,6 +6,7 @@ import { getShareWorksList, getShareWorksDetail, patchShareWorksConfirm } from '
import { convertVideoUrlToCoverUrl, exactFormatTime } from '@/utils/tools.ts'; import { convertVideoUrlToCoverUrl, exactFormatTime } from '@/utils/tools.ts';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts'; import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts';
import { RESULT_LIST, ENUM_OPINION } from './constants'; import { RESULT_LIST, ENUM_OPINION } from './constants';
import { handleUserHome } from '@/utils/user.ts';
import { useUserStore } from '@/stores'; import { useUserStore } from '@/stores';
import icon1 from '@/assets/logo.svg'; import icon1 from '@/assets/logo.svg';
@ -212,7 +213,9 @@ export default {
<div class="explore-page"> <div class="explore-page">
<header class="page-header"> <header class="page-header">
<div class="content w-full px-24px flex items-center bg-#fff justify-between"> <div class="content w-full px-24px flex items-center bg-#fff justify-between">
<img src={icon1} alt="" width={130} /> <div class="h-full flex items-center cursor-pointer" onClick={handleUserHome}>
<img src={icon1} alt="" width={130} />
</div>
<div class="flex items-center">{renderActionRow()}</div> <div class="flex items-center">{renderActionRow()}</div>
</div> </div>
</header> </header>

View File

@ -3,6 +3,7 @@ import TextOverTips from '@/components/text-over-tips';
import { Image, Spin } from '@arco-design/web-vue'; import { Image, Spin } from '@arco-design/web-vue';
import { exactFormatTime } from '@/utils/tools'; import { exactFormatTime } from '@/utils/tools';
import { handleUserHome } from '@/utils/user.ts';
import { getShareWorksList } from '@/api/all/generationWorkshop'; import { getShareWorksList } from '@/api/all/generationWorkshop';
import { ENUM_OPINION } from '../detail/constants'; import { ENUM_OPINION } from '../detail/constants';
@ -44,7 +45,9 @@ export default {
<div class="explore-page"> <div class="explore-page">
<header class="page-header"> <header class="page-header">
<div class="content w-full px-24px flex items-center bg-#fff"> <div class="content w-full px-24px flex items-center bg-#fff">
<img src={icon2} alt="" width={130} /> <div class="h-full flex items-center cursor-pointer" onClick={handleUserHome}>
<img src={icon2} alt="" />
</div>
</div> </div>
</header> </header>
{loading.value ? ( {loading.value ? (

View File

@ -26,7 +26,7 @@
} }
} }
.page-wrapper { .page-wrapper {
min-height: 500px; min-height: calc(100vh - $navbar-height);
.explore-container { .explore-container {
width: 1200px; width: 1200px;
.explore-list-wrap { .explore-list-wrap {

View File

@ -1,42 +1,53 @@
const FORM_RULES = { export const FORM_RULES = {
title: [{ required: true, message: '请输入标题' }], title: [{ required: true, message: '请输入标题' }],
}; };
const enumTab = { export const enumTab = {
TEXT: 0, TEXT: 0,
IMAGE: 1, IMAGE: 1,
}; };
const TAB_LIST = [ export const TAB_LIST = [
{ {
label: '文本', label: '文本',
value: enumTab.TEXT, value: enumTab.TEXT,
}, },
{ // {
label: '图片', // label: '图片',
value: enumTab.IMAGE, // value: enumTab.IMAGE,
}, // },
]; ];
export enum Enum_Level {
LOW = 0,
MEDIUM = 1,
HIGH = 2,
}
export const LEVEL_MAP = new Map([
[Enum_Level.LOW, { label: '低风险', value: 'low_risk_number', class: '!color-#6d4cfe' }],
[Enum_Level.MEDIUM, { label: '中风险', value: 'medium_risk_number', class: 'color-#FFAE00' }],
[Enum_Level.HIGH, { label: '高风险', value: 'high_risk_number', class: '!color-#F64B31' }],
]);
export const RESULT_LIST = [ export const RESULT_LIST = [
{ {
label: '合规程度', label: '合规程度',
value: 'compliance_degree', value: 'compliance_level',
class: '!color-#6d4cfe', class: LEVEL_MAP.get(Enum_Level.LOW)?.class,
suffix: '%',
}, },
{ {
label: '检验项', label: '检验项',
value: 'compliance', value: 'inspection_items',
class: '!color-#211F24', class: '!color-#211F24',
}, },
{ {
label: '高风险', label: '高风险',
value: 'high_risk', value: 'high_risk_number',
class: '!color-#F64B31', class: LEVEL_MAP.get(Enum_Level.HIGH)?.class,
}, },
{ {
label: '中风险', label: '中风险',
value: 'medium_risk', value: 'medium_risk_number',
class: '!color-#FFAE00', class: LEVEL_MAP.get(Enum_Level.MEDIUM)?.class,
}, },
]; ];
export { FORM_RULES, enumTab, TAB_LIST };

View File

@ -20,7 +20,7 @@ import TextOverTips from '@/components/text-over-tips';
import 'swiper/css'; import 'swiper/css';
import 'swiper/css/navigation'; import 'swiper/css/navigation';
import { Navigation } from 'swiper/modules'; import { Navigation } from 'swiper/modules';
import { FORM_RULES, enumTab, TAB_LIST, RESULT_LIST } from './constants'; import { FORM_RULES, enumTab, TAB_LIST, RESULT_LIST, LEVEL_MAP } from './constants';
import { getImagePreSignedUrl } from '@/api/all/common'; import { getImagePreSignedUrl } from '@/api/all/common';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants'; import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants';
@ -36,31 +36,25 @@ export default {
type: Object, type: Object,
default: {}, default: {},
}, },
checkResult: {
type: Object,
default: {},
},
selectedImageInfo: { selectedImageInfo: {
type: Object, type: Object,
default: {}, default: {},
}, },
checkLoading: {
type: Boolean,
default: false,
},
}, },
emits: ['update:modelValue', 'filesChange', 'selectImage'], emits: ['update:modelValue', 'filesChange', 'selectImage', 'againCheck', 'startCheck'],
setup(props, { emit, expose }) { setup(props, { emit, expose }) {
const activeTab = ref(enumTab.TEXT); const activeTab = ref(enumTab.TEXT);
const aiCheckLoading = ref(false); const aiCheckLoading = ref(false);
const formRef = ref(null); const formRef = ref(null);
const uploadRef = ref(null); const uploadRef = ref(null);
const modules = [Navigation]; const modules = [Navigation];
const checkLoading = ref(false);
const tabList = computed(() => {
if (props.modelValue.type === EnumManuscriptType.Image) {
return TAB_LIST;
}
return TAB_LIST.filter((item) => item.value !== enumTab.IMAGE);
});
const isTextTab = computed(() => activeTab.value === enumTab.TEXT); const isTextTab = computed(() => activeTab.value === enumTab.TEXT);
const aiReview = computed(() => props.modelValue.ai_review);
const onAiReplace = () => { const onAiReplace = () => {
if (aiCheckLoading.value) return; if (aiCheckLoading.value) return;
@ -71,15 +65,12 @@ export default {
}, 2000); }, 2000);
}; };
const onCheck = () => { const onAgainCheck = () => {
if (!isTextTab.value && !props.modelValue.files?.length) { if (!isTextTab.value && !props.modelValue.files?.length) {
AMessage.warning('请先上传需审核图片'); AMessage.warning('请先上传需审核图片');
return; return;
} }
checkLoading.value = true; emit('againCheck');
setTimeout(() => {
checkLoading.value = false;
}, 2000);
}; };
const onReplaceImage = () => { const onReplaceImage = () => {
uploadRef.value?.upload?.(); uploadRef.value?.upload?.();
@ -102,7 +93,6 @@ export default {
formRef.value?.resetFields?.(); formRef.value?.resetFields?.();
formRef.value?.clearValidate?.(); formRef.value?.clearValidate?.();
aiCheckLoading.value = false; aiCheckLoading.value = false;
checkLoading.value = false;
}; };
const getFileExtension = (filename) => { const getFileExtension = (filename) => {
const match = filename.match(/\.([^.]+)$/); const match = filename.match(/\.([^.]+)$/);
@ -180,7 +170,7 @@ export default {
const renderFooterRow = () => { const renderFooterRow = () => {
return ( return (
<> <>
<Button class="mr-12px" size="medium" onClick={onCheck}> <Button class="mr-12px" size="medium" onClick={onAgainCheck}>
再次审核 再次审核
</Button> </Button>
{isTextTab.value ? ( {isTextTab.value ? (
@ -220,7 +210,7 @@ export default {
size="large" size="large"
maxLength={30} maxLength={30}
show-word-limit show-word-limit
disabled={checkLoading.value} disabled={props.checkLoading}
/> />
</FormItem> </FormItem>
<FormItem label="作品描述" field="content" class="flex-1 content-form-item"> <FormItem label="作品描述" field="content" class="flex-1 content-form-item">
@ -231,7 +221,7 @@ export default {
show-word-limit show-word-limit
maxLength={1000} maxLength={1000}
show-word-limit show-word-limit
disabled={checkLoading.value} disabled={props.checkLoading}
/> />
</FormItem> </FormItem>
</Form> </Form>
@ -322,7 +312,7 @@ export default {
}; };
const renderRightBox = () => { const renderRightBox = () => {
if (checkLoading.value) { if (props.checkLoading) {
return ( return (
<div class="right-box flex-1 h-210px rounded-8px border-1px border-#E6E6E8 border-solid p-16px flex flex-col overflow-y-auto"> <div class="right-box flex-1 h-210px rounded-8px border-1px border-#E6E6E8 border-solid p-16px flex flex-col overflow-y-auto">
<p class="cts bold !text-16px !lh-24px !color-#211F24 mb-16px">审核结果</p> <p class="cts bold !text-16px !lh-24px !color-#211F24 mb-16px">审核结果</p>
@ -330,14 +320,14 @@ export default {
</div> </div>
); );
} else { } else {
if (isEmpty(props.checkResult)) { if (!aiReview.value?.violation_items?.length) {
return ( return (
<div class="right-box flex-1 h-372px rounded-8px border-1px border-#E6E6E8 border-solid p-16px flex flex-col overflow-y-auto"> <div class="right-box flex-1 h-372px rounded-8px border-1px border-#E6E6E8 border-solid p-16px flex flex-col overflow-y-auto">
<p class="cts bold !text-16px !lh-24px !color-#211F24 mb-16px">审核结果</p> <p class="cts bold !text-16px !lh-24px !color-#211F24 mb-16px">审核结果</p>
<div class="flex items-center mb-16px"> <div class="flex items-center mb-16px">
{RESULT_LIST.map((item, index) => ( {RESULT_LIST.map((item, index) => (
<div class="flex flex-col justify-center items-center flex-1 result-item" key={index}> <div class="flex flex-col justify-center items-center flex-1 result-item" key={index}>
<span class={`s1 ${item.class}`}>30</span> <span class={`s1 ${item.class}`}>{aiReview.value?.[item.value]}</span>
<span class="cts mt-4px !lh-20px !text-12px !color-#737478">{item.label}</span> <span class="cts mt-4px !lh-20px !text-12px !color-#737478">{item.label}</span>
</div> </div>
))} ))}
@ -364,7 +354,9 @@ export default {
<div class="flex items-center mb-16px"> <div class="flex items-center mb-16px">
{RESULT_LIST.map((item, index) => ( {RESULT_LIST.map((item, index) => (
<div class="flex flex-col justify-center items-center flex-1 result-item" key={index}> <div class="flex flex-col justify-center items-center flex-1 result-item" key={index}>
<span class={`s1 ${item.class}`}>30</span> <span class={`s1 color-#6d4cfe ${item.class}`}>{`${aiReview.value?.[item.value]}${
item.suffix || ''
}`}</span>
<span class="cts mt-4px !lh-20px !text-12px !color-#737478">{item.label}</span> <span class="cts mt-4px !lh-20px !text-12px !color-#737478">{item.label}</span>
</div> </div>
))} ))}
@ -374,7 +366,7 @@ export default {
<span class="ai-text">AI 审核建议</span> <span class="ai-text">AI 审核建议</span>
<img src={icon2} class="w-80px h-10.8px absolute bottom-1px left-1px" /> <img src={icon2} class="w-80px h-10.8px absolute bottom-1px left-1px" />
</div> </div>
{descs.map((item, index) => ( {aiReview.value?.suggestion?.map((item, index) => (
<p class="cts !color-#55585F !text-12px !lh-20px" key={index}>{`${index + 1}. ${item}`}</p> <p class="cts !color-#55585F !text-12px !lh-20px" key={index}>{`${index + 1}. ${item}`}</p>
))} ))}
</div> </div>
@ -382,16 +374,18 @@ export default {
<div class="forbid-word-box flex-1 flex"> <div class="forbid-word-box flex-1 flex">
<div class="left mr-32px w-56px"> <div class="left mr-32px w-56px">
<p class="mb-12px cts !text-12px">违禁词</p> <p class="mb-12px cts !text-12px">违禁词</p>
{forbidWords.map((item, index) => ( {aiReview.value?.violation_items?.map((item, index) => (
<p class={`mb-12px cts level${item.level}`} key={index}> <TextOverTips
{item.label} context={item.word}
</p> class={`mb-12px cts ${LEVEL_MAP.get(item.risk_level)?.class}`}
key={index}
/>
))} ))}
</div> </div>
<div class="right flex-1"> <div class="right flex-1 overflow-hidden">
<p class="mb-12px cts !text-12px">解释</p> <p class="mb-12px cts !text-12px">解释</p>
{forbidWords.map((item, index) => ( {aiReview.value?.violation_items?.map((item, index) => (
<TextOverTips context={item.desc} class="mb-12px" key={index} /> <TextOverTips context={item.reason} class="mb-12px" key={index} />
))} ))}
</div> </div>
</div> </div>
@ -405,44 +399,28 @@ export default {
reset, reset,
}); });
const descs = [
'删除 “效果炸裂”“医院都做不到” 等夸大对比的表述;',
'去掉 “顽固体质逆袭”“腰围小 10cm” 等具体效果承诺(食品 / 非药品不得宣称减肥等功效);',
'严禁提及 “孕妇能吃”,明确标注不适宜人群;',
'“进口纯天然” 需有依据,避免绝对化,可改为 “选用进口原料,成分温和”;',
'去掉 “当糖吃” 等误导性表述,强调正常食用量。',
];
const forbidWords = [
{
label: '纯天然',
desc: '涉嫌虚假内容相关词语',
level: 1,
},
{
label: '安全',
desc: '涉嫌绝对化承诺保证',
level: 2,
},
{
label: '副作用',
desc: '涉嫌夸大词语',
level: 3,
},
{
label: '副作用',
desc: '涉嫌夸大词语',
level: 3,
},
];
return () => { return () => {
return ( return (
<div class="h-full w-full px-24px pt-16px pb-24px content-wrap flex"> <div class="h-full w-full px-24px pt-16px pb-24px content-wrap flex">
<div class="flex-2 left-box mr-24px flex flex-col"> <div class="flex-2 left-box mr-24px flex flex-col">
<div class="flex-1 mb-12px rounded-8px border-1px pt-8px flex flex-col pb-16px bg-#F7F8FA border-#E6E6E8 border-solid"> <div class="flex-1 mb-12px rounded-8px border-1px pt-8px flex flex-col pb-16px bg-#F7F8FA border-#E6E6E8 border-solid">
<Tabs v-model={activeTab.value} onTabClick={handleTabClick} class="mb-16px"> <Tabs v-model={activeTab.value} onTabClick={handleTabClick} class="mb-16px">
{tabList.value.map((item) => ( {TAB_LIST.map((item) => (
<TabPane key={item.value} title={item.label}></TabPane> <TabPane
key={item.value}
v-slots={{
title: () => (
<div class="flex items-center relative">
<span>{item.label}</span>
{
activeTab.value === item.value && aiReview.value?.violation_items.length > 0 && (
<icon-exclamation-circle-fill size={14} class="color-#F64B31 absolute right--10px top-0" />
)
}
</div>
),
}}
/>
))} ))}
</Tabs> </Tabs>
<div class="flex-1 px-16px">{isTextTab.value ? renderTextForm() : renderImageForm()}</div> <div class="flex-1 px-16px">{isTextTab.value ? renderTextForm() : renderImageForm()}</div>

View File

@ -131,7 +131,6 @@
} }
.right-box { .right-box {
.s1 { .s1 {
color: var(--Brand-6, #6d4cfe);
font-family: $font-family-manrope-regular; font-family: $font-family-manrope-regular;
font-size: 24px; font-size: 24px;
font-style: normal; font-style: normal;
@ -175,14 +174,16 @@
line-height: 22px; line-height: 22px;
} }
.forbid-word-box { .forbid-word-box {
.level1 { :deep(.overflow-text) {
color: #6d4cfe; &.level0 {
} color: #6d4cfe;
.level2 { }
color: #f64b31; &.level2 {
} color: #f64b31;
.level3 { }
color: #ffae00; &.level1 {
color: #ffae00;
}
} }
} }
} }

View File

@ -7,6 +7,7 @@ import ContentCard from './components/content-card';
import CheckListDrawer from './components/check-list-drawer'; import CheckListDrawer from './components/check-list-drawer';
import { slsWithCatch, rlsWithCatch, glsWithCatch } from '@/utils/stroage.ts'; import { slsWithCatch, rlsWithCatch, glsWithCatch } from '@/utils/stroage.ts';
import useGetAiReviewResult from '@/hooks/useGetAiReviewResult.ts';
import { import {
patchWorkAuditsAudit, patchWorkAuditsAudit,
patchWorkAuditsBatchAudit, patchWorkAuditsBatchAudit,
@ -14,6 +15,7 @@ import {
putWorkAuditsAuditPass, putWorkAuditsAuditPass,
getWorkAuditsDetail, getWorkAuditsDetail,
getWorkAuditsBatchDetail, getWorkAuditsBatchDetail,
postWorkAuditsAiReview,
} from '@/api/all/generationWorkshop.ts'; } from '@/api/all/generationWorkshop.ts';
export default { export default {
@ -30,11 +32,18 @@ export default {
const submitLoading = ref(false); const submitLoading = ref(false);
const contentCardRef = ref(null); const contentCardRef = ref(null);
const checkListDrawerRef = ref(null); const checkListDrawerRef = ref(null);
const checkResult = ref({});
const selectCardInfo = ref({}); const selectCardInfo = ref({});
const selectedImageInfo = ref(null); const selectedImageInfo = ref(null);
const { handleStartCheck, handleAgainCheck, ticket, checkLoading } = useGetAiReviewResult({
cardInfo: selectCardInfo,
updateAiReview(ai_review) {
console.log('updateAiReview', ai_review);
selectCardInfo.value.ai_review = ai_review;
},
});
const onBack = () => { const onBack = () => {
router.push({ name: 'ManuscriptCheckList' }); router.push({ name: 'ManuscriptCheckList' });
}; };
@ -43,9 +52,16 @@ export default {
contentCardRef.value.reset(); contentCardRef.value.reset();
isSaved.value = false; isSaved.value = false;
submitLoading.value = false; submitLoading.value = false;
checkResult.value = {}; checkLoading.value = false;
ticket.value = '';
const { files = [], ai_review } = item;
selectCardInfo.value = cloneDeep(item); selectCardInfo.value = cloneDeep(item);
selectedImageInfo.value = cloneDeep(item.files?.[0] ?? {}); selectedImageInfo.value = cloneDeep(files?.[0] ?? {});
if (isEmpty(ai_review)) {
handleStartCheck();
}
}; };
const onCardClick = async (item) => { const onCardClick = async (item) => {
@ -71,8 +87,16 @@ export default {
dataSource.value = _data; dataSource.value = _data;
remoteDataSource.value = cloneDeep(_data); remoteDataSource.value = cloneDeep(_data);
selectCardInfo.value = cloneDeep(_data?.[0] ?? {});
selectedImageInfo.value = cloneDeep(_data?.[0].files?.[0] ?? {}); const _firstCard = _data?.[0] ?? {};
const { id, ai_review } = _firstCard;
selectCardInfo.value = cloneDeep(_firstCard);
selectedImageInfo.value = cloneDeep(_firstCard.files?.[0] ?? {});
if (isEmpty(ai_review)) {
handleStartCheck();
}
} }
}; };
@ -135,6 +159,10 @@ export default {
const onFilesChange = (files) => { const onFilesChange = (files) => {
selectCardInfo.value.files = cloneDeep(files); selectCardInfo.value.files = cloneDeep(files);
}; };
const onAgainCheck = () => {
handleAgainCheck();
};
const renderFooterRow = () => { const renderFooterRow = () => {
return ( return (
<> <>
@ -190,10 +218,12 @@ export default {
ref={contentCardRef} ref={contentCardRef}
v-model={selectCardInfo.value} v-model={selectCardInfo.value}
selectCardInfo={selectCardInfo.value} selectCardInfo={selectCardInfo.value}
checkResult={checkResult.value}
onFilesChange={onFilesChange} onFilesChange={onFilesChange}
selectedImageInfo={selectedImageInfo.value} selectedImageInfo={selectedImageInfo.value}
onSelectImage={onSelectImage} onSelectImage={onSelectImage}
checkLoading={checkLoading.value}
onAgainCheck={onAgainCheck}
onStartCheck={handleStartCheck}
/> />
</section> </section>
</div> </div>