create-bubbles 0.1.25 → 0.1.26
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/dist/index.js +3 -9
- package/package.json +1 -1
- package/template-nextjs-vinext-eslint/Dockerfile +4 -4
- package/template-nextjs-vinext-eslint/README.md +6 -2
- package/template-nextjs-vinext-eslint/docker-compose.yaml +4 -4
- package/template-nextjs-vinext-eslint/eslint.config.js +2 -0
- package/template-nextjs-vinext-eslint/package.json +28 -26
- package/template-nextjs-vinext-eslint/pnpm-workspace.yaml +13 -1
- package/template-nextjs-vinext-eslint/src/utils/request/core/index.ts +63 -45
- package/template-nextjs-vinext-eslint/src/utils/request/core/utils.ts +12 -6
- package/template-nextjs-vinext-eslint/vite.config.ts +1 -1
- package/template-react-rsbuild-biome/.agents/rules/SVG/344/275/277/347/224/250.md +8 -0
- package/template-react-rsbuild-biome/AGENTS.md +11 -0
- package/template-react-rsbuild-biome/index.html +2 -2
- package/template-react-rsbuild-biome/package.json +25 -24
- package/template-react-rsbuild-biome/pnpm-workspace.yaml +5 -0
- package/template-react-rsbuild-biome/rsbuild.config.ts +1 -1
- package/template-react-rsbuild-biome/src/assets/icon/logo.svg +1 -1
- package/template-react-rsbuild-biome/src/assets/svg/draft.svg +4 -0
- package/template-react-rsbuild-biome/src/components/Icon/svg-icon/README.md +37 -0
- package/template-react-rsbuild-biome/src/components/Icon/svg-icon/SvgIcon.tsx +27 -0
- package/template-react-rsbuild-biome/src/env.d.ts +7 -0
- package/template-react-rsbuild-biome/src/utils/request/index.ts +3 -4
- package/template-react-rsbuild-biome/tsconfig.json +1 -2
- package/template-taro-react-oxc/.oxlintrc.json +0 -1
- package/template-taro-react-oxc/package.json +53 -52
- package/template-taro-react-oxc/pnpm-workspace.yaml +46 -0
- package/template-taro-vue-eslint/package.json +56 -56
- package/template-vp-monorepo-react-hono/apps/web/.agents/rules/SVG/344/275/277/347/224/250.md +8 -0
- package/template-vp-monorepo-react-hono/apps/web/AGENTS.md +11 -0
- package/template-vp-monorepo-react-hono/apps/web/package.json +1 -0
- package/template-vp-monorepo-react-hono/apps/web/src/assets/svg/draft.svg +4 -0
- package/template-vp-monorepo-react-hono/apps/web/src/components/Icon/svg-icon/README.md +37 -0
- package/template-vp-monorepo-react-hono/apps/web/src/components/Icon/svg-icon/SvgIcon.tsx +27 -0
- package/template-vp-monorepo-react-hono/apps/web/tsconfig.json +1 -1
- package/template-vp-monorepo-react-hono/apps/web/vite.config.ts +2 -0
- package/template-vp-monorepo-react-hono/pnpm-workspace.yaml +1 -0
- package/template-vp-monorepo-react-nestjs/.agents/rules//344/273/243/347/240/201/350/256/276/350/256/241.md +4 -0
- package/template-vp-monorepo-react-nestjs/.agents/rules//345/205/261/344/272/253/344/273/243/347/240/201.md +4 -0
- package/template-vp-monorepo-react-nestjs/.spaces/01./344/274/201/344/270/232/347/272/247/351/241/271/347/233/256/347/272/247//351/234/200/346/261/202/346/226/207/346/241/243.md +177 -0
- package/template-vp-monorepo-react-nestjs/.spaces/server/04.upload.md +4504 -0
- package/template-vp-monorepo-react-nestjs/.spaces/server/05./344/270/212/344/274/240/346/224/271/351/200/240/346/226/271/346/241/210/README.md +858 -0
- package/template-vp-monorepo-react-nestjs/.spaces/server/06./345/205/254/345/205/261/351/230/237/345/210/227/346/216/245/345/205/245/346/226/271/346/241/210/README.md +1890 -0
- package/template-vp-monorepo-react-nestjs/.spaces/server/06./345/205/254/345/205/261/351/230/237/345/210/227/346/216/245/345/205/245/346/226/271/346/241/210//344/270/212/344/274/240/346/270/205/347/220/206.md +1465 -0
- package/template-vp-monorepo-react-nestjs/AGENTS.md +8 -12
- package/template-vp-monorepo-react-nestjs/apps/server/.agents/rules/error-handling.md +84 -0
- package/template-vp-monorepo-react-nestjs/apps/server/.env.development +60 -0
- package/template-vp-monorepo-react-nestjs/apps/server/.env.production +16 -0
- package/template-vp-monorepo-react-nestjs/apps/server/AGENTS.md +9 -0
- package/template-vp-monorepo-react-nestjs/apps/server/drizzle/0000_military_colonel_america.sql +11 -0
- package/template-vp-monorepo-react-nestjs/apps/server/drizzle/0001_loud_siren.sql +27 -0
- package/template-vp-monorepo-react-nestjs/apps/server/drizzle/meta/0000_snapshot.json +97 -0
- package/template-vp-monorepo-react-nestjs/apps/server/drizzle/meta/0001_snapshot.json +354 -0
- package/template-vp-monorepo-react-nestjs/apps/server/drizzle/meta/_journal.json +20 -0
- package/template-vp-monorepo-react-nestjs/apps/server/package.json +4 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/app.module.ts +14 -2
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/adapters/fastify.adapter.ts +6 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/config/index.ts +2 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/config/queue.config.ts +105 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/config/storage.config.ts +33 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/database/schema.ts +57 -1
- package/template-vp-monorepo-react-nestjs/apps/server/src/main.ts +1 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.service.ts +1 -3
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/dto/auth-repsponse.dto.ts +2 -2
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/task-queue/queue-worker.bootstrap.ts +24 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/task-queue/task-queue.constants.ts +24 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/task-queue/task-queue.contracts.ts +35 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/task-queue/task-queue.module.ts +56 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/task-queue/task-queue.processor.ts +62 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/task-queue/task-queue.service.ts +58 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/test/error-catelog.spec.ts +34 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/dto/initiate-mutipart-upload.dto.ts +26 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/dto/upload-params.dto.ts +15 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/storage/exact-size.transform.ts +66 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/storage/minio-storage.adapter.ts +239 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/storage/storage.port.ts +61 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/upload.constants.ts +23 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/upload.controller.ts +109 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/upload.errors.ts +80 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/upload.module.ts +20 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/upload.reponsitory.ts +166 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/upload.service.ts +696 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/upload/utils/object-key.ts +10 -0
- package/template-vp-monorepo-react-nestjs/apps/server/test/task-queue.integration.spec.ts +120 -0
- package/template-vp-monorepo-react-nestjs/apps/server/test/task-queue.processor.spec.ts +63 -0
- package/template-vp-monorepo-react-nestjs/apps/server/test/task-queue.service.spec.ts +106 -0
- package/template-vp-monorepo-react-nestjs/apps/web/.agents/rules/SVG/344/275/277/347/224/250.md +8 -0
- package/template-vp-monorepo-react-nestjs/apps/web/.agents/rules//345/274/271/347/252/227/347/273/204/344/273/266.md +4 -0
- package/template-vp-monorepo-react-nestjs/apps/web/.agents/rules//346/226/207/344/273/266/346/213/206/345/210/206.md +4 -0
- package/template-vp-monorepo-react-nestjs/apps/web/.agents/rules//347/273/204/344/273/266/345/221/275/345/220/215.md +3 -0
- package/template-vp-monorepo-react-nestjs/apps/web/.agents/rules//350/241/250/346/240/274/351/241/265/351/235/242.md +11 -0
- package/template-vp-monorepo-react-nestjs/apps/web/.agents/rules//351/241/265/351/235/242/346/216/245/345/217/243.md +3 -0
- package/template-vp-monorepo-react-nestjs/apps/web/.env.dev +1 -1
- package/template-vp-monorepo-react-nestjs/apps/web/AGENTS.md +16 -0
- package/template-vp-monorepo-react-nestjs/apps/web/README.MD +153 -0
- package/template-vp-monorepo-react-nestjs/apps/web/index.html +3 -2
- package/template-vp-monorepo-react-nestjs/apps/web/package.json +6 -1
- package/template-vp-monorepo-react-nestjs/apps/web/public/favicon.svg +9 -1
- package/template-vp-monorepo-react-nestjs/apps/web/src/App.module.css +5 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/App.tsx +16 -9
- package/template-vp-monorepo-react-nestjs/apps/web/src/api/auth.ts +9 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/assets/svg/draft.svg +4 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/DraftProTable/DraftProTable.module.css +78 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/DraftProTable/DraftProTable.tsx +99 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/DraftProTable/README.md +34 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/FullHeightProTable/FullHeightProTable.module.css +54 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/FullHeightProTable/FullHeightProTable.tsx +41 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/Icon/svg-icon/README.md +37 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/Icon/svg-icon/SvgIcon.tsx +27 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/Loading/PageLoading.module.css +7 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/components/Loading/PageLoading.tsx +2 -1
- package/template-vp-monorepo-react-nestjs/apps/web/src/config/theme.ts +20 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/layouts/BasicLayout.module.css +17 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/layouts/BasicLayout.tsx +106 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/i18n/index.module.css +23 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/i18n/index.tsx +53 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/components/ProjectFormDialog.tsx +132 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/config/columns.tsx +121 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/config/index.ts +77 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/draft/components/DraftProjectFormDialog.tsx +140 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/draft/config/columns.tsx +127 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/draft/config/index.ts +39 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/draft/config/projects.ts +48 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/draft/index.module.css +49 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/draft/index.tsx +163 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/index.module.css +53 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/examples/pro-table/index.tsx +135 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/home/index.module.css +23 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/home/index.tsx +26 -43
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/login/api.ts +11 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/login/index.tsx +183 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/pages/login/login.css +164 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/router/index.tsx +36 -12
- package/template-vp-monorepo-react-nestjs/apps/web/src/styles/index.css +11 -4
- package/template-vp-monorepo-react-nestjs/apps/web/src/utils/request/core/index.ts +55 -47
- package/template-vp-monorepo-react-nestjs/apps/web/src/utils/request/index.ts +10 -5
- package/template-vp-monorepo-react-nestjs/apps/web/src/utils/storage/cookie.ts +50 -0
- package/template-vp-monorepo-react-nestjs/apps/web/src/utils/storage/session.ts +33 -0
- package/template-vp-monorepo-react-nestjs/apps/web/test/draft-projects.spec.ts +89 -0
- package/template-vp-monorepo-react-nestjs/apps/web/test/request.spec.ts +145 -0
- package/template-vp-monorepo-react-nestjs/apps/web/test/storage.spec.ts +108 -0
- package/template-vp-monorepo-react-nestjs/apps/web/test/tsconfig.json +7 -0
- package/template-vp-monorepo-react-nestjs/apps/web/tsconfig.json +1 -1
- package/template-vp-monorepo-react-nestjs/apps/web/vite.config.ts +7 -0
- package/template-vp-monorepo-react-nestjs/apps/web-vue/tsconfig.tsbuildinfo +1 -0
- package/template-vp-monorepo-react-nestjs/docker-compose.yml +19 -0
- package/template-vp-monorepo-react-nestjs/mise.toml +1 -1
- package/template-vp-monorepo-react-nestjs/package.json +1 -6
- package/template-vp-monorepo-react-nestjs/pnpm-workspace.yaml +9 -1
- package/template-vp-react/.agents/rules/SVG/344/275/277/347/224/250.md +8 -0
- package/template-vp-react/AGENTS.md +11 -0
- package/template-vp-react/commitlint.config.js +0 -0
- package/template-vp-react/package.json +21 -26
- package/template-vp-react/pnpm-workspace.yaml +6 -0
- package/template-vp-react/src/assets/svg/draft.svg +4 -0
- package/template-vp-react/src/components/Icon/svg-icon/README.md +37 -0
- package/template-vp-react/src/components/Icon/svg-icon/SvgIcon.tsx +27 -0
- package/template-vp-react/src/utils/request/index.ts +18 -5
- package/template-vp-react/tsconfig.json +2 -3
- package/template-vp-react/vite.config.ts +2 -0
- package/template-vp-react-shadcn/.agents/rules/SVG/344/275/277/347/224/250.md +8 -0
- package/template-vp-react-shadcn/.vscode/settings.json +2 -2
- package/template-vp-react-shadcn/{agents.md → AGENTS.md} +12 -2
- package/template-vp-react-shadcn/README.md +41 -0
- package/template-vp-react-shadcn/commitlint.config.js +1 -1
- package/template-vp-react-shadcn/components.json +1 -1
- package/template-vp-react-shadcn/package.json +25 -32
- package/template-vp-react-shadcn/pnpm-workspace.yaml +10 -0
- package/template-vp-react-shadcn/src/App.tsx +10 -10
- package/template-vp-react-shadcn/src/assets/svg/draft.svg +4 -0
- package/template-vp-react-shadcn/src/components/Icon/svg-icon/README.md +37 -0
- package/template-vp-react-shadcn/src/components/Icon/svg-icon/SvgIcon.tsx +27 -0
- package/template-vp-react-shadcn/src/components/Loading/PageLoading.tsx +4 -4
- package/template-vp-react-shadcn/src/components/Player/VideoJS/index.tsx +94 -78
- package/template-vp-react-shadcn/src/components/Player/index.ts +1 -1
- package/template-vp-react-shadcn/src/components/ui/button.tsx +25 -32
- package/template-vp-react-shadcn/src/components/ui/spinner.tsx +8 -7
- package/template-vp-react-shadcn/src/components/ui/toast.tsx +229 -0
- package/template-vp-react-shadcn/src/lib/utils.ts +3 -3
- package/template-vp-react-shadcn/src/main.tsx +5 -4
- package/template-vp-react-shadcn/src/pages/home/index.tsx +43 -35
- package/template-vp-react-shadcn/src/router/index.tsx +15 -15
- package/template-vp-react-shadcn/src/styles/index.css +4 -4
- package/template-vp-react-shadcn/src/styles/shadcn.css +2 -2
- package/template-vp-react-shadcn/src/utils/env/index.tsx +2 -2
- package/template-vp-react-shadcn/src/utils/request/alova-core/index.ts +102 -30
- package/template-vp-react-shadcn/src/utils/request/alova-core/utils.ts +5 -2
- package/template-vp-react-shadcn/src/utils/request/index.ts +32 -19
- package/template-vp-react-shadcn/src/utils/request/readme.md +41 -38
- package/template-vp-react-shadcn/tsconfig.json +2 -3
- package/template-vp-react-shadcn/vite.config.ts +29 -15
- package/template-vp-vue-eslint-vapor/package.json +26 -33
- package/template-vp-vue-eslint-vapor/pnpm-workspace.yaml +29 -1
- package/template-vue-vp-eslint/README.md +3 -10
- package/template-vue-vp-eslint/package.json +27 -34
- package/template-vue-vp-eslint/pnpm-workspace.yaml +27 -2
- package/template-vue-vp-eslint/src/layout/default/index.vue +4 -3
- package/template-vp-monorepo-react-nestjs/.agents/auth.config.ts +0 -0
- package/template-vp-monorepo-react-nestjs/.spaces/server/todo.md +0 -991
- package/template-vp-monorepo-react-nestjs/apps/server/README.md +0 -3
- package/template-vp-react-shadcn/.oxfmtrc.jsonc +0 -8
- package/template-vp-react-shadcn/.oxlintrc.jsonc +0 -3
- package/template-vp-react-shadcn/src/components/ui/sonner.tsx +0 -43
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { AppstoreOutlined, ArrowRightOutlined, LockOutlined, UserOutlined } from '@ant-design/icons'
|
|
2
|
+
import { LoginForm, ProFormText } from '@ant-design/pro-components'
|
|
3
|
+
import { useRequest } from 'alova/client'
|
|
4
|
+
import { Alert } from 'antd'
|
|
5
|
+
import { useState } from 'react'
|
|
6
|
+
import { useNavigate } from 'react-router'
|
|
7
|
+
import type { LoginRequest } from 'shared/types'
|
|
8
|
+
import { ACCOUNT_PATTERN, normalizeAccount } from 'shared/utils'
|
|
9
|
+
import { cookie } from '@/utils/storage/cookie'
|
|
10
|
+
import { login } from './api'
|
|
11
|
+
import './login.css'
|
|
12
|
+
|
|
13
|
+
function ModuleDrawing() {
|
|
14
|
+
return (
|
|
15
|
+
<svg className="login-drawing" viewBox="0 0 540 360" fill="none" aria-hidden="true">
|
|
16
|
+
<g stroke="currentColor" strokeWidth="1.5">
|
|
17
|
+
<path d="M156 88h38a24 24 0 0 1 24 24v30M322 180h52a24 24 0 0 0 24-24v-28M218 218v38a24 24 0 0 1-24 24h-54M322 218v50a24 24 0 0 0 24 24h54" />
|
|
18
|
+
<path
|
|
19
|
+
d="M100 130v58a24 24 0 0 0 24 24h42M444 240v-28a24 24 0 0 0-24-24h-46"
|
|
20
|
+
strokeDasharray="4 7"
|
|
21
|
+
opacity=".35"
|
|
22
|
+
/>
|
|
23
|
+
<g fill="var(--login-panel-bg)">
|
|
24
|
+
<rect x="52" y="46" width="104" height="84" rx="12" />
|
|
25
|
+
<rect x="354" y="48" width="104" height="80" rx="12" />
|
|
26
|
+
<rect x="60" y="244" width="80" height="72" rx="12" />
|
|
27
|
+
<rect x="396" y="248" width="88" height="68" rx="12" />
|
|
28
|
+
</g>
|
|
29
|
+
<path
|
|
30
|
+
d="M76 72h24v24H76zM112 72h20M112 84h12M112 96h20M378 74h56M378 88h36M378 102h46M80 264h40M80 278h24M80 292h32"
|
|
31
|
+
opacity=".7"
|
|
32
|
+
/>
|
|
33
|
+
<circle cx="440" cy="282" r="14" />
|
|
34
|
+
<path d="m434 282 4 4 8-9" stroke="var(--login-accent)" />
|
|
35
|
+
<rect
|
|
36
|
+
x="218"
|
|
37
|
+
y="128"
|
|
38
|
+
width="104"
|
|
39
|
+
height="104"
|
|
40
|
+
rx="20"
|
|
41
|
+
fill="var(--login-panel-bg)"
|
|
42
|
+
stroke="var(--login-accent)"
|
|
43
|
+
/>
|
|
44
|
+
<g stroke="var(--login-accent)" strokeWidth="2">
|
|
45
|
+
<rect x="244" y="154" width="20" height="20" rx="3" />
|
|
46
|
+
<rect x="276" y="154" width="20" height="20" rx="3" />
|
|
47
|
+
<rect x="244" y="186" width="20" height="20" rx="3" />
|
|
48
|
+
<rect x="276" y="186" width="20" height="20" rx="3" />
|
|
49
|
+
</g>
|
|
50
|
+
<g fill="var(--login-accent)" stroke="none">
|
|
51
|
+
<circle cx="194" cy="88" r="3" />
|
|
52
|
+
<circle cx="374" cy="180" r="3" />
|
|
53
|
+
<circle cx="218" cy="256" r="3" />
|
|
54
|
+
</g>
|
|
55
|
+
</g>
|
|
56
|
+
</svg>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default function LoginPage() {
|
|
61
|
+
const navigate = useNavigate()
|
|
62
|
+
const { send, loading } = useRequest(login, { immediate: false })
|
|
63
|
+
const [error, setError] = useState<string | null>(null)
|
|
64
|
+
|
|
65
|
+
async function handleLogin(values: LoginRequest) {
|
|
66
|
+
if (loading) return false
|
|
67
|
+
setError(null)
|
|
68
|
+
try {
|
|
69
|
+
const result = await send({
|
|
70
|
+
account: normalizeAccount(values.account),
|
|
71
|
+
password: values.password,
|
|
72
|
+
})
|
|
73
|
+
cookie.set('token', result.accessToken, {
|
|
74
|
+
expires: new Date(result.absoluteExpiresAt),
|
|
75
|
+
})
|
|
76
|
+
void navigate('/home', { replace: true })
|
|
77
|
+
return true
|
|
78
|
+
} catch (cause) {
|
|
79
|
+
setError(cause instanceof Error ? cause.message : '登录失败,请稍后重试')
|
|
80
|
+
return false
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<main className="login-page">
|
|
86
|
+
<title>登录 - 通用平台</title>
|
|
87
|
+
<section className="login-brand-panel" aria-label="通用平台">
|
|
88
|
+
<div className="login-brand">
|
|
89
|
+
<AppstoreOutlined />
|
|
90
|
+
<span>通用平台</span>
|
|
91
|
+
</div>
|
|
92
|
+
<div className="login-story">
|
|
93
|
+
<p className="login-eyebrow">UNIVERSAL PLATFORM</p>
|
|
94
|
+
<h1>
|
|
95
|
+
连接业务,
|
|
96
|
+
<br />
|
|
97
|
+
从这里开始。
|
|
98
|
+
</h1>
|
|
99
|
+
<ModuleDrawing />
|
|
100
|
+
</div>
|
|
101
|
+
<div className="login-brand-footer">
|
|
102
|
+
<span>一个平台,多种可能</span>
|
|
103
|
+
<span>UNIVERSAL PLATFORM</span>
|
|
104
|
+
</div>
|
|
105
|
+
</section>
|
|
106
|
+
|
|
107
|
+
<section className="login-form-panel" aria-labelledby="login-title">
|
|
108
|
+
<div className="login-form-content">
|
|
109
|
+
<p className="login-form-eyebrow">WORKSPACE</p>
|
|
110
|
+
<h2 id="login-title">登录工作台</h2>
|
|
111
|
+
<p className="login-description">欢迎回来,请使用平台账号登录。</p>
|
|
112
|
+
<LoginForm<LoginRequest>
|
|
113
|
+
autoFocusFirstInput={false}
|
|
114
|
+
requiredMark={false}
|
|
115
|
+
contentStyle={{ width: '100%', minWidth: 0 }}
|
|
116
|
+
containerStyle={{ padding: 0, minWidth: 0 }}
|
|
117
|
+
onFinish={handleLogin}
|
|
118
|
+
onValuesChange={() => {
|
|
119
|
+
if (error) setError(null)
|
|
120
|
+
}}
|
|
121
|
+
submitter={{
|
|
122
|
+
searchConfig: { submitText: '登录' },
|
|
123
|
+
submitButtonProps: {
|
|
124
|
+
size: 'large',
|
|
125
|
+
loading,
|
|
126
|
+
icon: <ArrowRightOutlined />,
|
|
127
|
+
iconPlacement: 'end',
|
|
128
|
+
},
|
|
129
|
+
}}
|
|
130
|
+
>
|
|
131
|
+
{error && (
|
|
132
|
+
<Alert className="login-error" type="error" showIcon title={error} role="alert" />
|
|
133
|
+
)}
|
|
134
|
+
<ProFormText
|
|
135
|
+
name="account"
|
|
136
|
+
label="账号"
|
|
137
|
+
placeholder="请输入账号"
|
|
138
|
+
fieldProps={{
|
|
139
|
+
prefix: <UserOutlined />,
|
|
140
|
+
autoComplete: 'username',
|
|
141
|
+
maxLength: 32,
|
|
142
|
+
size: 'large',
|
|
143
|
+
autoCapitalize: 'none',
|
|
144
|
+
spellCheck: false,
|
|
145
|
+
}}
|
|
146
|
+
rules={[
|
|
147
|
+
{ required: true, whitespace: true, message: '请输入账号' },
|
|
148
|
+
{
|
|
149
|
+
min: 4,
|
|
150
|
+
max: 32,
|
|
151
|
+
transform: (value: string) => value?.trim(),
|
|
152
|
+
message: '账号长度为 4–32 位',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
pattern: ACCOUNT_PATTERN,
|
|
156
|
+
transform: (value: string) => value?.trim(),
|
|
157
|
+
message: '账号仅支持字母、数字和下划线',
|
|
158
|
+
},
|
|
159
|
+
]}
|
|
160
|
+
/>
|
|
161
|
+
<ProFormText.Password
|
|
162
|
+
name="password"
|
|
163
|
+
label="密码"
|
|
164
|
+
placeholder="请输入密码"
|
|
165
|
+
fieldProps={{
|
|
166
|
+
prefix: <LockOutlined />,
|
|
167
|
+
autoComplete: 'current-password',
|
|
168
|
+
maxLength: 128,
|
|
169
|
+
size: 'large',
|
|
170
|
+
}}
|
|
171
|
+
rules={[
|
|
172
|
+
{ required: true, message: '请输入密码' },
|
|
173
|
+
{ max: 128, message: '密码不能超过 128 位' },
|
|
174
|
+
]}
|
|
175
|
+
/>
|
|
176
|
+
</LoginForm>
|
|
177
|
+
<p className="login-account-hint">请使用已开通的账号,账号区分于显示名称。</p>
|
|
178
|
+
</div>
|
|
179
|
+
<footer className="login-footer">通用平台 · 业务工作空间</footer>
|
|
180
|
+
</section>
|
|
181
|
+
</main>
|
|
182
|
+
)
|
|
183
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.login-page {
|
|
3
|
+
--login-panel-bg: #102f40;
|
|
4
|
+
--login-accent: #7dd4ce;
|
|
5
|
+
display: grid;
|
|
6
|
+
grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
|
|
7
|
+
min-height: 100vh;
|
|
8
|
+
min-height: 100svh;
|
|
9
|
+
background: #fff;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.login-brand-panel {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
justify-content: space-between;
|
|
16
|
+
padding: 40px 56px 28px;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
color: #e3f1f4;
|
|
19
|
+
background-color: var(--login-panel-bg);
|
|
20
|
+
background-image:
|
|
21
|
+
linear-gradient(#ffffff03 1px, transparent 1px),
|
|
22
|
+
linear-gradient(90deg, #ffffff03 1px, transparent 1px);
|
|
23
|
+
background-size: 32px 32px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.login-brand {
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
gap: 12px;
|
|
30
|
+
font-size: 20px;
|
|
31
|
+
font-weight: 600;
|
|
32
|
+
letter-spacing: 0.06em;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.login-brand > .anticon {
|
|
36
|
+
color: var(--login-accent);
|
|
37
|
+
font-size: 28px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.login-story {
|
|
41
|
+
width: 100%;
|
|
42
|
+
max-width: 540px;
|
|
43
|
+
margin: 40px auto 24px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.login-eyebrow,
|
|
47
|
+
.login-form-eyebrow {
|
|
48
|
+
font-family: Bahnschrift, 'Segoe UI', sans-serif;
|
|
49
|
+
font-size: 11px;
|
|
50
|
+
letter-spacing: 0.16em;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.login-eyebrow {
|
|
54
|
+
margin-bottom: 20px;
|
|
55
|
+
color: #a8c4cc;
|
|
56
|
+
}
|
|
57
|
+
.login-story h1 {
|
|
58
|
+
margin: 0;
|
|
59
|
+
font-size: clamp(32px, 3.2vw, 48px);
|
|
60
|
+
font-weight: 500;
|
|
61
|
+
line-height: 1.5;
|
|
62
|
+
letter-spacing: 0.06em;
|
|
63
|
+
}
|
|
64
|
+
.login-drawing {
|
|
65
|
+
display: block;
|
|
66
|
+
width: 100%;
|
|
67
|
+
max-height: 310px;
|
|
68
|
+
margin-top: 20px;
|
|
69
|
+
color: #6d9cae;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.login-brand-footer {
|
|
73
|
+
display: flex;
|
|
74
|
+
justify-content: space-between;
|
|
75
|
+
gap: 20px;
|
|
76
|
+
color: #a8c4cc;
|
|
77
|
+
font-size: 11px;
|
|
78
|
+
letter-spacing: 0.08em;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.login-form-panel {
|
|
82
|
+
position: relative;
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
padding: 88px 40px 112px;
|
|
87
|
+
}
|
|
88
|
+
.login-form-content {
|
|
89
|
+
width: 100%;
|
|
90
|
+
max-width: 368px;
|
|
91
|
+
}
|
|
92
|
+
.login-form-eyebrow {
|
|
93
|
+
margin: 0 0 14px;
|
|
94
|
+
color: var(--ant-color-primary);
|
|
95
|
+
}
|
|
96
|
+
.login-form-content h2 {
|
|
97
|
+
margin: 0 0 12px;
|
|
98
|
+
font-size: 30px;
|
|
99
|
+
font-weight: 600;
|
|
100
|
+
letter-spacing: 0.02em;
|
|
101
|
+
}
|
|
102
|
+
.login-description {
|
|
103
|
+
margin: 0 0 36px;
|
|
104
|
+
color: var(--ant-color-text-secondary);
|
|
105
|
+
}
|
|
106
|
+
.login-error {
|
|
107
|
+
margin-bottom: 24px;
|
|
108
|
+
}
|
|
109
|
+
.login-form-content .ant-form-item {
|
|
110
|
+
margin-bottom: 24px;
|
|
111
|
+
}
|
|
112
|
+
.login-form-content .ant-input-prefix {
|
|
113
|
+
margin-inline-end: 10px;
|
|
114
|
+
color: var(--ant-color-text-tertiary);
|
|
115
|
+
}
|
|
116
|
+
.login-form-content .ant-btn-primary {
|
|
117
|
+
height: 44px;
|
|
118
|
+
margin-top: 8px;
|
|
119
|
+
box-shadow: none;
|
|
120
|
+
}
|
|
121
|
+
.login-account-hint {
|
|
122
|
+
margin: 24px 0 0;
|
|
123
|
+
color: var(--ant-color-text-secondary);
|
|
124
|
+
font-size: 12px;
|
|
125
|
+
text-align: center;
|
|
126
|
+
}
|
|
127
|
+
.login-footer {
|
|
128
|
+
position: absolute;
|
|
129
|
+
bottom: 28px;
|
|
130
|
+
inset-inline: 24px;
|
|
131
|
+
color: var(--ant-color-text-tertiary);
|
|
132
|
+
font-size: 12px;
|
|
133
|
+
text-align: center;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@media (max-width: 1023px) {
|
|
138
|
+
.login-brand-panel {
|
|
139
|
+
padding-inline: 32px;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@media (max-width: 767px) {
|
|
144
|
+
.login-page {
|
|
145
|
+
grid-template-columns: 1fr;
|
|
146
|
+
grid-template-rows: auto 1fr;
|
|
147
|
+
}
|
|
148
|
+
.login-brand-panel {
|
|
149
|
+
padding: 24px;
|
|
150
|
+
}
|
|
151
|
+
.login-brand {
|
|
152
|
+
font-size: 18px;
|
|
153
|
+
}
|
|
154
|
+
.login-story,
|
|
155
|
+
.login-brand-footer {
|
|
156
|
+
display: none;
|
|
157
|
+
}
|
|
158
|
+
.login-form-panel {
|
|
159
|
+
padding: 52px 24px 92px;
|
|
160
|
+
}
|
|
161
|
+
.login-form-content h2 {
|
|
162
|
+
font-size: 28px;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -1,20 +1,44 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Button, Result } from 'antd'
|
|
2
|
+
import { lazy } from 'react'
|
|
3
|
+
import { createBrowserRouter, Link, Navigate, type RouteObject } from 'react-router'
|
|
4
|
+
import BasicLayout from '@/layouts/BasicLayout'
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
const Home = lazy(() => import('@/pages/home'))
|
|
7
|
+
const I18nExample = lazy(() => import('@/pages/examples/i18n'))
|
|
8
|
+
const ProTableExample = lazy(() => import('@/pages/examples/pro-table'))
|
|
9
|
+
const ProTableDraftExample = lazy(() => import('@/pages/examples/pro-table/draft'))
|
|
10
|
+
const Login = lazy(() => import('@/pages/login'))
|
|
7
11
|
|
|
8
12
|
const routes: RouteObject[] = [
|
|
9
13
|
{
|
|
10
|
-
path: '/',
|
|
11
|
-
|
|
12
|
-
element: <Navigate to={'/home'} />,
|
|
14
|
+
path: '/login',
|
|
15
|
+
element: <Login />,
|
|
13
16
|
},
|
|
14
17
|
{
|
|
15
|
-
path: '/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
path: '/',
|
|
19
|
+
element: <BasicLayout />,
|
|
20
|
+
children: [
|
|
21
|
+
{ index: true, element: <Navigate to="/home" replace /> },
|
|
22
|
+
{ path: 'home', element: <Home /> },
|
|
23
|
+
{ path: 'examples/pro-table', element: <ProTableExample /> },
|
|
24
|
+
{ path: 'examples/pro-table/draft', element: <ProTableDraftExample /> },
|
|
25
|
+
{ path: 'examples/i18n', element: <I18nExample /> },
|
|
26
|
+
{
|
|
27
|
+
path: '*',
|
|
28
|
+
element: (
|
|
29
|
+
<Result
|
|
30
|
+
status="404"
|
|
31
|
+
title="404"
|
|
32
|
+
subTitle="页面不存在,请检查地址或返回工作台。"
|
|
33
|
+
extra={
|
|
34
|
+
<Link to="/home">
|
|
35
|
+
<Button type="primary">返回工作台</Button>
|
|
36
|
+
</Link>
|
|
37
|
+
}
|
|
38
|
+
/>
|
|
39
|
+
),
|
|
40
|
+
},
|
|
41
|
+
],
|
|
18
42
|
},
|
|
19
43
|
]
|
|
20
44
|
|
|
@@ -22,4 +46,4 @@ export const router = createBrowserRouter(routes, {
|
|
|
22
46
|
basename: '/',
|
|
23
47
|
})
|
|
24
48
|
|
|
25
|
-
export const navigator = router.navigate
|
|
49
|
+
export const navigator = router.navigate.bind(router)
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
@layer theme, base, antd, antd-pro, components, utilities;
|
|
2
|
+
|
|
3
|
+
@import 'antd/dist/reset.css' layer(base);
|
|
1
4
|
@import 'tailwindcss';
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
@layer base {
|
|
7
|
+
html,
|
|
8
|
+
body,
|
|
9
|
+
#root {
|
|
10
|
+
min-width: 320px;
|
|
11
|
+
min-height: 100%;
|
|
12
|
+
margin: 0;
|
|
13
|
+
}
|
|
7
14
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { axiosRequestAdapter, type AlovaAxiosRequestConfig } from '@alova/adapter-axios'
|
|
1
2
|
import type {
|
|
2
3
|
AlovaGlobalCacheAdapter,
|
|
3
4
|
AlovaOptions,
|
|
@@ -7,8 +8,7 @@ import type {
|
|
|
7
8
|
StatesHook,
|
|
8
9
|
} from 'alova'
|
|
9
10
|
import { createAlova } from 'alova'
|
|
10
|
-
import type {
|
|
11
|
-
import adapterFetch from 'alova/fetch'
|
|
11
|
+
import type { AxiosResponse, AxiosResponseHeaders } from 'axios'
|
|
12
12
|
import { deepMergeObject, isPlainObject, isReadableStream, tryParseJsonString } from './utils.ts'
|
|
13
13
|
|
|
14
14
|
type MaybePromise<T> = T | Promise<T>
|
|
@@ -23,7 +23,6 @@ type StatusMatcher<RE> = number | number[] | ((status: number, response: RE) =>
|
|
|
23
23
|
type CodeMatcher = Array<number | string>
|
|
24
24
|
|
|
25
25
|
export interface StatusMap<RE = unknown> {
|
|
26
|
-
success?: StatusMatcher<RE>
|
|
27
26
|
unAuthorized?: StatusMatcher<RE>
|
|
28
27
|
}
|
|
29
28
|
|
|
@@ -40,9 +39,9 @@ export interface RequestMeta {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
export interface BaseRequestOption<
|
|
43
|
-
RC extends object =
|
|
44
|
-
RE =
|
|
45
|
-
RH =
|
|
42
|
+
RC extends object = AlovaAxiosRequestConfig,
|
|
43
|
+
RE = AxiosResponse,
|
|
44
|
+
RH = AxiosResponseHeaders,
|
|
46
45
|
SE extends StatesExport<any> = StatesExport<any>,
|
|
47
46
|
> extends RequestMeta {
|
|
48
47
|
baseUrl?: string
|
|
@@ -60,7 +59,8 @@ export interface BaseRequestOption<
|
|
|
60
59
|
errorDefaultMessage?: string
|
|
61
60
|
successMessageFunc?: (message: string) => void
|
|
62
61
|
errorMessageFunc?: (message: string) => void
|
|
63
|
-
unAuthorizedResponseFunc?: () => void
|
|
62
|
+
unAuthorizedResponseFunc?: (response: RE) => void
|
|
63
|
+
/** 默认使用 Axios;自定义适配器也须拒绝 HTTP 错误,并通过 error.response 提供响应。 */
|
|
64
64
|
requestAdapter?: AlovaRequestAdapter<RC, RE, RH>
|
|
65
65
|
l1Cache?: AlovaGlobalCacheAdapter
|
|
66
66
|
l2Cache?: AlovaGlobalCacheAdapter
|
|
@@ -68,16 +68,16 @@ export interface BaseRequestOption<
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export type baseRequestOption<
|
|
71
|
-
RC extends object =
|
|
72
|
-
RE =
|
|
73
|
-
RH =
|
|
71
|
+
RC extends object = AlovaAxiosRequestConfig,
|
|
72
|
+
RE = AxiosResponse,
|
|
73
|
+
RH = AxiosResponseHeaders,
|
|
74
74
|
SE extends StatesExport<any> = StatesExport<any>,
|
|
75
75
|
> = BaseRequestOption<RC, RE, RH, SE>
|
|
76
76
|
|
|
77
77
|
export type RequestOption<
|
|
78
|
-
RC extends object =
|
|
79
|
-
RE =
|
|
80
|
-
RH =
|
|
78
|
+
RC extends object = AlovaAxiosRequestConfig,
|
|
79
|
+
RE = AxiosResponse,
|
|
80
|
+
RH = AxiosResponseHeaders,
|
|
81
81
|
SE extends StatesExport<any> = StatesExport<any>,
|
|
82
82
|
> = BaseRequestOption<RC, RE, RH, SE>
|
|
83
83
|
|
|
@@ -119,7 +119,6 @@ const defaultRequestOption: BaseRequestOption<any, any, any, any> = {
|
|
|
119
119
|
baseUrl: '/',
|
|
120
120
|
timeout: undefined,
|
|
121
121
|
statusMap: {
|
|
122
|
-
success: 200,
|
|
123
122
|
unAuthorized: 401,
|
|
124
123
|
},
|
|
125
124
|
codeMap: {
|
|
@@ -137,7 +136,7 @@ const defaultRequestOption: BaseRequestOption<any, any, any, any> = {
|
|
|
137
136
|
errorDefaultMessage: DEFAULT_ERROR_MESSAGE,
|
|
138
137
|
cacheFor: null,
|
|
139
138
|
cacheLogger: true,
|
|
140
|
-
requestAdapter:
|
|
139
|
+
requestAdapter: axiosRequestAdapter(),
|
|
141
140
|
}
|
|
142
141
|
|
|
143
142
|
function getMethodMeta(method: unknown): RequestMeta {
|
|
@@ -155,7 +154,7 @@ function isMatchedStatus<RE>(
|
|
|
155
154
|
matcher: StatusMatcher<RE> | undefined,
|
|
156
155
|
response: RE,
|
|
157
156
|
): boolean {
|
|
158
|
-
if (matcher === undefined) return
|
|
157
|
+
if (matcher === undefined) return false
|
|
159
158
|
|
|
160
159
|
if (typeof matcher === 'function') return matcher(status, response)
|
|
161
160
|
|
|
@@ -283,13 +282,21 @@ function resolveConfig<RC extends object, RE, RH, SE extends StatesExport<any>>(
|
|
|
283
282
|
}
|
|
284
283
|
|
|
285
284
|
export function createInstance<
|
|
286
|
-
RC extends object =
|
|
287
|
-
RE =
|
|
288
|
-
RH =
|
|
285
|
+
RC extends object = AlovaAxiosRequestConfig,
|
|
286
|
+
RE = AxiosResponse,
|
|
287
|
+
RH = AxiosResponseHeaders,
|
|
289
288
|
SE extends StatesExport<any> = StatesExport<any>,
|
|
290
289
|
>(option: RequestOption<RC, RE, RH, SE> = {}) {
|
|
291
290
|
const config = resolveConfig(option)
|
|
292
291
|
|
|
292
|
+
function responseError(data: unknown, status: number) {
|
|
293
|
+
const code = getResponseField(data, config.responseCodeKey)
|
|
294
|
+
return Object.assign(
|
|
295
|
+
new Error(getResponseMessage(data, config.responseMessageKey, config.errorDefaultMessage)),
|
|
296
|
+
{ status, code: typeof code === 'string' || typeof code === 'number' ? code : undefined },
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
|
|
293
300
|
const alovaOptions: AlovaOptions<RequestAlovaGenerics<RC, RE, RH, SE>> = {
|
|
294
301
|
baseURL: config.baseUrl,
|
|
295
302
|
timeout: config.timeout,
|
|
@@ -310,6 +317,7 @@ export function createInstance<
|
|
|
310
317
|
}
|
|
311
318
|
},
|
|
312
319
|
responded: {
|
|
320
|
+
// HTTP 成败由适配器判断;这里只解析成功响应并检查业务 code。
|
|
313
321
|
onSuccess: async (response, method) => {
|
|
314
322
|
const meta = getMethodMeta(method)
|
|
315
323
|
const shouldTransform = getMetaFlag(meta, 'isTransformResponse', config.isTransformResponse)
|
|
@@ -322,18 +330,6 @@ export function createInstance<
|
|
|
322
330
|
const status = getResponseStatus(response)
|
|
323
331
|
const data = await getResponseData(response)
|
|
324
332
|
|
|
325
|
-
if (!isMatchedStatus(status, config.statusMap.success, response)) {
|
|
326
|
-
if (isMatchedStatus(status, config.statusMap.unAuthorized, response))
|
|
327
|
-
config.unAuthorizedResponseFunc?.()
|
|
328
|
-
|
|
329
|
-
if (showError) {
|
|
330
|
-
config.errorMessageFunc?.(
|
|
331
|
-
getResponseMessage(data, config.responseMessageKey, config.errorDefaultMessage),
|
|
332
|
-
)
|
|
333
|
-
}
|
|
334
|
-
return Promise.reject(response)
|
|
335
|
-
}
|
|
336
|
-
|
|
337
333
|
if (!isWrapped) {
|
|
338
334
|
if (showSuccess) config.successMessageFunc?.(config.successDefaultMessage)
|
|
339
335
|
return data
|
|
@@ -348,30 +344,42 @@ export function createInstance<
|
|
|
348
344
|
)
|
|
349
345
|
|
|
350
346
|
if (!isMatchedCode(code, config.codeMap.success)) {
|
|
351
|
-
if (isMatchedCode(code, config.codeMap.unAuthorized))
|
|
347
|
+
if (isMatchedCode(code, config.codeMap.unAuthorized))
|
|
348
|
+
config.unAuthorizedResponseFunc?.(response)
|
|
352
349
|
|
|
353
350
|
if (showError) {
|
|
354
351
|
config.errorMessageFunc?.(
|
|
355
352
|
getResponseMessage(data, config.responseMessageKey, config.errorDefaultMessage),
|
|
356
353
|
)
|
|
357
354
|
}
|
|
358
|
-
|
|
355
|
+
throw responseError(data, status)
|
|
359
356
|
}
|
|
360
357
|
|
|
361
358
|
if (showSuccess) config.successMessageFunc?.(responseMessage)
|
|
362
359
|
|
|
363
360
|
return responseData
|
|
364
361
|
},
|
|
365
|
-
|
|
362
|
+
// 统一处理 HTTP 错误、网络故障和超时;onSuccess 抛出的业务错误直接传给调用方。
|
|
363
|
+
onError: async (error, method) => {
|
|
366
364
|
const meta = getMethodMeta(method)
|
|
367
365
|
const showError = getMetaFlag(meta, 'isShowErrorMessage', config.isShowErrorMessage)
|
|
366
|
+
const response = (error as { response?: RE } | undefined)?.response
|
|
367
|
+
let failure: Error
|
|
368
|
+
|
|
369
|
+
if (response) {
|
|
370
|
+
const status = getResponseStatus(response)
|
|
371
|
+
if (isMatchedStatus(status, config.statusMap.unAuthorized, response)) {
|
|
372
|
+
config.unAuthorizedResponseFunc?.(response)
|
|
373
|
+
}
|
|
374
|
+
failure = responseError(await getResponseData(response), status)
|
|
375
|
+
} else {
|
|
376
|
+
failure = new Error('无法连接服务,请检查网络后重试')
|
|
377
|
+
}
|
|
368
378
|
|
|
369
379
|
if (showError) {
|
|
370
|
-
config.errorMessageFunc?.(
|
|
371
|
-
error instanceof Error ? error.message : config.errorDefaultMessage,
|
|
372
|
-
)
|
|
380
|
+
config.errorMessageFunc?.(failure.message)
|
|
373
381
|
}
|
|
374
|
-
|
|
382
|
+
throw failure
|
|
375
383
|
},
|
|
376
384
|
},
|
|
377
385
|
}
|
|
@@ -380,24 +388,24 @@ export function createInstance<
|
|
|
380
388
|
}
|
|
381
389
|
|
|
382
390
|
export type RequestInstance<
|
|
383
|
-
RC extends object =
|
|
384
|
-
RE =
|
|
385
|
-
RH =
|
|
391
|
+
RC extends object = AlovaAxiosRequestConfig,
|
|
392
|
+
RE = AxiosResponse,
|
|
393
|
+
RH = AxiosResponseHeaders,
|
|
386
394
|
SE extends StatesExport<any> = StatesExport<any>,
|
|
387
395
|
> = ReturnType<typeof createInstance<RC, RE, RH, SE>>
|
|
388
396
|
|
|
389
397
|
export type DualCallInstance<
|
|
390
|
-
RC extends object =
|
|
391
|
-
RE =
|
|
392
|
-
RH =
|
|
398
|
+
RC extends object = AlovaAxiosRequestConfig,
|
|
399
|
+
RE = AxiosResponse,
|
|
400
|
+
RH = AxiosResponseHeaders,
|
|
393
401
|
SE extends StatesExport<any> = StatesExport<any>,
|
|
394
402
|
> = RequestInstance<RC, RE, RH, SE> &
|
|
395
403
|
((option?: RequestOption<RC, RE, RH, SE>) => RequestInstance<RC, RE, RH, SE>)
|
|
396
404
|
|
|
397
405
|
export function createDualCallInstance<
|
|
398
|
-
RC extends object =
|
|
399
|
-
RE =
|
|
400
|
-
RH =
|
|
406
|
+
RC extends object = AlovaAxiosRequestConfig,
|
|
407
|
+
RE = AxiosResponse,
|
|
408
|
+
RH = AxiosResponseHeaders,
|
|
401
409
|
SE extends StatesExport<any> = StatesExport<any>,
|
|
402
410
|
>(baseConfig: BaseRequestOption<RC, RE, RH, SE>): DualCallInstance<RC, RE, RH, SE> {
|
|
403
411
|
const defaultInstance = createInstance(baseConfig)
|