create-bubbles 0.1.24 → 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 +15 -0
- package/package.json +1 -2
- 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/dist/index.mjs +0 -422
- 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)
|