@jiangood/open-admin 2.5.9 → 3.0.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/package.json +20 -8
- package/src/framework/GlobalData.ts +85 -0
- package/src/framework/biz/OrgTree.tsx +2 -7
- package/src/framework/biz/Perm.tsx +11 -0
- package/src/framework/biz/PermActions.tsx +18 -15
- package/src/framework/biz/index.tsx +34 -19
- package/src/framework/components/ContextMenu/index.tsx +105 -78
- package/src/framework/components/DownloadModal/index.tsx +15 -17
- package/src/framework/components/ErrorBoundary/index.tsx +2 -2
- package/src/framework/components/FormModal/index.tsx +76 -0
- package/src/framework/components/Gap/index.tsx +1 -1
- package/src/framework/components/NamedIcon/index.tsx +55 -9
- package/src/framework/components/Page/index.less +0 -1
- package/src/framework/components/Page/index.tsx +34 -27
- package/src/framework/components/PageLoading/index.less +15 -0
- package/src/framework/components/PageLoading/index.tsx +32 -16
- package/src/framework/components/ProTable/index.tsx +86 -15
- package/src/framework/components/index.ts +1 -0
- package/src/framework/config/index.ts +1 -0
- package/src/framework/config/themeConfig.ts +39 -0
- package/src/framework/fields/FieldBoolean/index.tsx +11 -2
- package/src/framework/fields/FieldDate/index.tsx +22 -7
- package/src/framework/fields/FieldDateRange/index.tsx +24 -6
- package/src/framework/fields/FieldDictSelect/index.tsx +1 -0
- package/src/framework/fields/FieldEditor/index.tsx +7 -1
- package/src/framework/fields/FieldNumberRange/index.tsx +14 -5
- package/src/framework/fields/FieldPercent/index.tsx +16 -5
- package/src/framework/fields/FieldRemoteSelect/index.tsx +4 -2
- package/src/framework/fields/FieldRemoteTreeSelect/index.tsx +2 -1
- package/src/framework/fields/FieldSysOrgTree/index.tsx +6 -1
- package/src/framework/fields/FieldSysOrgTreeSelect/index.tsx +6 -1
- package/src/framework/fields/FieldTable/index.tsx +35 -6
- package/src/framework/fields/FieldTableSelect/index.tsx +18 -2
- package/src/framework/fields/FieldUploadFile/index.tsx +69 -28
- package/src/framework/fields/index.ts +0 -1
- package/src/framework/index.ts +2 -0
- package/src/framework/router/Link.tsx +26 -0
- package/src/framework/router/PageFrame.tsx +31 -0
- package/src/framework/router/history.ts +50 -0
- package/src/framework/router/index.ts +4 -0
- package/src/framework/router/matcher.ts +58 -0
- package/src/framework/utils/{ArrayUtils.js → ArrayUtils.ts} +5 -5
- package/src/framework/utils/{DateUtils.js → DateUtils.ts} +19 -19
- package/src/framework/utils/{DeviceUtils.js → DeviceUtils.ts} +8 -1
- package/src/framework/utils/{EventBus.js → EventBus.ts} +13 -6
- package/src/framework/utils/MessageApi.ts +5 -0
- package/src/framework/utils/ModalApi.ts +5 -0
- package/src/framework/utils/ObjectUtils.ts +15 -0
- package/src/framework/utils/{StorageUtils.js → StorageUtils.ts} +7 -7
- package/src/framework/utils/{StringUtils.js → StringUtils.ts} +15 -15
- package/src/framework/utils/{TreeUtils.js → TreeUtils.ts} +19 -12
- package/src/framework/utils/{UrlUtils.js → UrlUtils.ts} +10 -10
- package/src/framework/utils/index.ts +2 -1
- package/src/framework/utils/system/{DictUtils.js → DictUtils.ts} +16 -4
- package/src/framework/utils/system/{HttpUtils.js → HttpUtils.ts} +25 -21
- package/src/framework/utils/system/PageUtils.ts +49 -0
- package/src/framework/utils/system/{PermUtils.js → PermUtils.ts} +5 -6
- package/src/framework/utils/system/index.ts +0 -2
- package/src/framework/views/ViewBoolean/index.tsx +6 -3
- package/src/framework/views/ViewFileButton/index.tsx +13 -8
- package/src/framework/views/ViewImage/index.tsx +19 -14
- package/src/framework/views/ViewRange/index.tsx +10 -7
- package/src/framework/views/ViewText/index.tsx +9 -11
- package/src/layouts/admin/AdminTabs.jsx +79 -0
- package/src/layouts/admin/AdminTabs.less +63 -0
- package/src/layouts/admin/HeaderRight.jsx +27 -13
- package/src/layouts/admin/TabLayout.jsx +124 -0
- package/src/layouts/admin/index.jsx +5 -6
- package/src/layouts/admin/index.less +1 -82
- package/src/layouts/index.tsx +148 -0
- package/src/main.jsx +8 -0
- package/src/pages/account/changePassword.jsx +14 -10
- package/src/pages/article/$code.jsx +2 -2
- package/src/pages/index.jsx +6 -4
- package/src/pages/{login.jsx → public/login.jsx} +7 -10
- package/src/pages/public/test.jsx +30 -0
- package/src/pages/{forceUpdatePwd.jsx → standalone/forceUpdatePwd.jsx} +3 -24
- package/src/pages/system/article/index.jsx +51 -56
- package/src/pages/system/dict/index.jsx +60 -91
- package/src/pages/system/file/index.jsx +23 -17
- package/src/pages/system/job/index.jsx +63 -72
- package/src/pages/system/log/index.jsx +11 -8
- package/src/pages/system/org/index.jsx +60 -80
- package/src/pages/system/role/index.jsx +50 -86
- package/src/pages/system/role/rolePerm.jsx +2 -2
- package/src/pages/system/user/index.jsx +120 -73
- package/src/pages/system/user/userPerm.jsx +2 -2
- package/vite-plugin/index.js +107 -0
- package/config/common-plugin.js +0 -145
- package/config/config.js +0 -5
- package/config/utils.js +0 -73
- package/src/.umi-production/appData.json +0 -2257
- package/src/.umi-production/core/EmptyRoute.tsx +0 -9
- package/src/.umi-production/core/defineApp.ts +0 -16
- package/src/.umi-production/core/helmet.ts +0 -10
- package/src/.umi-production/core/helmetContext.ts +0 -4
- package/src/.umi-production/core/history.ts +0 -72
- package/src/.umi-production/core/historyIntelli.ts +0 -132
- package/src/.umi-production/core/plugin.ts +0 -40
- package/src/.umi-production/core/pluginConfig.ts +0 -330
- package/src/.umi-production/core/pluginConfigJoi.d.ts +0 -7
- package/src/.umi-production/core/polyfill.ts +0 -220
- package/src/.umi-production/core/route.tsx +0 -47
- package/src/.umi-production/core/routeProps.js +0 -5
- package/src/.umi-production/core/routeProps.ts +0 -6
- package/src/.umi-production/core/terminal.ts +0 -37
- package/src/.umi-production/exports.ts +0 -17
- package/src/.umi-production/testBrowser.tsx +0 -90
- package/src/.umi-production/tsconfig.json +0 -43
- package/src/.umi-production/typings.d.ts +0 -136
- package/src/.umi-production/umi.ts +0 -83
- package/src/framework/GlobalData.d.ts +0 -10
- package/src/framework/GlobalData.js +0 -42
- package/src/framework/biz/HasPerm.tsx +0 -14
- package/src/framework/fields/FieldRemoteSelectMultiple/index.tsx +0 -29
- package/src/framework/utils/ArrayUtils.d.ts +0 -6
- package/src/framework/utils/DateUtils.d.ts +0 -20
- package/src/framework/utils/DeviceUtils.d.ts +0 -3
- package/src/framework/utils/EventBus.d.ts +0 -6
- package/src/framework/utils/MessageUtils.d.ts +0 -10
- package/src/framework/utils/MessageUtils.js +0 -43
- package/src/framework/utils/ObjectUtils.d.ts +0 -14
- package/src/framework/utils/ObjectUtils.js +0 -12
- package/src/framework/utils/StorageUtils.d.ts +0 -4
- package/src/framework/utils/StringUtils.d.ts +0 -17
- package/src/framework/utils/TreeUtils.d.ts +0 -13
- package/src/framework/utils/UrlUtils.d.ts +0 -6
- package/src/framework/utils/system/DictUtils.d.ts +0 -20
- package/src/framework/utils/system/FormRegistry.d.ts +0 -8
- package/src/framework/utils/system/FormRegistry.js +0 -31
- package/src/framework/utils/system/HttpUtils.d.ts +0 -14
- package/src/framework/utils/system/PageUtils.d.ts +0 -14
- package/src/framework/utils/system/PageUtils.js +0 -59
- package/src/framework/utils/system/PermUtils.d.ts +0 -5
- package/src/framework/utils/system/ThemeUtils.d.ts +0 -6
- package/src/framework/utils/system/ThemeUtils.js +0 -52
- package/src/layouts/PageRender.tsx +0 -29
- package/src/layouts/admin/TabPageRender.jsx +0 -210
- package/src/layouts/index.jsx +0 -120
- package/src/loading.jsx +0 -19
- package/src/pages/about.jsx +0 -16
- /package/src/pages/{login.less → public/login.less} +0 -0
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
export class ArrayUtils {
|
|
2
|
-
static contains(arr, item) {
|
|
2
|
+
static contains<T>(arr: T[], item: T): boolean {
|
|
3
3
|
return arr.indexOf(item) !== -1;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
static containsAny(arr, ...items) {
|
|
6
|
+
static containsAny<T>(arr: T[], ...items: T[]): boolean {
|
|
7
7
|
for (const item of items) {
|
|
8
8
|
if (ArrayUtils.contains(arr, item)) return true;
|
|
9
9
|
}
|
|
10
10
|
return false;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
static maxBy(arr, key) {
|
|
13
|
+
static maxBy<T extends Record<K, any>, K extends keyof T>(arr: T[], key: K): T | undefined {
|
|
14
14
|
if (arr == null || arr.length === 0) return undefined;
|
|
15
|
-
let maxElement = undefined;
|
|
15
|
+
let maxElement: T | undefined = undefined;
|
|
16
16
|
let maxValue = -Infinity;
|
|
17
17
|
for (const element of arr) {
|
|
18
18
|
const value = element[key];
|
|
@@ -24,7 +24,7 @@ export class ArrayUtils {
|
|
|
24
24
|
return maxElement;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
static unique(arr) {
|
|
27
|
+
static unique<T>(arr: T[]): T[] {
|
|
28
28
|
return [...new Set(arr)];
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {StringUtils} from './StringUtils';
|
|
2
2
|
|
|
3
3
|
export class DateUtils {
|
|
4
|
-
static convertTypeToFormat(type) {
|
|
4
|
+
static convertTypeToFormat(type: string): string {
|
|
5
5
|
if (type === 'YEAR') type = 'YYYY';
|
|
6
6
|
else if (type === 'YEAR_MONTH') type = 'YYYY-MM';
|
|
7
7
|
else if (type === 'YEAR_QUARTER') type = 'YYYY-QQ';
|
|
@@ -9,35 +9,35 @@ export class DateUtils {
|
|
|
9
9
|
return type;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
static year(date) { return date.getFullYear(); }
|
|
13
|
-
static month(date) { return StringUtils.pad(date.getMonth() + 1, 2); }
|
|
14
|
-
static date(date) { return StringUtils.pad(date.getDate(), 2); }
|
|
15
|
-
static hour(date) { return StringUtils.pad(date.getHours(), 2); }
|
|
16
|
-
static minute(date) { return StringUtils.pad(date.getMinutes(), 2); }
|
|
17
|
-
static second(date) { return StringUtils.pad(date.getSeconds(), 2); }
|
|
12
|
+
static year(date: Date): number { return date.getFullYear(); }
|
|
13
|
+
static month(date: Date): string { return StringUtils.pad(date.getMonth() + 1, 2); }
|
|
14
|
+
static date(date: Date): string { return StringUtils.pad(date.getDate(), 2); }
|
|
15
|
+
static hour(date: Date): string { return StringUtils.pad(date.getHours(), 2); }
|
|
16
|
+
static minute(date: Date): string { return StringUtils.pad(date.getMinutes(), 2); }
|
|
17
|
+
static second(date: Date): string { return StringUtils.pad(date.getSeconds(), 2); }
|
|
18
18
|
|
|
19
|
-
static formatDate(d) {
|
|
19
|
+
static formatDate(d: Date): string {
|
|
20
20
|
return this.year(d) + '-' + this.month(d) + '-' + this.date(d);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
static formatTime(d) {
|
|
23
|
+
static formatTime(d: Date): string {
|
|
24
24
|
return this.hour(d) + ':' + this.minute(d) + ':' + this.second(d);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
static formatDateTime(d) {
|
|
27
|
+
static formatDateTime(d: Date): string {
|
|
28
28
|
return this.formatDate(d) + ' ' + this.formatTime(d);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
static formatDateCn(d) {
|
|
31
|
+
static formatDateCn(d: Date): string {
|
|
32
32
|
return this.year(d) + '年' + (d.getMonth() + 1) + '月' + d.getDate() + '日';
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
static now() { return this.formatDateTime(new Date()); }
|
|
36
|
-
static today() { return this.formatDate(new Date()); }
|
|
37
|
-
static thisYear() { return this.year(new Date()); }
|
|
38
|
-
static thisMonth() { return this.month(new Date()); }
|
|
35
|
+
static now(): string { return this.formatDateTime(new Date()); }
|
|
36
|
+
static today(): string { return this.formatDate(new Date()); }
|
|
37
|
+
static thisYear(): number { return this.year(new Date()); }
|
|
38
|
+
static thisMonth(): string { return this.month(new Date()); }
|
|
39
39
|
|
|
40
|
-
static friendlyTime(pastDate) {
|
|
40
|
+
static friendlyTime(pastDate: Date | string | number): string | undefined {
|
|
41
41
|
if (pastDate == null) return undefined;
|
|
42
42
|
if (!(pastDate instanceof Date)) pastDate = new Date(pastDate);
|
|
43
43
|
const currentDate = new Date();
|
|
@@ -59,9 +59,9 @@ export class DateUtils {
|
|
|
59
59
|
return `${elapsedSeconds} 秒${suffix}`;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
static friendlyTotalTime(time) {
|
|
62
|
+
static friendlyTotalTime(time: number | string | null): string | null {
|
|
63
63
|
if (time == null || time === '-') return null;
|
|
64
|
-
let seconds;
|
|
64
|
+
let seconds: number;
|
|
65
65
|
if (typeof time === 'string') seconds = parseInt(time, 10) / 1000;
|
|
66
66
|
else seconds = time / 1000;
|
|
67
67
|
seconds = Math.floor(seconds);
|
|
@@ -73,7 +73,7 @@ export class DateUtils {
|
|
|
73
73
|
return min + '分' + seconds + '秒';
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
static beginOfMonth() {
|
|
76
|
+
static beginOfMonth(): string {
|
|
77
77
|
const d = new Date();
|
|
78
78
|
d.setDate(1);
|
|
79
79
|
return this.formatDate(d);
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
opera?: string;
|
|
4
|
+
MSStream?: unknown;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
export class DeviceUtils {
|
|
2
9
|
|
|
3
|
-
static isMobileDevice() {
|
|
10
|
+
static isMobileDevice(): boolean {
|
|
4
11
|
const userAgent = navigator?.userAgent || navigator?.vendor || window?.opera || '';
|
|
5
12
|
if (/windows phone/i.test(userAgent)) return true;
|
|
6
13
|
if (/android/i.test(userAgent)) return true;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
type EventCallback = (...args: any[]) => void;
|
|
2
|
+
|
|
3
|
+
interface EventEntry {
|
|
4
|
+
fn: EventCallback & { __callback?: EventCallback };
|
|
5
|
+
ctx?: any;
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
export class EventBus {
|
|
2
|
-
static __stack = {};
|
|
9
|
+
private static __stack: Record<string, EventEntry[]> = {};
|
|
3
10
|
|
|
4
|
-
static on(name, callback, ctx) {
|
|
11
|
+
static on<T extends any[] = []>(name: string, callback: (...args: T) => void, ctx?: any): () => void {
|
|
5
12
|
if (!EventBus.__stack[name]) {
|
|
6
13
|
EventBus.__stack[name] = [];
|
|
7
14
|
}
|
|
@@ -9,9 +16,9 @@ export class EventBus {
|
|
|
9
16
|
return () => EventBus.off(name, callback);
|
|
10
17
|
}
|
|
11
18
|
|
|
12
|
-
static once(name, callback, ctx) {
|
|
19
|
+
static once<T extends any[] = []>(name: string, callback: (...args: T) => void, ctx?: any): () => void {
|
|
13
20
|
const unsubscribe = () => EventBus.off(name, callback);
|
|
14
|
-
const listener = (...args) => {
|
|
21
|
+
const listener: EventEntry['fn'] = (...args: any[]) => {
|
|
15
22
|
EventBus.off(name, listener);
|
|
16
23
|
callback.apply(ctx, args);
|
|
17
24
|
};
|
|
@@ -21,7 +28,7 @@ export class EventBus {
|
|
|
21
28
|
return unsubscribe;
|
|
22
29
|
}
|
|
23
30
|
|
|
24
|
-
static emit(name, ...args) {
|
|
31
|
+
static emit<T extends any[] = []>(name: string, ...args: T): void {
|
|
25
32
|
const list = EventBus.__stack[name];
|
|
26
33
|
if (list !== undefined) {
|
|
27
34
|
list.slice(0).forEach(entry => {
|
|
@@ -30,7 +37,7 @@ export class EventBus {
|
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
static off(name, callback) {
|
|
40
|
+
static off<T extends any[] = []>(name: string, callback?: (...args: T) => void): void {
|
|
34
41
|
const list = EventBus.__stack[name];
|
|
35
42
|
if (list === undefined) return;
|
|
36
43
|
if (callback === undefined) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class ObjectUtils {
|
|
2
|
+
|
|
3
|
+
static copyPropertyIfPresent<TSource extends object, TTarget extends object>(
|
|
4
|
+
source: TSource | null | undefined,
|
|
5
|
+
target: TTarget | null | undefined
|
|
6
|
+
): void {
|
|
7
|
+
if (!source || !target || typeof source !== 'object' || typeof target !== 'object') return;
|
|
8
|
+
const keys = Object.keys(target);
|
|
9
|
+
for (const key of keys) {
|
|
10
|
+
if (Object.hasOwn(source, key)) {
|
|
11
|
+
(target as Record<string, unknown>)[key] = (source as Record<string, unknown>)[key];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -6,11 +6,11 @@ export class StorageUtils {
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* 从 localStorage 获取数据。
|
|
9
|
-
* @param
|
|
10
|
-
* @param
|
|
11
|
-
* @returns
|
|
9
|
+
* @param key 存储的键。
|
|
10
|
+
* @param defaultValue 如果找不到键或值,返回的默认值。
|
|
11
|
+
* @returns 存储的值或默认值。
|
|
12
12
|
*/
|
|
13
|
-
static get(key, defaultValue = null) {
|
|
13
|
+
static get<T>(key: string, defaultValue: T | null = null): T | null {
|
|
14
14
|
const vStr = localStorage.getItem(key);
|
|
15
15
|
if (vStr == null) {
|
|
16
16
|
return defaultValue;
|
|
@@ -27,10 +27,10 @@ export class StorageUtils {
|
|
|
27
27
|
/**
|
|
28
28
|
* 将数据存储到 localStorage。
|
|
29
29
|
* 如果值为 null 或 undefined,则删除该键。
|
|
30
|
-
* @param
|
|
31
|
-
* @param
|
|
30
|
+
* @param key 存储的键。
|
|
31
|
+
* @param value 要存储的值。
|
|
32
32
|
*/
|
|
33
|
-
static set(key, value) {
|
|
33
|
+
static set<T>(key: string, value: T | null | undefined): void {
|
|
34
34
|
if (value == null) {
|
|
35
35
|
localStorage.removeItem(key);
|
|
36
36
|
return;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
export class StringUtils {
|
|
2
2
|
|
|
3
|
-
static ISO_SPLITTER = "/";
|
|
3
|
+
static readonly ISO_SPLITTER: string = "/";
|
|
4
4
|
|
|
5
|
-
static removePrefix(str, ch) {
|
|
5
|
+
static removePrefix(str: string | null | undefined, ch: string): string {
|
|
6
6
|
if (str != null && str.startsWith(ch)) {
|
|
7
7
|
return str.substring(ch.length);
|
|
8
8
|
}
|
|
9
9
|
return str ?? '';
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
static removeSuffix(str, ch) {
|
|
12
|
+
static removeSuffix(str: string | null | undefined, ch: string): string {
|
|
13
13
|
if (str != null && str.endsWith(ch)) {
|
|
14
14
|
return str.substring(0, str.length - ch.length);
|
|
15
15
|
}
|
|
16
16
|
return str ?? '';
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
static random(length) {
|
|
19
|
+
static random(length: number): string {
|
|
20
20
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
21
21
|
let result = '';
|
|
22
22
|
for (let i = 0; i < length; i++) {
|
|
@@ -25,30 +25,30 @@ export class StringUtils {
|
|
|
25
25
|
return result;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
static contains(str, subStr) {
|
|
28
|
+
static contains(str: string | null | undefined, subStr: string): boolean {
|
|
29
29
|
if (!str) return false;
|
|
30
30
|
return str.includes(subStr);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
static subAfter(source, str) {
|
|
33
|
+
static subAfter(source: string | null | undefined, str: string): string {
|
|
34
34
|
if (source == null) return '';
|
|
35
35
|
const index = source.indexOf(str);
|
|
36
36
|
return index === -1 ? source : source.substring(index + str.length);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
static subAfterLast(source, str) {
|
|
39
|
+
static subAfterLast(source: string | null | undefined, str: string): string {
|
|
40
40
|
if (source == null) return '';
|
|
41
41
|
const index = source.lastIndexOf(str);
|
|
42
42
|
return index === -1 ? source : source.substring(index + str.length);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
static subBefore(str, sub) {
|
|
45
|
+
static subBefore(str: string | null | undefined, sub: string): string {
|
|
46
46
|
if (str == null) return "";
|
|
47
47
|
const index = str.indexOf(sub);
|
|
48
48
|
return index === -1 ? str : str.substring(0, index);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
static pad(input, totalLen, padChar = '0') {
|
|
51
|
+
static pad(input: string | number | null | undefined, totalLen: number, padChar = '0'): string {
|
|
52
52
|
if (input == null) return padChar.repeat(totalLen);
|
|
53
53
|
let str = String(input);
|
|
54
54
|
const charsNeeded = totalLen - str.length;
|
|
@@ -58,7 +58,7 @@ export class StringUtils {
|
|
|
58
58
|
return str;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
static getWidth(str) {
|
|
61
|
+
static getWidth(str: string | null | undefined): number {
|
|
62
62
|
if (str == null || str.length === 0) return 0;
|
|
63
63
|
return str.split('').reduce((pre, cur) => {
|
|
64
64
|
const charCode = cur.charCodeAt(0);
|
|
@@ -66,7 +66,7 @@ export class StringUtils {
|
|
|
66
66
|
}, 0);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
static cutByWidth(str, maxWidth) {
|
|
69
|
+
static cutByWidth(str: string, maxWidth: number): string {
|
|
70
70
|
let showLength = 0;
|
|
71
71
|
return str.split('').reduce((pre, cur) => {
|
|
72
72
|
const charCode = cur.charCodeAt(0);
|
|
@@ -79,7 +79,7 @@ export class StringUtils {
|
|
|
79
79
|
}, '');
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
static ellipsis(str, len, suffix = '...') {
|
|
82
|
+
static ellipsis(str: string | null | undefined, len: number, suffix = '...'): string {
|
|
83
83
|
if (str == null) return '';
|
|
84
84
|
if (!StringUtils.isString(str)) return '';
|
|
85
85
|
if (str.length * 2 < len) return str;
|
|
@@ -88,17 +88,17 @@ export class StringUtils {
|
|
|
88
88
|
return StringUtils.cutByWidth(str, len) + suffix;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
static isString(value) {
|
|
91
|
+
static isString(value: any): value is string {
|
|
92
92
|
return typeof value === 'string';
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
static split(str, sp) {
|
|
95
|
+
static split(str: any, sp: string): string[] {
|
|
96
96
|
if (str == null || str.length === 0) return [];
|
|
97
97
|
if (Array.isArray(str)) return str;
|
|
98
98
|
return str.split(sp);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
static join(arr, sp) {
|
|
101
|
+
static join(arr: any, sp: string): string {
|
|
102
102
|
if (arr == null || !Array.isArray(arr)) {
|
|
103
103
|
return '';
|
|
104
104
|
}
|
|
@@ -1,19 +1,26 @@
|
|
|
1
|
+
export interface TreeNode<T = any> {
|
|
2
|
+
id: string | number;
|
|
3
|
+
pid: string | number | null;
|
|
4
|
+
children?: TreeNode<T>[];
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
export class TreeUtils {
|
|
2
|
-
static walk(tree, callback) {
|
|
9
|
+
static walk<T extends TreeNode>(tree: T[], callback: (node: T) => void): void {
|
|
3
10
|
if (tree == null) return;
|
|
4
11
|
for (const node of tree) {
|
|
5
12
|
callback(node);
|
|
6
13
|
if (node.children && node.children.length > 0) {
|
|
7
|
-
TreeUtils.walk(node.children, callback);
|
|
14
|
+
TreeUtils.walk(node.children as T[], callback);
|
|
8
15
|
}
|
|
9
16
|
}
|
|
10
17
|
}
|
|
11
18
|
|
|
12
|
-
static findByKey(key, list, keyName = 'id') {
|
|
19
|
+
static findByKey<T extends TreeNode>(key: string | number, list: T[], keyName: keyof T | 'id' = 'id'): T | undefined {
|
|
13
20
|
for (const item of list) {
|
|
14
|
-
if (item[keyName] === key) return item;
|
|
21
|
+
if (item[keyName as keyof T] === key) return item;
|
|
15
22
|
if (item.children && item.children.length) {
|
|
16
|
-
const rs = TreeUtils.findByKey(key, item.children, keyName);
|
|
23
|
+
const rs = TreeUtils.findByKey(key, item.children as T[], keyName);
|
|
17
24
|
if (rs) return rs;
|
|
18
25
|
}
|
|
19
26
|
}
|
|
@@ -21,9 +28,9 @@ export class TreeUtils {
|
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
/** @private */
|
|
24
|
-
static getChildRecursive(treeNode, buffer) {
|
|
31
|
+
static getChildRecursive<T extends TreeNode>(treeNode: T, buffer: T[]): T[] {
|
|
25
32
|
if (treeNode.children != null && treeNode.children.length > 0) {
|
|
26
|
-
treeNode.children.forEach((c) => {
|
|
33
|
+
(treeNode.children as T[]).forEach((c) => {
|
|
27
34
|
buffer.push(c);
|
|
28
35
|
TreeUtils.getChildRecursive(c, buffer);
|
|
29
36
|
});
|
|
@@ -31,8 +38,8 @@ export class TreeUtils {
|
|
|
31
38
|
return buffer;
|
|
32
39
|
}
|
|
33
40
|
|
|
34
|
-
static flattenTree(treeNodeList) {
|
|
35
|
-
const buffer = [];
|
|
41
|
+
static flattenTree<T extends TreeNode>(treeNodeList: T[]): T[] {
|
|
42
|
+
const buffer: T[] = [];
|
|
36
43
|
if (treeNodeList != null) {
|
|
37
44
|
treeNodeList.forEach((t) => {
|
|
38
45
|
buffer.push(t);
|
|
@@ -42,16 +49,16 @@ export class TreeUtils {
|
|
|
42
49
|
return buffer;
|
|
43
50
|
}
|
|
44
51
|
|
|
45
|
-
static getKeyList(tree, value) {
|
|
52
|
+
static getKeyList<T extends TreeNode>(tree: T[], value: string | number): (string | number)[] {
|
|
46
53
|
const list = TreeUtils.flattenTree(tree);
|
|
47
|
-
const map = new Map();
|
|
54
|
+
const map = new Map<string | number, T>();
|
|
48
55
|
list.forEach((t) => {
|
|
49
56
|
const key = t.key || t.id;
|
|
50
57
|
map.set(key, t);
|
|
51
58
|
});
|
|
52
59
|
const targetNode = map.get(value);
|
|
53
60
|
if (targetNode == null) return [];
|
|
54
|
-
const keys = [targetNode.key || targetNode.id];
|
|
61
|
+
const keys: (string | number)[] = [targetNode.key || targetNode.id];
|
|
55
62
|
let parentKey = targetNode.parentKey || targetNode.pid;
|
|
56
63
|
while (parentKey != null) {
|
|
57
64
|
const parent = map.get(parentKey);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {StringUtils} from './StringUtils';
|
|
2
2
|
|
|
3
3
|
export class UrlUtils {
|
|
4
|
-
static getParams(url = null) {
|
|
5
|
-
let targetUrl;
|
|
4
|
+
static getParams(url: string | null = null): Record<string, string> {
|
|
5
|
+
let targetUrl: string;
|
|
6
6
|
if (url === null || url === undefined) {
|
|
7
7
|
targetUrl = location.href;
|
|
8
8
|
} else {
|
|
@@ -12,21 +12,21 @@ export class UrlUtils {
|
|
|
12
12
|
if (!StringUtils.contains(targetUrl, '?')) return {};
|
|
13
13
|
const search = StringUtils.subAfter(targetUrl, '?');
|
|
14
14
|
const params = new URLSearchParams(search);
|
|
15
|
-
const result = {};
|
|
15
|
+
const result: Record<string, string> = {};
|
|
16
16
|
for (const [key, value] of params.entries()) {
|
|
17
17
|
result[key] = value;
|
|
18
18
|
}
|
|
19
19
|
return result;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
static getPathname(url) {
|
|
22
|
+
static getPathname(url: string | null | undefined): string | null {
|
|
23
23
|
if (!url) return null;
|
|
24
24
|
return StringUtils.subBefore(url, '?');
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
static paramsToSearch(params) {
|
|
27
|
+
static paramsToSearch(params: Record<string, string | number | boolean | null | undefined> | null | undefined): string {
|
|
28
28
|
if (!params) return "";
|
|
29
|
-
const buffer = [];
|
|
29
|
+
const buffer: string[] = [];
|
|
30
30
|
for (const k in params) {
|
|
31
31
|
if (Object.prototype.hasOwnProperty.call(params, k)) {
|
|
32
32
|
const v = params[k];
|
|
@@ -38,7 +38,7 @@ export class UrlUtils {
|
|
|
38
38
|
return buffer.join('&');
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
static setParam(url, key, value) {
|
|
41
|
+
static setParam(url: string, key: string, value: string | number | boolean | null | undefined): string {
|
|
42
42
|
const currentParams = this.getParams(url);
|
|
43
43
|
if (value === null || value === undefined) {
|
|
44
44
|
delete currentParams[key];
|
|
@@ -56,7 +56,7 @@ export class UrlUtils {
|
|
|
56
56
|
/**
|
|
57
57
|
* 根据当前页面协议和主机名构建 WebSocket 基础 URL
|
|
58
58
|
*/
|
|
59
|
-
static getWebsocketBaseUrl() {
|
|
59
|
+
static getWebsocketBaseUrl(): string {
|
|
60
60
|
const protocol = location.protocol === 'http:' ? 'ws:' : 'wss:';
|
|
61
61
|
return `${protocol}//${location.host}`;
|
|
62
62
|
}
|
|
@@ -64,8 +64,8 @@ export class UrlUtils {
|
|
|
64
64
|
/**
|
|
65
65
|
* 为路径添加 SERVLET_CONTEXT 前缀
|
|
66
66
|
*/
|
|
67
|
-
static contextPath(path) {
|
|
68
|
-
const base =
|
|
67
|
+
static contextPath(path: string): string {
|
|
68
|
+
const base = import.meta.env.VITE_SERVER_SERVLET_CONTEXT_PATH;
|
|
69
69
|
return base + path;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -2,25 +2,37 @@ import {GlobalData} from '../../GlobalData';
|
|
|
2
2
|
import {Tag} from 'antd';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
|
|
5
|
+
export interface DictItem {
|
|
6
|
+
code: string | number;
|
|
7
|
+
label: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
typeCode?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface DictOption {
|
|
13
|
+
value: string | number;
|
|
14
|
+
label: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
export class DictUtils {
|
|
6
|
-
static dictList(code) {
|
|
18
|
+
static dictList(code: string): DictItem[] {
|
|
7
19
|
const info = GlobalData.getDictInfo();
|
|
8
20
|
if (!info) return [];
|
|
9
21
|
return info.filter(e => e.typeCode === code);
|
|
10
22
|
}
|
|
11
23
|
|
|
12
|
-
static dictOptions(typeCode) {
|
|
24
|
+
static dictOptions(typeCode: string): DictOption[] {
|
|
13
25
|
const list = DictUtils.dictList(typeCode);
|
|
14
26
|
return list.map(i => ({ value: i.code, label: i.label }));
|
|
15
27
|
}
|
|
16
28
|
|
|
17
|
-
static dictLabel(typeCode, code) {
|
|
29
|
+
static dictLabel(typeCode: string, code: string | number): string | undefined {
|
|
18
30
|
const items = DictUtils.dictList(typeCode);
|
|
19
31
|
const item = items.find(i => i.code === code);
|
|
20
32
|
return item ? item.label : undefined;
|
|
21
33
|
}
|
|
22
34
|
|
|
23
|
-
static dictTag(typeCode, code) {
|
|
35
|
+
static dictTag(typeCode: string, code: string | number): React.ReactElement | string | null {
|
|
24
36
|
if (typeCode == null || code == null) return null;
|
|
25
37
|
const item = DictUtils.dictList(typeCode).find(i => i.code === code);
|
|
26
38
|
if (item == null) return null;
|
|
@@ -1,59 +1,63 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
|
+
import type {AxiosRequestConfig} from "axios";
|
|
2
3
|
import qs from 'qs';
|
|
3
4
|
import {PageUtils} from "./PageUtils";
|
|
4
|
-
import {
|
|
5
|
+
import {message as messageApi} from "antd";
|
|
6
|
+
import {EventBus} from "../EventBus";
|
|
7
|
+
|
|
8
|
+
interface RequestOptions extends AxiosRequestConfig {
|
|
9
|
+
showError?: boolean;
|
|
10
|
+
}
|
|
5
11
|
|
|
6
12
|
const axiosInstance = axios.create({
|
|
7
|
-
baseURL:
|
|
13
|
+
baseURL: import.meta.env.VITE_SERVER_SERVLET_CONTEXT_PATH,
|
|
8
14
|
withCredentials: true,
|
|
9
15
|
headers: { 'Content-Type': 'application/json' },
|
|
10
|
-
paramsSerializer: (params) => qs.stringify(params, {indices: false})
|
|
16
|
+
paramsSerializer: (params: Record<string, unknown>) => qs.stringify(params, {indices: false})
|
|
11
17
|
});
|
|
12
18
|
|
|
13
19
|
export class HttpUtils {
|
|
14
|
-
static coreRequest(config, transformData = true) {
|
|
15
|
-
const url = config.url;
|
|
20
|
+
static coreRequest<T = any>(config: RequestOptions, transformData = true): Promise<T> {
|
|
21
|
+
const url = config.url as string;
|
|
16
22
|
config.url = url.startsWith('admin') ? '/' + url : url;
|
|
17
23
|
|
|
18
|
-
return new Promise((resolve, reject) => {
|
|
24
|
+
return new Promise<T>((resolve, reject) => {
|
|
19
25
|
axiosInstance(config).then((response) => {
|
|
20
26
|
const body = response.data;
|
|
21
27
|
let {success, message, data} = body;
|
|
22
28
|
if (success == undefined) {
|
|
23
|
-
resolve(response);
|
|
29
|
+
resolve(response as unknown as T);
|
|
24
30
|
return;
|
|
25
31
|
}
|
|
26
32
|
if (!success) {
|
|
27
33
|
console.error(`[HttpUtils] 请求失败: ${url}`, {code: body.code, message, data: body});
|
|
28
34
|
if (config.showError !== false) {
|
|
29
|
-
|
|
35
|
+
messageApi.error(message || '操作失败');
|
|
30
36
|
}
|
|
31
37
|
reject(message || '操作失败');
|
|
32
38
|
return;
|
|
33
39
|
}
|
|
34
40
|
if (message) {
|
|
35
|
-
|
|
41
|
+
messageApi.success(message);
|
|
36
42
|
}
|
|
37
|
-
resolve(transformData ? data : response);
|
|
43
|
+
resolve((transformData ? data : response) as T);
|
|
38
44
|
}).catch((e) => {
|
|
39
45
|
console.error(`[HttpUtils] 请求异常: ${url}`, e);
|
|
40
46
|
if (axios.isAxiosError(e) && e.response?.status === 401) {
|
|
41
|
-
|
|
42
|
-
PageUtils.redirectToLogin();
|
|
43
|
-
});
|
|
47
|
+
EventBus.emit('loginExpired');
|
|
44
48
|
reject('登录过期');
|
|
45
49
|
return;
|
|
46
50
|
}
|
|
47
51
|
const msg = HttpUtils.extractErrorMessage(e);
|
|
48
52
|
if (config.showError !== false) {
|
|
49
|
-
|
|
53
|
+
messageApi.error(msg);
|
|
50
54
|
}
|
|
51
55
|
reject(msg);
|
|
52
56
|
});
|
|
53
57
|
});
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
static extractErrorMessage(e, defaultMsg = '操作失败') {
|
|
60
|
+
static extractErrorMessage(e: unknown, defaultMsg = '操作失败'): string {
|
|
57
61
|
if (axios.isAxiosError(e)) {
|
|
58
62
|
const responseData = e.response?.data;
|
|
59
63
|
const status = e.response?.status;
|
|
@@ -66,16 +70,16 @@ export class HttpUtils {
|
|
|
66
70
|
return defaultMsg;
|
|
67
71
|
}
|
|
68
72
|
|
|
69
|
-
static get(url, params = null, options = {}) {
|
|
70
|
-
return HttpUtils.coreRequest({...options, url, method: 'GET', params});
|
|
73
|
+
static get<T = any>(url: string, params: any = null, options: Partial<RequestOptions> = {}): Promise<T> {
|
|
74
|
+
return HttpUtils.coreRequest<T>({...options, url, method: 'GET', params});
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
static post(url, data = null, params = null, options = {}) {
|
|
74
|
-
return HttpUtils.coreRequest({...options, url, method: 'POST', data, params});
|
|
77
|
+
static post<T = any>(url: string, data: any = null, params: any = null, options: Partial<RequestOptions> = {}): Promise<T> {
|
|
78
|
+
return HttpUtils.coreRequest<T>({...options, url, method: 'POST', data, params});
|
|
75
79
|
}
|
|
76
80
|
|
|
77
|
-
static postForm(url, data, options = {}) {
|
|
78
|
-
return HttpUtils.coreRequest({
|
|
81
|
+
static postForm<T = any>(url: string, data: any, options: Partial<RequestOptions> = {}): Promise<T> {
|
|
82
|
+
return HttpUtils.coreRequest<T>({
|
|
79
83
|
...options,
|
|
80
84
|
url,
|
|
81
85
|
method: 'POST',
|