From dc430b3d962c76322710813b4175549afe2ad37c Mon Sep 17 00:00:00 2001 From: wsm <2746563060@qq.com> Date: Wed, 24 Jun 2026 10:10:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(xispeak):=20=E6=A8=A1=E6=9D=BF=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E6=A0=A1=E9=AA=8C=E5=A4=B1=E8=B4=A5=E6=97=B6=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E5=B1=95=E7=A4=BA=E9=80=90=E8=A1=8C=E5=85=B7=E4=BD=93?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- src/utils/helper/importError.ts | 53 ++++++++++++++++++++++++++ src/views/bg/xispeak/BgXiSpeakList.vue | 7 +++- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/utils/helper/importError.ts diff --git a/src/utils/helper/importError.ts b/src/utils/helper/importError.ts new file mode 100644 index 0000000..39f7c32 --- /dev/null +++ b/src/utils/helper/importError.ts @@ -0,0 +1,53 @@ +import { h } from 'vue'; +import { Modal } from 'ant-design-vue'; + +interface ValidationError { + row: number; + messages: string[]; +} + +const STYLES = { + wrapper: 'max-height: 450px; overflow-y: auto;', + hint: 'color: #666; margin-bottom: 12px;', + table: 'width: 100%; border-collapse: collapse; font-size: 13px;', + th: 'padding: 8px; border: 1px solid #e8e8e8; text-align: center; background: #fafafa;', + thRow: 'width: 80px;', + tdRow: 'padding: 8px; border: 1px solid #e8e8e8; text-align: center; vertical-align: top; color: #ff4d4f; font-weight: 500;', + tdMsg: 'padding: 8px; border: 1px solid #e8e8e8; vertical-align: top;', + ul: 'margin: 0; padding-left: 18px;', + li: 'line-height: 1.7; color: #333;', +}; + +export function showImportValidationErrors(title: string, errors: ValidationError[]) { + Modal.error({ + title, + width: 720, + content: h('div', { style: STYLES.wrapper }, [ + h('p', { style: STYLES.hint }, '以下行数据校验不通过,请修改后重新导入:'), + h('table', { style: STYLES.table }, [ + h('thead', null, [ + h('tr', null, [ + h('th', { style: STYLES.th + STYLES.thRow }, '行号'), + h('th', { style: STYLES.th }, '错误信息'), + ]), + ]), + h( + 'tbody', + null, + errors.map((err) => + h('tr', { key: err.row }, [ + h('td', { style: STYLES.tdRow }, err.row), + h('td', { style: STYLES.tdMsg }, [ + h( + 'ul', + { style: STYLES.ul }, + err.messages.map((msg, i) => h('li', { key: i, style: STYLES.li }, msg)), + ), + ]), + ]), + ), + ), + ]), + ]), + }); +} diff --git a/src/views/bg/xispeak/BgXiSpeakList.vue b/src/views/bg/xispeak/BgXiSpeakList.vue index 7986aee..8cd33cd 100644 --- a/src/views/bg/xispeak/BgXiSpeakList.vue +++ b/src/views/bg/xispeak/BgXiSpeakList.vue @@ -94,6 +94,7 @@ import { useModal } from '/@/components/Modal'; import { defHttp } from '/@/utils/http/axios'; import { useMessage } from '/@/hooks/web/useMessage'; + import { showImportValidationErrors } from '/@/utils/helper/importError'; import { startProcessSchedules } from '/@/api/common/api'; import { dateUtil } from '/@/utils/dateUtil'; @@ -755,7 +756,11 @@ import { defHttp } from '/@/utils/http/axios'; const isReturn = (fileInfo) => { try { if (fileInfo.code === 500 || fileInfo.code === 510) { - createMessage.error(fileInfo.message || `${data.file.name} 导入失败`); + if (fileInfo.result && Array.isArray(fileInfo.result) && fileInfo.result.length > 0) { + showImportValidationErrors(fileInfo.message || `${data.file.name} 导入失败`, fileInfo.result); + } else { + createMessage.error(fileInfo.message || `${data.file.name} 导入失败`); + } } else { createMessage.success(fileInfo.message || `${data.file.name} 导入成功`); }