@peng_kai/kit 0.1.17 → 0.2.0-beta.0

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/admin/adminPlugin.ts +47 -0
  2. package/admin/components/filter/src/FilterParam.vue +76 -78
  3. package/admin/components/filter/src/FilterReset.vue +2 -2
  4. package/admin/components/filter/src/useFilterParams.ts +75 -25
  5. package/admin/components/filter/src/useFilterQuery.ts +32 -16
  6. package/admin/components/rich-text/index.ts +2 -0
  7. package/admin/components/rich-text/src/RichText.vue +342 -0
  8. package/admin/components/rich-text/src/imageUploader.ts +34 -0
  9. package/admin/components/rich-text/src/type.d.ts +7 -0
  10. package/admin/components/text/src/Datetime.vue +47 -48
  11. package/admin/components/upload/index.ts +2 -0
  12. package/admin/components/upload/src/PictureCardUpload.vue +143 -0
  13. package/admin/components/upload/src/customRequests.ts +31 -0
  14. package/admin/defines/index.ts +1 -1
  15. package/admin/defines/route/helpers.ts +0 -1
  16. package/admin/defines/startup/defineStartup.ts +8 -1
  17. package/admin/defines/startup/index.ts +1 -1
  18. package/admin/defines/startup/{getStartups.ts → runStartup.ts} +16 -7
  19. package/admin/layout/large/Breadcrumb.vue +68 -69
  20. package/admin/layout/large/Content.vue +23 -24
  21. package/admin/layout/large/Menu.vue +68 -69
  22. package/admin/layout/large/PageTab.vue +70 -71
  23. package/admin/permission/index.ts +2 -4
  24. package/admin/permission/routerGuard.ts +41 -43
  25. package/admin/permission/vuePlugin.ts +46 -30
  26. package/admin/route-guards/collapseMenu.ts +3 -3
  27. package/admin/route-guards/pageTitle.ts +18 -19
  28. package/admin/{hooks/useMenu.ts → stores/createUseMenuStore.ts} +133 -128
  29. package/admin/{hooks/usePage.ts → stores/createUsePageStore.ts} +145 -141
  30. package/admin/stores/createUsePageTabStore.ts +43 -0
  31. package/admin/{permission/usePermission.ts → stores/createUsePermissionStore.ts} +57 -52
  32. package/admin/stores/index.ts +8 -0
  33. package/admin/styles/classCover.scss +8 -0
  34. package/antd/hooks/useAntdForm.helpers.ts +92 -8
  35. package/antd/hooks/useAntdForm.ts +55 -63
  36. package/antd/hooks/useAntdTable.ts +12 -0
  37. package/antd/index.ts +1 -1
  38. package/libs/a-calc.ts +1 -0
  39. package/libs/axios.ts +2 -0
  40. package/libs/bignumber.ts +2 -0
  41. package/libs/dayjs.ts +5 -0
  42. package/libs/echarts.ts +5 -0
  43. package/libs/localstorage-slim.ts +2 -0
  44. package/libs/lodash-es.ts +1 -0
  45. package/libs/pinia.ts +1 -0
  46. package/libs/vue-query.ts +1 -0
  47. package/libs/vueuse.ts +3 -0
  48. package/package.json +55 -16
  49. package/request/helpers.ts +20 -1
  50. package/request/queryClient.ts +34 -21
  51. package/utils/upload/AwsS3.ts +76 -0
  52. package/utils/upload/fileHandlers.ts +27 -0
  53. package/utils/upload/index.ts +2 -0
  54. package/vite/index.d.ts +1 -0
  55. package/vite/index.mjs +27 -0
  56. package/vue/components/echarts/index.ts +1 -0
  57. package/vue/components/echarts/src/ECharts.vue +48 -0
  58. package/vue/components/index.ts +1 -0
  59. package/vue/components/infinite-query/src/InfiniteQuery.vue +2 -8
  60. package/vue/components/test/KitTest.vue +9 -0
  61. package/vue/components/test/testStore.ts +11 -0
  62. package/admin/hooks/index.ts +0 -5
  63. package/admin/hooks/usePageTab.ts +0 -35
  64. package/kitDependencies.ts +0 -43
