@peng_kai/kit 0.1.4 → 0.1.6

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 (51) hide show
  1. package/admin/components/filter/src/FilterDrawer.vue +153 -153
  2. package/admin/components/filter/src/FilterParam.vue +76 -76
  3. package/admin/components/filter/src/FilterReset.vue +2 -2
  4. package/admin/components/filter/src/useFilterParams.ts +9 -0
  5. package/admin/components/scroll-nav/index.ts +1 -1
  6. package/admin/components/scroll-nav/src/ScrollNav.vue +59 -59
  7. package/admin/components/text/index.ts +13 -13
  8. package/admin/components/text/src/Amount.vue +117 -117
  9. package/admin/components/text/src/Datetime.vue +48 -48
  10. package/admin/components/text/src/Duration.vue +26 -26
  11. package/admin/components/text/src/Hash.vue +51 -51
  12. package/admin/components/text/src/createTagGetter.ts +13 -13
  13. package/admin/hooks/useMenu.ts +128 -128
  14. package/admin/hooks/usePage.ts +141 -141
  15. package/admin/hooks/usePageTab.ts +35 -35
  16. package/admin/layout/large/Breadcrumb.vue +69 -69
  17. package/admin/layout/large/Content.vue +24 -24
  18. package/admin/layout/large/Menu.vue +69 -69
  19. package/admin/layout/large/PageTab.vue +71 -71
  20. package/admin/permission/index.ts +4 -4
  21. package/admin/permission/routerGuard.ts +43 -43
  22. package/admin/permission/usePermission.ts +52 -52
  23. package/admin/permission/vuePlugin.ts +30 -30
  24. package/admin/route-guards/index.ts +3 -3
  25. package/admin/route-guards/pageProgress.ts +27 -27
  26. package/admin/route-guards/pageTitle.ts +19 -19
  27. package/admin/styles/classCover.scss +59 -2
  28. package/admin/styles/globalCover.scss +54 -54
  29. package/admin/types/assist.ts +2 -2
  30. package/antd/components/InputNumberRange.vue +53 -53
  31. package/antd/directives/formLabelAlign.ts +36 -36
  32. package/antd/hooks/useAntdDrawer.ts +73 -73
  33. package/antd/hooks/useAntdTable.ts +82 -71
  34. package/package.json +55 -54
  35. package/request/helpers.ts +49 -49
  36. package/request/interceptors/toLogin.ts +15 -15
  37. package/request/type.d.ts +92 -92
  38. package/stylelint.config.cjs +7 -7
  39. package/tsconfig.json +50 -50
  40. package/utils/date.ts +44 -0
  41. package/utils/index.ts +14 -8
  42. package/utils/number.ts +49 -0
  43. package/vue/components/infinite-query/index.ts +1 -1
  44. package/vue/components/infinite-query/src/InfiniteQuery.vue +205 -205
  45. package/vue/components/infinite-query/src/useCreateTrigger.ts +39 -39
  46. package/vue/hooks/useComponentRef.ts +7 -1
  47. package/vue/hooks/useIsDark.ts +5 -0
  48. package/vue/hooks/useIsMounted.ts +3 -0
  49. package/vue/hooks/useTeleportTarget.ts +35 -2
  50. package/vue/index.ts +1 -1
  51. package/pnpm-lock.yaml +0 -5242
