diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue index c1aeb4b..683d432 100644 --- a/frontend/src/views/Login.vue +++ b/frontend/src/views/Login.vue @@ -4,6 +4,7 @@ import { ref } from 'vue' import { useRouter } from 'vue-router' import { useUserStore } from '@/stores/user' import { ElMessage } from 'element-plus' +import { pb } from '@/api/pocketbase' import PasswordInput from '@/components/common/PasswordInput.vue' const router = useRouter() @@ -15,16 +16,29 @@ const loading = ref(false) async function handleLogin() { if (!identity.value || !password.value) { - ElMessage.warning('请输入邮箱和密码') + ElMessage.warning('请输入昵称/邮箱和密码') return } try { loading.value = true - await userStore.login(identity.value, password.value) + let loginIdentity = identity.value.trim() - const redirect = '/' - router.push(redirect) + // 如果不包含 @,按昵称或用户名查找对应 username 用于认证 + if (!loginIdentity.includes('@')) { + const result = await pb.collection('users').getList(1, 1, { + filter: `name="${loginIdentity}" || username="${loginIdentity}"`, + $autoCancel: false + }) + if (result.items.length === 0) { + ElMessage.error('用户不存在') + return + } + loginIdentity = (result.items[0] as any).username + } + + await userStore.login(loginIdentity, password.value) + router.push('/') } catch (error: any) { ElMessage.error(error.message || '登录失败') } finally { @@ -45,12 +59,11 @@ async function handleLogin() {
- +
diff --git a/frontend/src/views/Register.vue b/frontend/src/views/Register.vue index 2980f8a..3b4b62c 100644 --- a/frontend/src/views/Register.vue +++ b/frontend/src/views/Register.vue @@ -3,6 +3,7 @@ import { ref, computed } from 'vue' import { useRouter } from 'vue-router' import { useUserStore } from '@/stores/user' +import { pb } from '@/api/pocketbase' import PasswordInput from '@/components/common/PasswordInput.vue' const router = useRouter() @@ -17,6 +18,21 @@ const formError = ref('') // ── 实时校验 ── const nicknameOk = computed(() => nickname.value.length >= 2 && nickname.value.length <= 16) +const nicknameTaken = ref(false) +const nicknameChecking = ref(false) + +async function checkNickname() { + const val = nickname.value.trim() + if (!val || val.length < 2) { nicknameTaken.value = false; return } + try { + nicknameChecking.value = true + const result = await pb.collection('users').getList(1, 1, { + filter: `name="${val}"`, + $autoCancel: false + }) + nicknameTaken.value = result.items.length > 0 + } catch { /* ignore */ } finally { nicknameChecking.value = false } +} const hasLetter = computed(() => /[a-zA-Z]/.test(password.value)) const hasDigit = computed(() => /[0-9]/.test(password.value)) @@ -46,6 +62,10 @@ async function handleRegister() { formError.value = '昵称需 2-16 个字符' return } + if (nicknameTaken.value) { + formError.value = '该昵称已被使用' + return + } if (!passwordOk.value) { formError.value = '密码不符合要求' return @@ -89,7 +109,10 @@ async function handleRegister() {
- + + 检查中... + 该昵称已被使用 + 昵称可用
2-16 个字符,支持中英文
@@ -259,6 +282,10 @@ async function handleRegister() { color: var(--gg-danger); } +.field-hint.ok { + color: var(--gg-primary); +} + /* ── 密码强度 ── */ .password-strength { display: flex;