From 39c9d184034cf00a2f65e1a10abaafba11916aae Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 15 Dec 2025 21:55:56 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E4=BC=98=E5=8C=96=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E7=9A=84=E4=BB=A3=E7=A0=81=EF=BC=8C=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E5=88=B0=20components=20=E7=9B=AE=E5=BD=95=E4=B8=8B?= =?UTF-8?q?=20feat=EF=BC=9A=E5=9C=A8=20register.vue=E3=80=81code-login.vue?= =?UTF-8?q?=20=E9=87=8C=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- env/.env | 2 +- pnpm-lock.yaml | 8 ++++ src/api/login.ts | 43 +++---------------- src/components/verifition/index.ts | 1 + .../verifition}/utils/ase.ts | 1 + .../verifition/verify.vue} | 4 +- .../verifition/verify/verify-points.vue} | 0 .../verifition/verify/verify-slide.vue} | 0 src/http/http.ts | 2 +- src/http/types.ts | 1 + src/pages/auth/code-login.vue | 32 ++++++++++++++ src/pages/auth/login.vue | 14 ++++-- src/pages/auth/register.vue | 32 ++++++++++++++ 13 files changed, 95 insertions(+), 45 deletions(-) create mode 100644 src/components/verifition/index.ts rename src/{pages/auth/components/Verifition => components/verifition}/utils/ase.ts (99%) rename src/{pages/auth/components/Verifition/Verify.vue => components/verifition/verify.vue} (99%) rename src/{pages/auth/components/Verifition/Verify/VerifyPoints.vue => components/verifition/verify/verify-points.vue} (100%) rename src/{pages/auth/components/Verifition/Verify/VerifySlide.vue => components/verifition/verify/verify-slide.vue} (100%) diff --git a/env/.env b/env/.env index 0b6c165..1506024 100644 --- a/env/.env +++ b/env/.env @@ -36,7 +36,7 @@ VITE_COPY_NATIVE_RES_ENABLE = false # 租户开关 VITE_APP_TENANT_ENABLE=true # 验证码的开关 -VITE_APP_CAPTCHA_ENABLE=true +VITE_APP_CAPTCHA_ENABLE=false # 默认账户密码 VITE_APP_DEFAULT_LOGIN_TENANT_ID = 1 VITE_APP_DEFAULT_LOGIN_USERNAME = admin diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8db9364..a46dc29 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,6 +63,9 @@ importers: abortcontroller-polyfill: specifier: ^1.7.8 version: 1.7.8 + crypto-js: + specifier: ^4.2.0 + version: 4.2.0 dayjs: specifier: 1.11.10 version: 1.11.10 @@ -2947,6 +2950,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + css-font-size-keywords@1.0.0: resolution: {integrity: sha512-Q+svMDbMlelgCfH/RVDKtTDaf5021O486ZThQPIpahnIjUkMUslC+WuOQSWTgGSrNCH08Y7tYNEmmy0hkfMI8Q==} @@ -9802,6 +9808,8 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crypto-js@4.2.0: {} + css-font-size-keywords@1.0.0: {} css-font-stretch-keywords@1.0.1: {} diff --git a/src/api/login.ts b/src/api/login.ts index 7766609..cbe69c8 100644 --- a/src/api/login.ts +++ b/src/api/login.ts @@ -65,19 +65,12 @@ export interface AuthResetPasswordReqVO { password: string } -/** - * 获取验证码 - * @returns ICaptcha 验证码 - */ +/** 获取验证码 */ export function getCode(data: any) { return http.post('/system/captcha/get', data, null, null, { original: true }) } -/** - * 校验验证码 - * @param data 验证码校验参数 - * @returns Promise 包含校验结果 - */ +/** 校验验证码 */ export function checkCaptcha(data: any) { return http.post('/system/captcha/check', data, null, null, { original: true }) } @@ -117,24 +110,12 @@ export function smsResetPassword(data: AuthResetPasswordReqVO) { return http.post('/system/auth/reset-password', data) } -/** - * 刷新token - * @param refreshToken 刷新token - */ +/** 刷新token */ export function refreshToken(refreshToken: string) { return http.post(`/system/auth/refresh-token?refreshToken=${refreshToken}`) } -/** - * 获取用户信息 - */ -export function getUserInfo() { - return http.get('/user/info') -} - -/** - * 获取权限信息 - */ +/** 获取权限信息 */ export function getAuthPermissionInfo() { return http.get('/system/auth/get-permission-info') } @@ -144,20 +125,7 @@ export function logout() { return http.post('/system/auth/logout') } -/** - * 修改用户信息 - */ -export function updateInfo(data: IUpdateInfo) { - return http.post('/user/updateInfo', data) -} - -/** - * 修改用户密码 - */ -export function updateUserPassword(data: IUpdatePassword) { - return http.post('/user/updatePassword', data) -} - +// TODO @芋艿:三方登录 /** * 获取微信登录凭证 * @returns Promise 包含微信登录凭证(code) @@ -172,6 +140,7 @@ export function getWxCode() { }) } +// TODO @芋艿:三方登录 /** * 微信登录 * @param params 微信登录参数,包含code diff --git a/src/components/verifition/index.ts b/src/components/verifition/index.ts new file mode 100644 index 0000000..e5dea27 --- /dev/null +++ b/src/components/verifition/index.ts @@ -0,0 +1 @@ +export { default as Verify } from './verify.vue' diff --git a/src/pages/auth/components/Verifition/utils/ase.ts b/src/components/verifition/utils/ase.ts similarity index 99% rename from src/pages/auth/components/Verifition/utils/ase.ts rename to src/components/verifition/utils/ase.ts index 12e0ffd..c5c76a4 100644 --- a/src/pages/auth/components/Verifition/utils/ase.ts +++ b/src/components/verifition/utils/ase.ts @@ -1,4 +1,5 @@ import CryptoJS from 'crypto-js' + /** * @word 要加密的内容 * @keyWord String 服务器随机返回的关键字 diff --git a/src/pages/auth/components/Verifition/Verify.vue b/src/components/verifition/verify.vue similarity index 99% rename from src/pages/auth/components/Verifition/Verify.vue rename to src/components/verifition/verify.vue index ce8a519..e93df89 100644 --- a/src/pages/auth/components/Verifition/Verify.vue +++ b/src/components/verifition/verify.vue @@ -29,8 +29,8 @@ * @description 分发验证码使用 */ import { computed, ref, watchEffect } from 'vue' -import VerifyPoints from './Verify/VerifyPoints.vue' -import VerifySlide from './Verify/VerifySlide.vue' +import VerifyPoints from './verify/verify-points.vue' +import VerifySlide from './verify/verify-slide.vue' defineOptions({ options: { diff --git a/src/pages/auth/components/Verifition/Verify/VerifyPoints.vue b/src/components/verifition/verify/verify-points.vue similarity index 100% rename from src/pages/auth/components/Verifition/Verify/VerifyPoints.vue rename to src/components/verifition/verify/verify-points.vue diff --git a/src/pages/auth/components/Verifition/Verify/VerifySlide.vue b/src/components/verifition/verify/verify-slide.vue similarity index 100% rename from src/pages/auth/components/Verifition/Verify/VerifySlide.vue rename to src/components/verifition/verify/verify-slide.vue diff --git a/src/http/http.ts b/src/http/http.ts index 9197799..de9d081 100644 --- a/src/http/http.ts +++ b/src/http/http.ts @@ -100,7 +100,7 @@ export function http(options: CustomRequestOptions) { // 处理其他成功状态(HTTP状态码200-299) if (res.statusCode >= 200 && res.statusCode < 300) { - // add by panda 25.12.10:如果设置了 original 为 true,则返回原始数据 + // add by panda 25.12.10:如果设置了 original 为 true,则返回原始数据。例如说:滑块验证码,有自己的返回格式 if (options.original) { return resolve(responseData as unknown as T) } diff --git a/src/http/types.ts b/src/http/types.ts index 46cf60d..c72f449 100644 --- a/src/http/types.ts +++ b/src/http/types.ts @@ -34,5 +34,6 @@ export interface PageResult { list: T[] total: number } + /** 加载状态枚举 - 从 wot-design-uni 重新导出 */ export type { LoadMoreState } from 'wot-design-uni/components/wd-loadmore/types' diff --git a/src/pages/auth/code-login.vue b/src/pages/auth/code-login.vue index 455f9d9..cd93c65 100644 --- a/src/pages/auth/code-login.vue +++ b/src/pages/auth/code-login.vue @@ -24,6 +24,16 @@ :scene="21" :before-send="validateBeforeSend" /> + + + @@ -51,6 +61,7 @@ import { isMobile } from "@/utils/validator"; import CodeInput from "./components/code-input.vue"; import Header from "./components/header.vue"; import TenantPicker from "./components/tenant-picker.vue"; +import { Verify } from '@/components/verifition'; defineOptions({ name: "SmsLoginPage", @@ -67,10 +78,14 @@ const toast = useToast(); const loading = ref(false); // 加载状态 const redirectUrl = ref(); // 重定向地址 const tenantPickerRef = ref>(); // 租户选择器引用 +const captchaEnabled = import.meta.env.VITE_APP_CAPTCHA_ENABLE === 'true'; // 验证码开关 +const verifyRef = ref(); +const captchaType = ref('blockPuzzle'); // 滑块验证码 blockPuzzle|clickWord const formData = reactive({ mobile: "", code: "", + captchaVerification: "", // 验证码校验值 }); // 表单数据 /** 页面加载时处理重定向 */ @@ -85,6 +100,18 @@ function validateBeforeSend(): boolean { return tenantPickerRef.value?.validate() ?? false; } +/** 获取验证码 */ +async function getCode() { + // 情况一,未开启:则直接登录 + if (!captchaEnabled) { + await verifySuccess({}); + } else { + // 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录 + // 弹出验证码 + verifyRef.value.show(); + } +} + /** 登录处理 */ async function handleLogin() { // 校验租户 @@ -103,11 +130,16 @@ async function handleLogin() { toast.warning("请输入验证码"); return; } + await getCode(); +} +/** 验证码验证成功回调 */ +async function verifySuccess(params: any) { loading.value = true; try { // 调用短信登录接口 const tokenStore = useTokenStore(); + formData.captchaVerification = params.captchaVerification; await tokenStore.login({ type: "sms", ...formData, diff --git a/src/pages/auth/login.vue b/src/pages/auth/login.vue index 0149df0..6837c75 100644 --- a/src/pages/auth/login.vue +++ b/src/pages/auth/login.vue @@ -29,10 +29,15 @@ + @@ -86,7 +91,7 @@ import { useTokenStore } from '@/store/token' import { ensureDecodeURIComponent, redirectAfterLogin } from '@/utils' import Header from './components/header.vue' import TenantPicker from './components/tenant-picker.vue' -import Verify from './components/Verifition/Verify.vue' +import { Verify } from '@/components/verifition'; defineOptions({ name: 'LoginPage', @@ -149,7 +154,8 @@ async function handleLogin() { } await getCode() } -async function verifySuccess(params) { + +async function verifySuccess(params: any) { loading.value = true try { // 调用登录接口 diff --git a/src/pages/auth/register.vue b/src/pages/auth/register.vue index a23764a..4f8341d 100644 --- a/src/pages/auth/register.vue +++ b/src/pages/auth/register.vue @@ -48,6 +48,16 @@ no-border /> + + + @@ -89,6 +99,7 @@ import { useTokenStore } from "@/store/token"; import { redirectAfterLogin } from "@/utils"; import Header from "./components/header.vue"; import TenantPicker from "./components/tenant-picker.vue"; +import { Verify } from '@/components/verifition'; defineOptions({ name: "RegisterPage", @@ -104,14 +115,30 @@ const toast = useToast(); const loading = ref(false); // 加载状态 const agreePolicy = ref(false); // 用户协议勾选 const tenantPickerRef = ref>(); // 租户选择器引用 +const captchaEnabled = import.meta.env.VITE_APP_CAPTCHA_ENABLE === 'true'; // 验证码开关 +const verifyRef = ref(); +const captchaType = ref('blockPuzzle'); // 滑块验证码 blockPuzzle|clickWord const formData = reactive({ username: "", nickname: "", password: "", confirmPassword: "", + captchaVerification: "", // 验证码校验值 }); // 表单数据 +/** 获取验证码 */ +async function getCode() { + // 情况一,未开启:则直接注册 + if (!captchaEnabled) { + await verifySuccess({}); + } else { + // 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行注册 + // 弹出验证码 + verifyRef.value.show(); + } +} + /** 注册处理 */ async function handleRegister() { if (!tenantPickerRef.value?.validate()) { @@ -141,11 +168,16 @@ async function handleRegister() { toast.warning("两次输入的密码不一致"); return; } + await getCode(); +} +/** 验证码验证成功回调 */ +async function verifySuccess(params: any) { loading.value = true; try { // 调用注册接口 const tokenStore = useTokenStore(); + formData.captchaVerification = params.captchaVerification; await tokenStore.login({ type: "register", ...formData,