@befly-addon/admin 1.7.0 → 1.7.1
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/adminViews/config/dict/index.vue +1 -1
- package/adminViews/config/dictType/index.vue +1 -1
- package/adminViews/config/system/index.vue +1 -1
- package/adminViews/log/email/index.vue +1 -1
- package/adminViews/log/login/index.vue +1 -1
- package/adminViews/log/operate/index.vue +1 -1
- package/adminViews/login_1/index.vue +1 -1
- package/adminViews/people/admin/components/edit.vue +2 -2
- package/adminViews/people/admin/index.vue +1 -1
- package/adminViews/permission/api/index.vue +1 -1
- package/adminViews/permission/menu/index.vue +2 -2
- package/adminViews/permission/role/components/edit.vue +1 -1
- package/adminViews/permission/role/components/menu.vue +1 -1
- package/adminViews/permission/role/index.vue +1 -1
- package/package.json +3 -3
- package/adminViews/utils/cleanParams.ts +0 -39
- package/utils/arrayToTree.ts +0 -135
- package/utils/fieldClear.ts +0 -85
- package/utils/hashPassword.ts +0 -19
- package/utils/withDefaultColumns.ts +0 -44
|
@@ -83,7 +83,7 @@ import ILucideChevronDown from "~icons/lucide/chevron-down";
|
|
|
83
83
|
import EditDialog from "./components/edit.vue";
|
|
84
84
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
85
85
|
import { $Http } from "@/plugins/http";
|
|
86
|
-
import { withDefaultColumns } from "
|
|
86
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
87
87
|
|
|
88
88
|
const $Data = $ref({
|
|
89
89
|
tableData: [],
|
|
@@ -80,7 +80,7 @@ import ILucideChevronDown from "~icons/lucide/chevron-down";
|
|
|
80
80
|
import EditDialog from "./components/edit.vue";
|
|
81
81
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
82
82
|
import { $Http } from "@/plugins/http";
|
|
83
|
-
import { withDefaultColumns } from "
|
|
83
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
84
84
|
|
|
85
85
|
const $Data = $ref({
|
|
86
86
|
tableData: [],
|
|
@@ -91,7 +91,7 @@ import ILucideChevronDown from "~icons/lucide/chevron-down";
|
|
|
91
91
|
import EditDialog from "./components/edit.vue";
|
|
92
92
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
93
93
|
import { $Http } from "@/plugins/http";
|
|
94
|
-
import { withDefaultColumns } from "
|
|
94
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
95
95
|
|
|
96
96
|
// 响应式数据
|
|
97
97
|
const $Data = $ref({
|
|
@@ -90,7 +90,7 @@ import ILucideSend from "~icons/lucide/send";
|
|
|
90
90
|
import ILucideCheckCircle from "~icons/lucide/check-circle";
|
|
91
91
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
92
92
|
import { $Http } from "@/plugins/http";
|
|
93
|
-
import { withDefaultColumns } from "
|
|
93
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
94
94
|
|
|
95
95
|
const sendFormRef = $ref(null);
|
|
96
96
|
|
|
@@ -54,7 +54,7 @@ import { Button as TButton, Table as TTable, Tag as TTag, Pagination as TPaginat
|
|
|
54
54
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
55
55
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
56
56
|
import { $Http } from "@/plugins/http";
|
|
57
|
-
import { withDefaultColumns } from "
|
|
57
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
58
58
|
|
|
59
59
|
// 响应式数据
|
|
60
60
|
const $Data = $ref({
|
|
@@ -74,7 +74,7 @@ import { Button as TButton, Table as TTable, Tag as TTag, Pagination as TPaginat
|
|
|
74
74
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
75
75
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
76
76
|
import { $Http } from "@/plugins/http";
|
|
77
|
-
import { withDefaultColumns } from "
|
|
77
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
78
78
|
|
|
79
79
|
// 响应式数据
|
|
80
80
|
const $Data = $ref({
|
|
@@ -70,7 +70,7 @@ import ILucideUser from "~icons/lucide/user";
|
|
|
70
70
|
import ILucideLock from "~icons/lucide/lock";
|
|
71
71
|
import { $Http } from "@/plugins/http";
|
|
72
72
|
import { $Storage } from "@/plugins/storage";
|
|
73
|
-
import { hashPassword } from "
|
|
73
|
+
import { hashPassword } from "befly-shared/utils/hashPassword";
|
|
74
74
|
|
|
75
75
|
const router = useRouter();
|
|
76
76
|
|
|
@@ -47,8 +47,8 @@ import {
|
|
|
47
47
|
MessagePlugin
|
|
48
48
|
} from "tdesign-vue-next";
|
|
49
49
|
import { $Http } from "@/plugins/http";
|
|
50
|
-
import { fieldClear } from "
|
|
51
|
-
import { hashPassword } from "
|
|
50
|
+
import { fieldClear } from "befly-shared/utils/fieldClear";
|
|
51
|
+
import { hashPassword } from "befly-shared/utils/hashPassword";
|
|
52
52
|
|
|
53
53
|
const $Prop = defineProps({
|
|
54
54
|
modelValue: {
|
|
@@ -79,7 +79,7 @@ import ILucideChevronDown from "~icons/lucide/chevron-down";
|
|
|
79
79
|
import EditDialog from "./components/edit.vue";
|
|
80
80
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
81
81
|
import { $Http } from "@/plugins/http";
|
|
82
|
-
import { withDefaultColumns } from "
|
|
82
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
83
83
|
|
|
84
84
|
// 响应式数据
|
|
85
85
|
const $Data = $ref({
|
|
@@ -64,7 +64,7 @@ import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
|
64
64
|
import ILucideSearch from "~icons/lucide/search";
|
|
65
65
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
66
66
|
import { $Http } from "@/plugins/http";
|
|
67
|
-
import { withDefaultColumns } from "
|
|
67
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
68
68
|
|
|
69
69
|
// 响应式数据
|
|
70
70
|
const $Data = $ref({
|
|
@@ -44,8 +44,8 @@ import { Button as TButton, Table as TTable, Tag as TTag, MessagePlugin } from "
|
|
|
44
44
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
45
45
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
46
46
|
import { $Http } from "@/plugins/http";
|
|
47
|
-
import { arrayToTree } from "
|
|
48
|
-
import { withDefaultColumns } from "
|
|
47
|
+
import { arrayToTree } from "befly-shared/utils/arrayToTree";
|
|
48
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
49
49
|
|
|
50
50
|
// 响应式数据
|
|
51
51
|
const $Data = $ref({
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
MessagePlugin
|
|
44
44
|
} from "tdesign-vue-next";
|
|
45
45
|
import { $Http } from "@/plugins/http";
|
|
46
|
-
import { fieldClear } from "
|
|
46
|
+
import { fieldClear } from "befly-shared/utils/fieldClear";
|
|
47
47
|
|
|
48
48
|
const $Prop = defineProps({
|
|
49
49
|
modelValue: {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
import { Dialog as TDialog, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Button as TButton, Input as TInput, MessagePlugin } from "tdesign-vue-next";
|
|
45
45
|
import ILucideSearch from "~icons/lucide/search";
|
|
46
46
|
import { $Http } from "@/plugins/http";
|
|
47
|
-
import { arrayToTree } from "
|
|
47
|
+
import { arrayToTree } from "befly-shared/utils/arrayToTree";
|
|
48
48
|
|
|
49
49
|
const $Prop = defineProps({
|
|
50
50
|
modelValue: {
|
|
@@ -102,7 +102,7 @@ import MenuDialog from "./components/menu.vue";
|
|
|
102
102
|
import ApiDialog from "./components/api.vue";
|
|
103
103
|
import DetailPanel from "@/components/DetailPanel.vue";
|
|
104
104
|
import { $Http } from "@/plugins/http";
|
|
105
|
-
import { withDefaultColumns } from "
|
|
105
|
+
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
106
106
|
|
|
107
107
|
// 响应式数据
|
|
108
108
|
const $Data = $ref({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@befly-addon/admin",
|
|
3
|
-
"version": "1.7.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.7.1",
|
|
4
|
+
"gitHead": "540d9551c589cb33d711c593e561f0fffc0aac0c",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly - 管理后台功能组件",
|
|
7
7
|
"keywords": [
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"ua-parser-js": "^2.0.7"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"befly": "3.15.
|
|
56
|
+
"befly": "3.15.1"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"befly": "^3.14.0"
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export function cleanParams<TData extends Record<string, unknown>>(data: TData, dropValues?: readonly unknown[], dropKeyValue?: Record<string, readonly unknown[]>): Partial<TData> {
|
|
2
|
-
const globalDropValues = dropValues ?? [];
|
|
3
|
-
const perKeyDropValues = dropKeyValue ?? {};
|
|
4
|
-
|
|
5
|
-
const globalDropSet = new Set<unknown>(globalDropValues);
|
|
6
|
-
|
|
7
|
-
const out: Record<string, unknown> = {};
|
|
8
|
-
|
|
9
|
-
for (const key of Object.keys(data)) {
|
|
10
|
-
const value = data[key];
|
|
11
|
-
|
|
12
|
-
// 默认强制移除 null / undefined
|
|
13
|
-
if (value === null || value === undefined) {
|
|
14
|
-
continue;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// 如果该 key 配了规则:以 key 规则为准,不再应用全局 dropValues
|
|
18
|
-
if (Object.hasOwn(perKeyDropValues, key)) {
|
|
19
|
-
const keyDropValues = perKeyDropValues[key] ?? [];
|
|
20
|
-
const keyDropSet = new Set<unknown>(keyDropValues);
|
|
21
|
-
|
|
22
|
-
if (keyDropSet.has(value)) {
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
out[key] = value;
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// 未配置 key 规则:应用全局 dropValues
|
|
31
|
-
if (globalDropSet.has(value)) {
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
out[key] = value;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return out as Partial<TData>;
|
|
39
|
-
}
|
package/utils/arrayToTree.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
export type ArrayToTreeResult<T extends Record<string, any>> = {
|
|
2
|
-
flat: Array<T>;
|
|
3
|
-
tree: Array<T>;
|
|
4
|
-
map: Map<string, T>;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 将一维数组按 { id, pid } 组装为树形结构(纯函数 / 无副作用)。
|
|
9
|
-
*
|
|
10
|
-
* - 默认字段:id / pid / children / sort
|
|
11
|
-
* - pid 为空字符串或父节点不存在时,视为根节点
|
|
12
|
-
* - 内部会 clone 一份节点对象,并写入 children: []
|
|
13
|
-
* - 默认自带递归排序:按 sort 升序;sort 缺省/非法或 < 1 视为 999999;sort 相同按 id 自然序
|
|
14
|
-
*/
|
|
15
|
-
export function arrayToTree<T extends Record<string, any>>(items: T[], id: string = "id", pid: string = "pid", children: string = "children", sort: string = "sort"): ArrayToTreeResult<T> {
|
|
16
|
-
const idKey = typeof id === "string" && id.length > 0 ? id : "id";
|
|
17
|
-
const pidKey = typeof pid === "string" && pid.length > 0 ? pid : "pid";
|
|
18
|
-
const childrenKey = typeof children === "string" && children.length > 0 ? children : "children";
|
|
19
|
-
const sortKey = typeof sort === "string" && sort.length > 0 ? sort : "sort";
|
|
20
|
-
|
|
21
|
-
const map = new Map<string, T>();
|
|
22
|
-
const flat: T[] = [];
|
|
23
|
-
|
|
24
|
-
const safeItems = Array.isArray(items) ? items : [];
|
|
25
|
-
|
|
26
|
-
const normalizeKey = (value: unknown): string => {
|
|
27
|
-
if (typeof value === "string") {
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
31
|
-
return String(value);
|
|
32
|
-
}
|
|
33
|
-
return "";
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
for (const item of safeItems) {
|
|
37
|
-
const rawId = item ? (item as any)[idKey] : undefined;
|
|
38
|
-
const rawPid = item ? (item as any)[pidKey] : undefined;
|
|
39
|
-
|
|
40
|
-
const normalizedId = normalizeKey(rawId);
|
|
41
|
-
const normalizedPid = normalizeKey(rawPid);
|
|
42
|
-
|
|
43
|
-
const nextNode = Object.assign({}, item) as T;
|
|
44
|
-
(nextNode as any)[idKey] = normalizedId;
|
|
45
|
-
(nextNode as any)[pidKey] = normalizedPid;
|
|
46
|
-
(nextNode as any)[childrenKey] = [];
|
|
47
|
-
|
|
48
|
-
flat.push(nextNode);
|
|
49
|
-
|
|
50
|
-
if (normalizedId.length > 0) {
|
|
51
|
-
map.set(normalizedId, nextNode);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const tree: T[] = [];
|
|
56
|
-
|
|
57
|
-
for (const node of flat) {
|
|
58
|
-
const selfId = normalizeKey(node ? (node as any)[idKey] : undefined);
|
|
59
|
-
const parentId = normalizeKey(node ? (node as any)[pidKey] : undefined);
|
|
60
|
-
|
|
61
|
-
if (parentId.length > 0 && parentId !== selfId) {
|
|
62
|
-
const parent = map.get(parentId);
|
|
63
|
-
if (parent && Array.isArray((parent as any)[childrenKey])) {
|
|
64
|
-
(parent as any)[childrenKey].push(node);
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
tree.push(node);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" });
|
|
73
|
-
|
|
74
|
-
const getSortValue = (node: T): number => {
|
|
75
|
-
const raw = node ? (node as any)[sortKey] : undefined;
|
|
76
|
-
if (typeof raw !== "number") {
|
|
77
|
-
return 999999;
|
|
78
|
-
}
|
|
79
|
-
if (!Number.isFinite(raw)) {
|
|
80
|
-
return 999999;
|
|
81
|
-
}
|
|
82
|
-
if (raw < 1) {
|
|
83
|
-
return 999999;
|
|
84
|
-
}
|
|
85
|
-
return raw;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const compareNode = (a: T, b: T): number => {
|
|
89
|
-
const aSort = getSortValue(a);
|
|
90
|
-
const bSort = getSortValue(b);
|
|
91
|
-
|
|
92
|
-
if (aSort !== bSort) {
|
|
93
|
-
return aSort - bSort;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const aId = a ? (a as any)[idKey] : "";
|
|
97
|
-
const bId = b ? (b as any)[idKey] : "";
|
|
98
|
-
|
|
99
|
-
return collator.compare(typeof aId === "string" ? aId : "", typeof bId === "string" ? bId : "");
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const sortTreeInPlace = (nodes: Array<T>, seen: WeakSet<object>): void => {
|
|
103
|
-
if (!Array.isArray(nodes)) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (nodes.length > 1) {
|
|
108
|
-
nodes.sort(compareNode);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
for (const node of nodes) {
|
|
112
|
-
if (typeof node !== "object" || node === null) {
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (seen.has(node)) {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
seen.add(node);
|
|
120
|
-
|
|
121
|
-
const childNodes = (node as any)[childrenKey];
|
|
122
|
-
if (Array.isArray(childNodes) && childNodes.length > 0) {
|
|
123
|
-
sortTreeInPlace(childNodes, seen);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
sortTreeInPlace(tree, new WeakSet<object>());
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
flat: flat,
|
|
132
|
-
tree: tree,
|
|
133
|
-
map: map
|
|
134
|
-
};
|
|
135
|
-
}
|
package/utils/fieldClear.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
export interface FieldClearOptions {
|
|
2
|
-
pickKeys?: string[];
|
|
3
|
-
omitKeys?: string[];
|
|
4
|
-
keepValues?: any[];
|
|
5
|
-
excludeValues?: any[];
|
|
6
|
-
keepMap?: Record<string, any>;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type FieldClearResult<T> = T extends Array<infer U> ? Array<FieldClearResult<U>> : T extends object ? { [K in keyof T]?: T[K] } : T;
|
|
10
|
-
|
|
11
|
-
function isObject(val: unknown): val is Record<string, any> {
|
|
12
|
-
return val !== null && typeof val === "object" && !Array.isArray(val);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function isArray(val: unknown): val is any[] {
|
|
16
|
-
return Array.isArray(val);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function fieldClear<T = any>(data: T | T[], options: FieldClearOptions = {}): FieldClearResult<T> {
|
|
20
|
-
const pickKeys = options.pickKeys;
|
|
21
|
-
const omitKeys = options.omitKeys;
|
|
22
|
-
const keepValues = options.keepValues;
|
|
23
|
-
const excludeValues = options.excludeValues;
|
|
24
|
-
const keepMap = options.keepMap;
|
|
25
|
-
|
|
26
|
-
const filterObj = (obj: Record<string, any>) => {
|
|
27
|
-
const result: Record<string, any> = {};
|
|
28
|
-
|
|
29
|
-
let keys = Object.keys(obj);
|
|
30
|
-
if (pickKeys && pickKeys.length) {
|
|
31
|
-
keys = keys.filter((k) => pickKeys.includes(k));
|
|
32
|
-
}
|
|
33
|
-
if (omitKeys && omitKeys.length) {
|
|
34
|
-
keys = keys.filter((k) => !omitKeys.includes(k));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
for (const key of keys) {
|
|
38
|
-
const value = obj[key];
|
|
39
|
-
|
|
40
|
-
// 1. keepMap 优先
|
|
41
|
-
if (keepMap && Object.hasOwn(keepMap, key)) {
|
|
42
|
-
if (Object.is(keepMap[key], value)) {
|
|
43
|
-
result[key] = value;
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 2. keepValues
|
|
49
|
-
if (keepValues && keepValues.length && !keepValues.includes(value)) {
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// 3. excludeValues
|
|
54
|
-
if (excludeValues && excludeValues.length && excludeValues.includes(value)) {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
result[key] = value;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return result;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
if (isArray(data)) {
|
|
65
|
-
return (data as any[])
|
|
66
|
-
.map((item) => {
|
|
67
|
-
if (isObject(item)) {
|
|
68
|
-
return filterObj(item);
|
|
69
|
-
}
|
|
70
|
-
return item;
|
|
71
|
-
})
|
|
72
|
-
.filter((item) => {
|
|
73
|
-
if (isObject(item)) {
|
|
74
|
-
return Object.keys(item).length > 0;
|
|
75
|
-
}
|
|
76
|
-
return true;
|
|
77
|
-
}) as FieldClearResult<T>;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (isObject(data)) {
|
|
81
|
-
return filterObj(data as Record<string, any>) as FieldClearResult<T>;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return data as FieldClearResult<T>;
|
|
85
|
-
}
|
package/utils/hashPassword.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 使用 SHA-256 对密码进行哈希。
|
|
3
|
-
* @param password - 原始密码
|
|
4
|
-
* @param salt - 盐值,默认为 befly
|
|
5
|
-
* @returns 哈希后的密码(十六进制字符串)
|
|
6
|
-
*/
|
|
7
|
-
export async function hashPassword(password: string, salt: string = "befly"): Promise<string> {
|
|
8
|
-
const data = password + salt;
|
|
9
|
-
|
|
10
|
-
const encoder = new TextEncoder();
|
|
11
|
-
const dataBuffer = encoder.encode(data);
|
|
12
|
-
|
|
13
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", dataBuffer);
|
|
14
|
-
|
|
15
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
16
|
-
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
17
|
-
|
|
18
|
-
return hashHex;
|
|
19
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 为表格列添加默认配置(纯函数)。
|
|
3
|
-
*
|
|
4
|
-
* 默认行为:
|
|
5
|
-
* - base 默认:{ width: 200, ellipsis: true }
|
|
6
|
-
* - 特殊列:operation/state/id
|
|
7
|
-
* - colKey 以 At/At2 结尾时:默认 { align: "center" }
|
|
8
|
-
* - customConfig 可覆盖/扩展默认 specialColumnConfig
|
|
9
|
-
*/
|
|
10
|
-
export function withDefaultColumns(columns: any[], customConfig?: Record<string, any>): any[] {
|
|
11
|
-
const safeColumns = Array.isArray(columns) ? columns : [];
|
|
12
|
-
|
|
13
|
-
const specialColumnConfig: Record<string, any> = Object.assign(
|
|
14
|
-
{
|
|
15
|
-
operation: { width: 100, align: "center", fixed: "right" },
|
|
16
|
-
state: { width: 100, align: "center" },
|
|
17
|
-
id: { width: 200, align: "center" }
|
|
18
|
-
},
|
|
19
|
-
customConfig || {}
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
return safeColumns.map((col) => {
|
|
23
|
-
const colKey = col && (col as any).colKey;
|
|
24
|
-
|
|
25
|
-
let specialConfig = colKey ? specialColumnConfig[colKey] : undefined;
|
|
26
|
-
|
|
27
|
-
if (!specialConfig && typeof colKey === "string" && (colKey.endsWith("At") || colKey.endsWith("At2"))) {
|
|
28
|
-
specialConfig = { align: "center" };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const base = {
|
|
32
|
-
width: 200,
|
|
33
|
-
ellipsis: true
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const merged = Object.assign({}, base);
|
|
37
|
-
if (specialConfig) {
|
|
38
|
-
Object.assign(merged, specialConfig);
|
|
39
|
-
}
|
|
40
|
-
Object.assign(merged, col);
|
|
41
|
-
|
|
42
|
-
return merged;
|
|
43
|
-
});
|
|
44
|
-
}
|