@peng_kai/kit 0.1.2 → 0.1.4
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/admin/defines/route/getRoutes.ts +1 -1
- package/admin/defines/route-guard/getRouteGuards.ts +1 -1
- package/admin/defines/startup/getStartups.ts +1 -1
- package/admin/scripts/routeNameWatcher.ts +99 -0
- package/eslint.config.js +2 -2
- package/package.json +9 -2
- package/pnpm-lock.yaml +639 -233
- package/request/request.ts +4 -0
- package/request/type.d.ts +4 -1
- package/tsconfig.json +3 -0
- package/uno.config.ts +1 -0
- package/utils/index.ts +8 -0
- package/vue/components/infinite-query/src/InfiniteQuery.vue +86 -28
- package/vue/components/infinite-query/src/useCreateTrigger.ts +8 -4
package/request/request.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
+
import { isSSR } from '../utils';
|
|
2
3
|
|
|
3
4
|
export { createRequest };
|
|
4
5
|
|
|
@@ -17,6 +18,9 @@ function createRequest<Req, OResp, Resp = Api.TransformPageResult<OResp>>(
|
|
|
17
18
|
// 返回 API 数据中的 data 字段值,默认
|
|
18
19
|
async function request(reqData: Req, config?: ReqConfig): Promise<Api.GetDataField<Resp>>;
|
|
19
20
|
async function request(reqData: Req, config?: ReqConfig): Promise<any> {
|
|
21
|
+
// if (isSSR())
|
|
22
|
+
// return null;
|
|
23
|
+
|
|
20
24
|
const params = paramBuilder(reqData);
|
|
21
25
|
const serviceName = params.headers?.['Service-Name'] ?? '';
|
|
22
26
|
const service = createRequest.services[serviceName]?.server;
|
package/request/type.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
declare namespace Api {
|
|
2
|
-
type Request = ((reqData: any, options?: Options) => Promise<any>) & {
|
|
2
|
+
type Request = ((reqData: any, options?: Options) => Promise<any>) & {
|
|
3
|
+
id: string
|
|
4
|
+
setDefaultConfig: (config: Partial<import('axios').AxiosRequestConfig>) => Request
|
|
5
|
+
};
|
|
3
6
|
// type RequestPagination = (reqData: Partial<PageParam>, options?: Options) => Promise<PaginationData<any>>;
|
|
4
7
|
interface PageParam {
|
|
5
8
|
page: number
|
package/tsconfig.json
CHANGED
|
@@ -20,9 +20,12 @@
|
|
|
20
20
|
/* Linting */
|
|
21
21
|
"strict": true,
|
|
22
22
|
"noFallthroughCasesInSwitch": true,
|
|
23
|
+
"noImplicitAny": false,
|
|
23
24
|
"noUnusedLocals": true,
|
|
24
25
|
"noUnusedParameters": true,
|
|
25
26
|
"noEmit": true,
|
|
27
|
+
"allowSyntheticDefaultImports": true,
|
|
28
|
+
"esModuleInterop": true,
|
|
26
29
|
"isolatedModules": true,
|
|
27
30
|
"skipLibCheck": true
|
|
28
31
|
},
|
package/uno.config.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
package/utils/index.ts
CHANGED
|
@@ -30,6 +30,10 @@ export function hasToken() {
|
|
|
30
30
|
return document.cookie.includes('has_token=1');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export function isSSR() {
|
|
34
|
+
return typeof window === 'undefined';
|
|
35
|
+
}
|
|
36
|
+
|
|
33
37
|
export function fixed() {
|
|
34
38
|
|
|
35
39
|
// return (12).toFixed
|
|
@@ -90,6 +94,10 @@ export function getScanBrowser(chain: string, hash: string, type: 'transaction'
|
|
|
90
94
|
return `https://suiexplorer.com/${_type}/${hash}`;
|
|
91
95
|
},
|
|
92
96
|
ZKSYNC: () => `https://explorer.zksync.io/${evmType()}/${hash}`,
|
|
97
|
+
SOLANA: () => {
|
|
98
|
+
const _type = (<TypeMap>{ address: 'account' })[type] ?? type;
|
|
99
|
+
return `https://solscan.io/${_type}/${hash}`;
|
|
100
|
+
},
|
|
93
101
|
}[_chain] ?? (() => '');
|
|
94
102
|
|
|
95
103
|
return urlFn();
|
|
@@ -2,15 +2,30 @@
|
|
|
2
2
|
import { computed, ref, unref } from 'vue';
|
|
3
3
|
import type { UseInfiniteQueryReturnType } from '@tanstack/vue-query';
|
|
4
4
|
import { useCreateTrigger } from './useCreateTrigger';
|
|
5
|
+
|
|
6
|
+
export type { ISlotProvide };
|
|
7
|
+
|
|
8
|
+
interface ISlotProvide {
|
|
9
|
+
isInitialLoading: boolean
|
|
10
|
+
isInitialLoadingError: boolean
|
|
11
|
+
isEmpty: boolean
|
|
12
|
+
isMoreLoading: boolean
|
|
13
|
+
isMoreLoadingError: boolean
|
|
14
|
+
isNoMore: boolean
|
|
15
|
+
refetch: () => void
|
|
16
|
+
}
|
|
5
17
|
</script>
|
|
6
18
|
|
|
7
19
|
<script setup lang="ts" generic="T extends UseInfiniteQueryReturnType<any, any>">
|
|
8
20
|
type TPage = T extends UseInfiniteQueryReturnType<infer P, any> ? NonNullable<P> : any;
|
|
9
21
|
type TRecord = TPage extends { list: Array<infer I> } ? I : any;
|
|
10
22
|
|
|
11
|
-
const props = defineProps<{
|
|
23
|
+
const props = withDefaults(defineProps<{
|
|
12
24
|
queryier: T
|
|
13
|
-
|
|
25
|
+
distance?: string
|
|
26
|
+
}>(), {
|
|
27
|
+
distance: '50px',
|
|
28
|
+
});
|
|
14
29
|
|
|
15
30
|
const { queryier } = props;
|
|
16
31
|
const pages = computed(() => queryier.data.value?.pages);
|
|
@@ -20,8 +35,9 @@ const isInitialLoadingError = computed(() => queryier.isLoadingError.value && !i
|
|
|
20
35
|
const isMoreLoading = computed(
|
|
21
36
|
() => (queryier.isFetchingNextPage.value || queryier.isFetching.value) && !isInitialLoading.value,
|
|
22
37
|
);
|
|
38
|
+
const isEmpty = computed(() => queryier.isSuccess.value && !pages.value?.[0].list?.length);
|
|
23
39
|
const isMoreLoadingError = computed(() => queryier.isRefetchError.value && !isMoreLoading.value);
|
|
24
|
-
const
|
|
40
|
+
const isNoMore = computed(
|
|
25
41
|
() =>
|
|
26
42
|
!queryier.hasNextPage?.value
|
|
27
43
|
&& !isInitialLoading.value
|
|
@@ -43,10 +59,6 @@ const containerCssVars = computed(() => {
|
|
|
43
59
|
};
|
|
44
60
|
});
|
|
45
61
|
|
|
46
|
-
function refetch() {
|
|
47
|
-
queryier.refetch();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
62
|
function refetchLastPage() {
|
|
51
63
|
queryier.refetch({
|
|
52
64
|
refetchPage(lastPage: any, _index, allPages: any[]) {
|
|
@@ -65,6 +77,15 @@ function fetchNextPage() {
|
|
|
65
77
|
queryier.fetchNextPage();
|
|
66
78
|
}
|
|
67
79
|
|
|
80
|
+
function refetch() {
|
|
81
|
+
if (isNoMore.value)
|
|
82
|
+
refetchLastPage();
|
|
83
|
+
else if (isMoreLoadingError.value)
|
|
84
|
+
fetchNextPage();
|
|
85
|
+
else
|
|
86
|
+
queryier.refetch();
|
|
87
|
+
}
|
|
88
|
+
|
|
68
89
|
function triggerFetchNextPage() {
|
|
69
90
|
if (queryier.isError.value)
|
|
70
91
|
return;
|
|
@@ -72,34 +93,70 @@ function triggerFetchNextPage() {
|
|
|
72
93
|
fetchNextPage();
|
|
73
94
|
}
|
|
74
95
|
|
|
75
|
-
useCreateTrigger($container, triggerFetchNextPage);
|
|
96
|
+
useCreateTrigger($container, triggerFetchNextPage, props.distance);
|
|
97
|
+
|
|
98
|
+
const slotProvide = computed<ISlotProvide>(() => ({
|
|
99
|
+
isInitialLoading: isInitialLoading.value,
|
|
100
|
+
isInitialLoadingError: isInitialLoadingError.value,
|
|
101
|
+
isMoreLoading: isMoreLoading.value,
|
|
102
|
+
isMoreLoadingError: isMoreLoadingError.value,
|
|
103
|
+
isNoMore: isNoMore.value,
|
|
104
|
+
isEmpty: isEmpty.value,
|
|
105
|
+
refetch,
|
|
106
|
+
}));
|
|
76
107
|
</script>
|
|
77
108
|
|
|
78
109
|
<template>
|
|
79
110
|
<div ref="$container" class="infinite-query-wrapper" :style="containerCssVars">
|
|
80
|
-
<div
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<div v-for="(page, i) of pages" :key="i">
|
|
88
|
-
<template v-for="record of page.list">
|
|
89
|
-
<slot :record="record as TRecord" />
|
|
111
|
+
<div class="list">
|
|
112
|
+
<template v-for="(page) of pages">
|
|
113
|
+
<template v-for="record of page.list">
|
|
114
|
+
<!-- eslint-disable-next-line vue/no-extra-parens -->
|
|
115
|
+
<slot name="default" :record="(record as TRecord)" />
|
|
116
|
+
</template>
|
|
90
117
|
</template>
|
|
91
118
|
</div>
|
|
92
119
|
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
120
|
+
<slot
|
|
121
|
+
name="status" v-bind="slotProvide"
|
|
122
|
+
>
|
|
123
|
+
<slot name="initialLoading">
|
|
124
|
+
<div v-if="isInitialLoading" class="initial-loading">
|
|
125
|
+
<i class="i-svg-spinners:180-ring-with-bg loading-icon" />
|
|
126
|
+
</div>
|
|
127
|
+
</slot>
|
|
128
|
+
|
|
129
|
+
<slot name="initialLoadingError">
|
|
130
|
+
<div v-if="isInitialLoadingError" class="initial-loading-error" @click="refetch()">
|
|
131
|
+
<span>加载失败,点击重试</span>
|
|
132
|
+
</div>
|
|
133
|
+
</slot>
|
|
134
|
+
|
|
135
|
+
<slot name="empty">
|
|
136
|
+
<div v-if="isEmpty" class="empty">
|
|
137
|
+
<span>暂无数据</span>
|
|
138
|
+
</div>
|
|
139
|
+
</slot>
|
|
140
|
+
|
|
141
|
+
<slot name="oreLoading">
|
|
142
|
+
<div v-if="isMoreLoading" class="more-loading">
|
|
143
|
+
<i class="i-svg-spinners:180-ring-with-bg loading-icon" />
|
|
144
|
+
<span class="ml-1 text">加载中...</span>
|
|
145
|
+
</div>
|
|
146
|
+
</slot>
|
|
147
|
+
|
|
148
|
+
<slot name="moreLoadingError">
|
|
149
|
+
<div v-if="isMoreLoadingError" class="more-loading-error" @click="refetch()">
|
|
150
|
+
<span class="text">加载失败,点击重试</span>
|
|
151
|
+
</div>
|
|
152
|
+
</slot>
|
|
153
|
+
|
|
154
|
+
<slot name="noMore">
|
|
155
|
+
<div v-if="isNoMore" class="no-more" @click="refetch()">
|
|
156
|
+
<span class="text">暂无更多</span>
|
|
157
|
+
</div>
|
|
158
|
+
</slot>
|
|
159
|
+
</slot>
|
|
103
160
|
</div>
|
|
104
161
|
</template>
|
|
105
162
|
|
|
@@ -117,6 +174,7 @@ useCreateTrigger($container, triggerFetchNextPage);
|
|
|
117
174
|
|
|
118
175
|
.initial-loading,
|
|
119
176
|
.initial-loading-error,
|
|
177
|
+
.empty,
|
|
120
178
|
.more-loading,
|
|
121
179
|
.more-loading-error,
|
|
122
180
|
.no-more {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { watch } from 'vue';
|
|
1
|
+
import { onUnmounted, watch } from 'vue';
|
|
2
2
|
import type { Ref } from 'vue';
|
|
3
3
|
import { useIntersectionObserver, useIntervalFn } from '@vueuse/core';
|
|
4
4
|
|
|
5
|
-
export function useCreateTrigger(containerEle: Ref<HTMLElement | undefined>, callback: Function) {
|
|
5
|
+
export function useCreateTrigger(containerEle: Ref<HTMLElement | undefined>, callback: Function, distance: string) {
|
|
6
6
|
const triggerEl = document.createElement('div');
|
|
7
7
|
|
|
8
8
|
Object.assign(triggerEl.style, {
|
|
9
9
|
position: 'relative',
|
|
10
10
|
zIndex: '5',
|
|
11
|
-
marginTop:
|
|
12
|
-
marginBottom:
|
|
11
|
+
marginTop: `-${distance}`,
|
|
12
|
+
marginBottom: distance,
|
|
13
13
|
width: '5px',
|
|
14
14
|
height: '5px',
|
|
15
15
|
// background: 'red',
|
|
@@ -32,4 +32,8 @@ export function useCreateTrigger(containerEle: Ref<HTMLElement | undefined>, cal
|
|
|
32
32
|
if (ele)
|
|
33
33
|
ele.append(triggerEl);
|
|
34
34
|
});
|
|
35
|
+
|
|
36
|
+
onUnmounted(() => {
|
|
37
|
+
triggerEl.remove();
|
|
38
|
+
});
|
|
35
39
|
}
|