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 ? "登录中..." : "登录" }}
-
-
-
+
+
+
+ {{ isLoading ? "登录中..." : "登录" }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 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: "请填写注册码" }];