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 @@
+
+
+
+
+ {{ codeCountdown > 0 ? `${codeCountdown}s` : (isSendingCode ? '发送中' : '发送验证码') }}
+
+
+
+
\ 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 @@
-
+
@@ -99,9 +258,9 @@ async function changePassword(e) {
欢迎使用
请登录以管理您的账户
登录
@@ -113,120 +272,271 @@ async function changePassword(e) {
-
+
-
-
帐户
-
-
-
-
用户名
-
-
-
- {{ username }}
-
-
+
+
帐户
-
+
+
+
+
用户名
+
+
+ {{ authStore.user?.username }}
+
+
在此设置用户名
+
+
+
+
+
+
+
+
+
+
手机号
+
+
+ {{ authStore.user?.phone }}
+
+
在此设置手机号
+
+
+
+
+
+
+
+
+
原手机号不可用,点此申诉
+
+
+ 取消
+ 保存
+
+
+
+
-
+
-
电子邮箱
-
-
-
-
{{ email }}
+
电子邮箱
+
+
+ {{ authStore.user?.email }}
+
在此设置邮箱
+
+
+
+
+
+
-
+
-
+
-
设置密码
-
在此输入密码
+
设置密码
+
在此输入密码
+ class="transition-transform"
+ :class="['rotate-270','rotate-180'][showChangePwd?0:1]"/>
-
-
-
-
取消
-
保存
+
+
-
-
联系 {{ APP_NAME }} 客服
+ 联系 {{ APP_NAME }} 客服
-
-
在 {{ APP_NAME }} 上留下评论
+ 给 {{ APP_NAME }} 提交意见
-
+
登出
-
+
用户协议
、
隐私政策
@@ -291,4 +601,9 @@ async function changePassword(e) {
-
\ 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