2026-01-19 18:52:18 +08:00
|
|
|
|
<template>
|
2026-01-29 17:39:42 +08:00
|
|
|
|
<view class="login-page">
|
|
|
|
|
|
<view class="pt-lg px-15 flex flex-col items-center text-center">
|
|
|
|
|
|
<image src="/static/logo-plain.png" class="logo"></image>
|
|
|
|
|
|
<view class="mt-15 text-xl font-semibold text-dark">柚健康</view>
|
|
|
|
|
|
<view class="mt-12 text-base text-dark">生命全周期健康管理伙伴</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="login-btn-wrap">
|
|
|
|
|
|
<!-- <button v-if="checked" class="login-btn" type="primary" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
|
|
|
|
|
|
手机号快捷登录
|
|
|
|
|
|
</button> -->
|
|
|
|
|
|
<button v-if="checked" class="login-btn" type="primary" open-type="getPhoneNumber"
|
|
|
|
|
|
@getphonenumber="getPhoneNumber">
|
|
|
|
|
|
手机号快捷登录
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button v-else class="login-btn" type="primary" @click="remind()">
|
|
|
|
|
|
手机号快捷登录
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="mt-10 text-center">
|
|
|
|
|
|
<text class="mp-oauth-link" @click="toMpOauth">关联公众号(用于用户映射)</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="flex items-center justify-center mt-12 px-15" @click="checked = !checked">
|
|
|
|
|
|
<checkbox :checked="checked" style="transform: scale(0.7)" />
|
|
|
|
|
|
<view class="text-sm text-gray">我已阅读并同意</view>
|
|
|
|
|
|
<view class="text-sm text-primary">《用户协议》、</view>
|
|
|
|
|
|
<view class="text-sm text-primary">《隐私政策》</view>
|
|
|
|
|
|
</view>
|
2026-01-20 10:49:33 +08:00
|
|
|
|
</view>
|
2026-01-19 18:52:18 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2026-01-20 10:49:33 +08:00
|
|
|
|
import { ref } from "vue";
|
2026-01-23 14:36:28 +08:00
|
|
|
|
import { storeToRefs } from "pinia";
|
2026-01-19 18:52:18 +08:00
|
|
|
|
import { onLoad } from "@dcloudio/uni-app";
|
2026-01-20 10:49:33 +08:00
|
|
|
|
import useAccountStore from "@/store/account";
|
2026-01-29 17:39:42 +08:00
|
|
|
|
import { get, set } from "@/utils/cache";
|
2026-01-20 10:49:33 +08:00
|
|
|
|
import { toast } from "@/utils/widget";
|
2026-01-19 18:52:18 +08:00
|
|
|
|
|
2026-01-20 10:49:33 +08:00
|
|
|
|
const team = ref(true);
|
|
|
|
|
|
const checked = ref(false);
|
|
|
|
|
|
const redirectUrl = ref("");
|
2026-01-23 14:36:28 +08:00
|
|
|
|
const { doctorInfo } = storeToRefs(useAccountStore());
|
2026-01-19 18:52:18 +08:00
|
|
|
|
const { login } = useAccountStore();
|
|
|
|
|
|
|
|
|
|
|
|
function attempRedirect(url) {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
|
uni.redirectTo({
|
|
|
|
|
|
url,
|
|
|
|
|
|
success: () => resolve(true),
|
|
|
|
|
|
fail: () => reject(false),
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function attempSwitchTab(url) {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
|
uni.switchTab({
|
|
|
|
|
|
url,
|
|
|
|
|
|
success: () => resolve(true),
|
|
|
|
|
|
fail: () => reject(false),
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function remind() {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
toast("请先阅读并同意用户协议和隐私政策");
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function toHome() {
|
2026-01-23 14:36:28 +08:00
|
|
|
|
uni.switchTab({
|
|
|
|
|
|
url: "/pages/work/work",
|
2026-01-20 10:49:33 +08:00
|
|
|
|
});
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-29 17:39:42 +08:00
|
|
|
|
function toMpOauth() {
|
|
|
|
|
|
// 写死:公众号网页授权(snsapi_base)
|
|
|
|
|
|
// TODO: 把 YOUR_MP_APPID 替换为真实「公众号 appid」
|
|
|
|
|
|
// 注意:redirect_uri 的域名必须在公众号后台配置为“网页授权域名”(你们是 www.youcan365.com)
|
|
|
|
|
|
const MP_APPID = __VITE_ENV__.MP_WX_MP_APP_ID;
|
|
|
|
|
|
const REDIRECT_URI = "https://www.youcan365.com/wx-callback";
|
|
|
|
|
|
const state = `ykt_wxapp_${Date.now()}`;
|
|
|
|
|
|
const oauthUrl =
|
|
|
|
|
|
`https://open.weixin.qq.com/connect/oauth2/authorize` +
|
|
|
|
|
|
`?appid=${MP_APPID}` +
|
|
|
|
|
|
`&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
|
|
|
|
|
|
`&response_type=code` +
|
|
|
|
|
|
`&scope=snsapi_base` +
|
|
|
|
|
|
`&state=${encodeURIComponent(state)}` +
|
|
|
|
|
|
`#wechat_redirect`;
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/webview/webview?purpose=mp_oauth&url=${encodeURIComponent(oauthUrl)}`,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-19 18:52:18 +08:00
|
|
|
|
async function getPhoneNumber(e) {
|
2026-01-29 17:39:42 +08:00
|
|
|
|
console.log('e', e);
|
2026-01-20 10:49:33 +08:00
|
|
|
|
const phoneCode = e && e.detail && e.detail.code;
|
2026-01-29 17:39:42 +08:00
|
|
|
|
console.log('phoneCode', phoneCode);
|
2026-01-27 17:09:31 +08:00
|
|
|
|
// if (e && !phoneCode) return;
|
2026-01-20 10:49:33 +08:00
|
|
|
|
const res = await login(phoneCode);
|
2026-01-27 17:09:31 +08:00
|
|
|
|
|
2026-01-20 10:49:33 +08:00
|
|
|
|
if (res && redirectUrl.value) {
|
|
|
|
|
|
await attempToPage(redirectUrl.value);
|
2026-01-23 16:17:59 +08:00
|
|
|
|
} else if (res && !(doctorInfo.value && doctorInfo.value.anotherName)) {
|
2026-01-23 14:36:28 +08:00
|
|
|
|
uni.redirectTo({
|
|
|
|
|
|
url: '/pages/work/profile'
|
|
|
|
|
|
})
|
2026-01-20 10:49:33 +08:00
|
|
|
|
} else if (res) {
|
|
|
|
|
|
toHome();
|
|
|
|
|
|
}
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function attempToPage(url) {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
const res1 = attempRedirect(url);
|
|
|
|
|
|
if (res1) return;
|
|
|
|
|
|
const res2 = attempSwitchTab(url);
|
|
|
|
|
|
if (res2) return;
|
|
|
|
|
|
toHome();
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-20 10:49:33 +08:00
|
|
|
|
onLoad((opts) => {
|
2026-01-29 17:39:42 +08:00
|
|
|
|
// 如果你从公众号H5 OAuth回跳到小程序,可以把公众号 oauth code 通过参数带过来(比如 ?mpCode=xxx)
|
|
|
|
|
|
// 这里先缓存下来,供 store/account.js 登录时透传给后端做用户映射
|
|
|
|
|
|
if (opts && opts.mpCode) {
|
|
|
|
|
|
set("mp-oauth-code", opts.mpCode, 300); // 5分钟过期
|
|
|
|
|
|
}
|
2026-01-20 10:49:33 +08:00
|
|
|
|
if (opts.source === "teamInvite") {
|
|
|
|
|
|
team.value = get("invite-team-info");
|
|
|
|
|
|
redirectUrl.value = `/pages/archive/edit-archive?teamId=${team.value.teamId}&corpId=${team.value.corpId}`;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-01-20 16:30:03 +08:00
|
|
|
|
if (opts.redirect) {
|
|
|
|
|
|
redirectUrl.value = decodeURIComponent(opts.redirect);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
redirectUrl.value = opts.redirectUrl || "";
|
|
|
|
|
|
}
|
2026-01-20 10:49:33 +08:00
|
|
|
|
});
|
2026-01-19 18:52:18 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.pt-lg {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
padding-top: 20vh;
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.logo {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
width: 160rpx;
|
|
|
|
|
|
height: 160rpx;
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.login-btn-wrap {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
width: 100vw;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
margin-top: 80rpx;
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.login-btn-wrap-loading {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
pointer-events: none;
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.login-btn {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
width: calc(100vw - 112rpx);
|
|
|
|
|
|
max-width: 600rpx;
|
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
|
line-height: 80rpx;
|
|
|
|
|
|
background: linear-gradient(270deg, #1b5cc8 2.26%, #0877f1 94.33%);
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
|
border-radius: 48rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
box-shadow: 0 4rpx 16rpx rgba(59, 124, 255, 0.08);
|
|
|
|
|
|
border: none;
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.login-btn:active {
|
2026-01-20 10:49:33 +08:00
|
|
|
|
background: linear-gradient(270deg, #1b5cc8 2.26%, #0877f1 94.33%);
|
2026-01-19 18:52:18 +08:00
|
|
|
|
}
|
2026-01-29 17:39:42 +08:00
|
|
|
|
|
|
|
|
|
|
.mp-oauth-link {
|
|
|
|
|
|
color: #0877f1;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
}
|
2026-01-19 18:52:18 +08:00
|
|
|
|
</style>
|