@peng_kai/kit 0.2.0-beta.23 → 0.2.0-beta.25

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.
@@ -1,59 +1,59 @@
1
- <script lang="ts">
2
- import { computed } from 'vue';
3
- import { InputNumber as AInputNumber, Form } from 'ant-design-vue';
4
- </script>
5
-
6
- <script setup lang="ts">
7
- const props = withDefaults(
8
- defineProps<{
9
- value: [number | undefined, number | undefined]
10
- placeholder?: [string, string]
11
- min?: number
12
- max?: number
13
- }>(),
14
- {
15
- min: Number.NEGATIVE_INFINITY,
16
- max: Number.POSITIVE_INFINITY,
17
- },
18
- );
19
- const emits = defineEmits<{
20
- (e: 'update:value', value: typeof props.value): void
21
- }>();
22
-
23
- const formItemContext = Form.useInjectFormItemContext();
24
- const minValue = computed({
25
- get() {
26
- return props.value[0];
27
- },
28
- set(value) {
29
- updateValue(value, maxValue.value);
30
- },
31
- });
32
- const maxValue = computed({
33
- get() {
34
- return props.value[1];
35
- },
36
- set(value) {
37
- updateValue(minValue.value, value);
38
- },
39
- });
40
-
41
- function updateValue(...args: typeof props.value) {
42
- emits('update:value', args.sort());
43
- formItemContext.onFieldChange();
44
- }
45
- </script>
46
-
47
- <template>
48
- <div class="flex items-center">
49
- <AInputNumber
50
- v-model:value="minValue" class="w-full" :min="props.min"
51
- :max="props.max" :placeholder="props.placeholder?.[0]"
52
- />
53
- <span>&nbsp;-&nbsp;</span>
54
- <AInputNumber
55
- v-model:value="maxValue" class="w-full" :min="props.min"
56
- :max="props.max" :placeholder="props.placeholder?.[1]"
57
- />
58
- </div>
59
- </template>
1
+ <script lang="ts">
2
+ import { computed } from 'vue';
3
+ import { InputNumber as AInputNumber, Form } from 'ant-design-vue';
4
+ </script>
5
+
6
+ <script setup lang="ts">
7
+ const props = withDefaults(
8
+ defineProps<{
9
+ value: [number | undefined, number | undefined]
10
+ placeholder?: [string, string]
11
+ min?: number
12
+ max?: number
13
+ }>(),
14
+ {
15
+ min: Number.NEGATIVE_INFINITY,
16
+ max: Number.POSITIVE_INFINITY,
17
+ },
18
+ );
19
+ const emits = defineEmits<{
20
+ (e: 'update:value', value: typeof props.value): void
21
+ }>();
22
+
23
+ const formItemContext = Form.useInjectFormItemContext();
24
+ const minValue = computed({
25
+ get() {
26
+ return props.value[0];
27
+ },
28
+ set(value) {
29
+ updateValue(value, maxValue.value);
30
+ },
31
+ });
32
+ const maxValue = computed({
33
+ get() {
34
+ return props.value[1];
35
+ },
36
+ set(value) {
37
+ updateValue(minValue.value, value);
38
+ },
39
+ });
40
+
41
+ function updateValue(...args: typeof props.value) {
42
+ emits('update:value', args.sort());
43
+ formItemContext.onFieldChange();
44
+ }
45
+ </script>
46
+
47
+ <template>
48
+ <div class="flex items-center">
49
+ <AInputNumber
50
+ v-model:value="minValue" class="w-full" :min="props.min"
51
+ :max="props.max" :placeholder="props.placeholder?.[0]"
52
+ />
53
+ <span>&nbsp;-&nbsp;</span>
54
+ <AInputNumber
55
+ v-model:value="maxValue" class="w-full" :min="props.min"
56
+ :max="props.max" :placeholder="props.placeholder?.[1]"
57
+ />
58
+ </div>
59
+ </template>
@@ -1,36 +1,36 @@
1
- import type { App } from 'vue';
2
-
3
- export function formLabelAlign(app: App) {
4
- const directiveName = 'antd-form-label-align';
5
- const resizeObserverKey = `${directiveName}@resizeObserver`;
6
-
7
- function init(el: HTMLElement) {
8
- const labels = el.querySelectorAll('.ant-form-item .ant-form-item-label');
9
- const resizeObserver = new ResizeObserver((entries) => {
10
- const widths = entries.map(e => e.borderBoxSize?.[0]?.inlineSize ?? 0);
11
- const maxWidth = Math.max(...widths);
12
-
13
- if (maxWidth <= 0)
14
- return;
15
-
16
- el.style.setProperty('--max-label-width', `${maxWidth}px`);
17
- entries.forEach((e) => {
18
- const target = e.target as HTMLElement;
19
- target.style.setProperty('width', 'var(--max-label-width)');
20
- });
21
- });
22
-
23
- Array.from(labels).forEach(label => resizeObserver.observe(label));
24
-
25
- return resizeObserver;
26
- }
27
-
28
- app.directive(directiveName, {
29
- mounted(el: HTMLElement) {
30
- (el as any)[resizeObserverKey] = init(el);
31
- },
32
- updated(el) {
33
- (el as any)[resizeObserverKey] = init(el);
34
- },
35
- });
36
- }
1
+ import type { App } from 'vue';
2
+
3
+ export function formLabelAlign(app: App) {
4
+ const directiveName = 'antd-form-label-align';
5
+ const resizeObserverKey = `${directiveName}@resizeObserver`;
6
+
7
+ function init(el: HTMLElement) {
8
+ const labels = el.querySelectorAll('.ant-form-item .ant-form-item-label');
9
+ const resizeObserver = new ResizeObserver((entries) => {
10
+ const widths = entries.map(e => e.borderBoxSize?.[0]?.inlineSize ?? 0);
11
+ const maxWidth = Math.max(...widths);
12
+
13
+ if (maxWidth <= 0)
14
+ return;
15
+
16
+ el.style.setProperty('--max-label-width', `${maxWidth}px`);
17
+ entries.forEach((e) => {
18
+ const target = e.target as HTMLElement;
19
+ target.style.setProperty('width', 'var(--max-label-width)');
20
+ });
21
+ });
22
+
23
+ Array.from(labels).forEach(label => resizeObserver.observe(label));
24
+
25
+ return resizeObserver;
26
+ }
27
+
28
+ app.directive(directiveName, {
29
+ mounted(el: HTMLElement) {
30
+ (el as any)[resizeObserverKey] = init(el);
31
+ },
32
+ updated(el) {
33
+ (el as any)[resizeObserverKey] = init(el);
34
+ },
35
+ });
36
+ }
@@ -1,73 +1,73 @@
1
- import { Button as AButton, Drawer as ADrawer, Space as ASpace } from 'ant-design-vue';
2
- import { defineComponent, h, isProxy, reactive, toRef, toRefs } from 'vue';
3
- import type { Component } from 'vue';
4
- import type { ButtonProps, DrawerProps } from 'ant-design-vue';
5
- import type { ComponentProps } from 'vue-component-type-helpers';
6
- import type { Writable } from 'type-fest';
7
- import { useComponentRef } from '../../vue';
8
-
9
- const defaultDrawerProps: DrawerProps = { open: false, destroyOnClose: true, rootClassName: 'antd-cover__basic-drawer' };
10
-
11
- interface IComponentConfig<Comp extends Component> {
12
- is: Comp
13
- props?: Writable<ComponentProps<Comp>>
14
- }
15
-
16
- export function useAntdDrawer<Comp extends Component>(
17
- comp: IComponentConfig<Comp> | Comp,
18
- drawerProps = defaultDrawerProps,
19
- ) {
20
- const _comp = ({ props: {}, ...((comp as any)?.is ? comp : { is: comp }) }) as Required<IComponentConfig<Comp>>;
21
- const compProps = reactive(_comp.props);
22
- const compRef = useComponentRef(_comp.is);
23
- const _drawerProps: DrawerProps = reactive({
24
- ...defaultDrawerProps,
25
- ...isProxy(drawerProps) ? toRefs(drawerProps) : drawerProps,
26
- });
27
-
28
- const open = (newBodyProps?: Partial<typeof compProps>, newAntdModalProps?: Omit<Partial<DrawerProps>, 'open'>) => {
29
- Object.assign(_drawerProps, newAntdModalProps);
30
- Object.assign(compProps, newBodyProps);
31
- _drawerProps.open = true;
32
- };
33
- const close = () => {
34
- _drawerProps.open = false;
35
- };
36
-
37
- const DrawerFooter = defineComponent({
38
- setup() {
39
- const cancelBtnProps: ButtonProps = reactive({ onClick: close });
40
- const confirmBtnProps: ButtonProps = reactive({
41
- type: 'primary',
42
- loading: toRef(() => (compRef as any)?.loading),
43
- onClick: () => (compRef as any)?.confirm?.(),
44
- });
45
-
46
- return { cancelBtnProps, confirmBtnProps };
47
- },
48
- render() {
49
- const { cancelBtnProps, confirmBtnProps } = this;
50
-
51
- return h(ASpace, {}, () => [
52
- h(AButton, cancelBtnProps, () => '取消'),
53
- h(AButton, confirmBtnProps, () => '确定'),
54
- ]);
55
- },
56
- });
57
- const PresetComponent = defineComponent({
58
- render() {
59
- return h(ADrawer, _drawerProps, {
60
- default: () => h(_comp.is, compProps as any),
61
- });
62
- },
63
- });
64
-
65
- _drawerProps.footer = _drawerProps.footer === undefined ? h(DrawerFooter) : _drawerProps.footer;
66
- _drawerProps['onUpdate:open'] = (visiable) => {
67
- _drawerProps.open = visiable;
68
- };
69
- (compProps as any).ref = compRef;
70
- (compProps as any).onClose = close;
71
-
72
- return { PresetComponent, drawerProps: _drawerProps, open, close };
73
- }
1
+ import { Button as AButton, Drawer as ADrawer, Space as ASpace } from 'ant-design-vue';
2
+ import { defineComponent, h, isProxy, reactive, toRef, toRefs } from 'vue';
3
+ import type { Component } from 'vue';
4
+ import type { ButtonProps, DrawerProps } from 'ant-design-vue';
5
+ import type { ComponentProps } from 'vue-component-type-helpers';
6
+ import type { Writable } from 'type-fest';
7
+ import { useComponentRef } from '../../vue';
8
+
9
+ const defaultDrawerProps: DrawerProps = { open: false, destroyOnClose: true, rootClassName: 'antd-cover__basic-drawer' };
10
+
11
+ interface IComponentConfig<Comp extends Component> {
12
+ is: Comp
13
+ props?: Writable<ComponentProps<Comp>>
14
+ }
15
+
16
+ export function useAntdDrawer<Comp extends Component>(
17
+ comp: IComponentConfig<Comp> | Comp,
18
+ drawerProps = defaultDrawerProps,
19
+ ) {
20
+ const _comp = ({ props: {}, ...((comp as any)?.is ? comp : { is: comp }) }) as Required<IComponentConfig<Comp>>;
21
+ const compProps = reactive(_comp.props);
22
+ const compRef = useComponentRef(_comp.is);
23
+ const _drawerProps: DrawerProps = reactive({
24
+ ...defaultDrawerProps,
25
+ ...isProxy(drawerProps) ? toRefs(drawerProps) : drawerProps,
26
+ });
27
+
28
+ const open = (newBodyProps?: Partial<typeof compProps>, newAntdModalProps?: Omit<Partial<DrawerProps>, 'open'>) => {
29
+ Object.assign(_drawerProps, newAntdModalProps);
30
+ Object.assign(compProps, newBodyProps);
31
+ _drawerProps.open = true;
32
+ };
33
+ const close = () => {
34
+ _drawerProps.open = false;
35
+ };
36
+
37
+ const DrawerFooter = defineComponent({
38
+ setup() {
39
+ const cancelBtnProps: ButtonProps = reactive({ onClick: close });
40
+ const confirmBtnProps: ButtonProps = reactive({
41
+ type: 'primary',
42
+ loading: toRef(() => (compRef as any)?.loading),
43
+ onClick: () => (compRef as any)?.confirm?.(),
44
+ });
45
+
46
+ return { cancelBtnProps, confirmBtnProps };
47
+ },
48
+ render() {
49
+ const { cancelBtnProps, confirmBtnProps } = this;
50
+
51
+ return h(ASpace, {}, () => [
52
+ h(AButton, cancelBtnProps, () => '取消'),
53
+ h(AButton, confirmBtnProps, () => '确定'),
54
+ ]);
55
+ },
56
+ });
57
+ const PresetComponent = defineComponent({
58
+ render() {
59
+ return h(ADrawer, _drawerProps, {
60
+ default: () => h(_comp.is, compProps as any),
61
+ });
62
+ },
63
+ });
64
+
65
+ _drawerProps.footer = _drawerProps.footer === undefined ? h(DrawerFooter) : _drawerProps.footer;
66
+ _drawerProps['onUpdate:open'] = (visiable) => {
67
+ _drawerProps.open = visiable;
68
+ };
69
+ (compProps as any).ref = compRef;
70
+ (compProps as any).onClose = close;
71
+
72
+ return { PresetComponent, drawerProps: _drawerProps, open, close };
73
+ }
package/package.json CHANGED
@@ -1,92 +1,92 @@
1
- {
2
- "name": "@peng_kai/kit",
3
- "type": "module",
4
- "version": "0.2.0-beta.23",
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.1.2",
17
- "vue": "3.4.19",
18
- "vue-router": "4.2.5"
19
- },
20
- "dependencies": {
21
- "@aws-sdk/client-s3": "^3.515.0",
22
- "@aws-sdk/lib-storage": "^3.515.0",
23
- "@babel/generator": "^7.23.6",
24
- "@babel/parser": "^7.23.9",
25
- "@babel/traverse": "^7.23.9",
26
- "@babel/types": "^7.23.9",
27
- "@ckeditor/ckeditor5-adapter-ckfinder": "^41.1.0",
28
- "@ckeditor/ckeditor5-alignment": "^41.1.0",
29
- "@ckeditor/ckeditor5-autoformat": "^41.1.0",
30
- "@ckeditor/ckeditor5-basic-styles": "^41.1.0",
31
- "@ckeditor/ckeditor5-block-quote": "^41.1.0",
32
- "@ckeditor/ckeditor5-build-classic": "^41.1.0",
33
- "@ckeditor/ckeditor5-code-block": "^41.1.0",
34
- "@ckeditor/ckeditor5-document-outline": "^41.1.0",
35
- "@ckeditor/ckeditor5-editor-classic": "^41.1.0",
36
- "@ckeditor/ckeditor5-essentials": "^41.1.0",
37
- "@ckeditor/ckeditor5-font": "^41.1.0",
38
- "@ckeditor/ckeditor5-heading": "^41.1.0",
39
- "@ckeditor/ckeditor5-highlight": "^41.1.0",
40
- "@ckeditor/ckeditor5-horizontal-line": "^41.1.0",
41
- "@ckeditor/ckeditor5-html-embed": "^41.1.0",
42
- "@ckeditor/ckeditor5-html-support": "^41.1.0",
43
- "@ckeditor/ckeditor5-image": "^41.1.0",
44
- "@ckeditor/ckeditor5-import-word": "^41.1.0",
45
- "@ckeditor/ckeditor5-indent": "^41.1.0",
46
- "@ckeditor/ckeditor5-link": "^41.1.0",
47
- "@ckeditor/ckeditor5-list": "^41.1.0",
48
- "@ckeditor/ckeditor5-media-embed": "^41.1.0",
49
- "@ckeditor/ckeditor5-paragraph": "^41.1.0",
50
- "@ckeditor/ckeditor5-remove-format": "^41.1.0",
51
- "@ckeditor/ckeditor5-show-blocks": "^41.1.0",
52
- "@ckeditor/ckeditor5-source-editing": "^41.1.0",
53
- "@ckeditor/ckeditor5-table": "^41.1.0",
54
- "@ckeditor/ckeditor5-theme-lark": "^41.1.0",
55
- "@ckeditor/ckeditor5-typing": "^41.1.0",
56
- "@ckeditor/ckeditor5-upload": "^41.1.0",
57
- "@ckeditor/ckeditor5-vue": "^5.1.0",
58
- "@ckeditor/ckeditor5-word-count": "^41.1.0",
59
- "@tanstack/vue-query": "^5.21.4",
60
- "@vueuse/components": "^10.7.2",
61
- "@vueuse/core": "^10.7.2",
62
- "@vueuse/router": "^10.7.2",
63
- "a-calc": "^1.3.8",
64
- "ant-design-vue": "^4.1.2",
65
- "archiver": "^6.0.1",
66
- "axios": "^1.6.7",
67
- "bignumber.js": "^9.1.2",
68
- "chokidar": "^3.6.0",
69
- "dayjs": "^1.11.10",
70
- "echarts": "^5.4.3",
71
- "execa": "^8.0.1",
72
- "fast-glob": "^3.3.2",
73
- "localstorage-slim": "^2.7.0",
74
- "lodash-es": "^4.17.21",
75
- "nprogress": "^0.2.0",
76
- "pinia": "^2.1.7",
77
- "tsx": "^4.7.1",
78
- "vue": "^3.4.19",
79
- "vue-i18n": "^9.9.1",
80
- "vue-router": "^4.2.5"
81
- },
82
- "devDependencies": {
83
- "@peng_kai/lint": "^0.1.0",
84
- "@types/archiver": "^6.0.2",
85
- "@types/lodash-es": "^4.17.12",
86
- "@types/node": "18.19.15",
87
- "@types/nprogress": "^0.2.3",
88
- "type-fest": "^4.10.2",
89
- "typescript": "^5.3.3",
90
- "vue-component-type-helpers": "^1.8.27"
91
- }
92
- }
1
+ {
2
+ "name": "@peng_kai/kit",
3
+ "type": "module",
4
+ "version": "0.2.0-beta.25",
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.1.2",
17
+ "vue": "3.4.19",
18
+ "vue-router": "4.3.0"
19
+ },
20
+ "dependencies": {
21
+ "@aws-sdk/client-s3": "^3.521.0",
22
+ "@aws-sdk/lib-storage": "^3.521.0",
23
+ "@babel/generator": "^7.23.6",
24
+ "@babel/parser": "^7.23.9",
25
+ "@babel/traverse": "^7.23.9",
26
+ "@babel/types": "^7.23.9",
27
+ "@ckeditor/ckeditor5-adapter-ckfinder": "^41.1.0",
28
+ "@ckeditor/ckeditor5-alignment": "^41.1.0",
29
+ "@ckeditor/ckeditor5-autoformat": "^41.1.0",
30
+ "@ckeditor/ckeditor5-basic-styles": "^41.1.0",
31
+ "@ckeditor/ckeditor5-block-quote": "^41.1.0",
32
+ "@ckeditor/ckeditor5-build-classic": "^41.1.0",
33
+ "@ckeditor/ckeditor5-code-block": "^41.1.0",
34
+ "@ckeditor/ckeditor5-document-outline": "^41.1.0",
35
+ "@ckeditor/ckeditor5-editor-classic": "^41.1.0",
36
+ "@ckeditor/ckeditor5-essentials": "^41.1.0",
37
+ "@ckeditor/ckeditor5-font": "^41.1.0",
38
+ "@ckeditor/ckeditor5-heading": "^41.1.0",
39
+ "@ckeditor/ckeditor5-highlight": "^41.1.0",
40
+ "@ckeditor/ckeditor5-horizontal-line": "^41.1.0",
41
+ "@ckeditor/ckeditor5-html-embed": "^41.1.0",
42
+ "@ckeditor/ckeditor5-html-support": "^41.1.0",
43
+ "@ckeditor/ckeditor5-image": "^41.1.0",
44
+ "@ckeditor/ckeditor5-import-word": "^41.1.0",
45
+ "@ckeditor/ckeditor5-indent": "^41.1.0",
46
+ "@ckeditor/ckeditor5-link": "^41.1.0",
47
+ "@ckeditor/ckeditor5-list": "^41.1.0",
48
+ "@ckeditor/ckeditor5-media-embed": "^41.1.0",
49
+ "@ckeditor/ckeditor5-paragraph": "^41.1.0",
50
+ "@ckeditor/ckeditor5-remove-format": "^41.1.0",
51
+ "@ckeditor/ckeditor5-show-blocks": "^41.1.0",
52
+ "@ckeditor/ckeditor5-source-editing": "^41.1.0",
53
+ "@ckeditor/ckeditor5-table": "^41.1.0",
54
+ "@ckeditor/ckeditor5-theme-lark": "^41.1.0",
55
+ "@ckeditor/ckeditor5-typing": "^41.1.0",
56
+ "@ckeditor/ckeditor5-upload": "^41.1.0",
57
+ "@ckeditor/ckeditor5-vue": "^5.1.0",
58
+ "@ckeditor/ckeditor5-word-count": "^41.1.0",
59
+ "@tanstack/vue-query": "^5.24.1",
60
+ "@vueuse/components": "^10.8.0",
61
+ "@vueuse/core": "^10.8.0",
62
+ "@vueuse/router": "^10.8.0",
63
+ "a-calc": "^1.3.8",
64
+ "ant-design-vue": "^4.1.2",
65
+ "archiver": "^6.0.1",
66
+ "axios": "^1.6.7",
67
+ "bignumber.js": "^9.1.2",
68
+ "chokidar": "^3.6.0",
69
+ "dayjs": "^1.11.10",
70
+ "echarts": "^5.4.3",
71
+ "execa": "^8.0.1",
72
+ "fast-glob": "^3.3.2",
73
+ "localstorage-slim": "^2.7.0",
74
+ "lodash-es": "^4.17.21",
75
+ "nprogress": "^0.2.0",
76
+ "pinia": "^2.1.7",
77
+ "tsx": "^4.7.1",
78
+ "vue": "^3.4.19",
79
+ "vue-i18n": "^9.9.1",
80
+ "vue-router": "^4.3.0"
81
+ },
82
+ "devDependencies": {
83
+ "@peng_kai/lint": "^0.1.0",
84
+ "@types/archiver": "^6.0.2",
85
+ "@types/lodash-es": "^4.17.12",
86
+ "@types/node": "18.19.15",
87
+ "@types/nprogress": "^0.2.3",
88
+ "type-fest": "^4.10.3",
89
+ "typescript": "^5.3.3",
90
+ "vue-component-type-helpers": "^1.8.27"
91
+ }
92
+ }
@@ -1,68 +1,68 @@
1
- import type { AxiosInstance } from 'axios';
2
-
3
- export { isTimeout, getServices, getBaseUrlByEnv, ApiCode, ApiError };
4
-
5
- enum ApiCode {
6
- NORMAL = 0, // 正常
7
- UNKNOWN = -1, // 未知错误
8
- TIMEOUT = -2, // 请求超时
9
- }
10
-
11
- function getServices() {
12
- const serversModule = getServices.modules;
13
- const servers: Record<string, { server: AxiosInstance } | undefined> = {};
14
-
15
- for (const [key, module] of Object.entries(serversModule)) {
16
- const name = key.match(/\/([0-9a-zA-Z]+)\.ts$/)?.[1];
17
-
18
- if (name)
19
- servers[`${name}.api`] = module as any;
20
- }
21
-
22
- return servers;
23
- }
24
- getServices.modules = {} as any;
25
-
26
- function isTimeout(error: any) {
27
- return error?.message?.toLowerCase().includes('timeout');
28
- }
29
-
30
- function getBaseUrlByEnv(service: string, env: Record<string, string>) {
31
- let serviceName = '';
32
-
33
- if (/^https?:\/\//.test(service)) {
34
- const fileName = service.split('/').pop();
35
- serviceName = fileName?.split('.').shift() ?? '';
36
- }
37
- else {
38
- serviceName = service;
39
- }
40
-
41
- if (!serviceName)
42
- return '';
43
-
44
- const [prefix, target] = env[`VITE_HTTP_PREFIX_${serviceName}`]?.split(' => ') ?? ['', ''];
45
-
46
- return (prefix && target) ? prefix : '';
47
- }
48
-
49
- class ApiError<TResp = any> extends Error {
50
- public static is<ErrorResp = any>(error: any): error is ApiError<ErrorResp> {
51
- return !!error?.isApiError;
52
- }
53
-
54
- /**
55
- * 将HTTP status和Api code统一到一个code里
56
- */
57
- public code: number;
58
- public msg: string;
59
- public data: TResp;
60
- public isApiError = true;
61
-
62
- public constructor(info: { code: number, msg: string, data: TResp }) {
63
- super(info.msg);
64
- this.code = info.code;
65
- this.msg = info.msg;
66
- this.data = info.data;
67
- }
68
- }
1
+ import type { AxiosInstance } from 'axios';
2
+
3
+ export { isTimeout, getServices, getBaseUrlByEnv, ApiCode, ApiError };
4
+
5
+ enum ApiCode {
6
+ NORMAL = 0, // 正常
7
+ UNKNOWN = -1, // 未知错误
8
+ TIMEOUT = -2, // 请求超时
9
+ }
10
+
11
+ function getServices() {
12
+ const serversModule = getServices.modules;
13
+ const servers: Record<string, { server: AxiosInstance } | undefined> = {};
14
+
15
+ for (const [key, module] of Object.entries(serversModule)) {
16
+ const name = key.match(/\/([0-9a-zA-Z]+)\.ts$/)?.[1];
17
+
18
+ if (name)
19
+ servers[`${name}.api`] = module as any;
20
+ }
21
+
22
+ return servers;
23
+ }
24
+ getServices.modules = {} as any;
25
+
26
+ function isTimeout(error: any) {
27
+ return error?.message?.toLowerCase().includes('timeout');
28
+ }
29
+
30
+ function getBaseUrlByEnv(service: string, env: Record<string, string>) {
31
+ let serviceName = '';
32
+
33
+ if (/^https?:\/\//.test(service)) {
34
+ const fileName = service.split('/').pop();
35
+ serviceName = fileName?.split('.').shift() ?? '';
36
+ }
37
+ else {
38
+ serviceName = service;
39
+ }
40
+
41
+ if (!serviceName)
42
+ return '';
43
+
44
+ const [prefix, target] = env[`VITE_HTTP_PREFIX_${serviceName}`]?.split(' => ') ?? ['', ''];
45
+
46
+ return (prefix && target) ? prefix : '';
47
+ }
48
+
49
+ class ApiError<TResp = any> extends Error {
50
+ public static is<ErrorResp = any>(error: any): error is ApiError<ErrorResp> {
51
+ return !!error?.isApiError;
52
+ }
53
+
54
+ /**
55
+ * 将HTTP status和Api code统一到一个code里
56
+ */
57
+ public code: number;
58
+ public msg: string;
59
+ public data: TResp;
60
+ public isApiError = true;
61
+
62
+ public constructor(info: { code: number, msg: string, data: TResp }) {
63
+ super(info.msg);
64
+ this.code = info.code;
65
+ this.msg = info.msg;
66
+ this.data = info.data;
67
+ }
68
+ }