@@ -1,141 +1,145 @@
1
- import { createGlobalState, usePrevious } from '@vueuse/core';
2
- import type { RouteLocationNormalizedLoaded } from 'vue-router';
3
- import { computed, reactive, readonly, ref, shallowRef, watch } from 'vue';
4
- import type { VNode } from 'vue';
5
- import { getTitle } from '../defines/route';
6
- import { getDependencies } from '../../kitDependencies';
7
- import { useMenu } from './useMenu';
8
- import type { TMenu } from './useMenu';
9
-
10
- export { usePage };
11
- export type { TPageState, IBreadcrumb };
12
-
13
- type TPageState = ReturnType<typeof getPageState>;
14
-
15
- interface IBreadcrumb {
16
- title: string
17
- icon?: VNode | null
18
- trigger?: () => void
19
- children?: IBreadcrumb[]
20
- }
21
-
22
- const usePage = createGlobalState(() => {
23
- const { useRouter } = getDependencies();
24
- const router = useRouter();
25
- const currentPageNode = shallowRef<VNode>();
26
- const currentPageKey = ref('');
27
- const pageCacheList = reactive<string[]>([]);
28
- const pageStateMap = new Map<string, TPageState>();
29
- const currentPageState = computed(() => pageStateMap.get(currentPageKey.value));
30
- const previousPageState = usePrevious(currentPageState);
31
-
32
- const openPage = (key: string) => {
33
- const route = pageStateMap.get(key)?.route;
34
-
35
- if (!route)
36
- return;
37
-
38
- router.push(route.fullPath);
39
- };
40
-
41
- const closePage = (key: string) => {
42
- if (!pageStateMap.has(key))
43
- return;
44
-
45
- const cacheIndex = pageCacheList.indexOf(key);
46
- cacheIndex >= 0 && pageCacheList.splice(cacheIndex, 1);
47
- // 关闭当前页面则返回上一个路由
48
- currentPageKey.value === key && router.go(-1);
49
- pageStateMap.delete(key);
50
- };
51
-
52
- const setPage = (pageNode: VNode, route: RouteLocationNormalizedLoaded) => {
53
- const pageKey = route?.meta?.pageKeyFn?.(route) ?? route.fullPath;
54
- const pageInfo = getPageState(route);
55
- const canKeepAlive = route.meta.keepAlive && !pageCacheList.includes(pageKey);
56
-
57
- canKeepAlive && pageCacheList.push(pageKey);
58
- pageStateMap.has(pageKey) || pageStateMap.set(pageKey, pageInfo)
59
-
60
- ;(pageNode as any).type.name = pageKey;
61
- currentPageKey.value = pageKey;
62
- currentPageNode.value = pageNode;
63
-
64
- return pageNode;
65
- };
66
-
67
- const getCurrentPageState = () => {
68
- return pageStateMap.get(currentPageKey.value);
69
- };
70
-
71
- // 监听 title 变化
72
- watch(() => currentPageState.value?.title, (title) => {
73
- let _title = title;
74
-
75
- if (!_title) {
76
- const pageState = currentPageState.value;
77
-
78
- // 当前 title 为空时,使用路由 title
79
- if (pageState) {
80
- _title = getTitle(pageState?.route);
81
- pageState.title = _title!;
82
- }
83
- }
84
-
85
- document.title = _title!;
86
- });
87
-
88
- return {
89
- currentPageNode,
90
- pageCacheList,
91
- pageStateMap,
92
- currentPageKey,
93
- currentPageState,
94
- getCurrentPageState,
95
- previousPageState,
96
- setPage,
97
- openPage,
98
- closePage,
99
- };
100
- });
101
-
102
- function getPageState(route: RouteLocationNormalizedLoaded) {
103
- const deps = getDependencies();
104
- const appName = deps.appName as string;
105
- const { getMenuPath } = useMenu();
106
- const menuPath = getMenuPath(route.name as string);
107
- const currentMenu = menuPath.pop();
108
- const { icon: mIcon } = route.meta;
109
- const title = currentMenu?.label ?? getTitle(route) ?? appName;
110
- const icon = currentMenu?.icon ?? mIcon?.();
111
- const state = reactive({
112
- title,
113
- icon,
114
- breadcrumbs: menuPath.map(menuToBreadcrumb),
115
- route: readonly(route),
116
- refresh() {
117
- const menuKey = this.route.name as string;
118
- const { getMenu, getMenuPath } = useMenu();
119
- const menu = getMenu(menuKey);
120
- const menuPath = getMenuPath(menuKey);
121
-
122
- menuPath.pop();
123
-
124
- this.title = menu?.label ?? getTitle(this.route) ?? appName;
125
- this.breadcrumbs = menuPath.map(menuToBreadcrumb);
126
- },
127
- });
128
-
129
- return state;
130
- }
131
-
132
- function menuToBreadcrumb(menu: TMenu) {
133
- const ret: IBreadcrumb = reactive({
134
- title: menu.label,
135
- icon: menu.icon,
136
- trigger: menu.trigger,
137
- children: menu.children?.map(menuToBreadcrumb),
138
- });
139
-
140
- return ret;
141
- }
1
+ import { usePrevious } from '@vueuse/core';
2
+ import type { RouteLocationNormalizedLoaded } from 'vue-router';
3
+ import { defineStore } from 'pinia';
4
+ import { computed, reactive, readonly, ref, shallowRef, watch } from 'vue';
5
+ import type { VNode } from 'vue';
6
+ import { getTitle } from '../defines/route';
7
+ import { adminPlugin } from '../adminPlugin';
8
+ import type { TMenu } from './createUseMenuStore';
9
+
10
+ export { createUsePageStore };
11
+ export type { TPageState, TUsePageStore, IBreadcrumb };
12
+
13
+ type TPageState = ReturnType<typeof getPageState>;
14
+ type TUsePageStore = ReturnType<typeof createUsePageStore>;
15
+
16
+ interface IBreadcrumb {
17
+ title: string
18
+ icon?: VNode | null
19
+ trigger?: () => void
20
+ children?: IBreadcrumb[]
21
+ }
22
+
23
+ function createUsePageStore() {
24
+ return defineStore('appPage', () => {
25
+ return storeSetup();
26
+ });
27
+ }
28
+
29
+ function storeSetup() {
30
+ const router = adminPlugin.deps.router;
31
+ const currentPageNode = shallowRef<VNode>();
32
+ const currentPageKey = ref('');
33
+ const pageCacheList = reactive<string[]>([]);
34
+ const pageStateMap = new Map<string, TPageState>();
35
+ const currentPageState = computed(() => pageStateMap.get(currentPageKey.value));
36
+ const previousPageState = usePrevious(currentPageState);
37
+
38
+ const openPage = (key: string) => {
39
+ const route = pageStateMap.get(key)?.route;
40
+
41
+ if (!route)
42
+ return;
43
+
44
+ router.push(route.fullPath);
45
+ };
46
+
47
+ const closePage = (key: string) => {
48
+ if (!pageStateMap.has(key))
49
+ return;
50
+
51
+ const cacheIndex = pageCacheList.indexOf(key);
52
+ cacheIndex >= 0 && pageCacheList.splice(cacheIndex, 1);
53
+ // 关闭当前页面则返回上一个路由
54
+ currentPageKey.value === key && router.go(-1);
55
+ pageStateMap.delete(key);
56
+ };
57
+
58
+ const setPage = (pageNode: VNode, route: RouteLocationNormalizedLoaded) => {
59
+ const pageKey = route?.meta?.pageKeyFn?.(route) ?? route.fullPath;
60
+ const pageInfo = getPageState(route);
61
+ const canKeepAlive = route.meta.keepAlive && !pageCacheList.includes(pageKey);
62
+
63
+ canKeepAlive && pageCacheList.push(pageKey);
64
+ pageStateMap.has(pageKey) || pageStateMap.set(pageKey, pageInfo)
65
+
66
+ ;(pageNode as any).type.name = pageKey;
67
+ currentPageKey.value = pageKey;
68
+ currentPageNode.value = pageNode;
69
+
70
+ return pageNode;
71
+ };
72
+
73
+ const getCurrentPageState = () => {
74
+ return pageStateMap.get(currentPageKey.value);
75
+ };
76
+
77
+ // 监听 title 变化
78
+ watch(() => currentPageState.value?.title, (title) => {
79
+ let _title = title;
80
+
81
+ if (!_title) {
82
+ const pageState = currentPageState.value;
83
+
84
+ // 当前 title 为空时,使用路由 title
85
+ if (pageState) {
86
+ _title = getTitle(pageState?.route);
87
+ pageState.title = _title!;
88
+ }
89
+ }
90
+
91
+ document.title = _title!;
92
+ });
93
+
94
+ return {
95
+ currentPageNode,
96
+ pageCacheList,
97
+ pageStateMap,
98
+ currentPageKey,
99
+ currentPageState,
100
+ getCurrentPageState,
101
+ previousPageState,
102
+ setPage,
103
+ openPage,
104
+ closePage,
105
+ };
106
+ }
107
+
108
+ function getPageState(route: RouteLocationNormalizedLoaded) {
109
+ const menuStore = adminPlugin.deps.useMenuStore()!;
110
+ const appName = adminPlugin.meta.appName;
111
+ const menuPath = menuStore.getMenuPath(route.name as string);
112
+ const currentMenu = menuPath.pop();
113
+ const { icon: mIcon } = route.meta;
114
+ const title = currentMenu?.label ?? getTitle(route) ?? appName;
115
+ const icon = currentMenu?.icon ?? mIcon?.();
116
+ const state = reactive({
117
+ title,
118
+ icon,
119
+ breadcrumbs: menuPath.map(menuToBreadcrumb),
120
+ route: readonly(route),
121
+ refresh() {
122
+ const menuKey = this.route.name as string;
123
+ const menu = menuStore.getMenu(menuKey);
124
+ const menuPath = menuStore.getMenuPath(menuKey);
125
+
126
+ menuPath.pop();
127
+
128
+ this.title = menu?.label ?? getTitle(this.route) ?? appName;
129
+ this.breadcrumbs = menuPath.map(menuToBreadcrumb);
130
+ },
131
+ });
132
+
133
+ return state;
134
+ }
135
+
136
+ function menuToBreadcrumb(menu: TMenu) {
137
+ const ret: IBreadcrumb = reactive({
138
+ title: menu.label,
139
+ icon: menu.icon,
140
+ trigger: menu.trigger,
141
+ children: menu.children?.map(menuToBreadcrumb),
142
+ });
143
+
144
+ return ret;
145
+ }
@@ -0,0 +1,43 @@
1
+ import { defineStore, storeToRefs } from 'pinia';
2
+ import { computed, ref, watch } from 'vue';
3
+ import { adminPlugin } from '../adminPlugin';
4
+
5
+ export { createUsePageTabStore };
6
+ export type { TUsePageTabStore };
7
+
8
+ type TUsePageTabStore = ReturnType<typeof createUsePageTabStore>;
9
+
10
+ function createUsePageTabStore() {
11
+ return defineStore('appPageTab', () => storeSetup());
12
+ }
13
+
14
+ function storeSetup() {
15
+ const pageStore = adminPlugin.deps.usePageStore!();
16
+ const { currentPageKey } = storeToRefs(pageStore);
17
+ const tabKeyList = ref<string[]>([]);
18
+ const tabList = computed(() => tabKeyList.value.map((key) => {
19
+ const state = pageStore.pageStateMap.get(key);
20
+
21
+ return state ? { key, title: state.title, icon: state.icon } : undefined!;
22
+ }).filter(tab => !!tab));
23
+
24
+ const closeTab = (key: string) => {
25
+ const i = tabKeyList.value.indexOf(key);
26
+
27
+ if (i > -1) {
28
+ pageStore.closePage(key);
29
+ setTimeout(() => tabKeyList.value.splice(i, 1));
30
+ }
31
+ };
32
+
33
+ watch(
34
+ () => pageStore.currentPageKey,
35
+ (key) => {
36
+ if (!tabKeyList.value.includes(key))
37
+ tabKeyList.value.push(key);
38
+ },
39
+ { immediate: true },
40
+ );
41
+
42
+ return { activeTab: currentPageKey, tabList, closeTab, openTab: pageStore.openPage };
43
+ }
@@ -1,52 +1,57 @@
1
- import { createGlobalState } from '@vueuse/core';
2
- import type { AsyncReturnType } from 'type-fest';
3
- import { computed, readonly, ref, watch } from 'vue';
4
- import { getDependencies } from '../../kitDependencies';
5
-
6
- export { usePermission };
7
- export type { TRole };
8
-
9
- type TRole = () => Promise<Record<string, boolean> | null | undefined>;
10
-
11
- const usePermission = createGlobalState(() => {
12
- const { roles } = getDependencies();
13
- const role = ref('main');
14
- const permissionCodes = ref<AsyncReturnType<TRole>>();
15
- const permissionCodesStr = computed(() => Object.keys(permissionCodes.value ?? {}).sort().join(','));
16
-
17
- /**
18
- * 刷新权限
19
- */
20
- const refreshPermission = async () => {
21
- permissionCodes.value = await roles[role.value]?.();
22
-
23
- return permissionCodes.value;
24
- };
25
-
26
- /**
27
- * 是否满足权限要求
28
- * @param codes 权限 code
29
- */
30
- const hasPermissions = (codes: string | string[]) => {
31
- const _codes = Array.isArray(codes) ? codes : [codes];
32
- const _permissionCodes = permissionCodes.value;
33
-
34
- if (_permissionCodes === null)
35
- return false;
36
- else if (_permissionCodes === undefined)
37
- // undefined 则表示没有权限要求,返回 true
38
- return true;
39
- else
40
- return _codes.every(code => !!_permissionCodes[code]);
41
- };
42
-
43
- watch(role, refreshPermission, { immediate: true });
44
-
45
- return {
46
- permissionCodes: readonly(permissionCodes),
47
- permissionCodesStr,
48
- role,
49
- hasPermissions,
50
- refreshPermission,
51
- };
52
- });
1
+ import { computed, readonly, ref, watch } from 'vue';
2
+ import { defineStore } from 'pinia';
3
+ import type { AsyncReturnType } from 'type-fest';
4
+ import { adminPlugin } from '../adminPlugin';
5
+
6
+ export { createUsePermissionStore };
7
+ export type { TRole, TUsePermissionStore };
8
+
9
+ type TRole = () => Promise<Record<string, boolean> | null | undefined>;
10
+ type TUsePermissionStore = ReturnType<typeof createUsePermissionStore>;
11
+
12
+ function createUsePermissionStore() {
13
+ return defineStore('appPermission', () => storeSetup());
14
+ }
15
+
16
+ function storeSetup() {
17
+ const roles = adminPlugin.deps.roles;
18
+ const role = ref('main');
19
+ const permissionCodes = ref<AsyncReturnType<TRole>>();
20
+ const permissionCodesStr = computed(() => Object.keys(permissionCodes.value ?? {}).sort().join(','));
21
+
22
+ /**
23
+ * 刷新权限
24
+ */
25
+ const refreshPermission = async () => {
26
+ permissionCodes.value = await roles?.[role.value]?.();
27
+
28
+ return permissionCodes.value;
29
+ };
30
+
31
+ /**
32
+ * 是否满足权限要求
33
+ * @param codes 权限 code
34
+ */
35
+ const hasPermission = (codes: string | string[]) => {
36
+ const _codes = Array.isArray(codes) ? codes : [codes];
37
+ const _permissionCodes = permissionCodes.value;
38
+
39
+ if (_permissionCodes === null)
40
+ return false;
41
+ else if (_permissionCodes === undefined)
42
+ // undefined 则表示没有权限要求,返回 true
43
+ return true;
44
+ else
45
+ return _codes.every(code => !!_permissionCodes[code]);
46
+ };
47
+
48
+ watch(role, refreshPermission, { immediate: true });
49
+
50
+ return {
51
+ permissionCodes: readonly(permissionCodes),
52
+ permissionCodesStr,
53
+ role,
54
+ hasPermission,
55
+ refreshPermission,
56
+ };
57
+ }
@@ -0,0 +1,8 @@
1
+ export { createUsePageStore } from './createUsePageStore';
2
+ export { createUseMenuStore } from './createUseMenuStore';
3
+ export { createUsePageTabStore } from './createUsePageTabStore';
4
+ export { createUsePermissionStore } from './createUsePermissionStore';
5
+
6
+ export type { TPageState, TUsePageStore, IBreadcrumb } from './createUsePageStore';
7
+ export type { TUseMenuStore } from './createUseMenuStore';
8
+ export type { TUsePageTabStore } from './createUsePageTabStore';
@@ -48,6 +48,14 @@
48
48
  }
