@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.
Files changed (64) hide show
  1. package/.vscode/settings.json +2 -2
  2. package/admin/components/currency/src/CurrencyIcon.vue +37 -33
  3. package/admin/components/date/PeriodPicker.vue +122 -0
  4. package/admin/components/date/TimeFieldSelectForLabel.vue +24 -0
  5. package/admin/components/date/TtaTimeZone.vue +516 -0
  6. package/admin/components/date/TtaTimeZoneSimple.vue +104 -0
  7. package/admin/components/date/helpers.ts +250 -0
  8. package/admin/components/date/index.ts +6 -0
  9. package/admin/components/date/presetProps.ts +19 -0
  10. package/admin/components/filter/src/FilterReset.vue +55 -8
  11. package/admin/components/filter/src/more/TableSetting.vue +95 -0
  12. package/admin/components/filter/src/useFilterParams.ts +9 -7
  13. package/admin/components/provider/Admin.vue +17 -0
  14. package/admin/components/provider/admin-permission.ts +48 -0
  15. package/admin/components/provider/admin-router.ts +361 -0
  16. package/admin/components/provider/index.ts +3 -0
  17. package/admin/components/rich-text/src/RichText.new.vue +19 -6
  18. package/admin/components/rich-text/src/editorConfig.ts +76 -1
  19. package/admin/components/settings/index.ts +1 -1
  20. package/admin/components/settings/src/SchemaForm.vue +40 -6
  21. package/admin/components/settings/src/Settings.vue +1 -1
  22. package/admin/components/text/index.ts +2 -0
  23. package/admin/components/text/src/Amount.v2.vue +131 -0
  24. package/admin/components/text/src/Datetime.vue +17 -12
  25. package/admin/components/text/src/IP.vue +18 -4
  26. package/admin/components/text/src/Num.vue +192 -0
  27. package/admin/components/upload/src/PictureCardUpload.vue +56 -20
  28. package/admin/layout/large/Breadcrumb.vue +10 -23
  29. package/admin/layout/large/Content.vue +9 -6
  30. package/admin/layout/large/Layout.vue +129 -0
  31. package/admin/layout/large/Menu.vue +24 -17
  32. package/admin/layout/large/Notice.vue +168 -0
  33. package/admin/layout/large/Tabs.vue +183 -0
  34. package/admin/layout/large/index.ts +61 -1
  35. package/admin/layout/large/y682.mp3 +0 -0
  36. package/admin/permission/routerGuard.ts +24 -11
  37. package/admin/permission/vuePlugin.ts +5 -10
  38. package/admin/route-guards/index.ts +0 -1
  39. package/admin/stores/index.ts +1 -0
  40. package/admin/styles/classCover.scss +1 -1
  41. package/admin/styles/index.scss +2 -2
  42. package/antd/hooks/useAntdModal.ts +27 -12
  43. package/antd/hooks/useAntdTable.ts +10 -7
  44. package/antd/hooks/useAntdTheme.ts +7 -0
  45. package/antd/hooks/useTableColumns.ts +83 -0
  46. package/antd/index.ts +1 -1
  47. package/libs/bignumber.ts +1 -1
  48. package/libs/dayjs.ts +16 -2
  49. package/libs/fingerprintjs.ts +1 -0
  50. package/package.json +64 -95
  51. package/request/interceptors/getDeviceInfo.ts +14 -0
  52. package/utils/LocaleManager.ts +1 -1
  53. package/utils/index.ts +1 -4
  54. package/utils/locale/LocaleManager.ts +2 -1
  55. package/utils/locale/helpers.ts +9 -0
  56. package/utils/number.ts +8 -10
  57. package/utils/storage.ts +31 -0
  58. package/utils/string.ts +1 -2
  59. package/utils/upload/AwsS3.ts +12 -4
  60. package/admin/layout/large/PageTab.vue +0 -70
  61. package/admin/route-guards/collapseMenu.ts +0 -11
  62. package/libs/a-calc.ts +0 -1
  63. package/vue/components/test/KitTest.vue +0 -9
  64. 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 { adminPlugin } from '../adminPlugin';
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 = permissionStore.hasPermission(codes) ? '' : 'none';
15
+ el.style.display = permission.has(codes) ? '' : 'none';
19
16
  }
20
17
 
21
18
  (el as any)[UNWATCH_NAME] = watch(
22
- () => permissionStore.permissionCodesStr,
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
- const permissionStore = adminPlugin.deps.usePermissionStore();
36
-
37
- return permissionStore.hasPermission(codes);
32
+ return permission.has(codes);
38
33
  };
39
34
  },
40
35
  });
@@ -1,3 +1,2 @@
1
1
  export { setupPageProgress } from './pageProgress';
2
2
  export { setupPageTitle } from './pageTitle';
