import type { VNodeChild } from 'vue';
|
|
import { h } from 'vue';
|
|
import { message, Modal } from 'ant-design-vue';
|
|
export interface ImportResultNotifyOptions {
|
/** 业务主体,用于拼标题与建议,如「设备」「客户」 */
|
subject: string;
|
/** 新增成功的条数 */
|
createCount?: number;
|
/** 更新成功的条数 */
|
updateCount?: number;
|
/** 失败明细:key 为编码/名称,value 为后端失败原因 */
|
failures?: null | Record<string, string>;
|
/** 「不存在」类失败的落点提示,如「【设备类型】【车间】【工作站】中的对应编码」 */
|
masterDataHint?: string;
|
}
|
|
/**
|
* 统一展示 Excel 导入结果。
|
*
|
* 只要后端返回了失败明细,就绝不能再提示「操作成功」——改为弹窗逐行列出失败原因,
|
* 并按失败原因给出下一步动作;全部成功时才提示成功。
|
*
|
* 失败明细可能上百行,所以用弹窗(弹窗内列表可滚动),避免长消息糊满屏幕。
|
*
|
* @returns 实际写入的条数(新增 + 更新),供调用方决定是否需要刷新列表
|
*/
|
export function notifyImportResult(
|
options: ImportResultNotifyOptions,
|
): number {
|
const {
|
subject,
|
createCount = 0,
|
updateCount = 0,
|
failures,
|
masterDataHint,
|
} = options;
|
const failureEntries = Object.entries(failures ?? {});
|
const importedCount = createCount + updateCount;
|
|
if (failureEntries.length === 0) {
|
message.success(`导入成功:新增 ${createCount} 条,更新 ${updateCount} 条`);
|
return importedCount;
|
}
|
|
const hints = buildFailureHints(
|
failureEntries.map(([, reason]) => reason),
|
{ subject, masterDataHint },
|
);
|
|
const content: VNodeChild = h('div', [
|
h(
|
'div',
|
`新增成功 ${createCount} 条,更新成功 ${updateCount} 条,失败 ${failureEntries.length} 条。`,
|
),
|
h(
|
'div',
|
{
|
class:
|
'mt-2 max-h-72 overflow-y-auto rounded border border-solid border-gray-200 px-3 py-2 text-sm leading-6',
|
},
|
failureEntries.map(([name, reason]) =>
|
h('div', { class: 'py-0.5' }, `${name}:${reason}`),
|
),
|
),
|
...hints.map((hint) =>
|
h('div', { class: 'mt-2 text-red-500' }, hint),
|
),
|
]);
|
|
const openModal = importedCount === 0 ? Modal.error : Modal.warning;
|
openModal({
|
title:
|
importedCount === 0
|
? `${subject}导入失败:${failureEntries.length} 行全部未导入`
|
: `导入完成:成功 ${importedCount} 条,失败 ${failureEntries.length} 条`,
|
content,
|
width: 680,
|
centered: true,
|
okText: '知道了',
|
});
|
return importedCount;
|
}
|
|
/** 按失败原因归纳下一步动作,避免用户只看到「失败」却不知道改哪里 */
|
function buildFailureHints(
|
reasons: string[],
|
{
|
subject,
|
masterDataHint,
|
}: Pick<ImportResultNotifyOptions, 'masterDataHint' | 'subject'>,
|
): string[] {
|
const hints = new Set<string>();
|
for (const reason of reasons) {
|
if (reason.includes('不存在')) {
|
hints.add(
|
`提示「不存在」的:请先维护好${masterDataHint ?? '对应主数据'},或把 Excel 中的值改成已存在的,再重新导入。`,
|
);
|
} else if (reason.includes('已经存在') || reason.includes('已存在')) {
|
hints.add(
|
`提示「已存在」的:请修改 Excel 中的${subject}名称或编码,或勾选「支持更新」后重新导入以覆盖已有数据。`,
|
);
|
} else if (reason.includes('不能为空') || reason.includes('为空')) {
|
hints.add('提示「不能为空」的:请补齐 Excel 中对应列的内容后重新导入。');
|
}
|
}
|
return [...hints];
|
}
|