@peng_kai/kit 0.1.17 → 0.2.0-beta.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.
Files changed (84) hide show
  1. package/admin/adminPlugin.ts +47 -0
  2. package/admin/components/filter/src/FilterDrawer.vue +153 -153
  3. package/admin/components/filter/src/FilterParam.vue +76 -78
  4. package/admin/components/filter/src/FilterReset.vue +2 -2
  5. package/admin/components/filter/src/useFilterParams.ts +75 -25
  6. package/admin/components/filter/src/useFilterQuery.ts +32 -16
  7. package/admin/components/rich-text/index.ts +2 -0
  8. package/admin/components/rich-text/src/RichText.vue +342 -0
  9. package/admin/components/rich-text/src/imageUploader.ts +34 -0
  10. package/admin/components/rich-text/src/type.d.ts +7 -0
  11. package/admin/components/scroll-nav/index.ts +1 -1
  12. package/admin/components/scroll-nav/src/ScrollNav.vue +59 -59
  13. package/admin/components/text/index.ts +13 -13
  14. package/admin/components/text/src/Amount.vue +121 -121
  15. package/admin/components/text/src/Datetime.vue +47 -48
  16. package/admin/components/text/src/Duration.vue +26 -26
  17. package/admin/components/text/src/Hash.vue +51 -51
  18. package/admin/components/text/src/createTagGetter.ts +13 -13
  19. package/admin/components/upload/index.ts +2 -0
  20. package/admin/components/upload/src/PictureCardUpload.vue +143 -0
  21. package/admin/components/upload/src/customRequests.ts +31 -0
  22. package/admin/defines/index.ts +1 -1
  23. package/admin/defines/route/helpers.ts +0 -1
  24. package/admin/defines/startup/defineStartup.ts +8 -1
  25. package/admin/defines/startup/index.ts +1 -1
  26. package/admin/defines/startup/{getStartups.ts → runStartup.ts} +16 -7
  27. package/admin/layout/large/Breadcrumb.vue +68 -69
  28. package/admin/layout/large/Content.vue +23 -24
  29. package/admin/layout/large/Menu.vue +68 -69
  30. package/admin/layout/large/PageTab.vue +70 -71
  31. package/admin/permission/index.ts +2 -4
  32. package/admin/permission/routerGuard.ts +41 -43
  33. package/admin/permission/vuePlugin.ts +46 -30
  34. package/admin/route-guards/collapseMenu.ts +3 -3
  35. package/admin/route-guards/index.ts +3 -3
  36. package/admin/route-guards/pageProgress.ts +27 -27
  37. package/admin/route-guards/pageTitle.ts +18 -19
  38. package/admin/{hooks/useMenu.ts → stores/createUseMenuStore.ts} +133 -128
  39. package/admin/{hooks/usePage.ts → stores/createUsePageStore.ts} +145 -141
  40. package/admin/stores/createUsePageTabStore.ts +43 -0
  41. package/admin/{permission/usePermission.ts → stores/createUsePermissionStore.ts} +57 -52
  42. package/admin/stores/index.ts +8 -0
  43. package/admin/styles/classCover.scss +8 -0
  44. package/admin/styles/globalCover.scss +54 -54
  45. package/antd/components/InputNumberRange.vue +59 -59
  46. package/antd/directives/formLabelAlign.ts +36 -36
  47. package/antd/hooks/useAntdDrawer.ts +73 -73
  48. package/antd/hooks/useAntdForm.helpers.ts +92 -8
  49. package/antd/hooks/useAntdForm.ts +55 -63
  50. package/antd/hooks/useAntdTable.ts +127 -115
  51. package/antd/index.ts +1 -1
  52. package/libs/a-calc.ts +1 -0
  53. package/libs/axios.ts +2 -0
  54. package/libs/bignumber.ts +2 -0
  55. package/libs/dayjs.ts +5 -0
  56. package/libs/echarts.ts +5 -0
  57. package/libs/localstorage-slim.ts +2 -0
  58. package/libs/lodash-es.ts +1 -0
  59. package/libs/pinia.ts +1 -0
  60. package/libs/vue-query.ts +1 -0
  61. package/libs/vueuse.ts +3 -0
  62. package/package.json +91 -58
  63. package/request/helpers.ts +68 -49
  64. package/request/interceptors/toLogin.ts +26 -26
  65. package/request/queryClient.ts +34 -21
  66. package/request/type.d.ts +92 -92
  67. package/stylelint.config.cjs +7 -7
  68. package/tsconfig.json +50 -50
  69. package/utils/upload/AwsS3.ts +68 -0
  70. package/utils/upload/fileHandlers.ts +27 -0
  71. package/utils/upload/index.ts +2 -0
  72. package/vite/index.d.ts +1 -0
  73. package/vite/index.mjs +27 -0
  74. package/vue/components/echarts/index.ts +1 -0
  75. package/vue/components/echarts/src/ECharts.vue +48 -0
  76. package/vue/components/index.ts +1 -0
  77. package/vue/components/infinite-query/index.ts +1 -1
  78. package/vue/components/infinite-query/src/InfiniteQuery.vue +199 -205
  79. package/vue/components/infinite-query/src/useCreateTrigger.ts +39 -39
  80. package/vue/components/test/KitTest.vue +9 -0
  81. package/vue/components/test/testStore.ts +11 -0
  82. package/admin/hooks/index.ts +0 -5
  83. package/admin/hooks/usePageTab.ts +0 -35
  84. package/kitDependencies.ts +0 -43