@@ -1,153 +1,153 @@
1
- <script lang="ts" setup>
2
- import { computed, ref } from 'vue';
3
- import { Button as AButton, Drawer as ADrawer, Dropdown as ADropdown } from 'ant-design-vue';
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- });
8
-
9
- const props = withDefaults(defineProps<{
10
- loading?: boolean
11
- filterQuery?: any
12
- filterParams?: any
13
- filterForm?: any
14
- }>(), {
15
- loading: undefined,
16
- });
17
- const emits = defineEmits<{
18
- (e: 'filter'): void
19
- (e: 'reset', value: number): void
20
- }>();
21
-
22
- const filterVisible = ref(false);
23
- const loading = computed(() => {
24
- const _loading1 = props.loading;
25
- const _loading2: boolean = props.filterQuery?.isFetching.value;
26
-
27
- if (_loading1 === undefined && _loading2 === undefined)
28
- return false;
29
-
30
- if (_loading1 !== undefined)
31
- return _loading1;
32
-
33
- return _loading2;
34
- });
35
-
36
- function filter() {
37
- props.filterParams?.update?.();
38
- emits('filter');
39
- filterVisible.value = false;
40
- }
41
-
42
- function reset() {
43
- props.filterForm?.$form.resetFields?.();
44
- props.filterParams?.update?.();
45
- emits('reset', 1);
46
- filterVisible.value = false;
47
- }
48
- </script>
49
-
50
- <template>
51
- <div class="p-3 bg-$antd-colorBgContainer text-14px rounded-2" v-bind="$attrs">
52
- <!-- .filter-params 为空时显示 .filter-params-tips -->
53
-
54
- <div class="m--3 p-3" @click="filterVisible = true">
55
- <div class="filter-params">
56
- <slot name="params" />
57
- </div>
58
- <div class="filter-params-tips">
59
- 条件筛选,点击打开
60
- </div>
61
- </div>
62
-
63
- <!-- 操作区 -->
64
- <div v-if="$slots.actions || $slots.moreActions" class="actions">
65
- <slot name="actions" />
66
-
67
- <ADropdown v-if="$slots.moreActions" trigger="click" destroyPopupOnHide>
68
- <AButton type="link" size="small">
69
- 更多
70
- </AButton>
71
- <template #overlay>
72
- <slot name="moreActions" />
73
- </template>
74
- </ADropdown>
75
- </div>
76
- </div>
77
-
78
- <ADrawer
79
- v-model:open="filterVisible" class="filter-drawer" placement="bottom"
80
- height="50vh"
81
- >
82
- <template #extra>
83
- <AButton class="mr-3 my--3" :disabled="loading" @click="reset()">
84
- 重置
85
- </AButton>
86
- <AButton class="my--3" type="primary" :loading="loading" @click="filter()">
87
- 筛选
88
- </AButton>
89
- </template>
90
- <template #default>
91
- <slot />
92
- </template>
93
- </ADrawer>
94
- </template>
95
-
96
- <style scoped lang="scss">
97
- .filter-params {
98
- display: flex;
99
- flex-wrap: wrap;
100
- justify-content: flex-start;
101
- gap: 5px 15px;
102
- }
103
-
104
- // .filter-params 为空时显示 .filter-params-tips
105
- .filter-params-tips {
106
- display: none;
107
- color: theme('colors.gray.DEFAULT');
108
- }
109
-
110
- .filter-params:empty {
111
- display: none;
112
- }
113
-
114
- .filter-params:empty + .filter-params-tips {
115
- display: block;
116
- }
117
-
118
- .actions {
119
- display: flex;
120
- align-items: center;
121
- justify-content: flex-end;
122
- border-top: 1px solid var(--antd-colorBorderSecondary);
123
- margin-top: 0.75rem;
124
- padding-top: 0.75rem;
125
- }
126
- </style>
127
-
128
- <style lang="scss">
129
- .filter-drawer {
130
- .ant-drawer-header {
131
- padding: 16px;
132
-
133
- .ant-drawer-close {
134
- --expand: 5px;
135
-
136
- padding: var(--expand);
137
- margin: calc(var(--expand) * -1) var(--expand) calc(var(--expand) * -1) 0;
138
- }
139
- }
140
-
141
- .ant-drawer-body {
142
- padding: 16px;
143
- }
144
-
145
- .ant-form-item {
146
- margin-bottom: 0;
147
-
148
- .ant-form-item-label {
149
- padding-bottom: 0;
150
- }
151
- }
152
- }
153
- </style>
1
+ <script lang="ts" setup>
2
+ import { computed, ref } from 'vue';
3
+ import { Button as AButton, Drawer as ADrawer, Dropdown as ADropdown } from 'ant-design-vue';
4
+
5
+ defineOptions({
6
+ inheritAttrs: false,
7
+ });
8
+
9
+ const props = withDefaults(defineProps<{
10
+ loading?: boolean
11
+ filterQuery?: any
12
+ filterParams?: any
13
+ filterForm?: any
14
+ }>(), {
15
+ loading: undefined,
16
+ });
17
+ const emits = defineEmits<{
18
+ (e: 'filter'): void
19
+ (e: 'reset', value: number): void
20
+ }>();
21
+
22
+ const filterVisible = ref(false);
23
+ const loading = computed(() => {
24
+ const _loading1 = props.loading;
25
+ const _loading2: boolean = props.filterQuery?.isFetching.value;
26
+
27
+ if (_loading1 === undefined && _loading2 === undefined)
28
+ return false;
29
+
30
+ if (_loading1 !== undefined)
31
+ return _loading1;
32
+
33
+ return _loading2;
34
+ });
35
+
36
+ function filter() {
37
+ props.filterParams?.update?.();
38
+ emits('filter');
39
+ filterVisible.value = false;
40
+ }
41
+
42
+ function reset() {
43
+ props.filterForm?.$form.resetFields?.();
44
+ props.filterParams?.update?.();
45
+ emits('reset', 1);
46
+ filterVisible.value = false;
47
+ }
48
+ </script>
49
+
50
+ <template>
51
+ <div class="p-3 bg-$antd-colorBgContainer text-14px rounded-2" v-bind="$attrs">
52
+ <!-- .filter-params 为空时显示 .filter-params-tips -->
53
+
54
+ <div class="m--3 p-3" @click="filterVisible = true">
55
+ <div class="filter-params">
56
+ <slot name="params" />
57
+ </div>
58
+ <div class="filter-params-tips">
59
+ 条件筛选,点击打开
60
+ </div>
61
+ </div>
62
+
63
+ <!-- 操作区 -->
64
+ <div v-if="$slots.actions || $slots.moreActions" class="actions">
65
+ <slot name="actions" />
66
+
67
+ <ADropdown v-if="$slots.moreActions" trigger="click" destroyPopupOnHide>
68
+ <AButton type="link" size="small">
69
+ 更多
70
+ </AButton>
71
+ <template #overlay>
72
+ <slot name="moreActions" />
73
+ </template>
74
+ </ADropdown>
75
+ </div>
76
+ </div>
77
+
78
+ <ADrawer
79
+ v-model:open="filterVisible" class="filter-drawer" placement="bottom"
80
+ height="50vh"
81
+ >
82
+ <template #extra>
83
+ <AButton class="mr-3 my--3" :disabled="loading" @click="reset()">
84
+ 重置
85
+ </AButton>
86
+ <AButton class="my--3" type="primary" :loading="loading" @click="filter()">
87
+ 筛选
88
+ </AButton>
89
+ </template>
90
+ <template #default>
91
+ <slot />
92
+ </template>
93
+ </ADrawer>
94
+ </template>
95
+
96
+ <style scoped lang="scss">
97
+ .filter-params {
98
+ display: flex;
99
+ flex-wrap: wrap;
100
+ justify-content: flex-start;
101
+ gap: 5px 15px;
102
+ }
103
+
104
+ // .filter-params 为空时显示 .filter-params-tips
105
+ .filter-params-tips {
106
+ display: none;
107
+ color: theme('colors.gray.DEFAULT');
108
+ }
109
+
110
+ .filter-params:empty {
111
+ display: none;
112
+ }
113
+
114
+ .filter-params:empty + .filter-params-tips {
115
+ display: block;
116
+ }
117
+
118
+ .actions {
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: flex-end;
122
+ border-top: 1px solid var(--antd-colorBorderSecondary);
123
+ margin-top: 0.75rem;
124
+ padding-top: 0.75rem;
125
+ }
126
+ </style>
127
+
128
+ <style lang="scss">
129
+ .filter-drawer {
130
+ .ant-drawer-header {
131
+ padding: 16px;
132
+
133
+ .ant-drawer-close {
134
+ --expand: 5px;
135
+
136
+ padding: var(--expand);
137
+ margin: calc(var(--expand) * -1) var(--expand) calc(var(--expand) * -1) 0;
138
+ }
139
+ }
140
+
141
+ .ant-drawer-body {
142
+ padding: 16px;
143
+ }
144
+
145
+ .ant-form-item {
146
+ margin-bottom: 0;
147
+
148
+ .ant-form-item-label {
149
+ padding-bottom: 0;
150
+ }
151
+ }
152
+ }
153
+ </style>
@@ -1,76 +1,76 @@
1
- <script lang="ts">
2
- import isNil from 'lodash-es/isNil';
3
- import isFinite from 'lodash-es/isFinite';
4
- import dayjs from 'dayjs';
5
- import bignumber from 'bignumber.js';
6
-
7
- export const paramTypes = { numberRange, datetimeRange, options };
8
-
9
- /**
10
- * 时间范围格式化
11
- * @param range 数字范围
12
- * @param unit 单位
13
- */
14
- function numberRange(range?: [number, number], unit?: string) {
15
- if (!range?.every(isFinite))
16
- return '';
17
-
18
- return `${bignumber(range[0]).toFormat()}~${bignumber(range[1]).toFormat()}${unit}`;
19
- }
20
-
21
- /**
22
- * 时间范围格式化
23
- * @param range 时间范围
24
- * @param template 格式化模板(文档:https://dayjs.gitee.io/docs/zh-CN/display/format )
25
- */
26
- function datetimeRange(range?: [string | dayjs.Dayjs, string | dayjs.Dayjs], template = 'YYYY-MM-DD') {
27
- if (!range?.every(v => dayjs(v).isValid()))
28
- return '';
29
-
30
- return `${dayjs(range[0]).format(template)} ~ ${dayjs(range[1]).format(template)}`;
31
- }
32
-
33
- function options(
34
- value?: string | number | Array<string | number>,
35
- options?: Array<{ value: string | number, label: any }>,
36
- ) {
37
- if (isNil(value) || isNil(options))
38
- return;
39
- if (value === '')
40
- return;
41
-
42
- const _value = Array.isArray(value) ? value : [value];
43
-
44
- return options
45
- .filter(o => _value.includes(o.value))
46
- .map(o => o.label)
47
- .join(', ');
48
- }
49
- </script>
50
-
51
- <script setup lang="ts">
52
- const props = defineProps<{
53
- label: string
54
- content?: any
55
- }>();
56
- </script>
57
-
58
- <template>
59
- <div v-if="props.content" class="item-param">
60
- <span class="label">{{ props.label }}</span>
61
- <span class="content">{{ props.content }}</span>
62
- </div>
63
- </template>
64
-
65
- <style lang="scss" scoped>
66
- .label {
67
- display: inline-block;
68
- margin-right: 0.3em;
69
- color: theme('colors.gray.DEFAULT');
70
- }
71
-
72
- .content {
73
- color: theme('colors.primary.DEFAULT');
74
- word-break: break-all;
75
- }
76
- </style>
1
+ <script lang="ts">
2
+ import isNil from 'lodash-es/isNil';
3
+ import isFinite from 'lodash-es/isFinite';
4
+ import bignumber from 'bignumber.js';
5
+ import { dayjs } from '../../../../utils/date';
6
+
7
+ export const paramTypes = { numberRange, datetimeRange, options };
8
+
9
+ /**
10
+ * 时间范围格式化
11
+ * @param range 数字范围
12
+ * @param unit 单位
13
+ */
14
+ function numberRange(range?: [number, number], unit?: string) {
15
+ if (!range?.every(isFinite))
16
+ return '';
17
+
18
+ return `${bignumber(range[0]).toFormat()}~${bignumber(range[1]).toFormat()}${unit}`;
19
+ }
20
+
21
+ /**
22
+ * 时间范围格式化
23
+ * @param range 时间范围
24
+ * @param template 格式化模板(文档:https://dayjs.gitee.io/docs/zh-CN/display/format )
25
+ */
26
+ function datetimeRange(range?: [string | dayjs.Dayjs, string | dayjs.Dayjs], template = 'YYYY-MM-DD') {
27
+ if (!range?.every(v => dayjs(v).isValid()))
28
+ return '';
29
+
30
+ return `${dayjs(range[0]).format(template)} ~ ${dayjs(range[1]).format(template)}`;
31
+ }
32
+
33
+ function options(
34
+ value?: string | number | Array<string | number>,
35
+ options?: Array<{ value: string | number, label: any }>,
36
+ ) {
37
+ if (isNil(value) || isNil(options))
38
+ return;
39
+ if (value === '')
40
+ return;
41
+
42
+ const _value = Array.isArray(value) ? value : [value];
43
+
44
+ return options
45
+ .filter(o => _value.includes(o.value))
46
+ .map(o => o.label)
47
+ .join(', ');
48
+ }
49
+ </script>
50
+
51
+ <script setup lang="ts">
52
+ const props = defineProps<{
53
+ label: string
54
+ content?: any
55
+ }>();
56
+ </script>
57
+
58
+ <template>
59
+ <div v-if="props.content" class="item-param">
60
+ <span class="label">{{ props.label }}</span>
61
+ <span class="content">{{ props.content }}</span>
62
+ </div>
63
+ </template>
64
+
65
+ <style lang="scss" scoped>
66
+ .label {
67
+ display: inline-block;
68
+ margin-right: 0.3em;
69
+ color: theme('colors.gray.DEFAULT');
70
+ }
71
+
72
+ .content {
73
+ color: theme('colors.primary.DEFAULT');
74
+ word-break: break-all;
75
+ }
76
+ </style>
@@ -29,7 +29,7 @@ const loading = computed(() => {
29
29
  });
