hookehuyr

fix: 更新登录页面图标链接

更新美乐爱觉教育登录页面的品牌图标,使用新版本的logo图片地址。
<template>
<div
class="min-h-screen flex flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 py-8 px-4 sm:px-6 lg:px-8"
class="flex min-h-screen flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 px-4 py-8 sm:px-6 lg:px-8"
>
<div class="sm:mx-auto sm:w-full sm:max-w-md text-center">
<van-icon name="https://cdn.ipadbiz.cn/mlaj/icon/behalo-logo-1.png?imageMogr2/thumbnail/200x/strip/quality/70" size="10rem" style="margin-bottom: 0.5rem;" />
<h1 class="text-center text-3xl font-bold text-gray-800 mb-2">美乐爱觉教育</h1>
<div class="text-center sm:mx-auto sm:w-full sm:max-w-md">
<van-icon
name="https://cdn.ipadbiz.cn/mlaj/icon/behalo-logo-2.png?imageMogr2/thumbnail/200x/strip/quality/70"
size="10rem"
style="margin-bottom: 0.5rem"
/>
<h1 class="mb-2 text-center text-3xl font-bold text-gray-800">美乐爱觉教育</h1>
<!-- <h2 class="text-center text-xl font-medium text-gray-600">欢迎回来</h2> -->
</div>
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<FrostedGlass class="py-8 px-6 rounded-lg">
<FrostedGlass class="rounded-lg px-6 py-8">
<div
v-if="error"
class="mb-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-md"
class="mb-4 rounded-md border border-red-400 bg-red-100 px-4 py-3 text-red-700"
>
{{ error }}
</div>
......@@ -35,7 +39,7 @@
@input="mobile = $event.target.value.replace(/\D/g, '')"
@focus="handleInputFocus"
@blur="validatePhone"
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500"
class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
/>
</div>
......@@ -51,7 +55,7 @@
autocomplete="current-password"
required
placeholder="请输入6位密码"
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500"
class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
/>
</div>
......@@ -67,13 +71,13 @@
required
maxlength="6"
placeholder="请输入验证码"
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500"
class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
/>
<button
type="button"
:disabled="countdown > 0 || !isPhoneValid"
@click="sendVerificationCode"
class="mt-1 px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap"
class="mt-1 whitespace-nowrap rounded-md border border-transparent bg-green-600 px-4 py-2 text-sm font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
>
{{ countdown > 0 ? `${countdown}秒后重试` : '获取验证码' }}
</button>
......@@ -104,10 +108,10 @@
<button
type="submit"
:disabled="loading"
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"
:class="{ 'opacity-70 cursor-not-allowed': loading }"
class="flex w-full justify-center rounded-md border border-transparent bg-gradient-to-r from-green-500 to-green-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:from-green-600 hover:to-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2"
:class="{ 'cursor-not-allowed opacity-70': loading }"
>
{{ loading ? "登录中..." : "登录/注册BEHALO宇宙账号" }}
{{ loading ? '登录中...' : '登录/注册BEHALO宇宙账号' }}
</button>
</div>
</form>
......@@ -157,11 +161,11 @@
</router-link>
</p>
</div> -->
<div class="text-center mt-6">
<div class="mt-6 text-center">
<p class="text-sm text-gray-600">
登录即表示同意
<span
class="font-medium text-green-600 hover:text-green-500 cursor-pointer"
class="cursor-pointer font-medium text-green-600 hover:text-green-500"
@click="userAgreementRef.openAgreement()"
>
《美乐爱觉宇宙用户协议》
......@@ -170,10 +174,15 @@
</p>
</div>
<div class="mt-6 flex justify-center items-center gap-4" style="flex-direction: column;">
<div class="mt-6 flex items-center justify-center gap-4" style="flex-direction: column">
<div class="text-sm font-medium text-gray-600">其他登录方式</div>
<div>
<img :src="weixinLogo" alt="微信登录" style="width: 40px; height: 40px; border-radius: 8px;" @click="handleWxLoginClick">
<img
:src="weixinLogo"
alt="微信登录"
style="width: 40px; height: 40px; border-radius: 8px"
@click="handleWxLoginClick"
/>
</div>
</div>
</FrostedGlass>
......@@ -182,122 +191,126 @@
</template>
<script setup>
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import FrostedGlass from "@/components/effects/FrostedGlass.vue";
import { useAuth } from "@/contexts/auth";
import { loginAPI, getUserInfoAPI } from "@/api/users";
import { useTitle } from "@vueuse/core";
import { smsAPI } from "@/api/common";
import { showToast } from "vant";
import UserAgreement from "@/components/common/UserAgreement.vue";
import { setAuthHeaders } from "@/utils/axios";
import { applyUserInfoAuth } from "@/utils/auth_user_info";
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import FrostedGlass from '@/components/effects/FrostedGlass.vue'
import { useAuth } from '@/contexts/auth'
import { loginAPI, getUserInfoAPI } from '@/api/users'
import { useTitle } from '@vueuse/core'
import { smsAPI } from '@/api/common'
import { showToast } from 'vant'
import UserAgreement from '@/components/common/UserAgreement.vue'
import { setAuthHeaders } from '@/utils/axios'
import { applyUserInfoAuth } from '@/utils/auth_user_info'
import weixinLogo from '@/assets/images/weixin_logo_lg.jpeg'
import { startWxAuth } from '@/router/guards'
import { wxInfo } from '@/utils/tools'
const userAgreementRef = ref(null);
const userAgreementRef = ref(null)
const handleInputFocus = () => {
setTimeout(() => {
// 使用平滑滚动将页面向上移动200px(根据实际按钮区域高度调整)
window.scrollTo({
top: 150,
behavior: 'smooth'
});
}, 100);
};
const $route = useRoute();
useTitle($route.meta.title);
const router = useRouter();
const { login } = useAuth();
const mobile = ref("");
const password = ref("");
const verificationCode = ref("");
const error = ref("");
const loading = ref(false);
const isVerifyCodeLogin = ref(true);
const countdown = ref(0);
const isPhoneValid = ref(false);
behavior: 'smooth',
})
}, 100)
}
const $route = useRoute()
useTitle($route.meta.title)
const router = useRouter()
const { login } = useAuth()
const mobile = ref('')
const password = ref('')
const verificationCode = ref('')
const error = ref('')
const loading = ref(false)
const isVerifyCodeLogin = ref(true)
const countdown = ref(0)
const isPhoneValid = ref(false)
const validatePhone = () => {
if (!mobile.value) {
error.value = '请输入手机号';
isPhoneValid.value = false;
return;
error.value = '请输入手机号'
isPhoneValid.value = false
return
}
if (!/^1[3-9]\d{9}$/.test(mobile.value)) {
error.value = '请输入正确的手机号';
isPhoneValid.value = false;
return;
error.value = '请输入正确的手机号'
isPhoneValid.value = false
return
}
error.value = '';
isPhoneValid.value = true;
};
error.value = ''
isPhoneValid.value = true
}
const startCountdown = () => {
countdown.value = 60;
countdown.value = 60
const timer = setInterval(() => {
countdown.value--;
countdown.value--
if (countdown.value <= 0) {
clearInterval(timer);
clearInterval(timer)
}
}, 1000);
};
}, 1000)
}
/**
* @description 点击微信图标触发微信授权登录
* @returns {void}
*/
const handleWxLoginClick = async () => {
// 非微信环境提示并不触发授权
if (!import.meta.env.DEV && !wxInfo().isWeiXin) {
showToast('请在微信内打开以完成微信授权登录');
return;
}
// 非微信环境提示并不触发授权
if (!import.meta.env.DEV && !wxInfo().isWeiXin) {
showToast('请在微信内打开以完成微信授权登录')
return
}
try {
// 手动发起微信授权流程(guards.js中实现)
await startWxAuth();
} catch (e) {
console.error('微信授权触发失败:', e);
showToast('微信授权失败,请稍后重试');
}
};
try {
// 手动发起微信授权流程(guards.js中实现)
await startWxAuth()
} catch (e) {
console.error('微信授权触发失败:', e)
showToast('微信授权失败,请稍后重试')
}
}
const sendVerificationCode = async () => {
if (!isPhoneValid.value) {
return;
return
}
try {
const { code } = await smsAPI({ mobile: mobile.value });
const { code } = await smsAPI({ mobile: mobile.value })
if (code === 1) {
showToast('验证码已发送');
startCountdown();
return;
showToast('验证码已发送')
startCountdown()
return
}
} catch (err) {
console.error('Send verification code error:', err);
error.value = '发送验证码失败,请稍后重试';
console.error('Send verification code error:', err)
error.value = '发送验证码失败,请稍后重试'
}
};
}
const handleSubmit = async () => {
if (!mobile.value || (!isVerifyCodeLogin.value && !password.value) || (isVerifyCodeLogin.value && !verificationCode.value)) {
error.value = "请填写所有字段";
return;
if (
!mobile.value ||
(!isVerifyCodeLogin.value && !password.value) ||
(isVerifyCodeLogin.value && !verificationCode.value)
) {
error.value = '请填写所有字段'
return
}
try {
error.value = "";
loading.value = true;
error.value = ''
loading.value = true
// 调用登录接口
const response = await loginAPI({
......@@ -305,38 +318,36 @@ const handleSubmit = async () => {
...(isVerifyCodeLogin.value
? { sms_code: verificationCode.value }
: { password: password.value }),
});
})
if (response.code !== 1) {
error.value = response.msg || "登录失败,请检查您的输入项";
return;
} else {
applyUserInfoAuth(response, { set_auth_headers: setAuthHeaders, storage: localStorage })
error.value = response.msg || '登录失败,请检查您的输入项'
return
}
applyUserInfoAuth(response, { set_auth_headers: setAuthHeaders, storage: localStorage })
const { code, data } = await getUserInfoAPI();
const { code, data } = await getUserInfoAPI()
if (code === 1) {
// 登录成功,更新auth状态,传递完整的用户信息包括打卡信息
const success = login({ ...data.user, ...data.checkin });
const success = login({ ...data.user, ...data.checkin })
if (success) {
// 如果有重定向参数,登录成功后跳转到对应页面
// 说明:redirect 是经过 URL 编码的,需要先解码再跳转
const redirect_raw = $route.query.redirect;
const redirect = redirect_raw ? decodeURIComponent(redirect_raw) : "/";
router.push(redirect);
const redirect_raw = $route.query.redirect
const redirect = redirect_raw ? decodeURIComponent(redirect_raw) : '/'
router.push(redirect)
} else {
error.value = "登录失败,请检查您的输入项";
error.value = '登录失败,请检查您的输入项'
}
}
} catch (err) {
console.error("Login error:", err);
error.value = "登录时发生错误";
console.error('Login error:', err)
error.value = '登录时发生错误'
} finally {
loading.value = false;
loading.value = false
}
};
}
// 说明:授权回跳的重定向处理已移动到路由层
</script>
......