@@ -1,43 +1,41 @@
1
- import type { Router } from 'vue-router';
2
- import { getDependencies } from '../../kitDependencies';
3
- import { hasToken } from '../../utils';
4
-
5
- export function setupPermissionRouterGuard(router: Router, rouneNames: { index: string, login: string, 403: string }) {
6
- const { usePermission } = getDependencies();
7
- const { refreshPermission, hasPermissions } = usePermission();
8
-
9
- router.beforeEach(async (to, _, next) => {
10
- const isLogin = hasToken();
11
- const needLogin = Boolean(to.meta?.requireAuth);
12
- let hasPermission = false;
13
-
14
- if (isLogin) {
15
- await refreshPermission();
16
-
17
- const permissionCode = to.meta?.permissionCode;
18
- hasPermission = permissionCode ? hasPermissions(permissionCode) : true;
19
- }
20
-
21
- // 已登录状态跳转登录页,跳转至首页
22
- if (isLogin && to.name === rouneNames.login)
23
- return next({ name: rouneNames.index, replace: true });
24
-
25
- // 不需要登录权限的页面直接通行
26
- else if (!needLogin)
27
- return next(true);
28
-
29
- // 未登录状态进入需要登录权限的页面
30
- else if (!isLogin && needLogin)
31
- return next({ name: rouneNames.login, replace: true });
32
-
33
- // 登录状态进入需要登录权限的页面,有权限直接通行
34
- else if (isLogin && needLogin && hasPermission)
35
- return next(true);
36
-
37
- // 登录状态进入需要登录权限的页面,无权限,重定向到无权限页面
38
- else if (isLogin && needLogin && !hasPermission)
39
- return next({ name: rouneNames[403], replace: true });
40
-
41
- return next(false);
42
- });
43
- }
1
+ import type { Router } from 'vue-router';
2
+ import { adminPlugin } from '../adminPlugin';
3
+ import { hasToken } from '../../utils';
4
+
5
+ export function setupPermissionRouterGuard(router: Router, rouneNames: { index: string, login: string, 403: string }) {
6
+ router.beforeEach(async (to, _, next) => {
7
+ const permissionStore = adminPlugin.deps.usePermissionStore();
8
+ const isLogin = hasToken();
9
+ const needLogin = Boolean(to.meta?.requireAuth);
10
+ let hasPermission = false;
11
+
12
+ if (isLogin) {
13
+ await permissionStore.refreshPermission();
14
+
15
+ const permissionCode = to.meta?.permissionCode;
16
+ hasPermission = permissionCode ? permissionStore.hasPermission(permissionCode) : true;
17
+ }
18
+
19
+ // 已登录状态跳转登录页,跳转至首页
20
+ if (isLogin && to.name === rouneNames.login)
21
+ return next({ name: rouneNames.index, replace: true });
22
+
23
+ // 不需要登录权限的页面直接通行
24
+ else if (!needLogin)
25
+ return next(true);
26
+
27
+ // 未登录状态进入需要登录权限的页面
28
+ else if (!isLogin && needLogin)
29
+ return next({ name: rouneNames.login, replace: true });
30
+
31
+ // 登录状态进入需要登录权限的页面,有权限直接通行
32
+ else if (isLogin && needLogin && hasPermission)
33
+ return next(true);
34
+
35
+ // 登录状态进入需要登录权限的页面,无权限,重定向到无权限页面
36
+ else if (isLogin && needLogin && !hasPermission)
37
+ return next({ name: rouneNames[403], replace: true });
38
+
39
+ return next(false);
40
+ });
41
+ }
@@ -1,30 +1,46 @@
1
- import type { App } from 'vue';
2
- import { getDependencies } from '../../kitDependencies';
3
-
4
- export type THasPermissionsFn = ReturnType<ReturnType<typeof getDependencies>['usePermission']>['hasPermissions'];
5
-
6
- export function setupPermissionPlugin(app: App) {
7
- const { usePermission } = getDependencies();
8
- const { hasPermissions } = usePermission();
9
-
10
- app.directive('has-permissions', {
11
- mounted(el, binding) {
12
- const codes = binding.value;
13
-
14
- if (!hasPermissions(codes))
15
- el.remove();
16
- },
17
- updated(el, binding) {
18
- const codes = binding.value;
19
-
20
- if (!hasPermissions(codes))
21
- el.remove();
22
- },
23
- });
24
-
25
- app.use({
26
- install(app) {
27
- app.config.globalProperties.$hasPermission = hasPermissions;
28
- },
29
- });
30
- }
1
+ import type { App } from 'vue';
2
+ import { watch } from 'vue';
3
+ import { adminPlugin } from '../adminPlugin';
4
+
5
+ type TCodes = string | string[];
6
+
7
+ const PLUGIN_NAME = 'has-permission';
8
+ const UNWATCH_NAME = `v-${PLUGIN_NAME}@unwatch`;
9
+
10
+ export function setupPermissionPlugin(app: App) {
11
+ app.directive<HTMLElement, TCodes>(PLUGIN_NAME, {
12
+ mounted(el, binding) {
13
+ const permissionStore = adminPlugin.deps.usePermissionStore();
14
+
15
+ function updateVisibility() {
16
+ const codes = binding.value;
17
+ el.style.display = permissionStore.hasPermission(codes) ? '' : 'none';
18
+ }
19
+
20
+ (el as any)[UNWATCH_NAME] = watch(
21
+ () => permissionStore.permissionCodesStr,
22
+ updateVisibility,
23
+ { immediate: true },
24
+ );
25
+ },
26
+ unmounted(el) {
27
+ (el as any)[UNWATCH_NAME]?.();
28
+ },
29
+ });
30
+
31
+ app.use({
32
+ install(app) {
33
+ app.config.globalProperties.$hasPermission = (codes: TCodes) => {
34
+ const permissionStore = adminPlugin.deps.usePermissionStore();
35
+
36
+ return permissionStore.hasPermission(codes);
37
+ };
38
+ },
39
+ });
40
+ }
41
+
42
+ declare module 'vue' {
43
+ interface ComponentCustomProperties {
44
+ $hasPermission: (code: string | string[]) => boolean
45
+ }
46
+ }
@@ -1,11 +1,11 @@
1
1
  import type { Router } from 'vue-router';
