import type { VNodeChild } from 'vue';
|
|
import { h } from 'vue';
|
|
import { message, notification } 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 nodes: VNodeChild[] = [
|
h(
|
'div',
|
`新增成功 ${createCount} 条,更新成功 ${updateCount} 条,失败 ${failureEntries.length} 条:`,
|
),
|
...failureEntries.map(([name, reason]) => h('div', `${name}:${reason}`)),
|
...buildFailureHints(failureEntries.map(([, reason]) => reason), {
|
subject,
|
masterDataHint,
|
}).map((hint) => h('div', { class: 'mt-2 text-red-500' }, hint)),
|
];
|
|
const notify = importedCount === 0 ? notification.error : notification.warning;
|
notify({
|
message:
|
importedCount === 0
|
? `${subject}导入失败:${failureEntries.length} 行全部未导入`
|
: `导入完成,部分${subject}导入失败(成功 ${importedCount} 条 / 失败 ${failureEntries.length} 条)`,
|
description: () => h('div', nodes),
|
duration: null,
|
});
|
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];
|
}
|