create-bubbles 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.
Files changed (116) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/template-react-rsbuild-biome/biome.json +19 -4
  4. package/template-vue-rolldown-oxc/.gitlab-ci.yml +10 -2
  5. package/template-vue-rolldown-oxc/.oxlintrc.json +1 -14
  6. package/template-vue-rolldown-oxc/.vscode/settings.json +11 -0
  7. package/template-vue-rolldown-oxc/README.md +2 -30
  8. package/template-vue-rolldown-oxc/package.json +18 -16
  9. package/template-vue-rolldown-oxc/src/App.vue +12 -2
  10. package/template-vue-rolldown-oxc/src/utils/request/index.ts +1 -3
  11. package/template-vue-rolldown-oxc/src/views/home/index.vue +3 -2
  12. package/template-vue-rolldown-oxc/tsconfig.json +34 -2
  13. package/template-vue-rolldown-oxc/uno.config.ts +2 -5
  14. package/template-vue-rolldown-oxc/vite.config.ts +4 -3
  15. package/template-vue-rsbuild-biome/biome.json +33 -5
  16. package/template-vue-vite-biome/.env +4 -0
  17. package/template-vue-vite-biome/.env.development +1 -0
  18. package/template-vue-vite-biome/.env.production +1 -0
  19. package/template-vue-vite-biome/.gitlab-ci.yml +84 -0
  20. package/template-vue-vite-biome/.vscode/settings.json +10 -0
  21. package/template-vue-vite-biome/README.md +3 -0
  22. package/template-vue-vite-biome/biome.json +109 -0
  23. package/template-vue-vite-biome/commitlint.config.js +1 -0
  24. package/template-vue-vite-biome/index.html +13 -0
  25. package/template-vue-vite-biome/lefthook.yml +11 -0
  26. package/template-vue-vite-biome/package.json +50 -0
  27. package/template-vue-vite-biome/public/vite.svg +1 -0
  28. package/template-vue-vite-biome/src/App.vue +19 -0
  29. package/template-vue-vite-biome/src/assets/icon/vue.svg +1 -0
  30. package/template-vue-vite-biome/src/components/Icon/svg-icon.vue +29 -0
  31. package/template-vue-vite-biome/src/layout/default/index.vue +3 -0
  32. package/template-vue-vite-biome/src/main.ts +15 -0
  33. package/template-vue-vite-biome/src/router/guard/index.ts +7 -0
  34. package/template-vue-vite-biome/src/router/guard/permissionGuard.ts +13 -0
  35. package/template-vue-vite-biome/src/router/index.ts +17 -0
  36. package/template-vue-vite-biome/src/router/modules/index.ts +31 -0
  37. package/template-vue-vite-biome/src/store/index.ts +10 -0
  38. package/template-vue-vite-biome/src/store/modules/user.ts +17 -0
  39. package/template-vue-vite-biome/src/styles/element-plus-variables.css +4 -0
  40. package/template-vue-vite-biome/src/styles/font.scss +0 -0
  41. package/template-vue-vite-biome/src/styles/index.scss +31 -0
  42. package/template-vue-vite-biome/src/styles/variables.scss +3 -0
  43. package/template-vue-vite-biome/src/types/vite-env.d.ts +13 -0
  44. package/template-vue-vite-biome/src/utils/env.ts +10 -0
  45. package/template-vue-vite-biome/src/utils/request/core/index.ts +166 -0
  46. package/template-vue-vite-biome/src/utils/request/core/utils.ts +38 -0
  47. package/template-vue-vite-biome/src/utils/request/index.ts +39 -0
  48. package/template-vue-vite-biome/src/views/home/index.vue +16 -0
  49. package/template-vue-vite-biome/src/views/login/index.vue +11 -0
  50. package/template-vue-vite-biome/src/views/model/index.vue +7 -0
  51. package/{template-vue-rolldown-oxc/tsconfig.app.json → template-vue-vite-biome/tsconfig.json} +15 -4
  52. package/template-vue-vite-biome/uno.config.ts +10 -0
  53. package/template-vue-vite-biome/vite.config.ts +51 -0
  54. package/template-vue-vite-eslint/.env +6 -0
  55. package/template-vue-vite-eslint/.env.development +2 -0
  56. package/template-vue-vite-eslint/.env.production +1 -0
  57. package/template-vue-vite-eslint/.vscode/settings.json +62 -0
  58. package/template-vue-vite-eslint/README.md +3 -0
  59. package/template-vue-vite-eslint/commitlint.config.js +1 -0
  60. package/template-vue-vite-eslint/eslint.config.js +69 -0
  61. package/template-vue-vite-eslint/index.html +13 -0
  62. package/template-vue-vite-eslint/lefthook.yml +11 -0
  63. package/template-vue-vite-eslint/package.json +62 -0
  64. package/template-vue-vite-eslint/public/vite.svg +1 -0
  65. package/template-vue-vite-eslint/src/App.vue +19 -0
  66. package/template-vue-vite-eslint/src/api/index.ts +12 -0
  67. package/template-vue-vite-eslint/src/assets/icon/computer-data.svg +3 -0
  68. package/template-vue-vite-eslint/src/assets/icon/cpu.svg +3 -0
  69. package/template-vue-vite-eslint/src/assets/icon/data-search.svg +3 -0
  70. package/template-vue-vite-eslint/src/assets/icon/home.svg +3 -0
  71. package/template-vue-vite-eslint/src/assets/icon/knowledge-graph.svg +3 -0
  72. package/template-vue-vite-eslint/src/assets/icon/robot.svg +3 -0
  73. package/template-vue-vite-eslint/src/assets/icon/vue.svg +1 -0
  74. package/template-vue-vite-eslint/src/assets/image/.gitkeep +0 -0
  75. package/template-vue-vite-eslint/src/components/Icon/svg-icon.vue +29 -0
  76. package/template-vue-vite-eslint/src/hooks/chart/lib.ts +57 -0
  77. package/template-vue-vite-eslint/src/hooks/chart/useEcharts.ts +65 -0
  78. package/template-vue-vite-eslint/src/layout/default/header/index.vue +12 -0
  79. package/template-vue-vite-eslint/src/layout/default/index.vue +55 -0
  80. package/template-vue-vite-eslint/src/main.ts +17 -0
  81. package/template-vue-vite-eslint/src/router/guard/index.ts +7 -0
  82. package/template-vue-vite-eslint/src/router/guard/permissionGuard.ts +13 -0
  83. package/template-vue-vite-eslint/src/router/index.ts +18 -0
  84. package/template-vue-vite-eslint/src/router/interface.ts +9 -0
  85. package/template-vue-vite-eslint/src/router/modules/example.ts +21 -0
  86. package/template-vue-vite-eslint/src/router/modules/index.ts +79 -0
  87. package/template-vue-vite-eslint/src/store/index.ts +11 -0
  88. package/template-vue-vite-eslint/src/store/modules/user.ts +20 -0
  89. package/template-vue-vite-eslint/src/styles/element-plus-variables.css +3 -0
  90. package/template-vue-vite-eslint/src/styles/font.scss +0 -0
  91. package/template-vue-vite-eslint/src/styles/index.scss +32 -0
  92. package/template-vue-vite-eslint/src/styles/plus-pro-components-variables.css +3 -0
  93. package/template-vue-vite-eslint/src/styles/variables.scss +3 -0
  94. package/template-vue-vite-eslint/src/types/index.d.ts +1 -0
  95. package/template-vue-vite-eslint/src/types/vite-env.d.ts +15 -0
  96. package/template-vue-vite-eslint/src/utils/env.ts +11 -0
  97. package/template-vue-vite-eslint/src/utils/request/core/index.ts +186 -0
  98. package/template-vue-vite-eslint/src/utils/request/core/utils.ts +41 -0
  99. package/template-vue-vite-eslint/src/utils/request/index.ts +42 -0
  100. package/template-vue-vite-eslint/src/views/data-statistics/config.ts +11 -0
  101. package/template-vue-vite-eslint/src/views/data-statistics/index.vue +23 -0
  102. package/template-vue-vite-eslint/src/views/data-statistics/right/abc.vue +11 -0
  103. package/template-vue-vite-eslint/src/views/example/echart/config.ts +1794 -0
  104. package/template-vue-vite-eslint/src/views/example/echart/index.vue +22 -0
  105. package/template-vue-vite-eslint/src/views/example/h-full.vue +24 -0
  106. package/template-vue-vite-eslint/src/views/example/tree-chart.vue +94 -0
  107. package/template-vue-vite-eslint/src/views/home/index.vue +25 -0
  108. package/template-vue-vite-eslint/src/views/knowledge-graph/index.vue +11 -0
  109. package/template-vue-vite-eslint/src/views/login/index.vue +9 -0
  110. package/template-vue-vite-eslint/src/views/model/index.vue +7 -0
  111. package/{template-vue-rolldown-oxc/tsconfig.node.json → template-vue-vite-eslint/tsconfig.json} +20 -9
  112. package/template-vue-vite-eslint/uno.config.ts +21 -0
  113. package/template-vue-vite-eslint/vite.config.ts +62 -0
  114. package/template-vue-rolldown-oxc/components.d.ts +0 -18
  115. package/template-vue-rolldown-oxc/src/types/auto-import.d.ts +0 -78
  116. package/template-vue-rolldown-oxc/src/types/components.d.ts +0 -16
