diff --git a/src/axios.js b/src/axios.js index cd29fa6..9064c7d 100644 --- a/src/axios.js +++ b/src/axios.js @@ -223,7 +223,10 @@ axios.interceptors.response.use( }, error => { NProgress.done(); - return Promise.reject(new Error(error)); + // 保留原始 axios 错误对象:下游(如导入失败明细解析)需要 error.response + // 读取响应体。若包装成 new Error(error),response 会丢失、message 退化成 + // "[object Object]",用户只能看到无意义的通用提示。 + return Promise.reject(error); } ); diff --git a/src/utils/import-excel.js b/src/utils/import-excel.js index 425d5df..2e5126e 100644 --- a/src/utils/import-excel.js +++ b/src/utils/import-excel.js @@ -28,6 +28,34 @@ const parseBlobJson = async blob => { return text ? JSON.parse(text) : {}; }; +/** + * 解析导入失败时的错误提示文案。 + * + * 背景:导入接口统一用 `responseType: 'blob'` 请求,因此**非 2xx 响应体也是 Blob**。 + * axios 的错误分支不做解析,直接 reject,`error.message` 只有 + * 「Request failed with status code 400」这类通用文案(或全局兜底的「系统错误」), + * 用户会误以为系统崩了——而后端其实已返回了明确的中文业务提示(如「导入数据不能为空」)。 + * + * 这里补上这一步:从错误响应的 Blob 里取出后端 `msg`,取不到再退回通用文案。 + */ +const resolveErrorMessage = async error => { + const blob = error?.response?.data ?? error?.data; + if (blob instanceof Blob) { + try { + const result = await parseBlobJson(blob); + if (result?.msg) return result.msg; + } catch (ignored) { + // 响应体不是 JSON(如网关返回的 HTML 错误页),退回通用文案 + } + } + const fallback = error?.response?.data?.msg || error?.message; + // axios 的英文通用文案对用户没有意义,统一换成中文提示 + if (!fallback || /Request failed with status code/i.test(fallback)) { + return '导入失败,请检查导入文件后重试'; + } + return fallback; +}; + /** * 加工后端返回的导入失败明细 Excel。 * 若传入 failDetailDecorator(函数),则动态加载 exceljs 读取 blob 流, @@ -125,7 +153,7 @@ export const handleImportExcel = async (vm, option, column, businessName, onSucc option.onSuccess(res); } } catch (error) { - vm.$message.error(error.message || '导入失败'); + vm.$message.error(await resolveErrorMessage(error)); if (typeof option.onError === 'function') { option.onError(error); }