2
- import { getDependencies } from '../../kitDependencies';
2
+ import { adminPlugin } from '../adminPlugin';
3
3
 
4
4
  export function setupCollapseMenu(router: Router) {
5
- const deps = getDependencies();
5
+ const menuStore = adminPlugin.deps.useMenuStore();
6
6
 
7
7
  router.beforeEach(() => {
8
- deps.useMenu().collapsed.value = false;
8
+ menuStore.collapsed = false;
9
9
  return true;
10
10
  });
11
11
  }
@@ -1,3 +1,3 @@
1
- export { setupPageProgress } from './pageProgress';
2
- export { setupPageTitle } from './pageTitle';
3
- export { setupCollapseMenu } from './collapseMenu';
1
+ export { setupPageProgress } from './pageProgress';
2
+ export { setupPageTitle } from './pageTitle';
3
+ export { setupCollapseMenu } from './collapseMenu';
@@ -1,27 +1,27 @@
1
- import type { Router } from 'vue-router';
2
- import { useStyleTag } from '@vueuse/core';
3
- import NProgress from 'nprogress';
4
- import 'nprogress/nprogress.css';
5
-
6
- /**
7
- * 用于显示页面跳转时,页面顶部进度条
8
- */
9
- export function setupPageProgress(router: Router) {
10
- NProgress.configure({ showSpinner: false });
11
- useStyleTag(`
12
- #nprogress .bar {
13
- height: 3px;
14
- background: var(--antd-colorPrimary);
15
- }
16
- #nprogress .peg {
17
- box-shadow: 0 0 10px var(--antd-colorPrimary), 0 0 5px var(--antd-colorPrimary);
18
- }
19
- `);
20
-
21
- router.beforeEach(() => {
22
- NProgress.start();
23
- });
24
- router.afterEach(() => {
25
- setTimeout(() => NProgress.done(), 200);
26
- });
27
- }
1
+ import type { Router } from 'vue-router';
2
+ import { useStyleTag } from '@vueuse/core';
3
+ import NProgress from 'nprogress';
4
+ import 'nprogress/nprogress.css';
5
+
6
+ /**
7
+ * 用于显示页面跳转时,页面顶部进度条
8
+ */
9
+ export function setupPageProgress(router: Router) {
10
+ NProgress.configure({ showSpinner: false });
11
+ useStyleTag(`
12
+ #nprogress .bar {
13
+ height: 3px;
14
+ background: var(--antd-colorPrimary);
15
+ }
16
+ #nprogress .peg {
17
+ box-shadow: 0 0 10px var(--antd-colorPrimary), 0 0 5px var(--antd-colorPrimary);
18
+ }
19
+ `);
20
+
21
+ router.beforeEach(() => {
22
+ NProgress.start();
23
+ });
24
+ router.afterEach(() => {
25
+ setTimeout(() => NProgress.done(), 200);
26
+ });
27
+ }
@@ -1,19 +1,18 @@
1
- import type { Router } from 'vue-router';
2
- import { getDependencies } from '../../kitDependencies';
3
-
4
- /**
5
- * 用于在路由跳转后,同步修改 title
6
- */
7
- export function setupPageTitle(router: Router) {
8
- const deps = getDependencies();
9
-
10
- router.afterEach((to, _, err) => {
11
- const title = to.meta.title;
12
-
13
- if (!err) {
14
- document.title = typeof title === 'function'
15
- ? title()
16
- : title ?? deps.appName;
17
- }
18
- });
19
- }
1
+ import type { Router } from 'vue-router';
2
+ import { adminPlugin } from '../adminPlugin';
3
+
4
+ /**
5
+ * 用于在路由跳转后,同步修改 title
6
+ */
7
+ export function setupPageTitle(router: Router) {
8
+ router.afterEach((to, _, err) => {
9
+ const meta = adminPlugin.meta;
10
+ const title = to.meta.title;
11
+
12
+ if (!err) {
13
+ document.title = typeof title === 'function'
14
+ ? title()
15
+ : title ?? meta.appName;
16
+ }
17
+ });
18
+ }
@@ -1,128 +1,133 @@
1
- import { createGlobalState } from '@vueuse/core';
2
- import { computed, reactive, ref } from 'vue';
3
- import type { Ref, UnwrapNestedRefs, VNode } from 'vue';
4
-
5
- export { useMenu };
6
- export type { TMenu };
7
-
8
- interface IMenuConfig {
9
- key: string
10
- label: string | (() => string)
11
- icon?: () => VNode
12
- order: number
13
- trigger: () => void
14
- children?: IMenuConfig[]
15
- }
16
-
17
- interface IMenuReactive {
18
- key: string
19
- label: Ref<string>
20
- icon: Ref<VNode | null>
21
- order: number
22
- trigger: () => void
23
- children?: IMenuReactive[]
24
- }
25
-
26
- type TMenu = UnwrapNestedRefs<IMenuReactive>;
27
-
28
- const useMenu = createGlobalState(() => {
29
- const menus = reactive<TMenu[]>([]);
30
- const collapsed = ref(false);
31
-
32
- const findMenu = (menus: TMenu[], key: string) => {
33
- const queue = [...menus];
34
-
35
- while (queue.length > 0) {
36
- const menu = queue.shift()!;
37
-
38
- if (menu.key === key)
39
- return menu;
40
-
41
- if (menu.children)
42
- queue.push(...menu.children);
43
- }
44
-
45
- return undefined;
46
- };
47
-
48
- /**
49
- * 获取目标路由的路径
50
- * @param key 目标路由
51
- */
52
- const getMenuPath = (key: string) => {
53
- const path: TMenu[] = [];
54
-
55
- const _getMenuPath = (menus: TMenu[], key: string) => {
56
- for (const menu of menus) {
57
- if (menu.key === key) {
58
- path.push(menu);
59
- return true;
60
- }
61
-
62
- if (menu.children) {
63
- path.push(menu);
64
- if (_getMenuPath(menu.children, key))
65
- return true;
66
- path.pop();
67
- }
68
- }
69
-
70
- return false;
71
- };
72
-
73
- _getMenuPath(menus, key);
74
-
75
- return path;
76
- };
77
-
78
- const addMenu = (menuConfig: IMenuConfig, parentKey?: string) => {
79
- const labelGetter = typeof menuConfig.label === 'function' ? menuConfig.label : (() => menuConfig.label) as (() => string);
80
- const iconGetter = typeof menuConfig.icon === 'function' ? menuConfig.icon : () => null;
81
-
82
- const _menu = reactive<IMenuReactive>({
83
- key: menuConfig.key,
84
- label: computed(labelGetter),
85
- icon: computed(iconGetter),
86
- trigger: menuConfig.trigger,
87
- order: menuConfig.order,
88
- });
89
-
90
- if (parentKey) {
91
- const parentMenu = findMenu(menus, parentKey);
92
-
93
- if (!parentMenu)
94
- return;
95
-
96
- const children = reactive(parentMenu.children ?? []);
97
- children.push(_menu);
98
- children.sort((a, b) => b.order - a.order);
99
- parentMenu.children = children;
100
- }
101
- else {
102
- menus.push(_menu);
103
- menus.sort((a, b) => b.order - a.order);
104
- }
105
- };
106
-
107
- const removeMenu = (key: string) => {
108
- const _remove = (menus: TMenu[], key: string) => {
109
- for (let i = 0; i < menus.length; i++) {
110
- const menu = menus[i];
111
- if (menu.key === key) {
112
- menus.splice(i, 1);
113
- return;
114
- }
115
- if (menu.children)
116
- _remove(menu.children, key);
117
- }
118
- };
119
-
120
- return _remove(menus, key);
121
- };
122
-
123
- const getMenu = (key: string) => {
124
- return findMenu(menus, key);
125
- };
126
-
127
- return { menus, collapsed, getMenuPath, addMenu, removeMenu, getMenu };
128
- });
1
+ import { computed, reactive, ref } from 'vue';
2
+ import type { Ref, UnwrapNestedRefs, VNode } from 'vue';
3
+ import { defineStore } from 'pinia';
4
+
5
+ export { createUseMenuStore };
6
+ export type { TMenu, TUseMenuStore };
7
+
8
+ interface IMenuConfig {
9
+ key: string
10
+ label: string | (() => string)
11
+ icon?: () => VNode
12
+ order: number
13
+ trigger: () => void
14
+ children?: IMenuConfig[]
15
+ }
16
+
17
+ interface IMenuReactive {
18
+ key: string
19
+ label: Ref<string>
20
+ icon: Ref<VNode | null>
21
+ order: number
22
+ trigger: () => void
23
+ children?: IMenuReactive[]
24
+ }
25
+
26
+ type TMenu = UnwrapNestedRefs<IMenuReactive>;
27
+ type TUseMenuStore = ReturnType<typeof createUseMenuStore>;
28
+
29
+ function createUseMenuStore() {
30
+ return defineStore('appMenu', () => storeSetup());
31
+ }
32
+
33
+ function storeSetup() {
34
+ const menus = reactive<TMenu[]>([]);
35
+ const collapsed = ref(false);
36
+
37
+ const findMenu = (menus: TMenu[], key: string) => {
38
+ const queue = [...menus];
39
+
40
+ while (queue.length > 0) {
41
+ const menu = queue.shift()!;
42
+
43
+ if (menu.key === key)
44
+ return menu;
45
+
46
+ if (menu.children)
47
+ queue.push(...menu.children);
48
+ }
49
+
50
+ return undefined;
51
+ };
52
+
53
+ /**
54
+ * 获取目标路由的路径
55
+ * @param key 目标路由
56
+ */
57
+ const getMenuPath = (key: string) => {
58
+ const path: TMenu[] = [];
59
+
60
+ const _getMenuPath = (menus: TMenu[], key: string) => {
61
+ for (const menu of menus) {
62
+ if (menu.key === key) {
63
+ path.push(menu);
64
+ return true;
65
+ }
66
+
67
+ if (menu.children) {
68
+ path.push(menu);
69
+ if (_getMenuPath(menu.children, key))
70
+ return true;
71
+ path.pop();
72
+ }
73
+ }
74
+
75
+ return false;
76
+ };
77
+
78
+ _getMenuPath(menus, key);
79
+
80
+ return path;
81
+ };
82
+
83
+ const addMenu = (menuConfig: IMenuConfig, parentKey?: string) => {
84
+ const labelGetter = typeof menuConfig.label === 'function' ? menuConfig.label : (() => menuConfig.label) as (() => string);
85
+ const iconGetter = typeof menuConfig.icon === 'function' ? menuConfig.icon : () => null;
86
+
87
+ const _menu = reactive<IMenuReactive>({
88
+ key: menuConfig.key,
89
+ label: computed(labelGetter),
90
+ icon: computed(iconGetter),
91
+ trigger: menuConfig.trigger,
92
+ order: menuConfig.order,
93
+ });
94
+
95
+ if (parentKey) {
96
+ const parentMenu = findMenu(menus, parentKey);
97
+
98
+ if (!parentMenu)
99
+ return;
100
+
101
+ const children = reactive(parentMenu.children ?? []);
102
+ children.push(_menu);
103
+ children.sort((a, b) => b.order - a.order);
104
+ parentMenu.children = children;
105
+ }
106
+ else {
107
+ menus.push(_menu);
108
+ menus.sort((a, b) => b.order - a.order);
109
+ }
110
+ };
111
+
112
+ const removeMenu = (key: string) => {
113
+ const _remove = (menus: TMenu[], key: string) => {
114
+ for (let i = 0; i < menus.length; i++) {
115
+ const menu = menus[i];
116
+ if (menu.key === key) {
117
+ menus.splice(i, 1);
118
+ return;
119
+ }
120
+ if (menu.children)
121
+ _remove(menu.children, key);
122
+ }
123
+ };
124
+
125
+ return _remove(menus, key);
126
+ };
127
+
128
+ const getMenu = (key: string) => {
129
+ return findMenu(menus, key);
130
+ };
131
+
132
+ return { menus, collapsed, getMenuPath, addMenu, removeMenu, getMenu };
133
+ }