feat: 添加用户认证功能,优化登录和注册流程,集成表单验证和加载状态
This commit is contained in:
@@ -1,23 +1,65 @@
|
||||
<script lang='ts' setup>
|
||||
import { toastController } from "@ionic/vue";
|
||||
import { safeClient } from "@/api";
|
||||
import { authClient } from "@/auth";
|
||||
import { LoginSchema } from "./schema";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const phoneNumber = ref("");
|
||||
const password = ref("");
|
||||
const form = ref({
|
||||
phoneNumber: "",
|
||||
password: "",
|
||||
});
|
||||
const agreed = ref(false);
|
||||
const showPassword = ref(false);
|
||||
const isLoading = ref(false);
|
||||
|
||||
function handleLogin() {
|
||||
if (!phoneNumber.value || !password.value) {
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
async function showToast(message: string, color: "success" | "danger" | "warning" = "danger") {
|
||||
const toast = await toastController.create({
|
||||
message,
|
||||
duration: 2000,
|
||||
position: "top",
|
||||
color,
|
||||
});
|
||||
await toast.present();
|
||||
}
|
||||
async function handleLogin() {
|
||||
if (!agreed.value) {
|
||||
// TODO: 提示需要同意条款
|
||||
await showToast("请先阅读并同意服务条款和隐私政策", "warning");
|
||||
return;
|
||||
}
|
||||
// TODO: 实现登录逻辑
|
||||
console.log("登录", { phoneNumber: phoneNumber.value, password: password.value });
|
||||
const result = LoginSchema.safeParse({ ...form.value });
|
||||
if (!result.success) {
|
||||
const first = result.error.issues[0];
|
||||
await showToast(first.message);
|
||||
return;
|
||||
}
|
||||
|
||||
isLoading.value = true;
|
||||
try {
|
||||
const { data } = await safeClient(authClient.signIn.username({
|
||||
username: form.value.phoneNumber,
|
||||
password: form.value.password,
|
||||
}));
|
||||
if (!data.value?.token) {
|
||||
toastController.create({
|
||||
message: "登录失败,请检查手机号或密码",
|
||||
duration: 2000,
|
||||
color: "danger",
|
||||
}).then(toast => toast.present());
|
||||
}
|
||||
else {
|
||||
const userStore = useUserStore();
|
||||
userStore.setToken(data.value.token);
|
||||
await userStore.updateProfile();
|
||||
await showToast("登录成功!", "success");
|
||||
router.push(route.query.redirect as string || "/");
|
||||
}
|
||||
}
|
||||
finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleSignup() {
|
||||
@@ -71,7 +113,7 @@ function goToTerms(type: "service" | "privacy") {
|
||||
<!-- 手机号输入 -->
|
||||
<ion-item lines="none" class="input-item">
|
||||
<ion-input
|
||||
v-model="phoneNumber"
|
||||
v-model="form.phoneNumber"
|
||||
type="tel"
|
||||
placeholder="请输入手机号"
|
||||
class="custom-input"
|
||||
@@ -82,7 +124,7 @@ function goToTerms(type: "service" | "privacy") {
|
||||
<!-- 密码输入 -->
|
||||
<ion-item lines="none" class="input-item">
|
||||
<ion-input
|
||||
v-model="password"
|
||||
v-model="form.password"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
placeholder="请输入密码"
|
||||
class="custom-input"
|
||||
@@ -110,9 +152,11 @@ function goToTerms(type: "service" | "privacy") {
|
||||
<ion-button
|
||||
expand="block"
|
||||
class="login-button mt-2"
|
||||
:disabled="isLoading"
|
||||
@click="handleLogin"
|
||||
>
|
||||
登录
|
||||
<ion-spinner v-if="isLoading" name="crescent" class="mr-2" />
|
||||
{{ isLoading ? '登录中...' : '登录' }}
|
||||
</ion-button>
|
||||
|
||||
<!-- 注册按钮 -->
|
||||
|
||||
Reference in New Issue
Block a user