feat:优化验证码的代码,迁移到 components 目录下
feat:在 register.vue、code-login.vue 里,增加验证码
This commit is contained in:
2
env/.env
vendored
2
env/.env
vendored
@@ -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
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -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: {}
|
||||
|
||||
@@ -65,19 +65,12 @@ export interface AuthResetPasswordReqVO {
|
||||
password: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
* @returns ICaptcha 验证码
|
||||
*/
|
||||
/** 获取验证码 */
|
||||
export function getCode(data: any) {
|
||||
return http.post<ICaptcha>('/system/captcha/get', data, null, null, { original: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
* @param data 验证码校验参数
|
||||
* @returns Promise 包含校验结果
|
||||
*/
|
||||
/** 校验验证码 */
|
||||
export function checkCaptcha(data: any) {
|
||||
return http.post<boolean>('/system/captcha/check', data, null, null, { original: true })
|
||||
}
|
||||
@@ -117,24 +110,12 @@ export function smsResetPassword(data: AuthResetPasswordReqVO) {
|
||||
return http.post<boolean>('/system/auth/reset-password', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
* @param refreshToken 刷新token
|
||||
*/
|
||||
/** 刷新token */
|
||||
export function refreshToken(refreshToken: string) {
|
||||
return http.post<IDoubleTokenRes>(`/system/auth/refresh-token?refreshToken=${refreshToken}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
export function getUserInfo() {
|
||||
return http.get<IUserInfoRes>('/user/info')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取权限信息
|
||||
*/
|
||||
/** 获取权限信息 */
|
||||
export function getAuthPermissionInfo() {
|
||||
return http.get<AuthPermissionInfo>('/system/auth/get-permission-info')
|
||||
}
|
||||
@@ -144,20 +125,7 @@ export function logout() {
|
||||
return http.post<void>('/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
|
||||
|
||||
1
src/components/verifition/index.ts
Normal file
1
src/components/verifition/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Verify } from './verify.vue'
|
||||
@@ -1,4 +1,5 @@
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
/**
|
||||
* @word 要加密的内容
|
||||
* @keyWord String 服务器随机返回的关键字
|
||||
@@ -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: {
|
||||
@@ -100,7 +100,7 @@ export function http<T>(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)
|
||||
}
|
||||
|
||||
@@ -34,5 +34,6 @@ export interface PageResult<T> {
|
||||
list: T[]
|
||||
total: number
|
||||
}
|
||||
|
||||
/** 加载状态枚举 - 从 wot-design-uni 重新导出 */
|
||||
export type { LoadMoreState } from 'wot-design-uni/components/wd-loadmore/types'
|
||||
|
||||
@@ -24,6 +24,16 @@
|
||||
:scene="21"
|
||||
:before-send="validateBeforeSend"
|
||||
/>
|
||||
<view v-if="captchaEnabled">
|
||||
<Verify
|
||||
ref="verifyRef"
|
||||
:captcha-type="captchaType"
|
||||
explain="向右滑动完成验证"
|
||||
:img-size="{ width: '300px', height: '150px' }"
|
||||
mode="pop"
|
||||
@success="verifySuccess"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 登录按钮 -->
|
||||
<view class="mb-2 mt-2 flex justify-between">
|
||||
@@ -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<string>(); // 重定向地址
|
||||
const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>(); // 租户选择器引用
|
||||
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,
|
||||
|
||||
@@ -29,10 +29,15 @@
|
||||
</view>
|
||||
<view v-if="captchaEnabled">
|
||||
<Verify
|
||||
ref="verifyRef" :captcha-type="captchaType" explain="向右滑动完成验证"
|
||||
:img-size="{ width: '300px', height: '150px' }" mode="pop" @success="verifySuccess"
|
||||
ref="verifyRef"
|
||||
:captcha-type="captchaType"
|
||||
explain="向右滑动完成验证"
|
||||
:img-size="{ width: '300px', height: '150px' }"
|
||||
mode="pop"
|
||||
@success="verifySuccess"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 登录按钮 -->
|
||||
<view class="mb-2 mt-2 flex justify-between">
|
||||
<text class="text-28rpx text-[#1890ff]" @click="goToSmsLogin">
|
||||
@@ -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 {
|
||||
// 调用登录接口
|
||||
|
||||
@@ -48,6 +48,16 @@
|
||||
no-border
|
||||
/>
|
||||
</view>
|
||||
<view v-if="captchaEnabled">
|
||||
<Verify
|
||||
ref="verifyRef"
|
||||
:captcha-type="captchaType"
|
||||
explain="向右滑动完成验证"
|
||||
:img-size="{ width: '300px', height: '150px' }"
|
||||
mode="pop"
|
||||
@success="verifySuccess"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 用户协议 -->
|
||||
<view class="mb-24rpx flex items-center">
|
||||
@@ -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<InstanceType<typeof TenantPicker>>(); // 租户选择器引用
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user