@peng_kai/kit 0.3.0-beta.4 → 0.3.0-beta.40
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 +2 -2
- package/admin/components/currency/src/CurrencyIcon.vue +37 -33
- package/admin/components/date/PeriodPicker.vue +122 -0
- package/admin/components/date/TimeFieldSelectForLabel.vue +24 -0
- package/admin/components/date/TtaTimeZone.vue +516 -0
- package/admin/components/date/TtaTimeZoneSimple.vue +104 -0
- package/admin/components/date/helpers.ts +250 -0
- package/admin/components/date/index.ts +6 -0
- package/admin/components/date/presetProps.ts +19 -0
- package/admin/components/filter/src/FilterReset.vue +55 -8
- package/admin/components/filter/src/more/TableSetting.vue +95 -0
- package/admin/components/filter/src/useFilterParams.ts +9 -7
- package/admin/components/provider/Admin.vue +17 -0
- package/admin/components/provider/admin-permission.ts +48 -0
- package/admin/components/provider/admin-router.ts +361 -0
- package/admin/components/provider/index.ts +3 -0
- package/admin/components/rich-text/src/RichText.new.vue +19 -6
- package/admin/components/rich-text/src/editorConfig.ts +76 -1
- package/admin/components/settings/index.ts +1 -1
- package/admin/components/settings/src/SchemaForm.vue +40 -6
- package/admin/components/settings/src/Settings.vue +1 -1
- package/admin/components/text/index.ts +2 -0
- package/admin/components/text/src/Amount.v2.vue +131 -0
- package/admin/components/text/src/Datetime.vue +17 -12
- package/admin/components/text/src/IP.vue +18 -4
- package/admin/components/text/src/Num.vue +192 -0
- package/admin/components/upload/src/PictureCardUpload.vue +56 -20
- package/admin/layout/large/Breadcrumb.vue +10 -23
- package/admin/layout/large/Content.vue +9 -6
- package/admin/layout/large/Layout.vue +129 -0
- package/admin/layout/large/Menu.vue +24 -17
- package/admin/layout/large/Notice.vue +168 -0
- package/admin/layout/large/Tabs.vue +183 -0
- package/admin/layout/large/index.ts +61 -1
- package/admin/layout/large/y682.mp3 +0 -0
- package/admin/permission/routerGuard.ts +24 -11
- package/admin/permission/vuePlugin.ts +5 -10
- package/admin/route-guards/index.ts +0 -1
- package/admin/stores/index.ts +1 -0
- package/admin/styles/classCover.scss +1 -1
- package/admin/styles/index.scss +2 -2
- package/antd/hooks/useAntdModal.ts +27 -12
- package/antd/hooks/useAntdTable.ts +10 -7
- package/antd/hooks/useAntdTheme.ts +7 -0
- package/antd/hooks/useTableColumns.ts +83 -0
- package/antd/index.ts +1 -1
- package/libs/bignumber.ts +1 -1
- package/libs/dayjs.ts +16 -2
- package/libs/fingerprintjs.ts +1 -0
- package/package.json +64 -95
- package/request/interceptors/getDeviceInfo.ts +14 -0
- package/utils/LocaleManager.ts +1 -1
- package/utils/index.ts +1 -4
- package/utils/locale/LocaleManager.ts +2 -1
- package/utils/locale/helpers.ts +9 -0
- package/utils/number.ts +8 -10
- package/utils/storage.ts +31 -0
- package/utils/string.ts +1 -2
- package/utils/upload/AwsS3.ts +12 -4
- package/admin/layout/large/PageTab.vue +0 -70
- package/admin/route-guards/collapseMenu.ts +0 -11
- package/libs/a-calc.ts +0 -1
- package/vue/components/test/KitTest.vue +0 -9
- package/vue/components/test/testStore.ts +0 -11
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
import type { App } from 'vue';
|
|
2
2
|
import { watch } from 'vue';
|
|
3
|
-
import {
|
|
3
|
+
import type { createAdminPermission } from '../components/provider/admin-permission';
|
|
4
4
|
|
|
5
5
|
type TCodes = string | string[];
|
|
6
6
|
|
|
7
7
|
const PLUGIN_NAME = 'has-permission';
|
|
8
8
|
const UNWATCH_NAME = `v-${PLUGIN_NAME}@unwatch`;
|
|
9
9
|
|
|
10
|
-
export function setupPermissionPlugin(app: App) {
|
|
10
|
+
export function setupPermissionPlugin(app: App, permission: ReturnType<typeof createAdminPermission>) {
|
|
11
11
|
app.directive<HTMLElement, TCodes>(PLUGIN_NAME, {
|
|
12
12
|
mounted(el, binding) {
|
|
13
|
-
console.log('🤡 / el:', el);
|
|
14
|
-
const permissionStore = adminPlugin.deps.usePermissionStore();
|
|
15
|
-
|
|
16
13
|
function updateVisibility() {
|
|
17
14
|
const codes = binding.value;
|
|
18
|
-
el.style.display =
|
|
15
|
+
el.style.display = permission.has(codes) ? '' : 'none';
|
|
19
16
|
}
|
|
20
17
|
|
|
21
18
|
(el as any)[UNWATCH_NAME] = watch(
|
|
22
|
-
() =>
|
|
19
|
+
() => permission.codes,
|
|
23
20
|
updateVisibility,
|
|
24
21
|
{ immediate: true },
|
|
25
22
|
);
|
|
@@ -32,9 +29,7 @@ export function setupPermissionPlugin(app: App) {
|
|
|
32
29
|
app.use({
|
|
33
30
|
install(app) {
|
|
34
31
|
app.config.globalProperties.$hasPermission = (codes: TCodes) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return permissionStore.hasPermission(codes);
|
|
32
|
+
return permission.has(codes);
|
|
38
33
|
};
|
|
39
34
|
},
|
|
40
35
|
});
|
package/admin/stores/index.ts
CHANGED
package/admin/styles/index.scss
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Modal as AntModal } from 'ant-design-vue';
|
|
2
|
-
import {
|
|
3
|
-
import { createVNode, defineComponent, isProxy, onMounted, reactive, toRef, toRefs } from 'vue';
|
|
2
|
+
import { tryOnBeforeUnmount, tryOnMounted } from '@vueuse/core';
|
|
3
|
+
import { createVNode, defineComponent, isProxy, onBeforeUnmount, onDeactivated, onMounted, reactive, toRef, toRefs } from 'vue';
|
|
4
4
|
import type { Component } from 'vue';
|
|
5
5
|
import type { ModalProps } from 'ant-design-vue';
|
|
6
6
|
import type { ComponentEmit, ComponentProps } from 'vue-component-type-helpers';
|
|
@@ -53,8 +53,10 @@ export function useAntdModal<Comp extends Component>(
|
|
|
53
53
|
...defaultModalProps,
|
|
54
54
|
...isProxy(modalProps) ? toRefs(modalProps) : modalProps,
|
|
55
55
|
confirmLoading: toRef(() => (refs.comp as any)?.loading),
|
|
56
|
-
onOk: (e: MouseEvent) => {
|
|
57
|
-
|
|
56
|
+
onOk: async (e: MouseEvent) => {
|
|
57
|
+
const comp = refs.comp as any;
|
|
58
|
+
const isClosed = await comp?.confirm?.(e, (data: any) => promiseResolvers?.resolve(data));
|
|
59
|
+
// isClosed === true && (_modalProps.open = false);
|
|
58
60
|
modalProps.onOk?.(e);
|
|
59
61
|
},
|
|
60
62
|
});
|
|
@@ -78,19 +80,29 @@ export function useAntdModal<Comp extends Component>(
|
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
Object.assign(_modalProps, newAntdModalProps);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
|
|
84
|
+
// eslint-disable-next-line no-lone-blocks
|
|
85
|
+
{
|
|
86
|
+
if (!(comp as any).props) {
|
|
87
|
+
Object.keys(compProps).forEach((key) => {
|
|
88
|
+
if (!['ref', 'onClose', 'onConfirm'].includes(key))
|
|
89
|
+
delete compProps[key];
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
Object.assign(compProps, newCompProps);
|
|
94
|
+
}
|
|
83
95
|
|
|
84
96
|
promiseResolvers = Promise.withResolvers();
|
|
85
97
|
_modalProps.open = true;
|
|
86
98
|
|
|
87
99
|
return promiseResolvers.promise;
|
|
88
100
|
};
|
|
89
|
-
const
|
|
101
|
+
const onConfirm = (ev: any) => {
|
|
90
102
|
_modalProps.open = false;
|
|
91
103
|
promiseResolvers.resolve(ev);
|
|
92
104
|
};
|
|
93
|
-
const
|
|
105
|
+
const onClose = (reason?: any) => {
|
|
94
106
|
_modalProps.open = false;
|
|
95
107
|
_onClose(reason);
|
|
96
108
|
};
|
|
@@ -98,6 +110,8 @@ export function useAntdModal<Comp extends Component>(
|
|
|
98
110
|
const PresetComponent = defineComponent({
|
|
99
111
|
setup(props) {
|
|
100
112
|
onMounted(() => _modalProps.opener?.(open as any));
|
|
113
|
+
onBeforeUnmount(_onClose);
|
|
114
|
+
onDeactivated(_onClose);
|
|
101
115
|
|
|
102
116
|
return () => {
|
|
103
117
|
return createVNode(AntModal, { ..._modalProps, ...props }, {
|
|
@@ -112,10 +126,11 @@ export function useAntdModal<Comp extends Component>(
|
|
|
112
126
|
!visiable && _onClose();
|
|
113
127
|
};
|
|
114
128
|
(compProps as any).ref = setRefs.comp;
|
|
115
|
-
(compProps as any).onClose =
|
|
116
|
-
(compProps as any).onConfirm =
|
|
129
|
+
(compProps as any).onClose = onClose;
|
|
130
|
+
(compProps as any).onConfirm = onConfirm;
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
// tryOnBeforeUnmount(_onClose);
|
|
133
|
+
// tryOnMounted(() => onDeactivated(_onClose));
|
|
119
134
|
|
|
120
135
|
return {
|
|
121
136
|
PresetComponent,
|
|
@@ -125,6 +140,6 @@ export function useAntdModal<Comp extends Component>(
|
|
|
125
140
|
return refs.comp;
|
|
126
141
|
},
|
|
127
142
|
open,
|
|
128
|
-
close,
|
|
143
|
+
close: onClose,
|
|
129
144
|
};
|
|
130
145
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { computed, reactive, ref } from 'vue';
|
|
2
2
|
import { pick } from 'lodash-es';
|
|
3
|
+
import { useTableColumns } from './useTableColumns'
|
|
3
4
|
import type { UseQueryReturnType } from '@tanstack/vue-query';
|
|
4
5
|
import type { Table, TableProps } from 'ant-design-vue';
|
|
5
6
|
import type { ColumnType, FilterValue } from 'ant-design-vue/es/table/interface';
|
|
@@ -10,6 +11,12 @@ interface ISorter {
|
|
|
10
11
|
order?: string
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
type GetRecordType<T> = T extends UseQueryReturnType<infer D, any>
|
|
15
|
+
? D extends Api.PageData
|
|
16
|
+
? NonNullable<D['list']>[0]
|
|
17
|
+
: never
|
|
18
|
+
: never;
|
|
19
|
+
|
|
13
20
|
const defaultPageSizeOptions = ['10', '20', '50', '100'];
|
|
14
21
|
|
|
15
22
|
export function useAntdTable<
|
|
@@ -54,7 +61,7 @@ export function useAntdTable<
|
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
};
|
|
57
|
-
const defineColumns =
|
|
64
|
+
const { defineColumns } = useTableColumns<LocalColumnsType>();
|
|
58
65
|
const defineRowSelection = (rowSelectionGetter: () => LocalTableRowSelection = () => ({})) => {
|
|
59
66
|
const rowSelection = reactive(rowSelectionGetter());
|
|
60
67
|
|
|
@@ -78,6 +85,7 @@ export function useAntdTable<
|
|
|
78
85
|
showSizeChanger: true,
|
|
79
86
|
showQuickJumper: true,
|
|
80
87
|
pageSizeOptions,
|
|
88
|
+
size: 'default',
|
|
81
89
|
showTotal: total => `共 ${total} 条`,
|
|
82
90
|
},
|
|
83
91
|
loading: isLoading.value,
|
|
@@ -112,7 +120,7 @@ export function useAntdTable<
|
|
|
112
120
|
dataIndexs,
|
|
113
121
|
/** 【类型辅助】bodyCell 插槽数据的精确类型描述 */
|
|
114
122
|
bodyCellType,
|
|
115
|
-
/**
|
|
123
|
+
/** 用于定义 columns */
|
|
116
124
|
defineColumns,
|
|
117
125
|
/** 【类型辅助】用于定义出类型精确的 rowSelection */
|
|
118
126
|
defineRowSelection,
|
|
@@ -121,8 +129,3 @@ export function useAntdTable<
|
|
|
121
129
|
};
|
|
122
130
|
}
|
|
123
131
|
|
|
124
|
-
type GetRecordType<T> = T extends UseQueryReturnType<infer D, any>
|
|
125
|
-
? D extends Api.PageData
|
|
126
|
-
? NonNullable<D['list']>[0]
|
|
127
|
-
: never
|
|
128
|
-
: never;
|
|
@@ -20,6 +20,13 @@ export function useAntdTheme(mode: Ref<string>, config: Ref<Record<string, any>>
|
|
|
20
20
|
const token: ThemeConfig['token'] = {
|
|
21
21
|
...algorithm({ ...theme.defaultSeed, colorPrimary: _config.colors.primary.DEFAULT, colorInfo: '#17B2FF' }),
|
|
22
22
|
borderRadius: 4,
|
|
23
|
+
|
|
24
|
+
motionUnit: 0.05,
|
|
25
|
+
motionBase: 0,
|
|
26
|
+
motionDurationFast: "0.05s",
|
|
27
|
+
motionDurationMid: "0.1s",
|
|
28
|
+
motionDurationSlow: "0.15s",
|
|
29
|
+
|
|
23
30
|
screenXS,
|
|
24
31
|
screenXSMin: screenXS,
|
|
25
32
|
screenXSMax: screenSM - 0.1,
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { computed, reactive, ref, toValue, watch, provide } from 'vue';
|
|
2
|
+
import { extendRef } from '@vueuse/core';
|
|
3
|
+
|
|
4
|
+
export type ColumnConfig = { dataIndex: string, visible: boolean, compact: boolean }
|
|
5
|
+
interface TableConfig {
|
|
6
|
+
columns: ColumnConfig[];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const tableConfigStore = {
|
|
10
|
+
key: 'TABLE_CONFIG',
|
|
11
|
+
genTableId(columns: { dataIndex: string }[], extra = '') {
|
|
12
|
+
const indexsStr = columns.map((col: any) => col.dataIndex).join(',') + extra;
|
|
13
|
+
let hash = 0;
|
|
14
|
+
let len = 12;
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < indexsStr.length; i++) {
|
|
17
|
+
const ch = indexsStr.charCodeAt(i);
|
|
18
|
+
hash = (hash << 5) - hash + ch;
|
|
19
|
+
hash |= 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const base36 = (hash >>> 0).toString(36);
|
|
23
|
+
return base36.length >= len ? base36.slice(0, len) : base36.padStart(len, '0');
|
|
24
|
+
},
|
|
25
|
+
getTableConfig(tableId: string): TableConfig | null {
|
|
26
|
+
const configStr = localStorage.getItem(this.key);
|
|
27
|
+
const allConfig = configStr ? JSON.parse(configStr) : {};
|
|
28
|
+
return allConfig[tableId] || null;
|
|
29
|
+
},
|
|
30
|
+
setTableConfig(tableId: string, config: Partial<TableConfig>) {
|
|
31
|
+
const configStr = localStorage.getItem(this.key);
|
|
32
|
+
const allConfig = configStr ? JSON.parse(configStr) : {};
|
|
33
|
+
allConfig[tableId] = Object.assign({}, allConfig[tableId] || {}, config);
|
|
34
|
+
localStorage.setItem(this.key, JSON.stringify(allConfig));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function useTableColumns<LCT extends any[]>() {
|
|
39
|
+
const columnsConfig = ref<Array<ColumnConfig> | null | undefined>();
|
|
40
|
+
let originalColumns: LCT | null = null;
|
|
41
|
+
let tableId = ''
|
|
42
|
+
|
|
43
|
+
const defineColumns = (columnsGetter: () => LCT) => {
|
|
44
|
+
originalColumns = toValue(columnsGetter) || [] as unknown as LCT;
|
|
45
|
+
tableId = tableConfigStore.genTableId(originalColumns);
|
|
46
|
+
columnsConfig.value = tableConfigStore.getTableConfig(tableId)?.columns;
|
|
47
|
+
|
|
48
|
+
provide('tableColumns', originalColumns);
|
|
49
|
+
provide('tableColumnsConfig', columnsConfig);
|
|
50
|
+
|
|
51
|
+
const columns = computed(() => {
|
|
52
|
+
const config = columnsConfig.value;
|
|
53
|
+
let columns = columnsGetter();
|
|
54
|
+
|
|
55
|
+
if (config?.length) {
|
|
56
|
+
columns = columns.filter((col: any) => config.find(c => c.dataIndex === col.dataIndex)?.visible !== false) as LCT;
|
|
57
|
+
columns = columns.map((col: any) => {
|
|
58
|
+
const cf = config.find(c => c.dataIndex === col.dataIndex);
|
|
59
|
+
return { ...col, compact: cf?.compact };
|
|
60
|
+
}) as LCT;
|
|
61
|
+
const dataIndexOrderMap = new Map(config.map((c, i) => [c.dataIndex, i]));
|
|
62
|
+
columns.sort((a, b) => {
|
|
63
|
+
const indexA = dataIndexOrderMap.get(a.dataIndex);
|
|
64
|
+
const indexB = dataIndexOrderMap.get(b.dataIndex);
|
|
65
|
+
return (indexA ?? Infinity) - (indexB ?? Infinity);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return columns;
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
return extendRef(columns, {});
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
watch(columnsConfig, (newConfig) => {
|
|
76
|
+
newConfig && tableConfigStore.setTableConfig(tableId, { columns: newConfig });
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
defineColumns,
|
|
81
|
+
tableColumnsConfig: columnsConfig,
|
|
82
|
+
};
|
|
83
|
+
}
|
package/antd/index.ts
CHANGED
|
@@ -5,4 +5,4 @@ export { useAntdForm } from './hooks/useAntdForm';
|
|
|
5
5
|
export { useAntdTheme } from './hooks/useAntdTheme';
|
|
6
6
|
export { createAntdModal } from './hooks/createAntdModal';
|
|
7
7
|
export { default as InputNumberRange } from './components/InputNumberRange.vue';
|
|
8
|
-
export type { SchemaConfig, ItemSchema } from './hooks/useAntdForm.ts';
|
|
8
|
+
export type { SchemaConfig, ItemSchema } from './hooks/useAntdForm.ts';
|
package/libs/bignumber.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from 'bignumber.js';
|
|
2
|
-
export { BigNumber } from 'bignumber.js';
|
|
2
|
+
export { type BigNumber } from 'bignumber.js';
|
package/libs/dayjs.ts
CHANGED
|
@@ -5,15 +5,29 @@ import weekday from 'dayjs/esm/plugin/weekday';
|
|
|
5
5
|
import localeData from 'dayjs/esm/plugin/localeData';
|
|
6
6
|
import utc from 'dayjs/esm/plugin/utc';
|
|
7
7
|
import tz from 'dayjs/esm/plugin/timezone';
|
|
8
|
-
import 'dayjs/esm/
|
|
8
|
+
import weekOfYear from 'dayjs/esm/plugin/weekOfYear';
|
|
9
|
+
import weekYear from 'dayjs/esm/plugin/weekYear';
|
|
10
|
+
import quarterOfYear from 'dayjs/esm/plugin/quarterOfYear';
|
|
11
|
+
import advancedFormat from 'dayjs/esm/plugin/advancedFormat';
|
|
12
|
+
import customParseFormat from 'dayjs/esm/plugin/customParseFormat';
|
|
13
|
+
import updateLocale from 'dayjs/esm/plugin/updateLocale';
|
|
14
|
+
import isBetween from 'dayjs/esm/plugin/isBetween';
|
|
15
|
+
import 'dayjs/esm/locale/zh-cn';
|
|
9
16
|
import 'dayjs/esm/locale/en';
|
|
10
17
|
|
|
11
18
|
export type { Dayjs, PluginFunc, UnitType, UnitTypeLong, UnitTypeLongPlural, UnitTypeShort, QUnitType, ConfigType, ConfigTypeMap, OpUnitType, OptionType, ManipulateType } from 'dayjs';
|
|
12
19
|
export default dayjs;
|
|
13
20
|
|
|
14
|
-
dayjs.locale('zh');
|
|
15
21
|
dayjs.extend(relativeTime);
|
|
16
22
|
dayjs.extend(weekday);
|
|
17
23
|
dayjs.extend(localeData);
|
|
18
24
|
dayjs.extend(utc);
|
|
19
25
|
dayjs.extend(tz);
|
|
26
|
+
dayjs.extend(weekOfYear);
|
|
27
|
+
dayjs.extend(weekYear);
|
|
28
|
+
dayjs.extend(quarterOfYear);
|
|
29
|
+
dayjs.extend(advancedFormat);
|
|
30
|
+
dayjs.extend(customParseFormat);
|
|
31
|
+
dayjs.extend(updateLocale);
|
|
32
|
+
dayjs.extend(isBetween);
|
|
33
|
+
dayjs.locale('zh-cn');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@fingerprintjs/fingerprintjs';
|
package/package.json
CHANGED
|
@@ -1,95 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@peng_kai/kit",
|
|
3
|
-
"type": "module",
|
|
4
|
-
"version": "0.3.0-beta.
|
|
5
|
-
"description": "",
|
|
6
|
-
"author": "",
|
|
7
|
-
"license": "ISC",
|
|
8
|
-
"keywords": [],
|
|
9
|
-
"main": "index.js",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"dev:js": "tsx ./admin/scripts/deploy.ts",
|
|
12
|
-
"lint": "eslint .",
|
|
13
|
-
"lint:fix": "eslint . --fix"
|
|
14
|
-
},
|
|
15
|
-
"peerDependencies": {
|
|
16
|
-
"ant-design-vue": "4.2.
|
|
17
|
-
"vue": "3.5.
|
|
18
|
-
"vue-router": "4.4
|
|
19
|
-
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"@aws-sdk/client-s3": "^3.
|
|
22
|
-
"@aws-sdk/lib-storage": "^3.
|
|
23
|
-
"@babel/generator": "^7.
|
|
24
|
-
"@babel/parser": "^7.
|
|
25
|
-
"@babel/traverse": "^7.
|
|
26
|
-
"@babel/types": "^7.
|
|
27
|
-
"@ckeditor/ckeditor5-vue": "^
|
|
28
|
-
"@fingerprintjs/fingerprintjs": "^
|
|
29
|
-
"@tanstack/vue-query": "^5.
|
|
30
|
-
"@vueuse/components": "^
|
|
31
|
-
"@vueuse/core": "^
|
|
32
|
-
"@vueuse/router": "^
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"localstorage-slim": "^2.7.1",
|
|
44
|
-
"lodash-es": "^4.17.21",
|
|
45
|
-
"nprogress": "^0.2.0",
|
|
46
|
-
"pinia": "^
|
|
47
|
-
"tsx": "^4.16.00",
|
|
48
|
-
"vue": "^3.5.
|
|
49
|
-
"vue-i18n": "^
|
|
50
|
-
"vue-router": "^4.
|
|
51
|
-
},
|
|
52
|
-
"devDependencies": {
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
"@
|
|
57
|
-
"@
|
|
58
|
-
"@
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"@ckeditor/ckeditor5-highlight": "^41.1.0",
|
|
66
|
-
"@ckeditor/ckeditor5-horizontal-line": "^41.1.0",
|
|
67
|
-
"@ckeditor/ckeditor5-html-embed": "^41.1.0",
|
|
68
|
-
"@ckeditor/ckeditor5-html-support": "^41.1.0",
|
|
69
|
-
"@ckeditor/ckeditor5-image": "^41.1.0",
|
|
70
|
-
"@ckeditor/ckeditor5-import-word": "^41.1.0",
|
|
71
|
-
"@ckeditor/ckeditor5-indent": "^41.1.0",
|
|
72
|
-
"@ckeditor/ckeditor5-link": "^41.1.0",
|
|
73
|
-
"@ckeditor/ckeditor5-list": "^41.1.0",
|
|
74
|
-
"@ckeditor/ckeditor5-media-embed": "^41.1.0",
|
|
75
|
-
"@ckeditor/ckeditor5-paragraph": "^41.1.0",
|
|
76
|
-
"@ckeditor/ckeditor5-remove-format": "^41.1.0",
|
|
77
|
-
"@ckeditor/ckeditor5-show-blocks": "^41.1.0",
|
|
78
|
-
"@ckeditor/ckeditor5-source-editing": "^41.1.0",
|
|
79
|
-
"@ckeditor/ckeditor5-table": "^41.1.0",
|
|
80
|
-
"@ckeditor/ckeditor5-theme-lark": "^41.1.0",
|
|
81
|
-
"@ckeditor/ckeditor5-typing": "^41.1.0",
|
|
82
|
-
"@ckeditor/ckeditor5-upload": "^41.1.0",
|
|
83
|
-
"@ckeditor/ckeditor5-word-count": "^41.1.0",
|
|
84
|
-
"@peng_kai/lint": "^0.1.0",
|
|
85
|
-
"@types/archiver": "^6.0.2",
|
|
86
|
-
"@types/crypto-js": "^4.2.2",
|
|
87
|
-
"@types/lodash-es": "^4.17.12",
|
|
88
|
-
"@types/node": "^20.16.11",
|
|
89
|
-
"@types/nprogress": "^0.2.3",
|
|
90
|
-
"ant-design-vue": "^4.2.5",
|
|
91
|
-
"type-fest": "^4.26.1",
|
|
92
|
-
"typescript": "^5.6.3",
|
|
93
|
-
"vue-component-type-helpers": "^2.1.6"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@peng_kai/kit",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.3.0-beta.40",
|
|
5
|
+
"description": "",
|
|
6
|
+
"author": "",
|
|
7
|
+
"license": "ISC",
|
|
8
|
+
"keywords": [],
|
|
9
|
+
"main": "index.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev:js": "tsx ./admin/scripts/deploy.ts",
|
|
12
|
+
"lint": "eslint .",
|
|
13
|
+
"lint:fix": "eslint . --fix"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"ant-design-vue": "4.2.6",
|
|
17
|
+
"vue": "3.5.27",
|
|
18
|
+
"vue-router": "4.6.4"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@aws-sdk/client-s3": "^3.891.0",
|
|
22
|
+
"@aws-sdk/lib-storage": "^3.891.0",
|
|
23
|
+
"@babel/generator": "^7.28.3",
|
|
24
|
+
"@babel/parser": "^7.28.4",
|
|
25
|
+
"@babel/traverse": "^7.28.4",
|
|
26
|
+
"@babel/types": "^7.28.4",
|
|
27
|
+
"@ckeditor/ckeditor5-vue": "^7.3.0",
|
|
28
|
+
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
|
29
|
+
"@tanstack/vue-query": "^5.92.5",
|
|
30
|
+
"@vueuse/components": "^14.1.0",
|
|
31
|
+
"@vueuse/core": "^14.1.0",
|
|
32
|
+
"@vueuse/router": "^14.1.0",
|
|
33
|
+
"archiver": "^7.0.1",
|
|
34
|
+
"axios": "^1.13.2",
|
|
35
|
+
"bignumber.js": "^9.3.1",
|
|
36
|
+
"chokidar": "^4.0.3",
|
|
37
|
+
"crypto-es": "^3.1.2",
|
|
38
|
+
"dayjs": "^1.11.19",
|
|
39
|
+
"echarts": "^5.6.0",
|
|
40
|
+
"execa": "^9.6.0",
|
|
41
|
+
"fast-glob": "^3.3.3",
|
|
42
|
+
"fluid-dnd": "^2.6.2",
|
|
43
|
+
"localstorage-slim": "^2.7.1",
|
|
44
|
+
"lodash-es": "^4.17.21",
|
|
45
|
+
"nprogress": "^0.2.0",
|
|
46
|
+
"pinia": "^3.0.3",
|
|
47
|
+
"tsx": "^4.16.00",
|
|
48
|
+
"vue": "^3.5.21",
|
|
49
|
+
"vue-i18n": "^11.1.12",
|
|
50
|
+
"vue-router": "^4.5.1"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@peng_kai/lint": "^0.1.0",
|
|
54
|
+
"@types/archiver": "^7.0.0",
|
|
55
|
+
"@types/crypto-js": "^4.2.2",
|
|
56
|
+
"@types/lodash-es": "^4.17.12",
|
|
57
|
+
"@types/node": "^22.19.7",
|
|
58
|
+
"@types/nprogress": "^0.2.3",
|
|
59
|
+
"ant-design-vue": "^4.2.6",
|
|
60
|
+
"type-fest": "^5.0.0",
|
|
61
|
+
"typescript": "^5.9.2",
|
|
62
|
+
"vue-component-type-helpers": "^3.0.7"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -25,6 +25,7 @@ export function getDeviceInfo(callback: (base: Record<string, any>, all: GetResu
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
req.headers.set('Device', callback(base, result));
|
|
28
|
+
req.headers.set('Device-Id', getDeviceID(base.visitor_id));
|
|
28
29
|
req.headers.set('Accept-Date', getCurrentTimeZone());
|
|
29
30
|
|
|
30
31
|
return req;
|
|
@@ -32,6 +33,19 @@ export function getDeviceInfo(callback: (base: Record<string, any>, all: GetResu
|
|
|
32
33
|
];
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
function getDeviceID(visitorId: string) {
|
|
37
|
+
const key = 'backend_device_id';
|
|
38
|
+
let id = localStorage.getItem(key);
|
|
39
|
+
if (!id) {
|
|
40
|
+
id = visitorId
|
|
41
|
+
if (!id) {
|
|
42
|
+
id = crypto.randomUUID();
|
|
43
|
+
}
|
|
44
|
+
localStorage.setItem(key, id);
|
|
45
|
+
}
|
|
46
|
+
return id;
|
|
47
|
+
}
|
|
48
|
+
|
|
35
49
|
function getCurrentTimeZone() {
|
|
36
50
|
const now = new Date();
|
|
37
51
|
const [_, time, tz, describe] = now.toString().match(/(\w{3} \w{3} \d{2} \d{4} \d{2}:\d{2}:\d{2})? (GMT[+-]\d{4}) \((.*?)\)/) ?? [];
|
package/utils/LocaleManager.ts
CHANGED
|
@@ -63,7 +63,7 @@ export class LocaleManager {
|
|
|
63
63
|
|
|
64
64
|
for (const target of localeTargets) {
|
|
65
65
|
for (const codes of codeMatrix) {
|
|
66
|
-
const matched = codes.some(code =>
|
|
66
|
+
const matched = codes.some(code => target.toUpperCase().startsWith(code.toUpperCase()));
|
|
67
67
|
|
|
68
68
|
if (matched) {
|
|
69
69
|
localeFinal = codes[0];
|
package/utils/index.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { Utf8 as cryptUtf8 } from 'crypto-es
|
|
2
|
-
import { AES as cryptoAES } from 'crypto-es/lib/aes';
|
|
3
|
-
import { ECB as cryptoModeECB } from 'crypto-es/lib/mode-ecb';
|
|
4
|
-
import { Pkcs7 as cryptoPkcs7 } from 'crypto-es/lib/cipher-core';
|
|
1
|
+
import { Utf8 as cryptUtf8, AES as cryptoAES, ECB as cryptoModeECB, Pkcs7 as cryptoPkcs7 } from 'crypto-es';
|
|
5
2
|
import { at as objAt } from 'lodash-es';
|
|
6
3
|
|
|
7
4
|
export { desensitize, randomString } from './string';
|
|
@@ -65,7 +65,7 @@ export class LocaleManager {
|
|
|
65
65
|
|
|
66
66
|
for (const target of localeTargets) {
|
|
67
67
|
for (const codes of codeMatrix) {
|
|
68
|
-
const matched = codes.some(code =>
|
|
68
|
+
const matched = codes.some(code => target.toUpperCase().startsWith(code.toUpperCase()));
|
|
69
69
|
|
|
70
70
|
if (matched) {
|
|
71
71
|
localeFinal = codes[0];
|
|
@@ -92,6 +92,7 @@ export class LocaleManager {
|
|
|
92
92
|
if (!this.localesAvailable.includes(locale))
|
|
93
93
|
return;
|
|
94
94
|
|
|
95
|
+
// TODO: 这样可能无法支持code中的语言
|
|
95
96
|
const message = await this.messageLoaders[locale]?.().catch(() => undefined);
|
|
96
97
|
|
|
97
98
|
// 由于是异步加载,所以需要再判断是否已经加载过
|
package/utils/locale/helpers.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { I18nOptions } from 'vue-i18n';
|
|
1
2
|
import { omitBy } from '../../libs/lodash-es';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -32,6 +33,14 @@ export function omitLocale(modules: Record<string, any>, excludes: string[] = []
|
|
|
32
33
|
return omitBy(modules, (_, path) => excludes.some(locale => path.includes(locale)));
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
/** 添加语言格式 */
|
|
37
|
+
export function addDatetimeFormat<T extends string>(name: T, config: NonNullable<I18nOptions['datetimeFormats']>[string][string]) {
|
|
38
|
+
return {
|
|
39
|
+
[name]: config,
|
|
40
|
+
[`${name}-utc`]: { ...config, timeZone: 'UTC' },
|
|
41
|
+
} as Record<T | `${T}-utc`, typeof config>;
|
|
42
|
+
}
|
|
43
|
+
|
|
35
44
|
/**
|
|
36
45
|
* 加密 JSON 消息
|
|
37
46
|
*/
|