| | |
| | | <view class="login-container"> |
| | | <view class="header"> |
| | | <image src="/static/avatar/logo.png" class="logo" /> |
| | | <text class="hospital-name">青附院OPO管理平台</text> |
| | | <text class="hospital-name">青大附院OPO管理平台</text> |
| | | </view> |
| | | |
| | | <view class="form-container"> |
| | |
| | | |
| | | <script setup> |
| | | import { ref } from "vue"; |
| | | import { onLoad } from "@dcloudio/uni-app"; |
| | | import { onLoad, onShow } from "@dcloudio/uni-app"; |
| | | import { useUserStore } from "@/stores/user"; |
| | | import { getToken, setToken } from "@/utils/auth"; |
| | | import { encrypt } from "@/utils/crypto"; |
| | | |
| | | let isAutoLogining = false; |
| | | let hasAutoLogin = false; |
| | | |
| | | const username = ref(""); |
| | | const password = ref(""); |
| | | const showPassword = ref(false); |
| | | const isHarmonyOS = ref(false); |
| | | const redirect = ref("/pages/index/index"); // 默认跳转首页 |
| | | const redirect = ref(""); |
| | | |
| | | onLoad((options) => { |
| | | // 格式化当前日期为 YYYYMMDD |
| | | const getCurrentDate = () => { |
| | | const now = new Date(); |
| | | const year = now.getFullYear(); |
| | | const month = String(now.getMonth() + 1).padStart(2, "0"); |
| | | const day = String(now.getDate()).padStart(2, "0"); |
| | | return `${year}${month}${day}`; |
| | | }; |
| | | console.log("登录页onLoad,完整参数:", options); |
| | | console.log("页面栈:", getCurrentPages()); |
| | | |
| | | // 自动生成密码函数 |
| | | const generatePassword = () => { |
| | | const currentDate = getCurrentDate(); // 直接调用函数 |
| | | return `Hrs#${currentDate}*`; |
| | | }; |
| | | // uni.$uapi.post("/getToken", { |
| | | // userName: "测试吴龙", |
| | | // passWord: "13803963330", |
| | | // }); |
| | | // ✅ 获取完整URL参数 |
| | | const pages = getCurrentPages(); |
| | | if (pages.length > 0) { |
| | | const currentPage = pages[pages.length - 1]; |
| | | console.log("当前页面对象:", currentPage); |
| | | } |
| | | |
| | | // 处理redirect参数 |
| | | if (options.redirect) { |
| | | redirect.value = decodeURIComponent(options.redirect); |
| | | } else if (options.userName && options.passWord) { |
| | | // 如果没有redirect但有SSO参数,尝试从referrer获取 |
| | | const launchOptions = uni.getLaunchOptionsSync(); |
| | | if (launchOptions.referrerInfo && launchOptions.referrerInfo.extraData) { |
| | | const referrer = launchOptions.referrerInfo.extraData; |
| | | console.log("referrer信息:", referrer); |
| | | } |
| | | } |
| | | // password.value = generatePassword(); // 直接调用函数 |
| | | password.value = ""; // 直接调用函数 |
| | | username.value = ""; |
| | | // 检测是否鸿蒙系统 |
| | | // #ifdef HARMONY |
| | | isHarmonyOS.value = true; |
| | | |
| | | // #endif |
| | | // 检查是否已有token |
| | | if (getToken()) { |
| | | console.log("已存在token,直接跳转"); |
| | | setTimeout(() => { |
| | | navigateToTarget(); |
| | | }, 100); |
| | | return; |
| | | } |
| | | |
| | | // ✅ SSO登录:检查所有可能的参数位置 |
| | | let ssoUserName = options.userName; |
| | | let ssoPassWord = options.passWord; |
| | | |
| | | // 如果没有从options获取到,尝试从启动参数获取 |
| | | if (!ssoUserName || !ssoPassWord) { |
| | | const launchOptions = uni.getLaunchOptionsSync(); |
| | | if (launchOptions.query) { |
| | | ssoUserName = ssoUserName || launchOptions.query.userName; |
| | | ssoPassWord = ssoPassWord || launchOptions.query.passWord; |
| | | } |
| | | } |
| | | |
| | | if (ssoUserName && ssoPassWord) { |
| | | console.log("检测到SSO参数,自动登录", { ssoUserName }); |
| | | |
| | | // 合并所有页面参数 |
| | | const pageParams = { ...options }; |
| | | delete pageParams.userName; |
| | | delete pageParams.passWord; |
| | | delete pageParams.redirect; |
| | | |
| | | handleSSOLogin(ssoUserName, ssoPassWord, pageParams); |
| | | } else { |
| | | // 普通登录 |
| | | password.value = ""; |
| | | username.value = ""; |
| | | } |
| | | }); |
| | | |
| | | onShow(() => { |
| | | console.log("登录页onShow"); |
| | | if (hasAutoLogin) { |
| | | hasAutoLogin = false; |
| | | } |
| | | }); |
| | | |
| | | // ✅ 改进的SSO登录函数 |
| | | const handleSSOLogin = async (userName, passWord, pageParams = {}) => { |
| | | if (isAutoLogining) { |
| | | console.log("正在自动登录中,跳过"); |
| | | return; |
| | | } |
| | | |
| | | isAutoLogining = true; |
| | | console.log("开始SSO免登:", { userName, pageParams }); |
| | | |
| | | uni.showLoading({ title: "自动登录中...", mask: true }); |
| | | |
| | | try { |
| | | console.log(11); |
| | | |
| | | // 1. 获取token |
| | | const tokenRes = await uni.$uapi.post("/getToken", { |
| | | userName, |
| | | passWord, |
| | | }); |
| | | console.log(tokenRes.data); |
| | | |
| | | uni.hideLoading(); |
| | | |
| | | if (!tokenRes.data.token) { |
| | | throw new Error("获取token失败"); |
| | | } |
| | | |
| | | console.log("获取到token成功"); |
| | | |
| | | // 2. 保存token |
| | | setToken(tokenRes.data.token); |
| | | |
| | | // 3. 获取用户信息 |
| | | const userStore = useUserStore(); |
| | | const userInfo = await uni.$uapi.get("/getInfo"); |
| | | if (userInfo) { |
| | | userStore.setUserInfo(userInfo); |
| | | } |
| | | |
| | | // 4. 构建目标页面URL |
| | | let targetPage = redirect.value; |
| | | if (!targetPage && Object.keys(pageParams).length > 0) { |
| | | // 尝试从原始访问路径构建 |
| | | const launchOptions = uni.getLaunchOptionsSync(); |
| | | if (launchOptions.path && !launchOptions.path.includes("login/Login")) { |
| | | targetPage = "/" + launchOptions.path; |
| | | } |
| | | } |
| | | |
| | | // 5. 跳转 |
| | | hasAutoLogin = true; |
| | | await navigateToTargetPage(targetPage, pageParams); |
| | | } catch (err) { |
| | | uni.hideLoading(); |
| | | console.error("SSO免登失败:", err); |
| | | uni.showToast({ |
| | | title: "自动登录失败,请手动登录", |
| | | icon: "none", |
| | | duration: 3000, |
| | | }); |
| | | |
| | | uni.removeStorageSync("token"); |
| | | } finally { |
| | | isAutoLogining = false; |
| | | } |
| | | }; |
| | | |
| | | // 普通登录 |
| | | const handleLogin = async () => { |
| | | try { |
| | | const userStore = useUserStore(); |
| | | if (!username.value || !password.value) { |
| | | uni.showToast({ title: "请输入账号密码", icon: "none" }); |
| | | return; |
| | | } |
| | | |
| | | // ✅ 密码加密 |
| | | uni.showLoading({ title: "登录中...", mask: true }); |
| | | |
| | | const userStore = useUserStore(); |
| | | const encryptedPassword = encrypt(password.value); |
| | | const encryptedUsername = encrypt(username.value); |
| | | |
| | | const loginRes = await uni.$uapi.post("/login", { |
| | | username: encryptedUsername, |
| | | password: encryptedPassword, // ⚠️ 传密文 |
| | | password: encryptedPassword, |
| | | }); |
| | | |
| | | userStore.setToken(loginRes.token); |
| | | if (!loginRes || !loginRes.token) { |
| | | throw new Error("登录失败"); |
| | | } |
| | | |
| | | setToken(loginRes.token); |
| | | |
| | | const userInfo = await uni.$uapi.get("/getInfo"); |
| | | userStore.setUserInfo(userInfo); |
| | | |
| | | const redirects = redirect.value || "/pages/index/index"; |
| | | |
| | | const tabBarPages = [ |
| | | "/pages/index/index", |
| | | "/pages/appointment/index", |
| | | "/pages/consultation/index", |
| | | "/pages/my/index", |
| | | ]; |
| | | |
| | | if (tabBarPages.includes(redirects)) { |
| | | uni.switchTab({ url: redirects }); |
| | | } else { |
| | | uni.redirectTo({ url: redirects }); |
| | | if (userInfo) { |
| | | userStore.setUserInfo(userInfo); |
| | | } |
| | | |
| | | uni.hideLoading(); |
| | | await navigateToTarget(); |
| | | } catch (err) { |
| | | uni.hideLoading(); |
| | | console.error("登录失败:", err); |
| | | uni.showToast({ |
| | | title: err.message || "登录失败", |
| | | icon: "none", |
| | | duration: 3000, |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const gotoRegister = () => { |
| | | uni.navigateTo({ |
| | | url: "/pages/login/Register", |
| | | }); |
| | | // ✅ 改进的跳转函数 |
| | | const navigateToTarget = () => { |
| | | return navigateToTargetPage(redirect.value, {}); |
| | | }; |
| | | |
| | | const gotoForgetPassword = () => { |
| | | uni.navigateTo({ |
| | | url: "/pages/login/ForgetPwd", |
| | | }); |
| | | }; |
| | | const navigateToTargetPage = (targetPage, pageParams = {}) => { |
| | | return new Promise((resolve) => { |
| | | setTimeout(() => { |
| | | let targetUrl = targetPage || "/pages/index/index"; |
| | | |
| | | const appleLogin = () => { |
| | | uni.showToast({ |
| | | title: "暂未开通 Apple 登录", |
| | | icon: "none", |
| | | }); |
| | | }; |
| | | // 处理页面参数 |
| | | const paramKeys = Object.keys(pageParams).filter( |
| | | (key) => |
| | | pageParams[key] !== undefined && |
| | | pageParams[key] !== null && |
| | | key !== "userName" && |
| | | key !== "passWord" && |
| | | key !== "redirect", |
| | | ); |
| | | |
| | | const harmonyLogin = () => { |
| | | // 调用鸿蒙登录插件 |
| | | // #ifdef HARMONY |
| | | const harmonyAuth = uni.requireNativePlugin("Harmony-Auth"); |
| | | harmonyAuth.login((result) => { |
| | | console.log("鸿蒙登录结果:", result); |
| | | if (paramKeys.length > 0) { |
| | | const queryStr = paramKeys |
| | | .map((key) => `${key}=${encodeURIComponent(pageParams[key])}`) |
| | | .join("&"); |
| | | |
| | | targetUrl = targetUrl.includes("?") |
| | | ? `${targetUrl}&${queryStr}` |
| | | : `${targetUrl}?${queryStr}`; |
| | | } |
| | | |
| | | console.log("最终跳转目标:", targetUrl); |
| | | |
| | | const tabBarPages = [ |
| | | "/pages/index/index", |
| | | "/pages/appointment/index", |
| | | "/pages/consultation/index", |
| | | "/pages/my/index", |
| | | ]; |
| | | |
| | | const baseUrl = targetUrl.split("?")[0]; |
| | | const isTabBar = tabBarPages.includes(baseUrl); |
| | | |
| | | if (isTabBar) { |
| | | uni.switchTab({ |
| | | url: baseUrl, |
| | | success: () => resolve(true), |
| | | fail: () => { |
| | | uni.redirectTo({ url: "/pages/index/index" }); |
| | | resolve(false); |
| | | }, |
| | | }); |
| | | } else { |
| | | uni.redirectTo({ |
| | | url: targetUrl, |
| | | success: () => resolve(true), |
| | | fail: (err) => { |
| | | console.error("跳转失败:", err); |
| | | // 如果目标页跳转失败,跳首页 |
| | | uni.redirectTo({ url: "/pages/index/index" }); |
| | | resolve(false); |
| | | }, |
| | | }); |
| | | } |
| | | }, 300); |
| | | }); |
| | | // #endif |
| | | }; |
| | | </script> |
| | | |