<template>
|
<!-- #ifdef MP-WEIXIN -->
|
<view class="phone-auth" v-if="visible">
|
<view class="phone-auth__mask" @tap="later"></view>
|
<view class="phone-auth__panel">
|
<text class="phone-auth__title">授权手机号</text>
|
<text class="phone-auth__desc">
|
回收、预约等功能需要使用您的手机号。请授权后再继续使用。
|
</text>
|
<button
|
class="phone-auth__btn"
|
open-type="getPhoneNumber"
|
@getphonenumber="onGetPhone"
|
>
|
登录并授权手机号
|
</button>
|
<view class="phone-auth__later" @tap="later">暂不授权</view>
|
</view>
|
</view>
|
<!-- #endif -->
|
</template>
|
|
<script lang="ts" setup>
|
import { computed, ref } from "vue";
|
import { onShow } from "@dcloudio/uni-app";
|
import { useCool, useStore, useWx } from "/@/cool";
|
import { phoneAuthState } from "/@/cool/mini-login";
|
import { useUi } from "/$/cool-ui";
|
|
const authState = phoneAuthState();
|
|
const { service, router } = useCool();
|
const { user } = useStore();
|
const wx = useWx();
|
const ui = useUi();
|
const tick = ref(0);
|
const submitting = ref(false);
|
|
const visible = computed(() => {
|
tick.value;
|
return authState.ready && !authState.dismissed && (!user.token || !user.info?.phone);
|
});
|
|
function later() {
|
authState.dismissed = true;
|
tick.value++;
|
}
|
|
function phonePayload(detail: { code?: string; encryptedData?: string; iv?: string }) {
|
// 新版手机号按钮只返回动态令牌,必须原样提交,不能换成 wx.login 的 code
|
if (detail.code && !detail.encryptedData) {
|
return { code: detail.code };
|
}
|
return {
|
encryptedData: detail.encryptedData,
|
iv: detail.iv,
|
code: wx.code.value,
|
};
|
}
|
|
function enterHome(phone: string) {
|
user.set({
|
...(user.info || {}),
|
phone,
|
});
|
authState.dismissed = true;
|
tick.value++;
|
router.home();
|
}
|
|
function onGetPhone(e: {
|
detail: { errMsg?: string; code?: string; encryptedData?: string; iv?: string };
|
}) {
|
const detail = e.detail || {};
|
const errMsg = detail.errMsg || "";
|
if (errMsg.indexOf("ok") < 0) {
|
ui.showToast("未授权手机号");
|
return;
|
}
|
if (!detail.code && !detail.encryptedData) {
|
ui.showToast("未获取到手机号");
|
return;
|
}
|
if (submitting.value) {
|
return;
|
}
|
|
submitting.value = true;
|
ui.showLoading();
|
|
const task = new Promise<string>((resolve) => {
|
uni.login({
|
provider: "weixin",
|
success: (res) => resolve(res.code || ""),
|
fail: () => resolve(""),
|
});
|
})
|
.then((loginCode) => {
|
return service.user.login.miniPhone({
|
...phonePayload(detail),
|
loginCode,
|
});
|
})
|
.then(async (res) => {
|
user.setToken(res);
|
let info = user.info;
|
try {
|
info = (await service.user.info.person()) || info;
|
} catch (err) {
|
console.error(err);
|
}
|
const phone = info?.phone || res.phone;
|
user.set({
|
...(info || {}),
|
phone,
|
});
|
return phone as string | undefined;
|
});
|
|
task
|
.then((phone) => {
|
ui.hideLoading();
|
submitting.value = false;
|
if (!phone) {
|
ui.showToast("未获取到手机号");
|
return;
|
}
|
enterHome(phone);
|
})
|
.catch((err) => {
|
ui.hideLoading();
|
submitting.value = false;
|
ui.showToast(err?.message || "手机号授权失败");
|
});
|
}
|
|
onShow(() => {
|
tick.value++;
|
});
|
</script>
|
|
<style lang="scss" scoped>
|
.phone-auth {
|
position: fixed;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
left: 0;
|
z-index: 10000;
|
|
&__mask {
|
position: absolute;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
left: 0;
|
background: rgba(0, 0, 0, 0.45);
|
}
|
|
&__panel {
|
position: absolute;
|
left: 48rpx;
|
right: 48rpx;
|
top: 30%;
|
background: #fff;
|
border-radius: 24rpx;
|
padding: 48rpx 40rpx 36rpx;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
}
|
|
&__title {
|
font-size: 34rpx;
|
font-weight: 600;
|
color: #222;
|
}
|
|
&__desc {
|
margin-top: 20rpx;
|
font-size: 26rpx;
|
line-height: 1.6;
|
color: #666;
|
text-align: center;
|
}
|
|
&__btn {
|
margin-top: 36rpx;
|
width: 100%;
|
height: 84rpx;
|
line-height: 84rpx;
|
border-radius: 42rpx;
|
background: #2ecc71;
|
color: #fff;
|
font-size: 30rpx;
|
border: 0;
|
}
|
|
&__later {
|
margin-top: 24rpx;
|
font-size: 26rpx;
|
color: #999;
|
}
|
}
|
</style>
|