vome-core 0.0.89 → 0.0.91
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/dist/admin/config/plugin-dev.js +67 -1
- package/dist/admin/crud/config.js +33 -1
- package/dist/admin/crud/confirm.js +97 -1
- package/dist/admin/crud/dict.js +67 -1
- package/dist/admin/crud/index.js +81 -1
- package/dist/admin/crud/key.js +20 -1
- package/dist/admin/crud/mitt.js +21 -1
- package/dist/admin/crud/plugins.js +278 -1
- package/dist/admin/crud/span.js +35 -1
- package/dist/admin/crud/style.js +132 -1
- package/dist/admin/crud/validate.js +92 -1
- package/dist/admin/crud/vm-upsert.vue +29 -0
- package/dist/admin/directives/perm.js +14 -1
- package/dist/admin/hooks/useUpload.js +63 -1
- package/dist/admin/lib/browser.js +24 -1
- package/dist/admin/lib/cn.js +5 -1
- package/dist/admin/lib/dialog-float.js +13 -1
- package/dist/admin/lib/export-excel.js +64 -1
- package/dist/admin/lib/import-excel.js +61 -1
- package/dist/admin/lib/json.js +42 -1
- package/dist/admin/lib/menu.js +11 -1
- package/dist/admin/lib/tree.js +1 -1
- package/dist/admin/lib/upload.js +88 -1
- package/dist/admin/lib/video-frame.js +80 -1
- package/dist/client/dict.d.ts +8 -1
- package/dist/client/dict.js +13 -2
- package/dist/index.js +28215 -1
- package/dist/server/index.js +36228 -1
- package/dist/shared/excel.js +93 -1
- package/dist/shared/index.js +20 -1
- package/dist/shared/locale-json.js +68 -1
- package/dist/shared/tree.js +39 -1
- package/package.json +1 -1
package/dist/shared/excel.js
CHANGED
|
@@ -1 +1,93 @@
|
|
|
1
|
-
|
|
1
|
+
import * as XLSX from "xlsx";
|
|
2
|
+
export const IMPORT_SKIP_FIELDS = [
|
|
3
|
+
"id",
|
|
4
|
+
"createTime",
|
|
5
|
+
"updateTime",
|
|
6
|
+
"deletedAt",
|
|
7
|
+
"tenantId"
|
|
8
|
+
];
|
|
9
|
+
export function isImportSkipField(name) {
|
|
10
|
+
return IMPORT_SKIP_FIELDS.includes(name);
|
|
11
|
+
}
|
|
12
|
+
export function buildExcelBuffer(columns, rows, formatCell) {
|
|
13
|
+
const headers = columns.map((c) => c.label || c.prop);
|
|
14
|
+
const body = rows.map((row) => columns.map((col) => {
|
|
15
|
+
if (formatCell)
|
|
16
|
+
return formatCell(col.prop, row);
|
|
17
|
+
const val = row[col.prop];
|
|
18
|
+
if (val == null)
|
|
19
|
+
return "";
|
|
20
|
+
return String(val);
|
|
21
|
+
}));
|
|
22
|
+
const sheet = XLSX.utils.aoa_to_sheet([headers, ...body]);
|
|
23
|
+
const book = XLSX.utils.book_new();
|
|
24
|
+
XLSX.utils.book_append_sheet(book, sheet, "Sheet1");
|
|
25
|
+
return XLSX.write(book, { bookType: "xlsx", type: "array" });
|
|
26
|
+
}
|
|
27
|
+
export function buildImportTemplateBuffer(columns) {
|
|
28
|
+
return buildExcelBuffer(columns, []);
|
|
29
|
+
}
|
|
30
|
+
export function parseExcelBuffer(data, columns) {
|
|
31
|
+
const book = XLSX.read(data, { type: "array", cellDates: true });
|
|
32
|
+
const name = book.SheetNames[0];
|
|
33
|
+
if (!name)
|
|
34
|
+
return [];
|
|
35
|
+
const sheet = book.Sheets[name];
|
|
36
|
+
if (!sheet)
|
|
37
|
+
return [];
|
|
38
|
+
const aoa = XLSX.utils.sheet_to_json(sheet, {
|
|
39
|
+
header: 1,
|
|
40
|
+
defval: "",
|
|
41
|
+
raw: false
|
|
42
|
+
});
|
|
43
|
+
if (!aoa.length)
|
|
44
|
+
return [];
|
|
45
|
+
const headerRow = (aoa[0] || []).map((h) => String(h ?? "").trim());
|
|
46
|
+
const labelToProp = new Map;
|
|
47
|
+
if (columns?.length) {
|
|
48
|
+
for (const c of columns) {
|
|
49
|
+
labelToProp.set(c.label.trim(), c.prop);
|
|
50
|
+
labelToProp.set(c.prop, c.prop);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const props = headerRow.map((h) => {
|
|
54
|
+
if (!h)
|
|
55
|
+
return "";
|
|
56
|
+
return labelToProp.get(h) || h;
|
|
57
|
+
});
|
|
58
|
+
const rows = [];
|
|
59
|
+
for (let i = 1;i < aoa.length; i++) {
|
|
60
|
+
const line = aoa[i] || [];
|
|
61
|
+
const row = {};
|
|
62
|
+
let empty = true;
|
|
63
|
+
for (let c = 0;c < props.length; c++) {
|
|
64
|
+
const prop = props[c];
|
|
65
|
+
if (!prop)
|
|
66
|
+
continue;
|
|
67
|
+
let val = line[c];
|
|
68
|
+
if (val == null || val === "") {
|
|
69
|
+
row[prop] = val == null ? null : "";
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
empty = false;
|
|
73
|
+
if (typeof val === "string") {
|
|
74
|
+
row[prop] = val.trim();
|
|
75
|
+
} else {
|
|
76
|
+
row[prop] = val;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!empty)
|
|
80
|
+
rows.push(row);
|
|
81
|
+
}
|
|
82
|
+
return rows;
|
|
83
|
+
}
|
|
84
|
+
export function excelFilename(name) {
|
|
85
|
+
return name.endsWith(".xlsx") ? name : `${name}.xlsx`;
|
|
86
|
+
}
|
|
87
|
+
export function excelResponseHeaders(filename) {
|
|
88
|
+
const file = excelFilename(filename);
|
|
89
|
+
return {
|
|
90
|
+
"Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
91
|
+
"Content-Disposition": `attachment; filename*=UTF-8''${encodeURIComponent(file)}`
|
|
92
|
+
};
|
|
93
|
+
}
|
package/dist/shared/index.js
CHANGED
|
@@ -1 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
export { merge } from "../comm/merge";
|
|
2
|
+
export { deepTree, flattenTree } from "./tree";
|
|
3
|
+
export {
|
|
4
|
+
RES_CODE
|
|
5
|
+
} from "../routing/base";
|
|
6
|
+
export {
|
|
7
|
+
buildExcelBuffer,
|
|
8
|
+
buildImportTemplateBuffer,
|
|
9
|
+
parseExcelBuffer,
|
|
10
|
+
excelFilename,
|
|
11
|
+
excelResponseHeaders,
|
|
12
|
+
IMPORT_SKIP_FIELDS,
|
|
13
|
+
isImportSkipField
|
|
14
|
+
} from "./excel";
|
|
15
|
+
export {
|
|
16
|
+
flattenLocale,
|
|
17
|
+
unflattenLocale,
|
|
18
|
+
hashLocaleJson,
|
|
19
|
+
extractJsonObject
|
|
20
|
+
} from "./locale-json";
|
|
@@ -1 +1,68 @@
|
|
|
1
|
-
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export function flattenLocale(input, prefix = "") {
|
|
3
|
+
const out = {};
|
|
4
|
+
for (const [k, v] of Object.entries(input)) {
|
|
5
|
+
const key = prefix ? `${prefix}.${k}` : k;
|
|
6
|
+
if (v != null && typeof v === "object" && !Array.isArray(v)) {
|
|
7
|
+
Object.assign(out, flattenLocale(v, key));
|
|
8
|
+
} else if (typeof v === "string") {
|
|
9
|
+
out[key] = v;
|
|
10
|
+
} else if (v != null) {
|
|
11
|
+
out[key] = String(v);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return out;
|
|
15
|
+
}
|
|
16
|
+
export function unflattenLocale(flat) {
|
|
17
|
+
const root = {};
|
|
18
|
+
for (const [path, value] of Object.entries(flat)) {
|
|
19
|
+
const parts = path.split(".").filter(Boolean);
|
|
20
|
+
if (!parts.length)
|
|
21
|
+
continue;
|
|
22
|
+
let cur = root;
|
|
23
|
+
for (let i = 0;i < parts.length - 1; i++) {
|
|
24
|
+
const p = parts[i];
|
|
25
|
+
const next = cur[p];
|
|
26
|
+
if (!next || typeof next !== "object" || Array.isArray(next)) {
|
|
27
|
+
cur[p] = {};
|
|
28
|
+
}
|
|
29
|
+
cur = cur[p];
|
|
30
|
+
}
|
|
31
|
+
cur[parts[parts.length - 1]] = value;
|
|
32
|
+
}
|
|
33
|
+
return root;
|
|
34
|
+
}
|
|
35
|
+
export function hashLocaleJson(obj) {
|
|
36
|
+
const flat = flattenLocale(obj);
|
|
37
|
+
const keys = Object.keys(flat).sort();
|
|
38
|
+
const payload = keys.map((k) => `${k}=${flat[k]}`).join(`
|
|
39
|
+
`);
|
|
40
|
+
return createHash("sha256").update(payload).digest("hex").slice(0, 32);
|
|
41
|
+
}
|
|
42
|
+
export function extractJsonObject(text) {
|
|
43
|
+
const raw = String(text || "").trim();
|
|
44
|
+
if (!raw)
|
|
45
|
+
throw new Error("AI 返回空内容");
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(raw);
|
|
48
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
} catch {}
|
|
52
|
+
const fence = raw.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
53
|
+
if (fence?.[1]) {
|
|
54
|
+
const parsed = JSON.parse(fence[1].trim());
|
|
55
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
56
|
+
return parsed;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const start = raw.indexOf("{");
|
|
60
|
+
const end = raw.lastIndexOf("}");
|
|
61
|
+
if (start >= 0 && end > start) {
|
|
62
|
+
const parsed = JSON.parse(raw.slice(start, end + 1));
|
|
63
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
64
|
+
return parsed;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
throw new Error("AI 返回无法解析为 JSON 对象");
|
|
68
|
+
}
|
package/dist/shared/tree.js
CHANGED
|
@@ -1 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
export function deepTree(list, sort = "asc") {
|
|
2
|
+
const map = new Map;
|
|
3
|
+
for (const row of list) {
|
|
4
|
+
if (row.id == null)
|
|
5
|
+
continue;
|
|
6
|
+
map.set(row.id, { ...row, children: [] });
|
|
7
|
+
}
|
|
8
|
+
const roots = [];
|
|
9
|
+
for (const node of map.values()) {
|
|
10
|
+
const pid = node.parentId;
|
|
11
|
+
if (pid != null && pid !== "" && map.has(pid)) {
|
|
12
|
+
map.get(pid).children.push(node);
|
|
13
|
+
} else {
|
|
14
|
+
roots.push(node);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const sortRec = (arr) => {
|
|
18
|
+
arr.sort((a, b) => {
|
|
19
|
+
const ao = a.orderNum ?? 0;
|
|
20
|
+
const bo = b.orderNum ?? 0;
|
|
21
|
+
const d = sort === "desc" ? bo - ao : ao - bo;
|
|
22
|
+
return d || Number(a.id) - Number(b.id);
|
|
23
|
+
});
|
|
24
|
+
for (const n of arr)
|
|
25
|
+
if (n.children?.length)
|
|
26
|
+
sortRec(n.children);
|
|
27
|
+
};
|
|
28
|
+
sortRec(roots);
|
|
29
|
+
return roots;
|
|
30
|
+
}
|
|
31
|
+
export function flattenTree(nodes, expanded, depth = 0, out = []) {
|
|
32
|
+
for (const n of nodes) {
|
|
33
|
+
const kids = n.children || [];
|
|
34
|
+
out.push({ ...n, depth, hasChildren: kids.length > 0 });
|
|
35
|
+
if (kids.length && expanded.has(n.id))
|
|
36
|
+
flattenTree(kids, expanded, depth + 1, out);
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|