49
49
  }
50
50
 
51
+ // 表单两列布局
52
+ .ant-form.ant-cover__col2-form {
53
+ display: grid;
54
+ grid-template-columns: repeat(2, 1fr);
55
+ column-gap: 24px;
56
+ align-content: flex-start;
57
+ }
58
+
51
59
  // 弹窗的基本款样式
52
60
  .ant-modal-wrap.antd-cover__basic-modal {
53
61
  --padding-size: 22px;
@@ -1,15 +1,38 @@
1
- export { buildGroupFieldName, parseGroupFieldName, isSameGroup, isSameField, getGroupIndex, GROUP_SEP };
1
+ import type { FormItemProps } from 'ant-design-vue/es/form';
2
+
3
+ export {
4
+ buildGroupField,
5
+ parseGroupField,
6
+ groupingForm,
7
+ formatGroup,
8
+ isSameGroup,
9
+ isSameField,
10
+ getGroupIndex,
11
+ GROUP_SEP,
12
+ };
2
13
 
3
14
  const GROUP_SEP = '__';
4
15
  const groupFieldNameRE = new RegExp(
5
- `(?<groupName>[a-zA-Z0-9]+)${GROUP_SEP}(?<index>\\d+)${GROUP_SEP}(?<fieldName>[a-zA-Z0-9]+)`,
16
+ `(?<groupName>.+?)${GROUP_SEP}(?<index>\\d+)${GROUP_SEP}(?<fieldName>.+)`,
6
17
  );
7
18
 
8
- function buildGroupFieldName(name: string, index: number, field: string) {
19
+ /**
20
+ * 构建组字段名
21
+ * @param name - 组名
22
+ * @param index - 组索引
23
+ * @param field - 字段名
24
+ * @returns 返回组字段名
25
+ */
26
+ function buildGroupField(name: string, index: number, field: string) {
9
27
  return name + GROUP_SEP + index + GROUP_SEP + field;
10
28
  }
11
29
 
12
- function parseGroupFieldName(name: string) {
30
+ /**
31
+ * 解析组字段名
32
+ * @param name - 组字段名
33
+ * @returns 返回一个数组,包含组名、组索引和字段名
34
+ */
35
+ function parseGroupField(name: string) {
13
36
  const res = name.match(groupFieldNameRE);
14
37
  const ret = {
15
38
  fieldName: '',
@@ -26,23 +49,84 @@ function parseGroupFieldName(name: string) {
26
49
  return ret;
27
50
  }
28
51
 
52
+ /**
53
+ * 根据指定的组名对表单项进行分组
54
+ * @param groupName - 要分组的组名
55
+ * @param items - 包含表单项的对象
56
+ * @returns 返回一个对象,其键为组索引,值为该组内的表单项
57
+ */
58
+ function groupingForm(groupName: string, items: Record<string, FormItemProps>) {
59
+ const _groups: Record<number, typeof items> = {};
60
+
61
+ for (const [key, item] of Object.entries(items)) {
62
+ const { groupName: name, index } = parseGroupField(key);
63
+
64
+ if (name === groupName) {
65
+ _groups[index] ??= {};
66
+ _groups[index][key] = item;
67
+ }
68
+ }
69
+
70
+ return _groups;
71
+ }
72
+
73
+ /**
74
+ * 格式化表单项组
75
+ * @param name - 组名
76
+ * @param items - 包含表单数据
77
+ * @returns 返回一个数组,其元素为分组后的表单项对象,如果没有找到匹配的组名,则返回 undefined
78
+ */
79
+ function formatGroup(name: string, items: Record<string, any>) {
80
+ const group: any[] = [];
81
+
82
+ for (const k in items) {
83
+ const params = parseGroupField(k);
84
+
85
+ if (params.groupName !== name || params.index === -1)
86
+ continue;
87
+
88
+ group[params.index] ??= {};
89
+ group[params.index][params.fieldName] = items[k];
90
+ }
91
+
92
+ return group?.length ? group.filter(g => !!g) : undefined;
93
+ }
94
+
95
+ /**
96
+ * 获取指定组名的最大索引值
97
+ * @param name - 组名
98
+ * @param schemas - 包含组字段的对象
99
+ * @returns 返回指定组名的最大索引值,如果没有找到匹配的组名,则返回 -1
100
+ */
29
101
  function getGroupIndex(name: string, schemas: Record<string, any>) {
30
102
  const indexs = Object.keys(schemas).map((key) => {
31
- const { groupName, index } = parseGroupFieldName(key);
103
+ const { groupName, index } = parseGroupField(key);
32
104
  return groupName === name ? index : -1;
33
105
  });
34
106
 
35
- return Math.max.apply(undefined, indexs);
107
+ return Math.max(...indexs);
36
108
  }
37
109
 
110
+ /**
111
+ * 判断指定的名称是否属于同一组
112
+ * @param name - 要检查的名称
113
+ * @param groupName - 组名
114
+ * @returns 如果指定的名称属于同一组,则返回 true,否则返回 false
115
+ */
38
116
  function isSameGroup(name: string, groupName: string) {
39
- const { groupName: gn } = parseGroupFieldName(name);
117
+ const { groupName: gn } = parseGroupField(name);
40
118
 
41
119
  return gn === groupName;
42
120
  }
43
121
 
122
+ /**
123
+ * 判断指定的字段名是否相同
124
+ * @param name - 要检查的名称
125
+ * @param fieldName - 字段名
126
+ * @returns 如果指定的名称和字段名相同,则返回 true,否则返回 false
127
+ */
44
128
  function isSameField(name: string, fieldName: string) {
45
- const { fieldName: fn } = parseGroupFieldName(name);
129
+ const { fieldName: fn } = parseGroupField(name);
46
130
 
47
131
  return fn === fieldName;
48
132
  }