@skyfox2000/webui 1.3.4 → 1.3.6
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/.vscode/settings.json +1 -1
- package/lib/assets/modules/{file-upload-BBlFaIXB.js → file-upload-DhPgqGdk.js} +50 -50
- package/lib/assets/modules/index-02J2AYth.js +377 -0
- package/lib/assets/modules/{index-m5rogIyM.js → index-C31q4LHC.js} +2 -2
- package/lib/assets/modules/{index-BG1SqSVl.js → index-CCpTizF9.js} +1 -1
- package/lib/assets/modules/{menuTabs-tPIz4a89.js → menuTabs-DyhSKN9r.js} +2 -2
- package/lib/assets/modules/{toolIcon-DwWoD9TN.js → toolIcon-CqM4gBIc.js} +1 -1
- package/lib/assets/modules/{uploadList-D_Z-Y2tw.js → uploadList-DAVjJkqz.js} +511 -476
- package/lib/assets/modules/{uploadList-Da7mQUNK.js → uploadList-ZajZKqaS.js} +4 -4
- package/lib/components/common/alert/index.vue.d.ts +13 -0
- package/lib/components/common/icon/helper.vue.d.ts +1 -0
- package/lib/components/common/index.d.ts +2 -0
- package/lib/components/content/form/formItem.vue.d.ts +1 -0
- package/lib/components/content/table/index.vue.d.ts +95 -4
- package/lib/components/form/input/index.vue.d.ts +4 -1
- package/lib/components/form/select/index.vue.d.ts +2 -0
- package/lib/components/form/treeSelect/index.vue.d.ts +11 -2
- package/lib/components/index.d.ts +1 -1
- package/lib/es/AceEditor/index.js +3 -3
- package/lib/es/BasicLayout/index.js +3 -3
- package/lib/es/Error403/index.js +1 -1
- package/lib/es/Error404/index.js +1 -1
- package/lib/es/ExcelForm/index.js +317 -274
- package/lib/es/UploadForm/index.js +4 -4
- package/lib/index.d.ts +1 -1
- package/lib/typings/form.d.ts +2 -2
- package/lib/typings/option.d.ts +2 -2
- package/lib/utils/excel-preview.d.ts +24 -0
- package/lib/utils/form-excel.d.ts +17 -4
- package/lib/utils/options.d.ts +2 -2
- package/lib/webui.css +1 -1
- package/lib/webui.es.js +759 -747
- package/package.json +1 -1
- package/src/components/common/alert/index.vue +76 -0
- package/src/components/common/icon/helper.vue +7 -1
- package/src/components/common/index.ts +4 -1
- package/src/components/common/loading/index.vue +1 -1
- package/src/components/content/dialog/excelForm.vue +343 -313
- package/src/components/content/form/formItem.vue +6 -2
- package/src/components/content/table/index.vue +9 -6
- package/src/components/form/autoComplete/index.vue +9 -3
- package/src/components/form/cascader/index.vue +8 -6
- package/src/components/form/input/index.vue +16 -3
- package/src/components/form/select/index.vue +5 -11
- package/src/components/form/treeSelect/index.vue +22 -17
- package/src/components/index.ts +1 -0
- package/src/index.ts +1 -0
- package/src/typings/form.d.ts +2 -2
- package/src/typings/option.d.ts +2 -2
- package/src/utils/excel-preview.ts +188 -0
- package/src/utils/file-upload.ts +0 -2
- package/src/utils/form-excel.ts +132 -126
- package/src/utils/options.ts +80 -22
- package/src/utils/table.ts +15 -2
- package/lib/assets/modules/index-4kDAt8nS.js +0 -333
package/.vscode/settings.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
var m = Object.defineProperty;
|
|
2
|
-
var E = (
|
|
3
|
-
var d = (
|
|
2
|
+
var E = (e, r, o) => r in e ? m(e, r, { enumerable: !0, configurable: !0, writable: !0, value: o }) : e[r] = o;
|
|
3
|
+
var d = (e, r, o) => E(e, typeof r != "symbol" ? r + "" : r, o);
|
|
4
4
|
import { hostUrl as v } from "@skyfox2000/fapi";
|
|
5
|
-
import { ae as S, ad as w, u as g } from "./uploadList-
|
|
5
|
+
import { ae as S, ad as w, u as g } from "./uploadList-DAVjJkqz.js";
|
|
6
6
|
import { mainAppApis as a } from "@skyfox2000/microbase";
|
|
7
7
|
import y from "dayjs";
|
|
8
8
|
import p from "vue-m-message";
|
|
9
|
-
var i = /* @__PURE__ */ ((
|
|
10
|
-
const U = () => a.value ? a.value.getHostInfo() : S().hostInfo, x = () => a.value && a.value.getAppInfo ? a.value.getAppInfo() : w().appInfo, L = (
|
|
9
|
+
var i = /* @__PURE__ */ ((e) => (e.Pending = "pending", e.Uploading = "uploading", e.Success = "success", e.Error = "error", e.Online = "online", e.Offline = "offline", e))(i || {});
|
|
10
|
+
const U = () => a.value ? a.value.getHostInfo() : S().hostInfo, x = () => a.value && a.value.getAppInfo ? a.value.getAppInfo() : w().appInfo, L = (e) => a.value && a.value.userLogin ? a.value.userLogin(e) : g().login(e, !0), M = () => a.value && a.value.userLogout ? a.value.userLogout() : g().logout(), b = () => a.value && a.value.getToken ? a.value.getToken() : g().getToken(), N = () => a.value && a.value.getUserInfo ? a.value.getUserInfo() : g().getUserInfo();
|
|
11
11
|
class z {
|
|
12
12
|
/**
|
|
13
13
|
* 连接路径参数,已判断 undefined 或 null 值
|
|
@@ -24,7 +24,7 @@ class C {
|
|
|
24
24
|
* @param urlInfo 文件上传的 API 配置(IUrlInfo 对象)
|
|
25
25
|
* @param maxConcurrent 最大允许并发上传的文件数量
|
|
26
26
|
*/
|
|
27
|
-
constructor(r,
|
|
27
|
+
constructor(r, o = 3) {
|
|
28
28
|
/**
|
|
29
29
|
* 设置 API 端点和最大并发数,所有上传文件通过该类控制
|
|
30
30
|
*/
|
|
@@ -37,7 +37,7 @@ class C {
|
|
|
37
37
|
* 控制上传任务的中断信号
|
|
38
38
|
*/
|
|
39
39
|
d(this, "abortController");
|
|
40
|
-
this.urlInfo = r, this.maxConcurrent =
|
|
40
|
+
this.urlInfo = r, this.maxConcurrent = o;
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* 执行上传
|
|
@@ -48,17 +48,17 @@ class C {
|
|
|
48
48
|
* @param onProgress 上传进度回调
|
|
49
49
|
* @returns 上传结果
|
|
50
50
|
*/
|
|
51
|
-
async doUpload(r,
|
|
51
|
+
async doUpload(r, o, c, u, n) {
|
|
52
52
|
if (r.length) {
|
|
53
53
|
if (r.length === 0) {
|
|
54
54
|
p.warning("请选择上传的文件!");
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
let
|
|
57
|
+
o.value = !0, await this.uploadFiles(r, n, (f) => {
|
|
58
|
+
let t = !1, h = 0;
|
|
59
59
|
for (const s of f)
|
|
60
60
|
s.status === i.Error && h++;
|
|
61
|
-
h ? h < f.length ? c ? (p.error("上传结束,部分文件上传失败!"), p.warning("保存上传成功的文件!"),
|
|
61
|
+
h ? h < f.length ? c ? (p.error("上传结束,部分文件上传失败!"), p.warning("保存上传成功的文件!"), t = !0) : p.error("上传结束,部分文件上传失败,取消保存!") : p.error("上传结束,所有文件上传失败!") : (p.success("全部文件上传成功!"), t = !0), o.value = !1, u == null || u(t, f);
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -68,31 +68,31 @@ class C {
|
|
|
68
68
|
* @param onProgress 上传进度回调
|
|
69
69
|
* @param onComplete 上传完成回调
|
|
70
70
|
*/
|
|
71
|
-
async uploadFiles(r,
|
|
71
|
+
async uploadFiles(r, o, c) {
|
|
72
72
|
if (!r.length) return;
|
|
73
|
-
const u = Math.min(this.maxConcurrent, r.length),
|
|
74
|
-
for (const
|
|
75
|
-
switch (
|
|
73
|
+
const u = Math.min(this.maxConcurrent, r.length), n = [];
|
|
74
|
+
for (const t of r)
|
|
75
|
+
switch (t.status) {
|
|
76
76
|
case i.Success:
|
|
77
77
|
case i.Online:
|
|
78
78
|
case i.Offline:
|
|
79
79
|
break;
|
|
80
80
|
default:
|
|
81
|
-
|
|
81
|
+
t.status = i.Pending, n.push(t);
|
|
82
82
|
break;
|
|
83
83
|
}
|
|
84
84
|
const f = [];
|
|
85
85
|
this.abortController = new AbortController();
|
|
86
86
|
try {
|
|
87
|
-
for (; f.length < u &&
|
|
88
|
-
const
|
|
89
|
-
if (!
|
|
90
|
-
f.push(this.handleFileStatus(
|
|
87
|
+
for (; f.length < u && n.length > 0; ) {
|
|
88
|
+
const t = n.shift();
|
|
89
|
+
if (!t) break;
|
|
90
|
+
f.push(this.handleFileStatus(t, f, n, o));
|
|
91
91
|
}
|
|
92
92
|
await Promise.all(f);
|
|
93
|
-
} catch (
|
|
94
|
-
|
|
95
|
-
h.status = i.Error, h.error =
|
|
93
|
+
} catch (t) {
|
|
94
|
+
r.forEach((h) => {
|
|
95
|
+
h.status = i.Error, h.error = t instanceof Error ? t : new Error("上传失败"), o == null || o(h);
|
|
96
96
|
});
|
|
97
97
|
} finally {
|
|
98
98
|
c == null || c(r);
|
|
@@ -105,17 +105,17 @@ class C {
|
|
|
105
105
|
* @param pendingFiles 等待上传的文件列表
|
|
106
106
|
* @param onProgress 上传进度回调
|
|
107
107
|
*/
|
|
108
|
-
async handleFileStatus(r,
|
|
108
|
+
async handleFileStatus(r, o, c, u) {
|
|
109
109
|
try {
|
|
110
|
-
await this.uploadFile(r, this.abortController.signal, (
|
|
111
|
-
r.percent =
|
|
110
|
+
await this.uploadFile(r, this.abortController.signal, (n) => {
|
|
111
|
+
r.percent = n, u == null || u(r);
|
|
112
112
|
});
|
|
113
|
-
} catch (
|
|
114
|
-
r.error =
|
|
113
|
+
} catch (n) {
|
|
114
|
+
r.error = n instanceof Error ? n : new Error("上传失败");
|
|
115
115
|
} finally {
|
|
116
116
|
if (c.length > 0) {
|
|
117
|
-
const
|
|
118
|
-
|
|
117
|
+
const n = c.shift();
|
|
118
|
+
n && o.push(this.handleFileStatus(n, o, c, u));
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -125,38 +125,38 @@ class C {
|
|
|
125
125
|
* @param signal 中断信号
|
|
126
126
|
* @param onProgress 上传进度回调
|
|
127
127
|
*/
|
|
128
|
-
async uploadFile(r,
|
|
129
|
-
return r.status = i.Uploading, new Promise((u,
|
|
128
|
+
async uploadFile(r, o, c) {
|
|
129
|
+
return r.status = i.Uploading, new Promise((u, n) => {
|
|
130
130
|
const f = new FormData();
|
|
131
131
|
if (f.append("file", r.originFileObj), r.params)
|
|
132
132
|
for (const s in r.params)
|
|
133
133
|
f.append(s, r.params[s]);
|
|
134
|
-
const
|
|
134
|
+
const t = new XMLHttpRequest(), h = v(this.urlInfo);
|
|
135
135
|
if (h === !1) return Promise.resolve(r);
|
|
136
|
-
if (
|
|
137
|
-
|
|
136
|
+
if (t.open("POST", h, !0), this.urlInfo.header && typeof this.urlInfo.header == "object" && Object.entries(this.urlInfo.header).forEach(([s, l]) => {
|
|
137
|
+
t.setRequestHeader(s, l);
|
|
138
138
|
}), this.urlInfo.authorize) {
|
|
139
139
|
const s = b();
|
|
140
140
|
if (!s) {
|
|
141
|
-
|
|
141
|
+
n(new Error("未授权或授权过期"));
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
144
|
-
|
|
144
|
+
t.setRequestHeader("Authorization", "Bearer " + s);
|
|
145
145
|
}
|
|
146
|
-
|
|
146
|
+
t.upload.addEventListener("progress", (s) => {
|
|
147
147
|
if (s.lengthComputable && s.total > 0) {
|
|
148
148
|
const l = Math.round(s.loaded / s.total * 100);
|
|
149
149
|
c(l);
|
|
150
150
|
}
|
|
151
|
-
}),
|
|
152
|
-
if (
|
|
153
|
-
const s =
|
|
151
|
+
}), t.addEventListener("load", () => {
|
|
152
|
+
if (t.status >= 200 && t.status < 300) {
|
|
153
|
+
const s = t.getResponseHeader("Content-Type");
|
|
154
154
|
if (!s || !s.includes("application/json")) {
|
|
155
|
-
|
|
155
|
+
n(new Error("返回的结果不是 JSON 格式"));
|
|
156
156
|
return;
|
|
157
157
|
}
|
|
158
158
|
try {
|
|
159
|
-
const l = JSON.parse(
|
|
159
|
+
const l = JSON.parse(t.response);
|
|
160
160
|
if (l.status === "success")
|
|
161
161
|
l.data && (r.minioFile = {
|
|
162
162
|
ETag: l.data.ETag,
|
|
@@ -170,17 +170,17 @@ class C {
|
|
|
170
170
|
}), r.status = i.Success, u(r);
|
|
171
171
|
else {
|
|
172
172
|
const I = l.msg;
|
|
173
|
-
r.status = i.Error,
|
|
173
|
+
r.status = i.Error, n(new Error(I));
|
|
174
174
|
}
|
|
175
175
|
} catch (l) {
|
|
176
|
-
r.status = i.Error,
|
|
176
|
+
r.status = i.Error, n(new Error("无法解析返回的 JSON 数据: " + l));
|
|
177
177
|
}
|
|
178
178
|
} else
|
|
179
|
-
r.status = i.Error,
|
|
180
|
-
}),
|
|
181
|
-
r.status = i.Error,
|
|
182
|
-
}),
|
|
183
|
-
|
|
179
|
+
r.status = i.Error, n(new Error(`上传失败,状态码:${t.status}`));
|
|
180
|
+
}), t.addEventListener("error", () => {
|
|
181
|
+
r.status = i.Error, n(new Error("上传失败,网络异常"));
|
|
182
|
+
}), t.send(f), o.addEventListener("abort", () => {
|
|
183
|
+
t.abort(), n(new Error("上传已取消"));
|
|
184
184
|
});
|
|
185
185
|
});
|
|
186
186
|
}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import V from "async-validator";
|
|
2
|
+
import { httpPost as j, ResStatus as M } from "@skyfox2000/fapi";
|
|
3
|
+
import { i as T, ag as $ } from "./uploadList-DAVjJkqz.js";
|
|
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 A, normalizeStyle as O } from "vue";
|
|
6
|
+
import { Spin as N, Alert as L } from "ant-design-vue";
|
|
7
|
+
import { _ as K } from "./toolIcon-CqM4gBIc.js";
|
|
8
|
+
const H = (i) => {
|
|
9
|
+
const e = i.split(`
|
|
10
|
+
`).filter((c) => c.trim() !== "");
|
|
11
|
+
if (e.length === 0)
|
|
12
|
+
return { headers: [], rows: [] };
|
|
13
|
+
const s = e.map((c) => c.split(",").map((r) => {
|
|
14
|
+
const o = r.trim();
|
|
15
|
+
if (o === "" || o === "null") return null;
|
|
16
|
+
const t = Number(o);
|
|
17
|
+
return isNaN(t) ? o : t;
|
|
18
|
+
})), n = s[0].map((c) => String(c || "")), a = s.slice(1);
|
|
19
|
+
return { headers: n, rows: a };
|
|
20
|
+
}, S = async (i) => {
|
|
21
|
+
try {
|
|
22
|
+
const e = await import("exceljs"), s = new e.default.Workbook();
|
|
23
|
+
await s.xlsx.load(i);
|
|
24
|
+
const n = s.worksheets[0];
|
|
25
|
+
if (!n)
|
|
26
|
+
return { headers: [], rows: [] };
|
|
27
|
+
const a = [], c = [];
|
|
28
|
+
return n.getRow(1).eachCell((r) => {
|
|
29
|
+
let o = "";
|
|
30
|
+
r.value !== null && r.value !== void 0 && (typeof r.value == "object" ? "richText" in r.value && Array.isArray(r.value.richText) ? o = r.value.richText.map((t) => t.text || "").join("") : "text" in r.value && typeof r.value.text == "string" ? o = r.value.text : r.value instanceof Date ? o = r.value.toLocaleDateString() : o = String(r.value) : o = String(r.value)), a.push(o);
|
|
31
|
+
}), n.eachRow((r, o) => {
|
|
32
|
+
if (o > 1) {
|
|
33
|
+
const t = [];
|
|
34
|
+
a.forEach((u, l) => {
|
|
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((d) => d.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
|
+
}), c.push(t);
|
|
38
|
+
}
|
|
39
|
+
}), { headers: a, rows: c };
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return console.error("Excel解析失败:", e), { headers: [], rows: [] };
|
|
42
|
+
}
|
|
43
|
+
}, g = async (i, e, s) => {
|
|
44
|
+
try {
|
|
45
|
+
const n = await import("exceljs"), a = new n.default.Workbook(), c = a.addWorksheet("Sheet1"), { headers: r, rows: o } = i;
|
|
46
|
+
if (r.length === 0)
|
|
47
|
+
throw new Error("数据为空");
|
|
48
|
+
const t = /* @__PURE__ */ new Map();
|
|
49
|
+
s != null && s.markCells && s.markCells.forEach(({ row: d, col: w, color: p }) => {
|
|
50
|
+
const y = `${d}-${w}`;
|
|
51
|
+
t.set(y, p || "FFFF0000");
|
|
52
|
+
});
|
|
53
|
+
const u = c.getRow(1);
|
|
54
|
+
r.forEach((d, w) => {
|
|
55
|
+
const p = u.getCell(w + 1);
|
|
56
|
+
p.value = d, p.font = { bold: !0 }, p.fill = {
|
|
57
|
+
type: "pattern",
|
|
58
|
+
pattern: "solid",
|
|
59
|
+
fgColor: { argb: "FFE0E0E0" }
|
|
60
|
+
}, s != null && s.markHeaders && s.markHeaders.includes(d) && (p.fill = {
|
|
61
|
+
type: "pattern",
|
|
62
|
+
pattern: "solid",
|
|
63
|
+
fgColor: { argb: "FFFF0000" }
|
|
64
|
+
}, p.font = {
|
|
65
|
+
name: "Arial",
|
|
66
|
+
size: 10,
|
|
67
|
+
bold: !0,
|
|
68
|
+
color: { argb: "FFFFFFFF" }
|
|
69
|
+
});
|
|
70
|
+
}), o.forEach((d, w) => {
|
|
71
|
+
const p = c.getRow(w + 2);
|
|
72
|
+
d.forEach((y, k) => {
|
|
73
|
+
const F = p.getCell(k + 1);
|
|
74
|
+
F.value = y;
|
|
75
|
+
const C = `${w + 2}-${k + 1}`;
|
|
76
|
+
t.has(C) && (F.fill = {
|
|
77
|
+
type: "pattern",
|
|
78
|
+
pattern: "solid",
|
|
79
|
+
fgColor: { argb: t.get(C) }
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}), c.columns.forEach((d) => {
|
|
83
|
+
d.width = 15;
|
|
84
|
+
});
|
|
85
|
+
const l = await a.xlsx.writeBuffer(), h = new Blob([l], {
|
|
86
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
success: !0,
|
|
90
|
+
blobUrl: URL.createObjectURL(h),
|
|
91
|
+
fileName: e.replace(/\.(csv|xlsx?)$/i, ".xlsx")
|
|
92
|
+
};
|
|
93
|
+
} catch (n) {
|
|
94
|
+
return console.error("转换Excel失败:", n), {
|
|
95
|
+
success: !1,
|
|
96
|
+
error: n instanceof Error ? n.message : "未知错误"
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}, P = async (i, e) => {
|
|
100
|
+
try {
|
|
101
|
+
const s = H(i);
|
|
102
|
+
return await g(s, e);
|
|
103
|
+
} catch (s) {
|
|
104
|
+
return {
|
|
105
|
+
success: !1,
|
|
106
|
+
error: s instanceof Error ? s.message : "CSV处理失败"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}, W = async (i, e) => {
|
|
110
|
+
try {
|
|
111
|
+
const s = new Blob([i], {
|
|
112
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
success: !0,
|
|
116
|
+
blobUrl: URL.createObjectURL(s),
|
|
117
|
+
fileName: e
|
|
118
|
+
};
|
|
119
|
+
} catch (s) {
|
|
120
|
+
return {
|
|
121
|
+
success: !1,
|
|
122
|
+
error: s instanceof Error ? s.message : "Excel处理失败"
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}, q = async (i, e) => await g(i, e), ae = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
126
|
+
__proto__: null,
|
|
127
|
+
csvToExcelView: P,
|
|
128
|
+
csvToNormalized: H,
|
|
129
|
+
excelToExcelView: W,
|
|
130
|
+
excelToNormalized: S,
|
|
131
|
+
normalizedToExcelView: q,
|
|
132
|
+
toExcel: g
|
|
133
|
+
}, Symbol.toStringTag, { value: "Module" })), x = async (i) => {
|
|
134
|
+
const e = await S(i);
|
|
135
|
+
if (e.headers.length === 0)
|
|
136
|
+
return m.error("Excel文件不包含工作表"), null;
|
|
137
|
+
const s = [];
|
|
138
|
+
return e.rows.forEach((n) => {
|
|
139
|
+
const a = {};
|
|
140
|
+
e.headers.forEach((c, r) => {
|
|
141
|
+
c && (a[c] = n[r]);
|
|
142
|
+
}), s.push(a);
|
|
143
|
+
}), {
|
|
144
|
+
headers: e.headers,
|
|
145
|
+
excelData: s,
|
|
146
|
+
excelRows: e.rows
|
|
147
|
+
};
|
|
148
|
+
}, J = async (i, e, s) => {
|
|
149
|
+
const n = await x(i);
|
|
150
|
+
if (!n)
|
|
151
|
+
return { success: !1, error: "Excel文件处理失败" };
|
|
152
|
+
const { headers: a, excelRows: c } = n, { markHeaders: r } = e, o = [...a];
|
|
153
|
+
r && r.length > 0 && r.forEach((u) => {
|
|
154
|
+
o.includes(u) || o.push(u);
|
|
155
|
+
});
|
|
156
|
+
const t = c.map((u) => {
|
|
157
|
+
const l = [...u];
|
|
158
|
+
for (; l.length < o.length; )
|
|
159
|
+
l.push(null);
|
|
160
|
+
return l;
|
|
161
|
+
});
|
|
162
|
+
return await g({ headers: o, rows: t }, s, e);
|
|
163
|
+
}, G = async (i, e) => {
|
|
164
|
+
if (!e || T(e))
|
|
165
|
+
return { hasError: !1 };
|
|
166
|
+
const s = await x(i);
|
|
167
|
+
if (!s) return { hasError: !0 };
|
|
168
|
+
const { headers: n, excelData: a } = s, c = [];
|
|
169
|
+
if (Object.keys(e).forEach((t) => {
|
|
170
|
+
n.includes(t) || c.push(t);
|
|
171
|
+
}), n.length === 0 || a.length === 0)
|
|
172
|
+
return m.error("Excel文件不包含足够的数据"), { hasError: !0 };
|
|
173
|
+
const r = new V({});
|
|
174
|
+
r.messages($.messages()), r.define(e);
|
|
175
|
+
const o = await Q(n, a, r);
|
|
176
|
+
return o.length > 0 || c.length > 0 ? {
|
|
177
|
+
hasError: !0,
|
|
178
|
+
markCells: o.map((u) => ({
|
|
179
|
+
row: u.row + 2,
|
|
180
|
+
// 转为Excel行号(+2是因为表头占一行,且是1-based索引)
|
|
181
|
+
col: u.col + 1,
|
|
182
|
+
// 转为Excel列号(+1是因为是1-based索引)
|
|
183
|
+
color: "FFFF0000"
|
|
184
|
+
// 红色
|
|
185
|
+
})),
|
|
186
|
+
markHeaders: c
|
|
187
|
+
} : { hasError: !1 };
|
|
188
|
+
}, Q = async (i, e, s) => {
|
|
189
|
+
const n = [];
|
|
190
|
+
for (let a = 0; a < e.length; a++) {
|
|
191
|
+
const c = e[a];
|
|
192
|
+
try {
|
|
193
|
+
await s.validate(c).catch(({ errors: r }) => {
|
|
194
|
+
const o = [];
|
|
195
|
+
r.forEach((t) => {
|
|
196
|
+
const u = i.indexOf(t.field);
|
|
197
|
+
u >= 0 && (o.some((h) => h.row === a && h.col === u) || o.push({
|
|
198
|
+
row: a,
|
|
199
|
+
col: u,
|
|
200
|
+
header: t.field,
|
|
201
|
+
message: t.message.replace("${label}", i[u])
|
|
202
|
+
}));
|
|
203
|
+
}), n.push(...o);
|
|
204
|
+
});
|
|
205
|
+
} catch (r) {
|
|
206
|
+
console.error("验证表格数据时发生错误:", r), m.error("验证表格数据时发生错误:" + r);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return n;
|
|
210
|
+
}, X = async (i, e, s) => {
|
|
211
|
+
if (!e || e.length === 0)
|
|
212
|
+
return { hasError: !1 };
|
|
213
|
+
const n = await x(i);
|
|
214
|
+
if (!n) return { hasError: !0 };
|
|
215
|
+
const { headers: a, excelData: c } = n, r = [];
|
|
216
|
+
if (e.forEach((l) => {
|
|
217
|
+
a.includes(l) || r.push(l);
|
|
218
|
+
}), r.length > 0)
|
|
219
|
+
return m.error(`表头缺少重复检测所需字段: ${r.join(", ")}`), { hasError: !0 };
|
|
220
|
+
const o = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Set(), u = new Array();
|
|
221
|
+
if (c.forEach((l, h) => {
|
|
222
|
+
const f = e.map((p) => l[p]), d = f.join("|");
|
|
223
|
+
u.push(d);
|
|
224
|
+
const w = f.some((p) => p != null && p !== "");
|
|
225
|
+
w && o.has(d) ? (t.add(h), t.add(o.get(d))) : w && o.set(d, h);
|
|
226
|
+
}), s) {
|
|
227
|
+
const l = await j(s, {
|
|
228
|
+
Data: u
|
|
229
|
+
});
|
|
230
|
+
if (l != null && l.data && l.data.forEach((h) => {
|
|
231
|
+
t.add(h);
|
|
232
|
+
}), (l == null ? void 0 : l.status) === M.ERROR)
|
|
233
|
+
throw new Error(l.msg);
|
|
234
|
+
}
|
|
235
|
+
if (t.size > 0) {
|
|
236
|
+
const l = [];
|
|
237
|
+
return t.forEach((h) => {
|
|
238
|
+
e.forEach((f) => {
|
|
239
|
+
const d = a.indexOf(f);
|
|
240
|
+
d >= 0 && l.push({
|
|
241
|
+
row: h + 2,
|
|
242
|
+
// Excel行号 = 数组索引 + 2(表头和1-based索引)
|
|
243
|
+
col: d + 1,
|
|
244
|
+
// Excel列号 = 数组索引 + 1(1-based索引)
|
|
245
|
+
color: "FFA500"
|
|
246
|
+
// 黄橙色
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
}), {
|
|
250
|
+
hasError: !0,
|
|
251
|
+
markCells: l,
|
|
252
|
+
markHeaders: r
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
return { hasError: !1 };
|
|
256
|
+
}, ne = async (i, e, s, n) => {
|
|
257
|
+
const a = [], c = [];
|
|
258
|
+
let r = !1, o = !1, t = "数据验证成功", u = "数据验证通过";
|
|
259
|
+
const l = await G(i, e);
|
|
260
|
+
if (l.hasError && (r = !0, t = "数据验证失败", l.markCells && a.push(...l.markCells), l.markHeaders && c.push(...l.markHeaders)), s && s.length > 0) {
|
|
261
|
+
const h = await X(i, s, n);
|
|
262
|
+
h.hasError && (o = !0, u = "检测到重复数据", h.markCells && h.markCells.forEach((f) => {
|
|
263
|
+
const d = a.find(
|
|
264
|
+
(w) => w.row === f.row && w.col === f.col
|
|
265
|
+
);
|
|
266
|
+
d ? d.color = "8B0000" : a.push(f);
|
|
267
|
+
}), h.markHeaders && c.push(...h.markHeaders));
|
|
268
|
+
}
|
|
269
|
+
if (r || o) {
|
|
270
|
+
const h = await J(
|
|
271
|
+
i,
|
|
272
|
+
{
|
|
273
|
+
markCells: a,
|
|
274
|
+
markHeaders: c
|
|
275
|
+
},
|
|
276
|
+
"validation_errors.xlsx"
|
|
277
|
+
);
|
|
278
|
+
return h.success && h.blobUrl ? {
|
|
279
|
+
hasError: !0,
|
|
280
|
+
errBlob: await (await fetch(h.blobUrl)).blob(),
|
|
281
|
+
validationMsg: t,
|
|
282
|
+
duplicateMsg: u
|
|
283
|
+
} : {
|
|
284
|
+
hasError: !0,
|
|
285
|
+
validationMsg: t,
|
|
286
|
+
duplicateMsg: u
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
hasError: !1,
|
|
291
|
+
validationMsg: t,
|
|
292
|
+
duplicateMsg: u
|
|
293
|
+
};
|
|
294
|
+
}, ce = async (i, e, s) => {
|
|
295
|
+
const n = i.originFileObj;
|
|
296
|
+
if (n) {
|
|
297
|
+
const a = await n.arrayBuffer(), c = await x(a);
|
|
298
|
+
if (!c) {
|
|
299
|
+
m.error("上传的文件不是Excel文件");
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const { headers: r, excelRows: o, excelData: t } = c;
|
|
303
|
+
s && s.length > 0 ? s.forEach((u) => {
|
|
304
|
+
switch (u) {
|
|
305
|
+
case "Headers":
|
|
306
|
+
e.Headers = r;
|
|
307
|
+
break;
|
|
308
|
+
case "RawRows":
|
|
309
|
+
e.RawRows = o;
|
|
310
|
+
break;
|
|
311
|
+
case "Records":
|
|
312
|
+
e.Records = t;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}) : (e.Headers = r, e.RawRows = o, e.Records = t);
|
|
316
|
+
}
|
|
317
|
+
}, Y = { class: "absolute z-[9999] w-full h-full top-0 flex flex-flow row items-center justify-center" }, le = /* @__PURE__ */ R({
|
|
318
|
+
__name: "index",
|
|
319
|
+
setup(i) {
|
|
320
|
+
const e = U();
|
|
321
|
+
return (s, n) => (b(), z("div", Y, [
|
|
322
|
+
B(v(N), D({ style: { "margin-top": "-10%" } }, v(e)), null, 16)
|
|
323
|
+
]));
|
|
324
|
+
}
|
|
325
|
+
}), ie = /* @__PURE__ */ R({
|
|
326
|
+
__name: "index",
|
|
327
|
+
props: {
|
|
328
|
+
icon: {},
|
|
329
|
+
type: { default: "info" },
|
|
330
|
+
showIcon: { type: Boolean, default: !0 },
|
|
331
|
+
message: {}
|
|
332
|
+
},
|
|
333
|
+
setup(i) {
|
|
334
|
+
const e = i, s = {
|
|
335
|
+
success: "#52c41a",
|
|
336
|
+
info: "#1890ff",
|
|
337
|
+
warning: "#faad14",
|
|
338
|
+
error: "#ff4d4f"
|
|
339
|
+
}, n = {
|
|
340
|
+
success: "icon-success-fill",
|
|
341
|
+
info: "icon-info-fill",
|
|
342
|
+
warning: "icon-warn-fill",
|
|
343
|
+
error: "icon-error-fill"
|
|
344
|
+
}, a = E(() => e.type || "info"), c = E(() => s[a.value]), r = E(() => n[a.value]), o = Math.random().toString(36).substring(2, 9), t = E(() => `${o}-${a.value}-${r.value}`);
|
|
345
|
+
return (u, l) => (b(), _(v(L), D({
|
|
346
|
+
"show-icon": u.showIcon,
|
|
347
|
+
type: u.type,
|
|
348
|
+
message: u.message
|
|
349
|
+
}, u.$attrs), {
|
|
350
|
+
icon: A(() => [
|
|
351
|
+
(b(), _(K, {
|
|
352
|
+
icon: r.value,
|
|
353
|
+
style: O({ color: c.value }),
|
|
354
|
+
key: t.value
|
|
355
|
+
}, null, 8, ["icon", "style"]))
|
|
356
|
+
]),
|
|
357
|
+
_: 1
|
|
358
|
+
}, 16, ["show-icon", "type", "message"]));
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
export {
|
|
362
|
+
ie as _,
|
|
363
|
+
X as a,
|
|
364
|
+
ce as b,
|
|
365
|
+
P as c,
|
|
366
|
+
J as d,
|
|
367
|
+
H as e,
|
|
368
|
+
S as f,
|
|
369
|
+
W as g,
|
|
370
|
+
le as h,
|
|
371
|
+
ne as i,
|
|
372
|
+
ae as j,
|
|
373
|
+
q as n,
|
|
374
|
+
x as p,
|
|
375
|
+
g as t,
|
|
376
|
+
G as v
|
|
377
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { defineComponent as F, provide as _, ref as w, watch as p, onMounted as B, createBlock as n, openBlock as r, unref as a, withCtx as i, createElementVNode as N, renderSlot as b, createVNode as V, createCommentVNode as d, createTextVNode as u, toDisplayString as v } from "vue";
|
|
2
|
-
import { _ as m } from "./index-
|
|
2
|
+
import { _ as m } from "./index-CCpTizF9.js";
|
|
3
3
|
import { Modal as D, Space as E } from "ant-design-vue";
|
|
4
4
|
import "@skyfox2000/fapi";
|
|
5
|
-
import { P as M, d as P, o as $, b as K } from "./uploadList-
|
|
5
|
+
import { P as M, d as P, o as $, b as K } from "./uploadList-DAVjJkqz.js";
|
|
6
6
|
import "@skyfox2000/microbase";
|
|
7
7
|
import "vue-m-message";
|
|
8
8
|
import "async-validator";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent as d, useAttrs as f, createElementBlock as u, openBlock as x, createVNode as e, withCtx as n, unref as o, mergeProps as r, renderSlot as p } from "vue";
|
|
2
2
|
import { Button as _ } from "ant-design-vue";
|
|
3
|
-
import { a as P, _ as k } from "./toolIcon-
|
|
3
|
+
import { a as P, _ as k } from "./toolIcon-CqM4gBIc.js";
|
|
4
4
|
const C = /* @__PURE__ */ d({
|
|
5
5
|
inheritAttrs: !1,
|
|
6
6
|
__name: "index",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent as x, createBlock as h, createCommentVNode as I, openBlock as u, unref as t, mergeProps as C, useAttrs as q, computed as j, ref as y, watch as k, withCtx as d, createElementBlock as g, normalizeStyle as T, createElementVNode as m, inject as J, onMounted as N, createVNode as l, toDisplayString as $, Fragment as L, createTextVNode as K, reactive as W, nextTick as Y, renderList as G, withModifiers as Q } from "vue";
|
|
2
|
-
import { a as w, _ as b } from "./toolIcon-
|
|
3
|
-
import { c as D, S as E, af as P, V as U, U as M, u as F, a as V, T as X, r as H, ad as z } from "./uploadList-
|
|
2
|
+
import { a as w, _ as b } from "./toolIcon-CqM4gBIc.js";
|
|
3
|
+
import { c as D, S as E, af as P, V as U, U as M, u as F, a as V, T as X, r as H, ad as z } from "./uploadList-DAVjJkqz.js";
|
|
4
4
|
import { _ as Z } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
5
5
|
import { theme as O, Breadcrumb as ee, Modal as te, Flex as ne, LayoutHeader as oe, Space as se, Menu as ie, Tabs as ce, TabPane as ae } from "ant-design-vue";
|
|
6
6
|
import { mainAppApis as R } from "@skyfox2000/microbase";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineComponent as i, createBlock as s, openBlock as l, unref as a, withCtx as p, renderSlot as f, createCommentVNode as u, mergeProps as d } from "vue";
|
|
2
2
|
import { Tooltip as I } from "ant-design-vue";
|
|
3
3
|
import { SERVER_HOST as r } from "@skyfox2000/fapi";
|
|
4
|
-
import { c as S } from "./uploadList-
|
|
4
|
+
import { c as S } from "./uploadList-DAVjJkqz.js";
|
|
5
5
|
const T = /* @__PURE__ */ i({
|
|
6
6
|
__name: "index",
|
|
7
7
|
props: {
|