@@ -0,0 +1,65 @@
1
+ import type { EChartsOption } from 'echarts'
2
+
3
+ import type { ShallowRef } from 'vue'
4
+
5
+ import { debounce } from 'radashi'
6
+
7
+ import echarts from './lib'
8
+
9
+ type setOptionsType = (options: EChartsOption, clear?: boolean) => void
10
+
11
+ export function useECharts(elRef: Ref<HTMLDivElement> | Readonly<ShallowRef<HTMLDivElement | null>>) {
12
+ let chartInstance: echarts.ECharts | null = null
13
+ let resizeObserver: ResizeObserver | undefined
14
+
15
+ const resize = () => {
16
+ chartInstance?.resize()
17
+ }
18
+
19
+ const initCharts = () => {
20
+ if (!elRef)
21
+ return
22
+ const el = unref(elRef)
23
+ if (!el)
24
+ return
25
+
26
+ resizeObserver = new ResizeObserver(debounce(
27
+ {
28
+ delay: 100,
29
+ },
30
+ resize,
31
+ ))
32
+ resizeObserver.observe(el)
33
+
34
+ chartInstance = echarts.init(el)
35
+ }
36
+
37
+ const setOptions: setOptionsType = (options, clear = true) => {
38
+ if (!chartInstance) {
39
+ initCharts()
40
+ if (!chartInstance)
41
+ return
42
+ }
43
+ clear && chartInstance?.clear()
44
+ chartInstance?.setOption(options)
45
+ }
46
+
47
+ const getInstance: () => echarts.ECharts | null = () => {
48
+ if (!chartInstance)
49
+ initCharts()
50
+ return chartInstance
51
+ }
52
+
53
+ onUnmounted(() => {
54
+ chartInstance?.dispose()
55
+ resizeObserver?.disconnect()
56
+ resizeObserver = undefined
57
+ })
58
+
59
+ return {
60
+ setOptions,
61
+ resize,
62
+ echarts,
63
+ getInstance,
64
+ }
65
+ }
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ </script>
3
+
4
+ <template>
5
+ <div class="index-container">
6
+ 111
7
+ </div>
8
+ </template>
9
+
10
+ <style lang="scss" scoped>
11
+
12
+ </style>
@@ -0,0 +1,55 @@
1
+ <script lang="ts" setup>
2
+ import type { MenuRouteRecordRawType } from '@/router/interface'
3
+
4
+ import LogoIcon from '@/assets/icon/logo.svg'
5
+ import { menuRoutes } from '@/router/modules'
6
+
7
+ import SvgIcon from '@/components/Icon/svg-icon.vue'
8
+
9
+ import Header from './header/index.vue'
10
+
11
+ function getRoutes(routes: MenuRouteRecordRawType[]) {
12
+ const result = routes.map((item) => {
13
+ const isSvgIcon = (item.meta?.icon as string | undefined)?.startsWith('svg-')
14
+ return ({
15
+ path: item.path,
16
+ name: item.name,
17
+ component: item.component,
18
+ meta: {
19
+ title: item.meta?.title,
20
+ icon: isSvgIcon ? h(SvgIcon, { icon: (item.meta?.icon as string).replace('svg-', ''), style: { fontSize: '20px' } }) : undefined,
21
+ hideInMenu: item.meta?.hideInMenu,
22
+ },
23
+ children: item.children,
24
+ })
25
+ })
26
+ result.forEach((item) => {
27
+ if (item.children) {
28
+ item.children = getRoutes(item.children) as MenuRouteRecordRawType[]
29
+ }
30
+ })
31
+ return result
32
+ }
33
+
34
+ const routes = getRoutes(menuRoutes)
35
+ </script>
36
+
37
+ <template>
38
+ <PlusLayout
39
+ :sidebar-props="{ routes }"
40
+ :has-breadcrumb="false"
41
+ :header-props="{
42
+ hasUserInfo: false,
43
+ }"
44
+ >
45
+ <template #header-left>
46
+ <h1>111</h1>
47
+ </template>
48
+
49
+ <template #header-right>
50
+ <Header />
51
+ </template>
52
+
53
+ <router-view />
54
+ </PlusLayout>
55
+ </template>
@@ -0,0 +1,17 @@
1
+ import { createApp } from 'vue'
2
+
3
+ import App from './App.vue'
4
+ import { setupRouter } from './router'
5
+ import { setupStore } from './store'
6
+
7
+ import 'virtual:svg-icons-register'
8
+
9
+ import '@/styles/element-plus-variables.css'
10
+ import '@/styles/index.scss'
11
+ import 'virtual:uno.css'
12
+
13
+ const app = createApp(App)
14
+ setupRouter(app)
15
+ setupStore(app)
16
+
17
+ app.mount('#app')
@@ -0,0 +1,7 @@
1
+ import type { Router } from 'vue-router'
2
+
3
+ import { createPermissionGuard } from './permissionGuard'
4
+
5
+ export function setupGuard(router: Router) {
6
+ createPermissionGuard(router)
7
+ }
@@ -0,0 +1,13 @@
1
+ import type { Router } from 'vue-router'
2
+
3
+ import NProgress from 'nprogress'
4
+
5
+ export function createPermissionGuard(router: Router) {
6
+ router.beforeEach((_to, _from, next) => {
7
+ NProgress.start()
8
+ next()
9
+ })
10
+ router.afterEach((_to, _from) => {
11
+ NProgress.done()
12
+ })
13
+ }
@@ -0,0 +1,18 @@
1
+ import type { App } from 'vue'
2
+
3
+ import { createRouter, createWebHistory } from 'vue-router'
4
+
5
+ import { setupGuard } from './guard'
6
+ import { routes } from './modules'
7
+
8
+ export const router = createRouter({
9
+ history: createWebHistory(import.meta.env.PUBLIC_PATH),
10
+ routes,
11
+ strict: true,
12
+ scrollBehavior: () => ({ left: 0, top: 0 }),
13
+ })
14
+
15
+ export function setupRouter(app: App) {
16
+ setupGuard(router)
17
+ app.use(router)
18
+ }
@@ -0,0 +1,9 @@
1
+ import type { RouteRecordRaw } from 'vue-router'
2
+
3
+ export type MenuRouteRecordRawType = RouteRecordRaw & {
4
+ meta?: {
5
+ title?: string
6
+ icon?: string
7
+ hideInMenu?: boolean
8
+ }
9
+ }
@@ -0,0 +1,21 @@
1
+ import type { RouteRecordRaw } from 'vue-router'
2
+
3
+ export const ExampleRoutes: RouteRecordRaw[] = [
4
+ {
5
+ path: '/example',
6
+ name: 'Example',
7
+ children: [
8
+ {
9
+ path: 'echart',
10
+ name: 'Echart',
11
+ component: () => import('@/views/example/echart/index.vue'),
12
+ },
13
+
14
+ {
15
+ path: 'tree-chart',
16
+ name: 'TreeChart',
17
+ component: () => import('@/views/example/tree-chart.vue'),
18
+ },
19
+ ],
20
+ },
21
+ ]
@@ -0,0 +1,79 @@
1
+ import type { RouteRecordRaw } from 'vue-router'
2
+
3
+ import type { MenuRouteRecordRawType } from '../interface'
4
+
5
+ import { ExampleRoutes } from './example'
6
+
7
+ export const menuRoutes: MenuRouteRecordRawType [] = [
8
+ {
9
+ path: '/home',
10
+ name: 'Home',
11
+ meta: { title: '首页概览', icon: 'svg-home' },
12
+ component: () => import('@/views/home/index.vue'),
13
+ },
14
+ {
15
+ path: '/data-search-statistics',
16
+ name: 'DataSearchStatistics',
17
+ meta: { title: '数据查询统计', icon: 'svg-data-search' },
18
+ children: [
19
+ {
20
+ path: '/abc',
21
+ name: 'abc',
22
+ meta: { title: '测试' },
23
+ component: () => import('@/views/home/index.vue'),
24
+ },
25
+ {
26
+ path: '/data-statistics',
27
+ name: 'DataStatistics',
28
+ meta: { title: '数据统计' },
29
+ component: () => import('@/views/data-statistics/index.vue'),
30
+ },
31
+ ],
32
+ },
33
+ {
34
+ path: '/knowledge-graph',
35
+ name: 'KnowledgeGraph',
36
+ meta: { title: '知识图谱', icon: 'svg-knowledge-graph' },
37
+ component: () => import('@/views/knowledge-graph/index.vue'),
38
+ },
39
+ {
40
+ path: '/ai-search-tools',
41
+ name: 'AISearchTools',
42
+ meta: { title: 'AI研究工具', icon: 'svg-cpu' },
43
+ component: () => import('@/views/home/index.vue'),
44
+ },
45
+ {
46
+ path: '/data-mgt',
47
+ name: 'DataMgt',
48
+ meta: { title: '数据管理', icon: 'svg-computer-data' },
49
+ component: () => import('@/views/home/index.vue'),
50
+ },
51
+ {
52
+ path: '/platform-ai-assistant',
53
+ name: 'PlatformAIAssistant',
54
+ meta: { title: '平台智能助手', icon: 'svg-robot' },
55
+ component: () => import('@/views/home/index.vue'),
56
+ },
57
+ ]
58
+
59
+ export const routes: RouteRecordRaw[] = [
60
+ {
61
+ path: '/',
62
+ name: 'layout',
63
+ component: () => import('@/layout/default/index.vue'),
64
+ children: [
65
+ {
66
+ path: '/',
67
+ redirect: '/home',
68
+ },
69
+ ...menuRoutes,
70
+ ],
71
+ },
72
+ ...ExampleRoutes,
73
+ {
74
+ path: '/login',
75
+ name: 'login',
76
+ meta: { title: '登录' },
77
+ component: () => import('@/views/login/index.vue'),
78
+ },
79
+ ]
@@ -0,0 +1,11 @@
1
+ import type { App } from 'vue'
2
+
3
+ import { createPinia } from 'pinia'
4
+ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
5
+
6
+ export const store = createPinia()
7
+ store.use(piniaPluginPersistedstate)
8
+
9
+ export function setupStore(app: App) {
10
+ app.use(store)
11
+ }
@@ -0,0 +1,20 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ import { store } from '..'
4
+
5
+ export const useUserStore = defineStore(
6
+ 'user',
7
+ {
8
+ state: () => {
9
+ return {
10
+ name: 'admin',
11
+ token: 'admin',
12
+ avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
13
+ }
14
+ },
15
+ },
16
+ )
17
+
18
+ export function useUserStoreWithOut() {
19
+ return useUserStore(store)
20
+ }
@@ -0,0 +1,3 @@
1
+ :root:has(#app) {
2
+ --el-color-primary: #409effff;
3
+ }
File without changes
@@ -0,0 +1,32 @@
1
+ @use './font.scss';
2
+ @use './variables.scss';
3
+ @use './element-plus-variables.css';
4
+ @use './plus-pro-components-variables.css';
5
+ @use 'element-plus/theme-chalk/dark/css-vars.css';
6
+
7
+ html,
8
+ body,
9
+ #root {
10
+ width: 100%;
11
+ height: 100%;
12
+ font-family: 'SourceHanSansCN';
13
+ }
14
+
15
+ *,
16
+ *::before,
17
+ *::after {
18
+ margin: 0;
19
+ padding: 0;
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ //弹窗的标题样式
24
+ .dialog-title {
25
+ border-left: 3px solid #22b5ffff;
26
+ padding-left: 10px;
27
+ height: 16px;
28
+ color: #ffffffb8;
29
+ font: 700;
30
+ font-size: 16px;
31
+ line-height: 16px;
32
+ }
@@ -0,0 +1,3 @@
1
+ :root .el-header {
2
+ --el-header-height: 56px;
3
+ }
@@ -0,0 +1,3 @@
1
+ :root {
2
+ --header-height: 80px;
3
+ }
@@ -0,0 +1 @@
1
+ // 扩展 vue-router 的类型
@@ -0,0 +1,15 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ /* eslint-disable */
4
+ declare module '*.vue' {
5
+ import type { DefineComponent } from 'vue'
6
+
7
+ const component: DefineComponent<{}, {}, any>
8
+ export default component
9
+ }
10
+
11
+ // vite-plugin-svg-icons 类型声明
12
+ declare module 'virtual:svg-icons-register' {
13
+ const register: () => void
14
+ export default register
15
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 通过一个文件导出所有的环境变量这样方便统一修改
3
+ * @returns
4
+ */
5
+ export const envVariables = {
6
+ PORT: import.meta.env.VITE_PORT,
7
+ PATH: import.meta.env.VITE_PATH,
8
+ APP_NAME: import.meta.env.VITE_APP_NAME,
9
+ /** 后端接口前缀 */
10
+ API_AFFIX: import.meta.env.VITE_API_AFFIX,
11
+ }
@@ -0,0 +1,186 @@
1
+ import type { AlovaGenerics, AlovaOptions } from 'alova'
2
+
3
+ import { createAlova } from 'alova'
4
+ import adapterFetch from 'alova/fetch'
5
+
6
+ import { deepMergeObject, isReadableStream } from './utils'
7
+
8
+ interface statusMap {
9
+ success?: number
10
+ unAuthorized?: number
11
+ }
12
+
13
+ interface codeMap {
14
+ success?: number[]
15
+ unAuthorized?: number[]
16
+ }
17
+
18
+ export interface baseRequestOption<AG extends AlovaGenerics> {
19
+ baseUrl?: string
20
+ timeout?: number
21
+ commonHeaders?: Record<string, string | (() => string)>
22
+ statusMap?: statusMap
23
+ isWrapped?: boolean
24
+ cacheFor?: AlovaOptions<AG>['cacheFor']
25
+ cacheLogger?: boolean
26
+ codeMap?: codeMap
27
+ responseDataKey?: string
28
+ responseMessageKey?: string
29
+ isTransformResponse?: boolean
30
+ isShowSuccessMessage?: boolean
31
+ successDefaultMessage?: string
32
+ isShowErrorMessage?: boolean
33
+ errorDefaultMessage?: string
34
+ statesHook?: AlovaOptions<AG>['statesHook']
35
+ successMessageFunc?: (message: string) => void
36
+ errorMessageFunc?: (message: string) => void
37
+ unAuthorizedResponseFunc?: () => void
38
+ requestAdapter?: AlovaOptions<AG>['requestAdapter']
39
+ }
40
+
41
+ export interface CustomConfig {
42
+ isTransformResponse?: boolean
43
+ isShowSuccessMessage?: boolean
44
+ isShowErrorMessage?: boolean
45
+ }
46
+
47
+ type requestOption = baseRequestOption<AlovaGenerics> & CustomConfig
48
+
49
+ export function createInstance(option: requestOption) {
50
+ const defaultOption: requestOption = {
51
+ baseUrl: '/',
52
+ timeout: 0,
53
+ statusMap: {
54
+ success: 200,
55
+ unAuthorized: 401,
56
+ },
57
+ isWrapped: true,
58
+ cacheFor: null,
59
+ cacheLogger: true,
60
+ codeMap: {
61
+ success: [200],
62
+ unAuthorized: [401],
63
+ },
64
+ responseDataKey: 'data',
65
+ responseMessageKey: 'message',
66
+ isTransformResponse: true,
67
+ isShowSuccessMessage: false,
68
+ successDefaultMessage: '操作成功',
69
+ isShowErrorMessage: true,
70
+ errorDefaultMessage: '服务异常',
71
+ requestAdapter: adapterFetch(),
72
+ }
73
+
74
+ const mergeOption: baseRequestOption<AlovaGenerics> & CustomConfig = deepMergeObject(
75
+ defaultOption,
76
+ option,
77
+ )
78
+
79
+ const instance = createAlova({
80
+ baseURL: mergeOption.baseUrl,
81
+ timeout: mergeOption.timeout,
82
+ cacheFor: mergeOption.cacheFor,
83
+ cacheLogger: mergeOption.cacheLogger,
84
+ statesHook: mergeOption?.statesHook,
85
+ requestAdapter: mergeOption.requestAdapter as AlovaOptions<AlovaGenerics>['requestAdapter'],
86
+ beforeRequest: async (method) => {
87
+ for (const [key, value] of Object.entries(option?.commonHeaders ?? {})) {
88
+ method.config.headers[key] = typeof value === 'function' ? value() : value
89
+ }
90
+ },
91
+ responded: {
92
+ onSuccess: async (response) => {
93
+ if (!mergeOption?.isTransformResponse)
94
+ return response
95
+ const { status } = response
96
+
97
+ // 判断响应类型:如果使用 adapterFetch,response.data 是可读流,则调用 json();否则直接使用 response.data
98
+ const data
99
+ = response?.body && isReadableStream(response.body)
100
+ ? await response.json() // adapterFetch 的响应,使用 json() 解析可读流
101
+ : response.data // 其他适配器的响应
102
+ // 不成功的情况
103
+ if (status !== mergeOption.statusMap?.success) {
104
+ // 如果后端使用status 字段来表示未授权,则返回401
105
+ if (mergeOption?.statusMap?.unAuthorized === status) {
106
+ mergeOption?.unAuthorizedResponseFunc?.()
107
+ }
108
+ return Promise.reject(response)
109
+ }
110
+ const { isWrapped, isShowSuccessMessage, successDefaultMessage } = mergeOption
111
+ if (!isWrapped) {
112
+ if (isShowSuccessMessage) {
113
+ mergeOption?.successMessageFunc?.(successDefaultMessage!)
114
+ }
115
+ return data
116
+ }
117
+
118
+ const {
119
+ responseDataKey,
120
+ codeMap,
121
+ responseMessageKey,
122
+ errorDefaultMessage,
123
+ isShowErrorMessage,
124
+ } = mergeOption
125
+ const {
126
+ code,
127
+ [responseDataKey as string]: responseData,
128
+ [responseMessageKey as string]: responseMessage,
129
+ } = data
130
+ if (!codeMap?.success?.includes(+code)) {
131
+ // code unAuthorized 处理
132
+ if (codeMap?.unAuthorized?.includes(+code)) {
133
+ mergeOption?.unAuthorizedResponseFunc?.()
134
+ return Promise.reject(response)
135
+ }
136
+ // 其他错误直接打印msg
137
+
138
+ const errorMessage = data[responseMessageKey as string] ?? errorDefaultMessage
139
+ if (isShowErrorMessage)
140
+ mergeOption?.errorMessageFunc?.(errorMessage)
141
+ return Promise.reject(response)
142
+ }
143
+ if (isShowSuccessMessage)
144
+ mergeOption?.successMessageFunc?.(responseMessage ?? successDefaultMessage)
145
+ return responseData
146
+ },
147
+ onError: (error) => {
148
+ if (mergeOption?.isShowErrorMessage) {
149
+ mergeOption.errorMessageFunc?.(
150
+ mergeOption?.errorDefaultMessage ?? error.message,
151
+ )
152
+ }
153
+ },
154
+ // onComplete: (_method) => {},
155
+ },
156
+ })
157
+
158
+ return instance
159
+ }
160
+
161
+ // 🚀 创建双重调用实例的工厂函数
162
+ export function createDualCallInstance(baseConfig: baseRequestOption<AlovaGenerics>) {
163
+ // 创建默认实例
164
+ const defaultInstance = createInstance(baseConfig)
165
+
166
+ // 双重调用函数
167
+ const dualInstance = (option?: CustomConfig) => {
168
+ if (option) {
169
+ // 合并配置并创建新实例
170
+ const mergedConfig = { ...baseConfig, ...option }
171
+ return createInstance(mergedConfig)
172
+ }
173
+ return defaultInstance
174
+ }
175
+
176
+ dualInstance.Get = defaultInstance.Get.bind(defaultInstance)
177
+ dualInstance.Post = defaultInstance.Post.bind(defaultInstance)
178
+ dualInstance.Put = defaultInstance.Put.bind(defaultInstance)
179
+ dualInstance.Delete = defaultInstance.Delete.bind(defaultInstance)
180
+ dualInstance.Patch = defaultInstance.Patch.bind(defaultInstance)
181
+ dualInstance.Head = defaultInstance.Head.bind(defaultInstance)
182
+ dualInstance.Options = defaultInstance.Options.bind(defaultInstance)
183
+ dualInstance.Request = defaultInstance.Request.bind(defaultInstance)
184
+
185
+ return dualInstance
186
+ }
@@ -0,0 +1,41 @@
1
+ export function deepMergeObject<T = any>(source: T, target: Partial<T>): T {
2
+ const isObject = (obj: any): obj is Record<string, any> =>
3
+ obj && typeof obj === 'object' && !Array.isArray(obj)
4
+
5
+ const merge = (src: any, tgt: any): any => {
6
+ if (isObject(src) && isObject(tgt)) {
7
+ Object.keys(tgt).forEach((key) => {
8
+ if (isObject(tgt[key])) {
9
+ src[key] = merge(src[key] || {}, tgt[key])
10
+ }
11
+ else {
12
+ src[key] = tgt[key]
13
+ }
14
+ })
15
+ }
16
+ return src
17
+ }
18
+
19
+ return merge({ ...source }, target)
20
+ }
21
+
22
+ /**
23
+ * 判断一个变量是不是可读流
24
+ * @param data
25
+ */
26
+ export function isReadableStream(data: unknown): boolean {
27
+ if (!(data instanceof ReadableStream)) {
28
+ return false
29
+ }
30
+ if (typeof data.locked !== 'boolean')
31
+ return false
32
+
33
+ const instanceFunc = ['cancel', 'getReader', 'pipeThrough', 'pipeTo', 'tee'] as const
34
+
35
+ for (const func of instanceFunc) {
36
+ if (typeof data[func] !== 'function')
37
+ return false
38
+ }
39
+
40
+ return true
41
+ }