3
- export { setupCollapseMenu } from './collapseMenu';
@@ -1,3 +1,4 @@
1
+ /* 已弃用 */
1
2
  export { createUsePageStore } from './createUsePageStore';
2
3
  export { createUseMenuStore } from './createUseMenuStore';
3
4
  export { createUsePageTabStore } from './createUsePageTabStore';
@@ -103,7 +103,7 @@
103
103
  z-index: 2;
104
104
  margin-bottom: -9px !important;
105
105
  background-color: var(--pagination-bg-color);
106
- box-shadow: 0 0 0 16px var(--pagination-bg-color);
106
+ box-shadow: 0 0 0 14.5px var(--pagination-bg-color);
107
107
  }
108
108
  }
109
109
 
@@ -1,5 +1,5 @@
1
- @import './classCover';
2
- @import './globalCover';
1
+ @use './classCover';
2
+ @use './globalCover';
3
3
 
4
4
  @media (pointer: fine) {
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { Modal as AntModal } from 'ant-design-vue';
2
- import { tryOnUnmounted } from '@vueuse/core';
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
- (refs.comp as any)?.confirm?.(e);
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
- Object.keys(compProps).forEach(key => delete compProps[key]);
82
- Object.assign(compProps, newCompProps);
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 confirm = (ev: any) => {
101
+ const onConfirm = (ev: any) => {
90
102
  _modalProps.open = false;
91
103
  promiseResolvers.resolve(ev);
92
104
  };
93
- const close = (reason?: any) => {
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 = close;
116
- (compProps as any).onConfirm = confirm;
129
+ (compProps as any).onClose = onClose;
130
+ (compProps as any).onConfirm = onConfirm;
117
131
 
118
- tryOnUnmounted(_onClose);
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 = (columnsGetter: () => LocalColumnsType) => computed(columnsGetter);
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
- /** 【类型辅助】用于定义出类型精确的 columns */
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/locale/zh';
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.4",
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.5",
17
- "vue": "3.5.11",
18
- "vue-router": "4.4.5"
19
- },
20
- "dependencies": {
21
- "@aws-sdk/client-s3": "^3.667.0",
22
- "@aws-sdk/lib-storage": "^3.667.0",
23
- "@babel/generator": "^7.25.7",
24
- "@babel/parser": "^7.25.7",
25
- "@babel/traverse": "^7.25.7",
26
- "@babel/types": "^7.25.7",
27
- "@ckeditor/ckeditor5-vue": "^5.1.0",
28
- "@fingerprintjs/fingerprintjs": "^4.5.0",
29
- "@tanstack/vue-query": "^5.59.1",
30
- "@vueuse/components": "^11.1.0",
31
- "@vueuse/core": "^11.1.0",
32
- "@vueuse/router": "^11.1.0",
33
- "a-calc": "^2.2.10",
34
- "archiver": "^7.0.1",
35
- "axios": "^1.7.7",
36
- "bignumber.js": "^9.1.2",
37
- "chokidar": "^3.6.0",
38
- "crypto-es": "^2.1.0",
39
- "dayjs": "^1.11.13",
40
- "echarts": "^5.5.1",
41
- "execa": "^9.4.0",
42
- "fast-glob": "^3.3.2",
43
- "localstorage-slim": "^2.7.1",
44
- "lodash-es": "^4.17.21",
45
- "nprogress": "^0.2.0",
46
- "pinia": "^2.2.4",
47
- "tsx": "^4.16.00",
48
- "vue": "^3.5.11",
49
- "vue-i18n": "^10.0.4",
50
- "vue-router": "^4.4.5"
51
- },
52
- "devDependencies": {
53
- "@ckeditor/ckeditor5-adapter-ckfinder": "^41.1.0",
54
- "@ckeditor/ckeditor5-alignment": "^41.1.0",
55
- "@ckeditor/ckeditor5-autoformat": "^41.1.0",
56
- "@ckeditor/ckeditor5-basic-styles": "^41.1.0",
57
- "@ckeditor/ckeditor5-block-quote": "^41.1.0",
58
- "@ckeditor/ckeditor5-build-classic": "^41.1.0",
59
- "@ckeditor/ckeditor5-code-block": "^41.1.0",
60
- "@ckeditor/ckeditor5-document-outline": "^41.1.0",
61
- "@ckeditor/ckeditor5-editor-classic": "^41.1.0",
62
- "@ckeditor/ckeditor5-essentials": "^41.1.0",
63
- "@ckeditor/ckeditor5-font": "^41.1.0",
64
- "@ckeditor/ckeditor5-heading": "^41.1.0",
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}) \((.*?)\)/) ?? [];
@@ -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 => code.toUpperCase().startsWith(target.toUpperCase()));
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/lib/core';
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 => code.toUpperCase().startsWith(target.toUpperCase()));
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
  // 由于是异步加载,所以需要再判断是否已经加载过
@@ -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
  */