30
30
 
31
31
  function filter() {
32
- props.filterParams?.update?.();
32
+ props.filterParams?.update?.({ page: 1 });
33
33
  emits('filter');
34
34
  }
35
35
 
@@ -42,7 +42,7 @@ function reset() {
42
42
 
43
43
  <template>
44
44
  <div class="flex-none flex w-min ml-auto">
45
- <AButton class="mr-2 filter-btn" type="primary" htmlType="submit" :loading="loading" @click="filter()">
45
+ <AButton class="filter-btn mr2" type="primary" htmlType="submit" :loading="loading" @click="filter()">
46
46
  查询
47
47
  </AButton>
48
48
  <AButton :disabled="loading" @click="reset()">
@@ -4,6 +4,15 @@ import { reactive } from 'vue';
4
4
  interface PageParams { page?: string | number, page_size?: string | number };
5
5
  const defaultPageParams: PageParams = { page: 1, page_size: 10 };
6
6
 
7
+ /**
8
+ * 用于管理筛选参数
9
+ *
10
+ * @param _api - API 函数。
11
+ * @param buildParams - 构建参数的函数。
12
+ * @param pageParams - 默认的页面参数。
13
+ *
14
+ * @returns 包含筛选参数和更新函数的对象。
15
+ */
7
16
  export function useFilterParams<R extends Api.Request, AP extends Api.GetParam<R>, BP extends AP>(
8
17
  _api: R,
9
18
  buildParams: () => BP,
@@ -1 +1 @@
1
- export { default as ScrollNav } from './src/ScrollNav.vue';
1
+ export { default as ScrollNav } from './src/ScrollNav.vue';
@@ -1,59 +1,59 @@
1
- <script setup lang="ts">
2
- import { computed } from 'vue';
3
- import { useElementSize } from '@vueuse/core';
4
-
5
- const props = defineProps<{
6
- selector: string
7
- }>();
8
-
9
- const $content = document.querySelector(props.selector) as HTMLElement;
10
- const $contentParent = $content.parentElement;
11
- const { height: contentParentH } = useElementSize($contentParent);
12
- const { height: contentH } = useElementSize($content);
13
- const visible = computed(() => contentParentH.value * 2 < contentH.value);
14
-
15
- function scrollTo(top: number) {
16
- $contentParent?.scrollTo({ top });
17
- }
18
- </script>
19
-
20
- <template>
21
- <div v-if="visible" class="wrapper">
22
- <div class="btn" @click="scrollTo(0)">
23
- <i class="i-fluent:arrow-previous-24-filled rotate-90" />
24
- </div>
25
- <div class="btn" @click="scrollTo($contentParent?.scrollHeight ?? Infinity)">
26
- <i class="i-fluent:arrow-previous-24-filled rotate-270" />
27
- </div>
28
- <!-- <div v-if="showReturn" class="btn" @click="toLastY()">
29
- <i class="i-fluent:arrow-hook-down-left-24-filled rotate-270" />
30
- </div> -->
31
- </div>
32
- </template>
33
-
34
- <style lang="scss" scoped>
35
- .wrapper {
36
- font-size: 18px;
37
- }
38
-
39
- .btn {
40
- display: flex;
41
- width: 2em;
42
- height: 2em;
43
- align-items: center;
44
- justify-content: center;
45
- border-radius: 2px;
46
- background: #bcbcbc;
47
- color: #000;
48
- cursor: pointer;
49
- opacity: 0.5;
50
-
51
- &:active {
52
- transform: scale(0.9);
53
- }
54
-
55
- & + & {
56
- margin-top: 1px;
57
- }
58
- }
59
- </style>
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import { useElementSize } from '@vueuse/core';
4
+
5
+ const props = defineProps<{
6
+ selector: string
7
+ }>();
8
+
9
+ const $content = document.querySelector(props.selector) as HTMLElement;
10
+ const $contentParent = $content.parentElement;
11
+ const { height: contentParentH } = useElementSize($contentParent);
12
+ const { height: contentH } = useElementSize($content);
13
+ const visible = computed(() => contentParentH.value * 2 < contentH.value);
14
+
15
+ function scrollTo(top: number) {
16
+ $contentParent?.scrollTo({ top });
17
+ }
18
+ </script>
19
+
20
+ <template>
21
+ <div v-if="visible" class="wrapper">
22
+ <div class="btn" @click="scrollTo(0)">
23
+ <i class="i-fluent:arrow-previous-24-filled rotate-90" />
24
+ </div>
25
+ <div class="btn" @click="scrollTo($contentParent?.scrollHeight ?? Infinity)">
26
+ <i class="i-fluent:arrow-previous-24-filled rotate-270" />
27
+ </div>
28
+ <!-- <div v-if="showReturn" class="btn" @click="toLastY()">
29
+ <i class="i-fluent:arrow-hook-down-left-24-filled rotate-270" />
30
+ </div> -->
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss" scoped>
35
+ .wrapper {
36
+ font-size: 18px;
37
+ }
38
+
39
+ .btn {
40
+ display: flex;
41
+ width: 2em;
42
+ height: 2em;
43
+ align-items: center;
44
+ justify-content: center;
45
+ border-radius: 2px;
46
+ background: #bcbcbc;
47
+ color: #000;
48
+ cursor: pointer;
49
+ opacity: 0.5;
50
+
51
+ &:active {
52
+ transform: scale(0.9);
53
+ }
54
+
55
+ & + & {
56
+ margin-top: 1px;
57
+ }
58
+ }
59
+ </style>
@@ -1,13 +1,13 @@
1
- import Hash from './src/Hash.vue';
2
- import Amount from './src/Amount.vue';
3
- import Datetime from './src/Datetime.vue';
4
- import Duration from './src/Duration.vue';
5
-
6
- export { createTagGetter } from './src/createTagGetter';
7
-
8
- export const Text = {
9
- Hash,
10
- Amount,
11
- Datetime,
12
- Duration,
13
- };
1
+ import Hash from './src/Hash.vue';
2
+ import Amount from './src/Amount.vue';
3
+ import Datetime from './src/Datetime.vue';
4
+ import Duration from './src/Duration.vue';
5
+
6
+ export { createTagGetter } from './src/createTagGetter';
7
+
8
+ export const Text = {
9
+ Hash,
10
+ Amount,
11
+ Datetime,
12
+ Duration,
13
+ };