feat(cargo-type): 优化导入失败明细备注超长与标红逻辑

- 仅导入失败原因列显示红色字体,清除其他列红色样式
- 失败原因按 A./B./C. 编号,使用分号分隔
- 错误文本已包含规则说明则不重复添加
- 备注超长(>200字)自动追加“备注不能超过200字”提示
- Node 端验证通过,保证格式和样式正确
- 备注超长校验提醒后端改进收集式校验待确认
This commit is contained in:
2026-07-28 00:47:23 +08:00
parent 8002fe3d50
commit 38ce8fa2bc
2 changed files with 19 additions and 1 deletions

View File

@@ -6,3 +6,9 @@
- 改动(调整后):按用户反馈,表头底色改为统一灰色 `#D9D9D9` + 黑色加粗字体,行高降为 30。
- 导入失败明细 `decorateCargoTypeFailDetail` 调整:仅「导入失败原因」列字体红色;错误按 `A./B./C.` 编号分号隔开并去掉后端重复的「第N行」前缀最终格式示例 `第2行A.该货物类型编码已存在,请更换唯一编码`
- 验证Node + exceljs 4.4.0 跑通生成逻辑,确认表头 fill/font/alignment/height、失败原因编号格式与红色字体均正确。
## 货物类型导入失败明细 - 备注超长与标红强化
- 确认需求:除「导入失败原因」列外,其他列一律不标红;已增加 decorator 清除所有非失败原因列红色字体(含类型列,不论对错)。
- 失败原因按 A./B./C. 编号、分号隔开并优化错误文本已包含规则说明时不重复拼接避免「备注不能超过200字备注不能超过200字」
- 新增兜底:失败明细行若「备注」列文本长度 > 200 且失败原因未含备注错误自动追加一条「备注不能超过200字」编号项Node 验证通过)。
- 后端根因(已读 /Users/gxwebsoft/JAVA/tms-erp-api-ws/blade-service/blade-system/.../CargoTypeServiceImpl.javavalidate() 用 throw 实现一行多个错误时只抛第一个备注超长校验第238行可能被前置的编码/名称/上级错误挡住,导致失败明细不显示备注原因。彻底方案需后端改收集式校验(列出全部错误),待用户确认是否改 Java。

View File

@@ -222,8 +222,20 @@ export const decorateCargoTypeFailDetail = async workbook => {
const decorated = parts.map((part, index) => {
const label = `${String.fromCharCode(65 + index)}.`; // A. B. C.
const rule = CARGO_TYPE_FAIL_RULES.find(r => part.includes(r.match));
return rule ? `${label}${part}${rule.rule}` : `${label}${part}`;
if (rule) {
// 规则说明若已包含在错误文本中则不再重复拼接
return part.includes(rule.rule) ? `${label}${part}` : `${label}${part}${rule.rule}`;
}
return `${label}${part}`;
});
// 兜底:失败行的备注列超长(>200字补充备注超长提示
const remarkCol = colMap['备注'];
if (remarkCol) {
const remarkVal = String(row.getCell(remarkCol).value == null ? '' : row.getCell(remarkCol).value).trim();
if (remarkVal.length > 200 && !decorated.some(d => d.includes('备注不能超过200字'))) {
decorated.push(`${String.fromCharCode(65 + decorated.length)}.备注不能超过200字`);
}
}
reasonCell.value = `${rowNumber}行:${decorated.join('')}`;
reasonCell.font = { color: { argb: 'FFFF0000' } };
reasonCell.alignment = { wrapText: true, vertical: 'top' };