Files
shoot-miniprograms/src/pages/org-bind.vue
T

180 lines
4.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import Signin from "@/components/Signin.vue";
import SButton from "@/components/SButton.vue";
import DeviceChargingDialog from "@/components/DeviceChargingDialog.vue";
import { tempBindOrgAPI } from "@/apis";
const scene = ref("");
const status = ref("idle");
const errorMessage = ref("");
const showSignin = ref(false);
const binding = ref(false);
const getToken = () => {
try {
const env = uni.getAccountInfoSync().miniProgram.envVersion;
return uni.getStorageSync(`${env}_token`);
} catch (error) {
return "";
}
};
const openSignin = () => {
showSignin.value = true;
};
const closeSignin = () => {
showSignin.value = false;
};
const bindOrg = async () => {
if (binding.value || !scene.value) return;
if (!getToken()) {
status.value = "login";
return;
}
binding.value = true;
status.value = "binding";
errorMessage.value = "";
try {
await tempBindOrgAPI(scene.value);
status.value = "success";
} catch (error) {
if (error?.type === "AUTH_INVALID") {
status.value = "login";
errorMessage.value = "登录已失效,请重新登录后完成绑定。";
} else {
status.value = "failed";
errorMessage.value = error?.message || "网络异常,请稍后重试。";
}
} finally {
binding.value = false;
}
};
const handleLoginSuccess = async () => {
await bindOrg();
};
onLoad((options) => {
try {
const value = decodeURIComponent(String(options?.scene || ""));
if (!/^org_\d+$/.test(value)) {
status.value = "invalid";
return;
}
scene.value = value;
if (getToken()) {
void bindOrg();
} else {
status.value = "login";
}
} catch (error) {
status.value = "invalid";
}
});
</script>
<template>
<view class="page">
<view class="content">
<text class="title">机构设备绑定</text>
<view v-if="status === 'idle' || status === 'binding'" class="state">
<text class="state-title">正在绑定</text>
<text class="description">正在绑定机构设备请稍候……</text>
</view>
<view v-else-if="status === 'login'" class="state">
<text class="state-title">请先登录</text>
<text class="description">
{{
errorMessage ||
"登录后即可绑定当前机构设备。关闭登录窗口后,也可以再次点击下方按钮继续。"
}}
</text>
<SButton width="560rpx" :rounded="20" :onClick="openSignin">
<text>立即登录</text>
</SButton>
</view>
<view v-else-if="status === 'success'" class="state">
<text class="state-title">绑定成功</text>
<text class="description">
您的账号已成功绑定机构设备请返回 iPad 继续操作
</text>
</view>
<view v-else-if="status === 'failed'" class="state">
<text class="state-title">绑定失败</text>
<text class="description">{{ errorMessage }}</text>
<SButton width="560rpx" :rounded="20" :onClick="bindOrg">
<text>重新绑定</text>
</SButton>
</view>
<view v-else class="state">
<text class="state-title">二维码无效</text>
<text class="description">请重新扫描机构设备上的小程序码</text>
</view>
</view>
<Signin
:show="showSignin"
:onClose="closeSignin"
:onSuccess="handleLoginSuccess"
/>
<DeviceChargingDialog />
</view>
</template>
<style scoped lang="scss">
.page {
box-sizing: border-box;
width: 100%;
min-height: 100vh;
padding: calc(var(--status-bar-height) + 120rpx) 48rpx 80rpx;
background-color: #000;
color: #fff;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
}
.title {
font-size: 44rpx;
font-weight: 600;
}
.state {
width: 100%;
margin-top: 120rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.state-title {
font-size: 36rpx;
font-weight: 600;
}
.description {
max-width: 600rpx;
margin: 32rpx 0 64rpx;
color: #b8b8b8;
font-size: 28rpx;
line-height: 1.8;
text-align: center;
}
</style>