From 0441302f889ddee491e5773113f9e3e5aab9ba3b Mon Sep 17 00:00:00 2001 From: Zyronon Date: Thu, 13 Nov 2025 11:09:33 +0000 Subject: [PATCH] save --- src/apis/user.ts | 21 +- src/assets/css/style.scss | 2 +- src/components/base/BaseInput.vue | 27 ++ src/components/base/form/FormItem.vue | 1 - src/config/env.ts | 1 + src/pages/setting/Setting.vue | 4 +- src/pages/user/Code.vue | 66 +++ src/pages/user/User.vue | 565 ++++++++++++++++++++------ src/pages/user/login.vue | 123 ++---- src/stores/auth.ts | 13 +- src/types/types.ts | 3 + src/utils/validation.ts | 46 ++- 12 files changed, 647 insertions(+), 225 deletions(-) create mode 100644 src/pages/user/Code.vue diff --git a/src/apis/user.ts b/src/apis/user.ts index 49811367..04349fc2 100644 --- a/src/apis/user.ts +++ b/src/apis/user.ts @@ -1,5 +1,5 @@ import http from '@/utils/http.ts' -import { CodeType } from "@/types/types.ts"; +import {CodeType} from "@/types/types.ts"; // 用户登录接口 export interface LoginParams { @@ -88,6 +88,21 @@ export function getUserInfo() { } // 设置密码 -export function setPassword(password: string) { - return http('user/setPassword', {password}, null, 'post') +export function setPassword(data) { + return http('user/setPassword', data, null, 'post') +} + +// 修改邮箱 +export function changeEmailApi(data) { + return http('user/changeEmail', data, null, 'post') +} + +// 修改手机号 +export function changePhoneApi(data) { + return http('user/changePhone', data, null, 'post') +} + +// 修改用户信息 +export function updateUserInfoApi(data) { + return http('user/updateUserInfo', data, null, 'post') } diff --git a/src/assets/css/style.scss b/src/assets/css/style.scss index 3d783419..b56693b8 100644 --- a/src/assets/css/style.scss +++ b/src/assets/css/style.scss @@ -184,7 +184,7 @@ html, body { z-index: 1; height: 100%; width: 100%; - font-size: .9rem; + font-size: 1rem; display: flex; flex-direction: column; } diff --git a/src/components/base/BaseInput.vue b/src/components/base/BaseInput.vue index b3490a14..d57853b1 100644 --- a/src/components/base/BaseInput.vue +++ b/src/components/base/BaseInput.vue @@ -106,6 +106,15 @@ const vFocus = { ref="inputEl" :class="{ 'is-disabled': disabled, 'error': props.error, focus, [`base-input--${size}`]: true }"> + +
+ +
+ + + + + { if (rule.validator) { try { rule.validator(rule, val) - return true } catch (e) { error = e.message return false diff --git a/src/config/env.ts b/src/config/env.ts index 6409b952..efacd189 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -1,5 +1,6 @@ export const GITHUB = 'https://github.com/zyronon/TypeWords' export const Host = '2study.top' +export const EMAIL = 'zyronon@163.com' export const Origin = `https://${Host}` export const APP_NAME = 'Type Words' diff --git a/src/pages/setting/Setting.vue b/src/pages/setting/Setting.vue index dcc2c1c6..d6124324 100644 --- a/src/pages/setting/Setting.vue +++ b/src/pages/setting/Setting.vue @@ -10,7 +10,7 @@ import VolumeIcon from "@/components/icon/VolumeIcon.vue"; import {useBaseStore} from "@/stores/base.ts"; import {saveAs} from "file-saver"; import { - APP_NAME, APP_VERSION, + APP_NAME, APP_VERSION, EMAIL, EXPORT_DATA_KEY, GITHUB, LOCAL_FILE_KEY, Origin, @@ -824,7 +824,7 @@ function importOldData() { 反馈:{{ GITHUB }}/issues

- 作者邮箱:zyronon@163.com + 作者邮箱:{{ EMAIL }}

Build {{ gitLastCommitHash }} diff --git a/src/pages/user/Code.vue b/src/pages/user/Code.vue new file mode 100644 index 00000000..3bc85f23 --- /dev/null +++ b/src/pages/user/Code.vue @@ -0,0 +1,66 @@ + + + + + \ No newline at end of file diff --git a/src/pages/user/User.vue b/src/pages/user/User.vue index a9a59c2a..687fb777 100644 --- a/src/pages/user/User.vue +++ b/src/pages/user/User.vue @@ -1,14 +1,24 @@ \ No newline at end of file + + \ No newline at end of file diff --git a/src/pages/user/login.vue b/src/pages/user/login.vue index 59a922f2..106f5f21 100644 --- a/src/pages/user/login.vue +++ b/src/pages/user/login.vue @@ -6,7 +6,7 @@ import BaseButton from "@/components/BaseButton.vue"; import {APP_NAME} from "@/config/env.ts"; import {useAuthStore} from "@/stores/auth.ts"; import {loginApi, LoginParams, registerApi, resetPasswordApi, sendCode} from "@/apis/user.ts"; -import {validateEmail, validatePhone} from "@/utils/validation.ts"; +import {accountRules, codeRules, passwordRules, phoneRules, validateEmail, validatePhone} from "@/utils/validation.ts"; import Toast from "@/components/base/toast/Toast.ts"; import FormItem from "@/components/base/form/FormItem.vue"; import Form from "@/components/base/form/Form.vue"; @@ -15,6 +15,7 @@ import {FormInstance} from "@/components/base/form/types.ts"; import {PASSWORD_CONFIG, PHONE_CONFIG} from "@/config/auth.ts"; import {CodeType} from "@/types/types.ts"; import router from "@/router.ts"; +import Code from "@/pages/user/Code.vue"; // 状态管理 const authStore = useAuthStore() @@ -34,40 +35,6 @@ let qrExpireTimer: ReturnType | null = null let qrCheckInterval: ReturnType | null = null const QR_EXPIRE_TIME = 5 * 60 * 1000 // 5分钟过期 -const codeRules = [ - {required: true, message: '请输入验证码', trigger: 'blur'}, - {min: PHONE_CONFIG.codeLength, message: `请输入 ${PHONE_CONFIG.codeLength} 位验证码`, trigger: 'blur'}, -] -const accountRules = [ - {required: true, message: '请输入手机号/邮箱地址', trigger: 'blur'}, - { - validator: (rule: any, value: any) => { - if (!validatePhone(value) && !validateEmail(value)) { - throw new Error('请输入有效的手机号或邮箱地址') - } - }, trigger: 'blur' - }, -] -const phoneRules = [ - {required: true, message: '请输入手机号', trigger: 'blur'}, - { - validator: (rule: any, value: any) => { - if (!validatePhone(value)) { - throw new Error('请输入有效的手机号') - } - }, trigger: 'blur' - }, -] -const passwordRules = [ - {required: true, message: '请输入密码', trigger: 'blur'}, - { - min: PASSWORD_CONFIG.minLength, - max: PASSWORD_CONFIG.maxLength, - message: `密码长度为 ${PASSWORD_CONFIG.minLength}-${PASSWORD_CONFIG.maxLength} 位`, - trigger: 'blur' - }, -] - let phoneLoginForm = $ref({phone: '', code: ''}) let phoneLoginFormRef = $ref() @@ -178,18 +145,10 @@ async function handleLogin() { let data = {} //手机号登录 if (loginType === 'code') { - data = { - phone: phoneLoginForm.phone, - code: phoneLoginForm.code, - type: 'code' - } + data = {...phoneLoginForm, type: 'code'} } else { //密码登录 - data = { - account: loginForm2.account, - password: loginForm2.password, - type: 'pwd' - } + data = {...loginForm2, type: 'pwd'} } let res = await loginApi(data as LoginParams) if (res.success) { @@ -215,11 +174,7 @@ async function handleRegister() { if (!valid) return try { loading = true - let res = await registerApi({ - account: registerForm.account, - password: registerForm.password, - code: registerForm.code, - }) + let res = await registerApi(registerForm) if (res.success) { authStore.setToken(res.data.token) authStore.setUser(res.data.user) @@ -243,11 +198,7 @@ async function handleForgotPassword() { if (!valid) return try { loading = true - const res = await resetPasswordApi({ - account: forgotForm.account, - code: forgotForm.code, - newPassword: forgotForm.newPassword - }) + const res = await resetPasswordApi(forgotForm) if (res.success) { Toast.success('密码重置成功,请重新登录') switchMode('login') @@ -405,6 +356,8 @@ onBeforeUnmount(() => { @@ -413,20 +366,14 @@ onBeforeUnmount(() => {
- - {{ codeCountdown > 0 ? `${codeCountdown}s` : (isSendingCode ? '发送中' : '发送验证码') }} - +
@@ -439,7 +386,9 @@ onBeforeUnmount(() => { :model="loginForm2"> @@ -449,6 +398,8 @@ onBeforeUnmount(() => { @@ -487,6 +438,8 @@ onBeforeUnmount(() => { @@ -495,26 +448,22 @@ onBeforeUnmount(() => {
- - {{ codeCountdown > 0 ? `${codeCountdown}s` : (isSendingCode ? '发送中' : '获取验证码') }} - +
@@ -523,6 +472,8 @@ onBeforeUnmount(() => { @@ -557,6 +508,8 @@ onBeforeUnmount(() => { @@ -565,26 +518,22 @@ onBeforeUnmount(() => {
- - {{ codeCountdown > 0 ? `${codeCountdown}s` : (isSendingCode ? '发送中' : '获取验证码') }} - +
@@ -593,6 +542,8 @@ onBeforeUnmount(() => { diff --git a/src/stores/auth.ts b/src/stores/auth.ts index efeb3324..1adf6b3b 100644 --- a/src/stores/auth.ts +++ b/src/stores/auth.ts @@ -9,8 +9,9 @@ export interface User { id: string email?: string phone?: string - nickname?: string - avatar?: string + username?: string + avatar?: string, + hasPwd?: boolean } export const useAuthStore = defineStore('auth', () => { @@ -37,15 +38,15 @@ export const useAuthStore = defineStore('auth', () => { } // 登出 - const logout = async () => { + function logout() { clearToken() - Toast.success('已退出登录') + // Toast.success('已退出登录') //这行会引起hrm失效 // router.push('/') } // 获取用户信息 - const fetchUserInfo = async () => { + async function fetchUserInfo() { try { const res = await getUserInfo() if (res.success) { @@ -61,7 +62,7 @@ export const useAuthStore = defineStore('auth', () => { // 初始化用户状态 - const init = async () => { + async function init() { if (AppEnv.CAN_REQUEST) { const success = await fetchUserInfo() if (!success) { diff --git a/src/types/types.ts b/src/types/types.ts index a846c744..5ab35aca 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -235,4 +235,7 @@ export enum CodeType { Login = 0, Register = 1, ResetPwd = 2, + ChangeEmail = 3, + ChangePhoneNew = 4, + ChangePhoneOld = 5 } diff --git a/src/utils/validation.ts b/src/utils/validation.ts index ffff054e..c89bf941 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -1,5 +1,5 @@ // 邮箱验证 -import {EMAIL_CONFIG, PHONE_CONFIG} from "@/config/auth.ts"; +import {EMAIL_CONFIG, PASSWORD_CONFIG, PHONE_CONFIG} from "@/config/auth.ts"; export const validateEmail = (email: string): boolean => { return EMAIL_CONFIG.emailRegex.test(email) @@ -8,3 +8,47 @@ export const validateEmail = (email: string): boolean => { export const validatePhone = (phone: string): boolean => { return PHONE_CONFIG.phoneRegex.test(phone) } + +export const codeRules = [ + {required: true, message: '请输入验证码', trigger: 'blur'}, + {min: PHONE_CONFIG.codeLength, message: `请输入 ${PHONE_CONFIG.codeLength} 位验证码`, trigger: 'blur'}, +] +export const accountRules = [ + {required: true, message: '请输入手机号/邮箱地址', trigger: 'blur'}, + { + validator: (rule: any, value: any) => { + if (!validatePhone(value) && !validateEmail(value)) { + throw new Error('请输入有效的手机号或邮箱地址') + } + }, trigger: 'blur' + }, +] +export const emailRules = [ + {required: true, message: '请输入邮箱地址', trigger: 'blur'}, + { + validator: (rule: any, value: any) => { + if (!validateEmail(value)) { + throw new Error('请输入有效的邮箱地址') + } + }, trigger: 'blur' + }, +] +export const phoneRules = [ + {required: true, message: '请输入手机号', trigger: 'blur'}, + { + validator: (rule: any, value: any) => { + if (!validatePhone(value)) { + throw new Error('请输入有效的手机号') + } + }, trigger: 'blur' + }, +] +export const passwordRules = [ + {required: true, message: '请输入密码', trigger: 'blur'}, + { + min: PASSWORD_CONFIG.minLength, + max: PASSWORD_CONFIG.maxLength, + message: `密码长度为 ${PASSWORD_CONFIG.minLength}-${PASSWORD_CONFIG.maxLength} 位`, + trigger: 'blur' + }, +] \ No newline at end of file