@skyfox2000/webui 1.3.10 → 1.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/assets/modules/{index-B_XPl41L.js → index-Dd8HdGOL.js} +66 -63
- package/lib/es/ExcelForm/index.js +109 -110
- package/lib/utils/form-excel.d.ts +2 -1
- package/lib/webui.es.js +2 -2
- package/package.json +1 -1
- package/src/components/content/dialog/excelForm.vue +12 -13
- package/src/utils/form-excel.ts +18 -8
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { httpPost as
|
|
1
|
+
import S from "async-validator";
|
|
2
|
+
import { httpPost as M, ResStatus as V } from "@skyfox2000/fapi";
|
|
3
3
|
import { i as T, ag as $ } from "./uploadList-B4wb8I9a.js";
|
|
4
4
|
import m from "vue-m-message";
|
|
5
|
-
import { defineComponent as R, useAttrs as U, createElementBlock as z, openBlock as b, createVNode as B, unref as v, mergeProps as D, computed as E, createBlock as _, withCtx as
|
|
5
|
+
import { defineComponent as R, useAttrs as U, createElementBlock as z, openBlock as b, createVNode as B, unref as v, mergeProps as D, computed as E, createBlock as _, withCtx as O, normalizeStyle as A } from "vue";
|
|
6
6
|
import { Spin as N, Alert as L } from "ant-design-vue";
|
|
7
7
|
import { _ as K } from "./toolIcon-BSjgzw0G.js";
|
|
8
|
-
const
|
|
8
|
+
const j = (i) => {
|
|
9
9
|
const e = i.split(`
|
|
10
10
|
`).filter((c) => c.trim() !== "");
|
|
11
11
|
if (e.length === 0)
|
|
@@ -17,7 +17,7 @@ const H = (i) => {
|
|
|
17
17
|
return isNaN(t) ? o : t;
|
|
18
18
|
})), n = s[0].map((c) => String(c || "")), a = s.slice(1);
|
|
19
19
|
return { headers: n, rows: a };
|
|
20
|
-
},
|
|
20
|
+
}, H = async (i) => {
|
|
21
21
|
try {
|
|
22
22
|
const e = await import("exceljs"), s = new e.default.Workbook();
|
|
23
23
|
await s.xlsx.load(i);
|
|
@@ -33,7 +33,7 @@ const H = (i) => {
|
|
|
33
33
|
const t = [];
|
|
34
34
|
a.forEach((u, l) => {
|
|
35
35
|
const f = r.getCell(l + 1).value;
|
|
36
|
-
f != null ? typeof f == "object" ? "richText" in f && Array.isArray(f.richText) ? t.push(f.richText.map((
|
|
36
|
+
f != null ? typeof f == "object" ? "richText" in f && Array.isArray(f.richText) ? t.push(f.richText.map((h) => h.text || "").join("")) : "text" in f && typeof f.text == "string" ? t.push(f.text) : (f instanceof Date, t.push(f)) : t.push(f) : t.push(null);
|
|
37
37
|
}), c.push(t);
|
|
38
38
|
}
|
|
39
39
|
}), { headers: a, rows: c };
|
|
@@ -46,31 +46,31 @@ const H = (i) => {
|
|
|
46
46
|
if (r.length === 0)
|
|
47
47
|
throw new Error("数据为空");
|
|
48
48
|
const t = /* @__PURE__ */ new Map();
|
|
49
|
-
s != null && s.markCells && s.markCells.forEach(({ row:
|
|
50
|
-
const y = `${
|
|
51
|
-
t.set(y,
|
|
49
|
+
s != null && s.markCells && s.markCells.forEach(({ row: h, col: w, color: d }) => {
|
|
50
|
+
const y = `${h}-${w}`;
|
|
51
|
+
t.set(y, d || "FFFF0000");
|
|
52
52
|
});
|
|
53
53
|
const u = c.getRow(1);
|
|
54
|
-
r.forEach((
|
|
55
|
-
const
|
|
56
|
-
|
|
54
|
+
r.forEach((h, w) => {
|
|
55
|
+
const d = u.getCell(w + 1);
|
|
56
|
+
d.value = h, d.font = { bold: !0 }, d.fill = {
|
|
57
57
|
type: "pattern",
|
|
58
58
|
pattern: "solid",
|
|
59
59
|
fgColor: { argb: "FFE0E0E0" }
|
|
60
|
-
}, s != null && s.markHeaders && s.markHeaders.includes(
|
|
60
|
+
}, s != null && s.markHeaders && s.markHeaders.includes(h) && (d.fill = {
|
|
61
61
|
type: "pattern",
|
|
62
62
|
pattern: "solid",
|
|
63
63
|
fgColor: { argb: "FFFF0000" }
|
|
64
|
-
},
|
|
64
|
+
}, d.font = {
|
|
65
65
|
name: "Arial",
|
|
66
66
|
size: 10,
|
|
67
67
|
bold: !0,
|
|
68
68
|
color: { argb: "FFFFFFFF" }
|
|
69
69
|
});
|
|
70
|
-
}), o.forEach((
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
const F =
|
|
70
|
+
}), o.forEach((h, w) => {
|
|
71
|
+
const d = c.getRow(w + 2);
|
|
72
|
+
h.forEach((y, k) => {
|
|
73
|
+
const F = d.getCell(k + 1);
|
|
74
74
|
F.value = y;
|
|
75
75
|
const C = `${w + 2}-${k + 1}`;
|
|
76
76
|
t.has(C) && (F.fill = {
|
|
@@ -79,15 +79,15 @@ const H = (i) => {
|
|
|
79
79
|
fgColor: { argb: t.get(C) }
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
|
-
}), c.columns.forEach((
|
|
83
|
-
|
|
82
|
+
}), c.columns.forEach((h) => {
|
|
83
|
+
h.width = 15;
|
|
84
84
|
});
|
|
85
|
-
const l = await a.xlsx.writeBuffer(),
|
|
85
|
+
const l = await a.xlsx.writeBuffer(), p = new Blob([l], {
|
|
86
86
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
87
87
|
});
|
|
88
88
|
return {
|
|
89
89
|
success: !0,
|
|
90
|
-
blobUrl: URL.createObjectURL(
|
|
90
|
+
blobUrl: URL.createObjectURL(p),
|
|
91
91
|
fileName: e.replace(/\.(csv|xlsx?)$/i, ".xlsx")
|
|
92
92
|
};
|
|
93
93
|
} catch (n) {
|
|
@@ -98,7 +98,7 @@ const H = (i) => {
|
|
|
98
98
|
}
|
|
99
99
|
}, P = async (i, e) => {
|
|
100
100
|
try {
|
|
101
|
-
const s =
|
|
101
|
+
const s = j(i);
|
|
102
102
|
return await g(s, e);
|
|
103
103
|
} catch (s) {
|
|
104
104
|
return {
|
|
@@ -125,13 +125,13 @@ const H = (i) => {
|
|
|
125
125
|
}, q = async (i, e) => await g(i, e), ae = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
126
126
|
__proto__: null,
|
|
127
127
|
csvToExcelView: P,
|
|
128
|
-
csvToNormalized:
|
|
128
|
+
csvToNormalized: j,
|
|
129
129
|
excelToExcelView: W,
|
|
130
|
-
excelToNormalized:
|
|
130
|
+
excelToNormalized: H,
|
|
131
131
|
normalizedToExcelView: q,
|
|
132
132
|
toExcel: g
|
|
133
133
|
}, Symbol.toStringTag, { value: "Module" })), x = async (i) => {
|
|
134
|
-
const e = await
|
|
134
|
+
const e = await H(i);
|
|
135
135
|
if (e.headers.length === 0)
|
|
136
136
|
return m.error("Excel文件不包含工作表"), null;
|
|
137
137
|
const s = [];
|
|
@@ -170,7 +170,7 @@ const H = (i) => {
|
|
|
170
170
|
n.includes(t) || c.push(t);
|
|
171
171
|
}), n.length === 0 || a.length === 0)
|
|
172
172
|
return m.error("Excel文件不包含足够的数据"), { hasError: !0 };
|
|
173
|
-
const r = new
|
|
173
|
+
const r = new S({});
|
|
174
174
|
r.messages($.messages()), r.define(e);
|
|
175
175
|
const o = await Q(n, a, r);
|
|
176
176
|
return o.length > 0 || c.length > 0 ? {
|
|
@@ -194,7 +194,7 @@ const H = (i) => {
|
|
|
194
194
|
const o = [];
|
|
195
195
|
r.forEach((t) => {
|
|
196
196
|
const u = i.indexOf(t.field);
|
|
197
|
-
u >= 0 && (o.some((
|
|
197
|
+
u >= 0 && (o.some((p) => p.row === a && p.col === u) || o.push({
|
|
198
198
|
row: a,
|
|
199
199
|
col: u,
|
|
200
200
|
header: t.field,
|
|
@@ -218,29 +218,29 @@ const H = (i) => {
|
|
|
218
218
|
}), r.length > 0)
|
|
219
219
|
return m.error(`表头缺少重复检测所需字段: ${r.join(", ")}`), { hasError: !0 };
|
|
220
220
|
const o = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Set(), u = new Array();
|
|
221
|
-
if (c.forEach((l,
|
|
222
|
-
const f = e.map((
|
|
223
|
-
u.push(
|
|
224
|
-
const w = f.some((
|
|
225
|
-
w && o.has(
|
|
221
|
+
if (c.forEach((l, p) => {
|
|
222
|
+
const f = e.map((d) => l[d]), h = f.join("|");
|
|
223
|
+
u.push(h);
|
|
224
|
+
const w = f.some((d) => d != null && d !== "");
|
|
225
|
+
w && o.has(h) ? (t.add(p), t.add(o.get(h))) : w && o.set(h, p);
|
|
226
226
|
}), s) {
|
|
227
|
-
const l = await
|
|
227
|
+
const l = await M(s, {
|
|
228
228
|
Data: u
|
|
229
229
|
});
|
|
230
|
-
if (l != null && l.data && l.data.forEach((
|
|
231
|
-
t.add(
|
|
232
|
-
}), (l == null ? void 0 : l.status) ===
|
|
230
|
+
if (l != null && l.data && l.data.forEach((p) => {
|
|
231
|
+
t.add(p);
|
|
232
|
+
}), (l == null ? void 0 : l.status) === V.ERROR)
|
|
233
233
|
throw new Error(l.msg);
|
|
234
234
|
}
|
|
235
235
|
if (t.size > 0) {
|
|
236
236
|
const l = [];
|
|
237
|
-
return t.forEach((
|
|
237
|
+
return t.forEach((p) => {
|
|
238
238
|
e.forEach((f) => {
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
row:
|
|
239
|
+
const h = a.indexOf(f);
|
|
240
|
+
h >= 0 && l.push({
|
|
241
|
+
row: p + 2,
|
|
242
242
|
// Excel行号 = 数组索引 + 2(表头和1-based索引)
|
|
243
|
-
col:
|
|
243
|
+
col: h + 1,
|
|
244
244
|
// Excel列号 = 数组索引 + 1(1-based索引)
|
|
245
245
|
color: "FFA500"
|
|
246
246
|
// 黄橙色
|
|
@@ -255,19 +255,19 @@ const H = (i) => {
|
|
|
255
255
|
return { hasError: !1 };
|
|
256
256
|
}, ne = async (i, e, s, n) => {
|
|
257
257
|
const a = [], c = [];
|
|
258
|
-
let r = !1, o = !1, t = "数据验证成功", u = "
|
|
258
|
+
let r = !1, o = !1, t = "数据验证成功", u = "待验证重复数据";
|
|
259
259
|
const l = await G(i, e);
|
|
260
|
-
if (l.hasError
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
(
|
|
260
|
+
if (l.hasError ? (r = !0, t = "数据验证失败", l.markCells && a.push(...l.markCells), l.markHeaders && c.push(...l.markHeaders)) : e && Object.keys(e).length > 0 && (t = "数据验证通过"), s && s.length > 0) {
|
|
261
|
+
const f = await X(i, s, n);
|
|
262
|
+
f.hasError ? (o = !0, u = "检测到重复数据", f.markCells && f.markCells.forEach((h) => {
|
|
263
|
+
const w = a.find(
|
|
264
|
+
(d) => d.row === h.row && d.col === h.col
|
|
265
265
|
);
|
|
266
|
-
|
|
267
|
-
}),
|
|
266
|
+
w ? w.color = "8B0000" : a.push(h);
|
|
267
|
+
}), f.markHeaders && c.push(...f.markHeaders)) : u = "重复性检验通过";
|
|
268
268
|
}
|
|
269
269
|
if (r || o) {
|
|
270
|
-
const
|
|
270
|
+
const f = await J(
|
|
271
271
|
i,
|
|
272
272
|
{
|
|
273
273
|
markCells: a,
|
|
@@ -275,21 +275,24 @@ const H = (i) => {
|
|
|
275
275
|
},
|
|
276
276
|
"validation_errors.xlsx"
|
|
277
277
|
);
|
|
278
|
-
return
|
|
279
|
-
|
|
280
|
-
errBlob: await (await fetch(h.blobUrl)).blob(),
|
|
278
|
+
return f.success && f.blobUrl ? {
|
|
279
|
+
errBlob: await (await fetch(f.blobUrl)).blob(),
|
|
281
280
|
validationMsg: t,
|
|
282
|
-
duplicateMsg: u
|
|
281
|
+
duplicateMsg: u,
|
|
282
|
+
hasFormatError: r,
|
|
283
|
+
hasDuplicateError: o
|
|
283
284
|
} : {
|
|
284
|
-
hasError: !0,
|
|
285
285
|
validationMsg: t,
|
|
286
|
-
duplicateMsg: u
|
|
286
|
+
duplicateMsg: u,
|
|
287
|
+
hasFormatError: r,
|
|
288
|
+
hasDuplicateError: o
|
|
287
289
|
};
|
|
288
290
|
}
|
|
289
291
|
return {
|
|
290
|
-
hasError: !1,
|
|
291
292
|
validationMsg: t,
|
|
292
|
-
duplicateMsg: u
|
|
293
|
+
duplicateMsg: u,
|
|
294
|
+
hasFormatError: !1,
|
|
295
|
+
hasDuplicateError: !1
|
|
293
296
|
};
|
|
294
297
|
}, ce = async (i, e, s) => {
|
|
295
298
|
const n = i.originFileObj;
|
|
@@ -347,10 +350,10 @@ const H = (i) => {
|
|
|
347
350
|
type: u.type,
|
|
348
351
|
message: u.message
|
|
349
352
|
}, u.$attrs), {
|
|
350
|
-
icon:
|
|
353
|
+
icon: O(() => [
|
|
351
354
|
(b(), _(K, {
|
|
352
355
|
icon: r.value,
|
|
353
|
-
style:
|
|
356
|
+
style: A({ color: c.value }),
|
|
354
357
|
key: t.value
|
|
355
358
|
}, null, 8, ["icon", "style"]))
|
|
356
359
|
]),
|
|
@@ -364,8 +367,8 @@ export {
|
|
|
364
367
|
ce as b,
|
|
365
368
|
P as c,
|
|
366
369
|
J as d,
|
|
367
|
-
|
|
368
|
-
|
|
370
|
+
j as e,
|
|
371
|
+
H as f,
|
|
369
372
|
W as g,
|
|
370
373
|
le as h,
|
|
371
374
|
ne as i,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { defineComponent as we, ref as
|
|
1
|
+
import { defineComponent as we, ref as f, computed as T, watch as W, onMounted as be, createBlock as H, openBlock as d, unref as i, withCtx as S, renderSlot as J, createElementBlock as g, createCommentVNode as K, createElementVNode as h, createVNode as C, createTextVNode as X, toDisplayString as E, normalizeClass as Ce, Fragment as ie, renderList as ne } from "vue";
|
|
2
2
|
import { _ as Y } from "../../assets/modules/index-BRWQ6SRp.js";
|
|
3
3
|
import { Modal as Fe, Upload as ue, Space as _e } from "ant-design-vue";
|
|
4
4
|
import { httpGet as Ue, ResStatus as fe } from "@skyfox2000/fapi";
|
|
5
5
|
import { E as Te, a1 as Se, a7 as Ee } from "../../assets/modules/uploadList-B4wb8I9a.js";
|
|
6
6
|
import { A as Re, p as De, U as ce } from "../../assets/modules/file-upload-CwyUkWwi.js";
|
|
7
7
|
import "@skyfox2000/microbase";
|
|
8
|
-
import
|
|
9
|
-
import { c as ke, _ as Z, h as Le, p as Ne, i as Ke } from "../../assets/modules/index-
|
|
8
|
+
import p from "vue-m-message";
|
|
9
|
+
import { c as ke, _ as Z, h as Le, p as Ne, i as Ke } from "../../assets/modules/index-Dd8HdGOL.js";
|
|
10
10
|
import "dayjs";
|
|
11
11
|
import "vue-draggable-next";
|
|
12
12
|
import "async-validator";
|
|
@@ -54,7 +54,7 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
54
54
|
throw new Error("不支持的文件格式");
|
|
55
55
|
}, Pe = async (l, s) => {
|
|
56
56
|
if (!l || !s)
|
|
57
|
-
return
|
|
57
|
+
return p.error("预览URL或Excel控制器未配置"), { success: !1 };
|
|
58
58
|
try {
|
|
59
59
|
let e = null;
|
|
60
60
|
if (l.method === "GET") {
|
|
@@ -82,15 +82,15 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
82
82
|
} else
|
|
83
83
|
throw new Error((e == null ? void 0 : e.msg) || "文件加载失败");
|
|
84
84
|
} catch (e) {
|
|
85
|
-
throw console.error("预览文件加载错误:", e),
|
|
85
|
+
throw console.error("预览文件加载错误:", e), p.error("文件加载失败:" + ((e == null ? void 0 : e.message) || "未知错误")), e;
|
|
86
86
|
}
|
|
87
87
|
}, $e = {
|
|
88
88
|
key: 0,
|
|
89
89
|
class: "mb-4 flex items-center"
|
|
90
|
-
},
|
|
90
|
+
}, je = {
|
|
91
91
|
key: 0,
|
|
92
92
|
class: "ml-3 text-gray-600"
|
|
93
|
-
},
|
|
93
|
+
}, Ae = { class: "flex gap-4 relative" }, Oe = {
|
|
94
94
|
key: 1,
|
|
95
95
|
class: "w-[22%] flex-grow overflow-hidden flex flex-col"
|
|
96
96
|
}, Ge = { class: "bg-gray-50 p-2 rounded border flex-grow flex flex-col" }, Ie = {
|
|
@@ -120,7 +120,7 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
120
120
|
fileType: {}
|
|
121
121
|
},
|
|
122
122
|
setup(l, { expose: s }) {
|
|
123
|
-
const e = l, a = e.excelCtrl, m =
|
|
123
|
+
const e = l, a = e.excelCtrl, m = f(!1), b = f(""), le = f([]), y = f(""), z = T(() => !!e.previewUrl), te = T(() => e.enableUpload), de = T(() => {
|
|
124
124
|
switch (e.fileType || "both") {
|
|
125
125
|
case "excel":
|
|
126
126
|
return ".xlsx,.xls";
|
|
@@ -130,7 +130,7 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
130
130
|
default:
|
|
131
131
|
return ".xlsx,.xls,.csv";
|
|
132
132
|
}
|
|
133
|
-
}), pe =
|
|
133
|
+
}), pe = T(() => {
|
|
134
134
|
switch (e.fileType || "both") {
|
|
135
135
|
case "excel":
|
|
136
136
|
return "请选择Excel文件";
|
|
@@ -140,16 +140,16 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
140
140
|
default:
|
|
141
141
|
return "请选择Excel或CSV文件";
|
|
142
142
|
}
|
|
143
|
-
}), V =
|
|
143
|
+
}), V = f("待验证数据规则"), B = f("warning"), P = f("待验证重复数据"), $ = f("warning");
|
|
144
144
|
W(
|
|
145
145
|
() => a.visible.value,
|
|
146
146
|
() => {
|
|
147
|
-
m.value = a.visible.value, m.value && (
|
|
147
|
+
m.value = a.visible.value, m.value && (A(), e.previewUrl && I());
|
|
148
148
|
}
|
|
149
149
|
), W(
|
|
150
150
|
() => m.value,
|
|
151
151
|
() => {
|
|
152
|
-
a.visible.value = m.value, m.value ||
|
|
152
|
+
a.visible.value = m.value, m.value || A();
|
|
153
153
|
}
|
|
154
154
|
), W(
|
|
155
155
|
() => e.previewUrl,
|
|
@@ -158,13 +158,13 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
158
158
|
},
|
|
159
159
|
{ deep: !0 }
|
|
160
160
|
);
|
|
161
|
-
const F =
|
|
161
|
+
const F = f(e.uploadParams), R = T(() => {
|
|
162
162
|
var t;
|
|
163
163
|
return (t = F.value) == null ? void 0 : t.uploadUrl;
|
|
164
|
-
}),
|
|
164
|
+
}), _ = T(() => {
|
|
165
165
|
var t;
|
|
166
166
|
return (t = F.value) == null ? void 0 : t.duplicateRules;
|
|
167
|
-
}), D =
|
|
167
|
+
}), D = T(() => {
|
|
168
168
|
var t;
|
|
169
169
|
return (t = F.value) == null ? void 0 : t.duplicateUrl;
|
|
170
170
|
}), I = async () => {
|
|
@@ -172,7 +172,7 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
172
172
|
a.isFormLoading.value = !0;
|
|
173
173
|
try {
|
|
174
174
|
const t = await Pe(e.previewUrl, a);
|
|
175
|
-
t.success && (
|
|
175
|
+
t.success && (b.value = t.blobUrl, y.value = t.fileName);
|
|
176
176
|
} finally {
|
|
177
177
|
setTimeout(() => {
|
|
178
178
|
a.isFormLoading.value = !1;
|
|
@@ -184,36 +184,36 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
184
184
|
F.value = e.uploadParams;
|
|
185
185
|
const t = R.value;
|
|
186
186
|
if (!t) {
|
|
187
|
-
|
|
187
|
+
p.error("未配置文件上传地址!");
|
|
188
188
|
return;
|
|
189
189
|
}
|
|
190
|
-
if (
|
|
191
|
-
|
|
190
|
+
if (U.value) {
|
|
191
|
+
p.error("表格数据存在验证错误,请修正后再上传!");
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
194
194
|
a.isFormSaving.value = !0;
|
|
195
195
|
try {
|
|
196
196
|
if (!L.value || !y.value) {
|
|
197
|
-
|
|
197
|
+
p.warning("请先选择文件!"), a.isFormSaving.value = !1;
|
|
198
198
|
return;
|
|
199
199
|
}
|
|
200
200
|
const r = new Re(t, 1), u = q.value || "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", n = new File([L.value], y.value, {
|
|
201
201
|
type: u
|
|
202
|
-
}),
|
|
202
|
+
}), c = De.join(((o = F.value) == null ? void 0 : o.basePath) ?? "", y.value), v = {
|
|
203
203
|
uid: "1",
|
|
204
204
|
name: y.value,
|
|
205
205
|
originFileObj: n,
|
|
206
206
|
status: ce.Uploading,
|
|
207
207
|
percent: 0,
|
|
208
208
|
params: {
|
|
209
|
-
FileKey:
|
|
209
|
+
FileKey: c
|
|
210
210
|
}
|
|
211
|
-
},
|
|
212
|
-
(await r.uploadFile(
|
|
213
|
-
|
|
214
|
-
})).status === ce.Success && (
|
|
211
|
+
}, x = new AbortController();
|
|
212
|
+
(await r.uploadFile(v, x.signal, (w) => {
|
|
213
|
+
v.percent = w;
|
|
214
|
+
})).status === ce.Success && (p.success("文件上传成功,开始业务处理!"), ye(v));
|
|
215
215
|
} catch (r) {
|
|
216
|
-
console.error("上传处理错误:", r),
|
|
216
|
+
console.error("上传处理错误:", r), p.error("上传处理失败:" + ((r == null ? void 0 : r.message) || "未知错误"));
|
|
217
217
|
} finally {
|
|
218
218
|
a.isFormSaving.value = !1;
|
|
219
219
|
}
|
|
@@ -222,16 +222,16 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
222
222
|
if (e.excelRecordsKey || e.excelRowsKey) {
|
|
223
223
|
const n = await Ne(L.value);
|
|
224
224
|
if (!n) return null;
|
|
225
|
-
const { excelData:
|
|
225
|
+
const { excelData: c, excelRows: v } = n, x = c.map((N) => {
|
|
226
226
|
var Q;
|
|
227
|
-
const
|
|
227
|
+
const w = {};
|
|
228
228
|
for (const O in N) {
|
|
229
229
|
const G = (Q = e.excelFieldMap) == null ? void 0 : Q[O];
|
|
230
|
-
G && (
|
|
230
|
+
G && (w[G] = N[O]);
|
|
231
231
|
}
|
|
232
|
-
return
|
|
232
|
+
return w;
|
|
233
233
|
});
|
|
234
|
-
e.excelRecordsKey && (a.formData.value[e.excelRecordsKey] =
|
|
234
|
+
e.excelRecordsKey && (a.formData.value[e.excelRecordsKey] = x), e.excelRowsKey && (a.formData.value[e.excelRowsKey] = v);
|
|
235
235
|
}
|
|
236
236
|
const o = e.fileField ?? "FileInfo";
|
|
237
237
|
a.formData.value[o] = t;
|
|
@@ -254,82 +254,81 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
254
254
|
});
|
|
255
255
|
(n == null ? void 0 : n.status) === fe.SUCCESS && (a.afterSave && a.afterSave(), a.visible.value = !1);
|
|
256
256
|
} catch (n) {
|
|
257
|
-
console.error("保存错误:", n),
|
|
257
|
+
console.error("保存错误:", n), p.error("数据保存失败,请稍后再试!");
|
|
258
258
|
} finally {
|
|
259
259
|
a.isFormSaving.value = !1;
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
|
-
},
|
|
262
|
+
}, U = f(!1), k = f(!1), L = f(null), q = f(""), re = async (t) => {
|
|
263
263
|
const o = e.gridCtrl;
|
|
264
264
|
if (o) {
|
|
265
265
|
F.value = e.uploadParams;
|
|
266
266
|
try {
|
|
267
267
|
D.value && (D.value.api || (D.value.api = o.page.api), D.value.authorize === void 0 && (D.value.authorize = o.page.authorize));
|
|
268
268
|
const {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
269
|
+
errBlob: r,
|
|
270
|
+
validationMsg: u,
|
|
271
|
+
duplicateMsg: n,
|
|
272
|
+
hasFormatError: c,
|
|
273
|
+
hasDuplicateError: v
|
|
274
|
+
} = await Ke(t, a.formRules.value, _.value, D.value);
|
|
275
|
+
if (V.value = u, P.value = n, B.value = c ? "error" : a.formRules.value && Object.keys(a.formRules.value).length > 0 ? "success" : "warning", $.value = v ? "error" : _.value && _.value.length > 0 ? "success" : "warning", r) {
|
|
276
|
+
U.value = c ?? !1, k.value = v ?? !1;
|
|
277
|
+
const x = URL.createObjectURL(r);
|
|
278
|
+
b.value = x;
|
|
280
279
|
} else
|
|
281
|
-
|
|
280
|
+
U.value = !1, k.value = !1;
|
|
282
281
|
} catch {
|
|
283
|
-
V.value = "验证异常",
|
|
282
|
+
V.value = "验证异常", P.value = "验证异常", B.value = "error", $.value = "error";
|
|
284
283
|
}
|
|
285
284
|
}
|
|
286
285
|
}, xe = async (t) => {
|
|
287
286
|
if (!e.gridCtrl) {
|
|
288
|
-
|
|
287
|
+
p.error("未配置表格控制器!");
|
|
289
288
|
return;
|
|
290
289
|
}
|
|
291
290
|
F.value = e.uploadParams;
|
|
292
291
|
const r = t.type === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || t.type === "application/vnd.ms-excel", u = t.type === "text/csv" || t.name.toLowerCase().endsWith(".csv"), n = e.fileType || "both";
|
|
293
|
-
let
|
|
292
|
+
let c = !1, v = "";
|
|
294
293
|
switch (n) {
|
|
295
294
|
case "excel":
|
|
296
|
-
|
|
295
|
+
c = r, v = "只能上传Excel文件!";
|
|
297
296
|
break;
|
|
298
297
|
case "csv":
|
|
299
|
-
|
|
298
|
+
c = u, v = "只能上传CSV文件!";
|
|
300
299
|
break;
|
|
301
300
|
case "both":
|
|
302
301
|
default:
|
|
303
|
-
|
|
302
|
+
c = r || u, v = "只能上传Excel文件或CSV文件!";
|
|
304
303
|
break;
|
|
305
304
|
}
|
|
306
|
-
if (!
|
|
307
|
-
return
|
|
305
|
+
if (!c)
|
|
306
|
+
return p.error(v), ue.LIST_IGNORE;
|
|
308
307
|
try {
|
|
309
|
-
if (
|
|
310
|
-
const
|
|
311
|
-
if (!
|
|
312
|
-
throw new Error(
|
|
313
|
-
const oe = await (await fetch(
|
|
314
|
-
return L.value = oe, await re(oe), !
|
|
308
|
+
if (A(), y.value = t.name, q.value = u ? "text/csv" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", u) {
|
|
309
|
+
const w = await t.arrayBuffer(), O = new TextDecoder("utf-8").decode(w), { csvToExcelView: G } = await import("../../assets/modules/index-Dd8HdGOL.js").then((he) => he.j), M = await G(O, t.name);
|
|
310
|
+
if (!M.success)
|
|
311
|
+
throw new Error(M.error || "CSV文件处理失败");
|
|
312
|
+
const oe = await (await fetch(M.blobUrl)).arrayBuffer();
|
|
313
|
+
return L.value = oe, await re(oe), !U.value && !k.value && (b.value = M.blobUrl), y.value = M.fileName, a.isFormLoading.value = !1, !1;
|
|
315
314
|
}
|
|
316
|
-
const
|
|
317
|
-
L.value =
|
|
315
|
+
const x = await t.arrayBuffer();
|
|
316
|
+
L.value = x;
|
|
318
317
|
const N = new FileReader();
|
|
319
|
-
N.readAsDataURL(t), N.onload = async (
|
|
320
|
-
|
|
318
|
+
N.readAsDataURL(t), N.onload = async (w) => {
|
|
319
|
+
w.target ? (await re(x), !U.value && !k.value && (b.value = w.target.result), a.isFormLoading.value = !1) : p.error("加载文件失败,请检查文件格式!");
|
|
321
320
|
};
|
|
322
|
-
} catch (
|
|
323
|
-
console.error("文件处理错误:",
|
|
321
|
+
} catch (x) {
|
|
322
|
+
console.error("文件处理错误:", x), p.error("文件处理失败,请检查文件格式!"), a.isFormLoading.value = !1, V.value = "文件处理错误", B.value = "error";
|
|
324
323
|
}
|
|
325
324
|
return !1;
|
|
326
|
-
},
|
|
325
|
+
}, j = Se(a.formRules.value);
|
|
327
326
|
be(() => {
|
|
328
327
|
var o;
|
|
329
328
|
const t = (o = e.gridCtrl) == null ? void 0 : o.page;
|
|
330
|
-
if (t && !
|
|
329
|
+
if (t && !z.value) {
|
|
331
330
|
if (!R.value) {
|
|
332
|
-
|
|
331
|
+
p.error("未配置文件上传地址!");
|
|
333
332
|
return;
|
|
334
333
|
}
|
|
335
334
|
R.value.api || (R.value.api = t.api), R.value.authorize === void 0 && (R.value.authorize = t.authorize);
|
|
@@ -338,8 +337,8 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
338
337
|
}
|
|
339
338
|
m.value = a.visible.value, m.value && e.previewUrl && I();
|
|
340
339
|
});
|
|
341
|
-
const
|
|
342
|
-
if (
|
|
340
|
+
const A = () => {
|
|
341
|
+
if (b.value = "", y.value = "", le.value = [], L.value = null, q.value = "", a.isFormLoading.value = !1, V.value = "待验证数据规则", B.value = "warning", P.value = "待验证重复数据", $.value = "warning", U.value = !1, k.value = !1, a.formData.value) {
|
|
343
342
|
const t = e.fileField ?? "FileInfo", o = e.excelRecordsKey, r = e.excelRowsKey;
|
|
344
343
|
delete a.formData.value[t], o && delete a.formData.value[o], r && delete a.formData.value[r];
|
|
345
344
|
}
|
|
@@ -348,8 +347,8 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
348
347
|
}, ge = () => {
|
|
349
348
|
};
|
|
350
349
|
return s({
|
|
351
|
-
clearAll:
|
|
352
|
-
}), (t, o) => (
|
|
350
|
+
clearAll: A
|
|
351
|
+
}), (t, o) => (d(), H(i(Fe), {
|
|
353
352
|
title: t.title ?? "文件上传",
|
|
354
353
|
open: m.value,
|
|
355
354
|
"onUpdate:open": o[0] || (o[0] = (r) => m.value = r),
|
|
@@ -357,26 +356,26 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
357
356
|
width: 940,
|
|
358
357
|
onClose: se
|
|
359
358
|
}, {
|
|
360
|
-
footer:
|
|
359
|
+
footer: S(() => [
|
|
361
360
|
C(i(_e), null, {
|
|
362
|
-
default:
|
|
361
|
+
default: S(() => {
|
|
363
362
|
var r;
|
|
364
363
|
return [
|
|
365
364
|
C(i(Y), { onClick: se }, {
|
|
366
|
-
default:
|
|
367
|
-
X(
|
|
365
|
+
default: S(() => [
|
|
366
|
+
X(E(t.cancelText ?? (z.value ? "关闭" : "取消")), 1)
|
|
368
367
|
]),
|
|
369
368
|
_: 1
|
|
370
369
|
}),
|
|
371
|
-
|
|
370
|
+
z.value ? K("", !0) : (d(), H(i(Y), {
|
|
372
371
|
key: 0,
|
|
373
372
|
onClick: me,
|
|
374
373
|
type: "primary",
|
|
375
374
|
loading: ((r = i(a)) == null ? void 0 : r.isFormSaving.value) ?? !1,
|
|
376
|
-
disabled: !
|
|
375
|
+
disabled: !b.value || U.value || k.value || i(a).isFormLoading.value
|
|
377
376
|
}, {
|
|
378
|
-
default:
|
|
379
|
-
X(
|
|
377
|
+
default: S(() => [
|
|
378
|
+
X(E(t.saveText ?? "上传文件"), 1)
|
|
380
379
|
]),
|
|
381
380
|
_: 1
|
|
382
381
|
}, 8, ["loading", "disabled"]))
|
|
@@ -385,9 +384,9 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
385
384
|
_: 1
|
|
386
385
|
})
|
|
387
386
|
]),
|
|
388
|
-
default:
|
|
387
|
+
default: S(() => [
|
|
389
388
|
J(t.$slots, "default"),
|
|
390
|
-
|
|
389
|
+
z.value ? K("", !0) : (d(), g("div", $e, [
|
|
391
390
|
J(t.$slots, "file-before"),
|
|
392
391
|
C(i(ue), {
|
|
393
392
|
"file-list": le.value,
|
|
@@ -396,20 +395,20 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
396
395
|
showUploadList: !0,
|
|
397
396
|
disabled: !te.value
|
|
398
397
|
}, {
|
|
399
|
-
default:
|
|
398
|
+
default: S(() => [
|
|
400
399
|
C(i(Y), {
|
|
401
400
|
type: "primary",
|
|
402
401
|
disabled: !te.value
|
|
403
402
|
}, {
|
|
404
|
-
default:
|
|
405
|
-
X(
|
|
403
|
+
default: S(() => [
|
|
404
|
+
X(E(pe.value), 1)
|
|
406
405
|
]),
|
|
407
406
|
_: 1
|
|
408
407
|
}, 8, ["disabled"])
|
|
409
408
|
]),
|
|
410
409
|
_: 1
|
|
411
410
|
}, 8, ["file-list", "accept", "disabled"]),
|
|
412
|
-
|
|
411
|
+
b.value && y.value ? (d(), g("div", je, [
|
|
413
412
|
C(i(Z), {
|
|
414
413
|
message: y.value,
|
|
415
414
|
type: "info",
|
|
@@ -418,17 +417,17 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
418
417
|
])) : K("", !0),
|
|
419
418
|
J(t.$slots, "file-after")
|
|
420
419
|
])),
|
|
421
|
-
|
|
422
|
-
i(a).isFormLoading.value ? (
|
|
420
|
+
h("div", Ae, [
|
|
421
|
+
i(a).isFormLoading.value ? (d(), H(i(Le), {
|
|
423
422
|
key: 0,
|
|
424
423
|
size: "large"
|
|
425
424
|
})) : K("", !0),
|
|
426
|
-
|
|
427
|
-
class: Ce(["flex-shrink-0 relative border border-gray-200 rounded-md overflow-hidden", [i(
|
|
425
|
+
h("div", {
|
|
426
|
+
class: Ce(["flex-shrink-0 relative border border-gray-200 rounded-md overflow-hidden", [i(j).length === 0 ? "w-[100%]" : "w-[80%]"]]),
|
|
428
427
|
style: { height: "430px" }
|
|
429
428
|
}, [
|
|
430
429
|
C(i(Ve), {
|
|
431
|
-
src:
|
|
430
|
+
src: b.value,
|
|
432
431
|
onError: ge,
|
|
433
432
|
style: { width: "100%", height: "100%" },
|
|
434
433
|
options: {
|
|
@@ -441,40 +440,40 @@ const Be = (l) => l.includes(",") || l.includes(`
|
|
|
441
440
|
}
|
|
442
441
|
}, null, 8, ["src"])
|
|
443
442
|
], 2),
|
|
444
|
-
i(
|
|
445
|
-
|
|
446
|
-
i(
|
|
443
|
+
i(j).length > 0 ? (d(), g("div", Oe, [
|
|
444
|
+
h("div", Ge, [
|
|
445
|
+
i(j).length === 0 ? (d(), g("div", Ie, "没有设置验证规则")) : (d(), g("div", qe, [
|
|
447
446
|
C(i(Z), {
|
|
448
447
|
message: V.value,
|
|
449
|
-
type:
|
|
448
|
+
type: B.value,
|
|
450
449
|
"show-icon": "",
|
|
451
450
|
class: "mb-2"
|
|
452
451
|
}, null, 8, ["message", "type"]),
|
|
453
|
-
|
|
454
|
-
(
|
|
452
|
+
h("div", Qe, [
|
|
453
|
+
(d(!0), g(ie, null, ne(i(j), (r, u) => (d(), g("div", {
|
|
455
454
|
key: u,
|
|
456
455
|
class: "border-b pb-0"
|
|
457
456
|
}, [
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
(
|
|
461
|
-
key:
|
|
457
|
+
h("div", We, E(r.field), 1),
|
|
458
|
+
h("ul", He, [
|
|
459
|
+
(d(!0), g(ie, null, ne(r.rules, (n, c) => (d(), g("li", {
|
|
460
|
+
key: c,
|
|
462
461
|
class: "text-[12px] text-gray-600"
|
|
463
|
-
},
|
|
462
|
+
}, E(n), 1))), 128))
|
|
464
463
|
])
|
|
465
464
|
]))), 128))
|
|
466
465
|
]),
|
|
467
|
-
|
|
466
|
+
_.value && _.value.length > 0 ? (d(), g("div", Je, [
|
|
468
467
|
C(i(Z), {
|
|
469
|
-
message:
|
|
470
|
-
type:
|
|
468
|
+
message: P.value,
|
|
469
|
+
type: $.value,
|
|
471
470
|
"show-icon": "",
|
|
472
471
|
class: "mt-2 mb-2"
|
|
473
472
|
}, null, 8, ["message", "type"]),
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
473
|
+
h("div", Xe, [
|
|
474
|
+
h("div", Ye, " 以下" + E(_.value.length > 1 ? "组合" : "字段") + "必须唯一 ", 1),
|
|
475
|
+
h("ul", Ze, [
|
|
476
|
+
h("li", ea, E(_.value.join(", ")), 1)
|
|
478
477
|
])
|
|
479
478
|
])
|
|
480
479
|
])) : K("", !0)
|
|
@@ -27,9 +27,10 @@ export declare const checkExcelDuplicates: (excelBuffer: ArrayBuffer, duplicateR
|
|
|
27
27
|
markHeaders?: string[];
|
|
28
28
|
}>;
|
|
29
29
|
export declare const validateExcelUnified: (excelBuffer: ArrayBuffer, rules?: Record<string, ValidateRule>, duplicateRules?: string[], duplicateUrl?: IUrlInfo) => Promise<{
|
|
30
|
-
hasError: boolean;
|
|
31
30
|
errBlob?: Blob;
|
|
32
31
|
validationMsg: string;
|
|
33
32
|
duplicateMsg: string;
|
|
33
|
+
hasFormatError?: boolean;
|
|
34
|
+
hasDuplicateError?: boolean;
|
|
34
35
|
}>;
|
|
35
36
|
export declare const appendExcelData: (fileInfo: UploadFile, fileData: Record<string, any>, fields?: string[]) => Promise<void>;
|
package/lib/webui.es.js
CHANGED
|
@@ -11,8 +11,8 @@ import { Popover as Sa, theme as Le, Drawer as Ca, Space as te, Form as ze, mess
|
|
|
11
11
|
import { VueDraggableNext as za } from "vue-draggable-next";
|
|
12
12
|
import { d as Ke } from "./assets/modules/uploadList-1Zmhwr0q.js";
|
|
13
13
|
import { C as gs, U as bs, a as xs, p as _s } from "./assets/modules/uploadList-1Zmhwr0q.js";
|
|
14
|
-
import { c as We } from "./assets/modules/index-
|
|
15
|
-
import { _ as ks, h as ws, b as Ss, a as Cs, d as Ts, e as $s, g as Is, f as Ds, n as Es, p as Ps, t as Fs, v as Ns } from "./assets/modules/index-
|
|
14
|
+
import { c as We } from "./assets/modules/index-Dd8HdGOL.js";
|
|
15
|
+
import { _ as ks, h as ws, b as Ss, a as Cs, d as Ts, e as $s, g as Is, f as Ds, n as Es, p as Ps, t as Fs, v as Ns } from "./assets/modules/index-Dd8HdGOL.js";
|
|
16
16
|
import { _ as O } from "./assets/modules/index-BRWQ6SRp.js";
|
|
17
17
|
import { _ as U } from "./assets/modules/toolIcon-BSjgzw0G.js";
|
|
18
18
|
import { a as Rs } from "./assets/modules/toolIcon-BSjgzw0G.js";
|
package/package.json
CHANGED
|
@@ -451,32 +451,31 @@ const performDataValidation = async (buffer: ArrayBuffer): Promise<void> => {
|
|
|
451
451
|
|
|
452
452
|
// 统一验证(格式验证和重复验证)
|
|
453
453
|
const {
|
|
454
|
-
hasError,
|
|
455
454
|
errBlob,
|
|
456
455
|
validationMsg: valMsg,
|
|
457
456
|
duplicateMsg: dupMsg,
|
|
457
|
+
hasFormatError,
|
|
458
|
+
hasDuplicateError
|
|
458
459
|
} = await validateExcelUnified(buffer, excelCtrl.formRules.value, duplicateRules.value, duplicateUrl.value);
|
|
459
460
|
|
|
460
461
|
// 更新验证状态
|
|
461
462
|
validationMsg.value = valMsg;
|
|
462
463
|
duplicateMsg.value = dupMsg;
|
|
463
464
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
465
|
+
// 根据验证结果设置正确的状态类型
|
|
466
|
+
validationType.value = hasFormatError ? 'error' : (excelCtrl.formRules.value && Object.keys(excelCtrl.formRules.value).length > 0 ? 'success' : 'warning');
|
|
467
|
+
duplicateType.value = hasDuplicateError ? 'error' : (duplicateRules.value && duplicateRules.value.length > 0 ? 'success' : 'warning');
|
|
468
|
+
|
|
469
|
+
// 有验证错误
|
|
470
|
+
if (errBlob) {
|
|
471
|
+
excelError.value = hasFormatError ?? false;
|
|
472
|
+
duplicateError.value = hasDuplicateError ?? false;
|
|
473
|
+
const blobUrl = URL.createObjectURL(errBlob);
|
|
474
|
+
excelUrl.value = blobUrl;
|
|
474
475
|
} else {
|
|
475
476
|
// 验证成功
|
|
476
477
|
excelError.value = false;
|
|
477
478
|
duplicateError.value = false;
|
|
478
|
-
validationType.value = 'success';
|
|
479
|
-
duplicateType.value = 'success';
|
|
480
479
|
// 验证成功时,excelUrl会在beforeUpload中设置
|
|
481
480
|
}
|
|
482
481
|
} catch (error) {
|
package/src/utils/form-excel.ts
CHANGED
|
@@ -316,22 +316,23 @@ export const validateExcelUnified = async (
|
|
|
316
316
|
duplicateRules?: string[],
|
|
317
317
|
duplicateUrl?: IUrlInfo,
|
|
318
318
|
): Promise<{
|
|
319
|
-
hasError: boolean;
|
|
320
319
|
errBlob?: Blob;
|
|
321
320
|
validationMsg: string;
|
|
322
321
|
duplicateMsg: string;
|
|
322
|
+
hasFormatError?: boolean;
|
|
323
|
+
hasDuplicateError?: boolean;
|
|
323
324
|
}> => {
|
|
324
325
|
const allMarkCells: Array<{ row: number; col: number; color: string }> = [];
|
|
325
326
|
const allMarkHeaders: string[] = [];
|
|
326
|
-
let
|
|
327
|
+
let hasFormatError = false;
|
|
327
328
|
let hasDuplicateError = false;
|
|
328
329
|
let validationMsg = '数据验证成功';
|
|
329
|
-
let duplicateMsg = '
|
|
330
|
+
let duplicateMsg = '待验证重复数据';
|
|
330
331
|
|
|
331
332
|
// 1. 格式验证
|
|
332
333
|
const validationResult = await validateExcel(excelBuffer, rules);
|
|
333
334
|
if (validationResult.hasError) {
|
|
334
|
-
|
|
335
|
+
hasFormatError = true;
|
|
335
336
|
validationMsg = '数据验证失败';
|
|
336
337
|
if (validationResult.markCells) {
|
|
337
338
|
allMarkCells.push(...validationResult.markCells);
|
|
@@ -339,6 +340,8 @@ export const validateExcelUnified = async (
|
|
|
339
340
|
if (validationResult.markHeaders) {
|
|
340
341
|
allMarkHeaders.push(...validationResult.markHeaders);
|
|
341
342
|
}
|
|
343
|
+
} else if (rules && Object.keys(rules).length > 0) {
|
|
344
|
+
validationMsg = '数据验证通过';
|
|
342
345
|
}
|
|
343
346
|
|
|
344
347
|
// 2. 重复验证
|
|
@@ -363,11 +366,15 @@ export const validateExcelUnified = async (
|
|
|
363
366
|
if (duplicateResult.markHeaders) {
|
|
364
367
|
allMarkHeaders.push(...duplicateResult.markHeaders);
|
|
365
368
|
}
|
|
369
|
+
} else {
|
|
370
|
+
duplicateMsg = '重复性检验通过';
|
|
366
371
|
}
|
|
367
372
|
}
|
|
368
373
|
|
|
374
|
+
const hasError = hasFormatError || hasDuplicateError;
|
|
375
|
+
|
|
369
376
|
// 3. 如果有任何错误,创建统一的标记Excel
|
|
370
|
-
if (
|
|
377
|
+
if (hasError) {
|
|
371
378
|
const markResult = await createMarkedExcelView(
|
|
372
379
|
excelBuffer,
|
|
373
380
|
{
|
|
@@ -381,24 +388,27 @@ export const validateExcelUnified = async (
|
|
|
381
388
|
const response = await fetch(markResult.blobUrl);
|
|
382
389
|
const errBlob = await response.blob();
|
|
383
390
|
return {
|
|
384
|
-
hasError: true,
|
|
385
391
|
errBlob,
|
|
386
392
|
validationMsg,
|
|
387
393
|
duplicateMsg,
|
|
394
|
+
hasFormatError,
|
|
395
|
+
hasDuplicateError
|
|
388
396
|
};
|
|
389
397
|
} else {
|
|
390
398
|
return {
|
|
391
|
-
hasError: true,
|
|
392
399
|
validationMsg,
|
|
393
400
|
duplicateMsg,
|
|
401
|
+
hasFormatError,
|
|
402
|
+
hasDuplicateError
|
|
394
403
|
};
|
|
395
404
|
}
|
|
396
405
|
}
|
|
397
406
|
|
|
398
407
|
return {
|
|
399
|
-
hasError: false,
|
|
400
408
|
validationMsg,
|
|
401
409
|
duplicateMsg,
|
|
410
|
+
hasFormatError: false,
|
|
411
|
+
hasDuplicateError: false
|
|
402
412
|
};
|
|
403
413
|
};
|
|
404
414
|
|