diff --git a/frontend/components.d.ts b/frontend/components.d.ts index d85c927..326a461 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -50,12 +50,15 @@ declare module 'vue' { VanCheckbox: typeof import('vant/es')['Checkbox'] VanCheckboxGroup: typeof import('vant/es')['CheckboxGroup'] VanEmpty: typeof import('vant/es')['Empty'] + VanField: typeof import('vant/es')['Field'] + VanForm: typeof import('vant/es')['Form'] VanIcon: typeof import('vant/es')['Icon'] VanImage: typeof import('vant/es')['Image'] VanLoading: typeof import('vant/es')['Loading'] VanOverlay: typeof import('vant/es')['Overlay'] VanPopup: typeof import('vant/es')['Popup'] VanSearch: typeof import('vant/es')['Search'] + VanSwitch: typeof import('vant/es')['Switch'] VanTab: typeof import('vant/es')['Tab'] VanTabbar: typeof import('vant/es')['Tabbar'] VanTabbarItem: typeof import('vant/es')['TabbarItem'] diff --git a/frontend/src/views/mobile/Login.vue b/frontend/src/views/mobile/Login.vue index 71a5ae6..608b967 100644 --- a/frontend/src/views/mobile/Login.vue +++ b/frontend/src/views/mobile/Login.vue @@ -11,64 +11,140 @@

Cloud Saver

- - - - - - - + + - -
- -
-
+ +
+ + {{ isLoading ? "登录中..." : "登录" }} + +
+ + + + + + + + + + + + @@ -77,7 +153,7 @@ import { ref, onMounted } from "vue"; import { useRouter } from "vue-router"; import { showNotify } from "vant"; -import type { FieldInstance } from "vant"; +import type { FieldInstance, FieldRule } from "vant"; import { userApi } from "@/api/user"; import logo from "@/assets/images/logo.png"; import { STORAGE_KEYS } from "@/constants/storage"; @@ -88,21 +164,42 @@ interface LoginForm { password: string; } +interface RegisterForm { + username: string; + password: string; + confirmPassword: string; + registerCode: string; +} + // 响应式数据 -const formData = ref({ +const activeTab = ref("login"); +const isLoading = ref(false); +const loginPasswordRef = ref(); +const rememberPassword = ref(false); + +const loginForm = ref({ username: "", password: "", }); -const isLoading = ref(false); -const passwordRef = ref(); -const rememberPassword = ref(false); + +const registerForm = ref({ + username: "", + password: "", + confirmPassword: "", + registerCode: "", +}); // 工具函数 const router = useRouter(); // 方法定义 -const focusPassword = () => { - passwordRef.value?.focus(); +const focusLoginPassword = () => { + loginPasswordRef.value?.focus(); +}; + +// 表单验证 +const validateConfirmPassword = (value: string) => { + return value === registerForm.value.password; }; // 在组件加载时检查是否有保存的账号密码 @@ -110,22 +207,22 @@ onMounted(() => { const savedUsername = localStorage.getItem(STORAGE_KEYS.USERNAME); const savedPassword = localStorage.getItem(STORAGE_KEYS.PASSWORD); if (savedUsername && savedPassword) { - formData.value.username = savedUsername; - formData.value.password = savedPassword; + loginForm.value.username = savedUsername; + loginForm.value.password = savedPassword; rememberPassword.value = true; } }); -const handleSubmit = async () => { +// 登录处理 +const handleLogin = async () => { try { isLoading.value = true; - const res = await userApi.login(formData.value); + const res = await userApi.login(loginForm.value); if (res.code === 0) { - // 处理记住密码 if (rememberPassword.value) { - localStorage.setItem(STORAGE_KEYS.USERNAME, formData.value.username); - localStorage.setItem(STORAGE_KEYS.PASSWORD, formData.value.password); + localStorage.setItem(STORAGE_KEYS.USERNAME, loginForm.value.username); + localStorage.setItem(STORAGE_KEYS.PASSWORD, loginForm.value.password); } else { localStorage.removeItem(STORAGE_KEYS.USERNAME); localStorage.removeItem(STORAGE_KEYS.PASSWORD); @@ -134,22 +231,65 @@ const handleSubmit = async () => { localStorage.setItem(STORAGE_KEYS.TOKEN, res.data.token); await router.push("/"); } else { - showNotify({ - type: "danger", - message: res.message || "登录失败", - duration: 2000, - }); + showNotify({ type: "danger", message: res.message || "登录失败" }); } } catch (error) { - showNotify({ - type: "danger", - message: "登录失败", - duration: 2000, - }); + showNotify({ type: "danger", message: "登录失败" }); } finally { isLoading.value = false; } }; + +// 注册处理 +const handleRegister = async () => { + try { + isLoading.value = true; + const res = await userApi.register({ + username: registerForm.value.username, + password: registerForm.value.password, + registerCode: registerForm.value.registerCode, + }); + + if (res.code === 0) { + showNotify({ type: "success", message: "注册成功" }); + // 自动填充登录表单 + loginForm.value.username = registerForm.value.username; + loginForm.value.password = registerForm.value.password; + activeTab.value = "login"; + // 清空注册表单 + registerForm.value = { + username: "", + password: "", + confirmPassword: "", + registerCode: "", + }; + } else { + showNotify({ type: "danger", message: res.message || "注册失败" }); + } + } catch (error) { + showNotify({ type: "danger", message: "注册失败" }); + } finally { + isLoading.value = false; + } +}; + +// 定义验证规则 +const usernameRules: FieldRule[] = [ + { required: true, message: "请填写用户名" }, + { pattern: /.{3,}/, message: "用户名至少3个字符" }, +]; + +const passwordRules: FieldRule[] = [ + { required: true, message: "请填写密码" }, + { pattern: /.{6,}/, message: "密码至少6个字符" }, +]; + +const confirmPasswordRules: FieldRule[] = [ + { required: true, message: "请确认密码" }, + { validator: validateConfirmPassword, message: "两次密码不一致" }, +]; + +const registerCodeRules: FieldRule[] = [{ required: true, message: "请填写注册码" }];