588 lines
15 KiB
Vue
588 lines
15 KiB
Vue
<template>
|
||
<view class="page">
|
||
<BackBar title="扫码绑定" />
|
||
<view class="content">
|
||
<view class="robotCont">
|
||
<image :src="`${OSS_URL}/urm/bindDevice/jqr.png`" class="robot" mode="scaleToFill" />
|
||
<image :src="`${OSS_URL}/urm/bindDevice/jqrMsg.png`" class="robotMsg" mode="scaleToFill" />
|
||
</view>
|
||
<!-- 流程 -->
|
||
<view class="process">
|
||
<view class="title">
|
||
<image
|
||
class="UnionLeft"
|
||
:src="`${OSS_URL}/urm/bindDevice/Union.png`"
|
||
mode="scaleToFill"
|
||
/>
|
||
<text>扫码绑定流程</text>
|
||
<image
|
||
class="UnionRight"
|
||
:src="`${OSS_URL}/urm/bindDevice/Union.png`"
|
||
mode="scaleToFill"
|
||
/>
|
||
</view>
|
||
<!-- list -->
|
||
<view v-for="(item, index) in stepList" :key="index" class="list">
|
||
<view class="num">{{ item.num }}</view>
|
||
<view class="cont">
|
||
<view class="contentRight">
|
||
<text class="lest">{{ item.title }}</text>
|
||
<text class="lestCont">{{ item.content }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!--扫码 -->
|
||
<view class="QRbutton" @click="queryBinding">
|
||
<wd-icon name="scan1" size="22px"></wd-icon>
|
||
<text class="QRbuttonText">扫描二维码</text>
|
||
</view>
|
||
</view>
|
||
|
||
<wd-popup v-model="show" custom-style="border-radius: 10px;">
|
||
<view
|
||
class="popuCont"
|
||
:style="{
|
||
height:
|
||
bindProject[0].bindFlag === 0 && bindProject[1].bindFlag === 0 ? '592rpx' : '648rpx',
|
||
}"
|
||
>
|
||
<text class="title">请确定您要绑定的项目</text>
|
||
<view class="option">
|
||
<view v-for="(item2, index2) in bindProject" :key="index2" class="bind_info">
|
||
<view :class="{ Select: item2.show, item: true }" @click="SelectProject(item2)">
|
||
<text>{{ item2.name }}</text>
|
||
<image :src="item2.icon" class="icons" mode="scaleToFill" />
|
||
<image
|
||
class="SelectIcon"
|
||
:src="
|
||
item2.show
|
||
? `${OSS_URL}/urm/bindDevice/SelectIcon.png`
|
||
: `${OSS_URL}/urm/bindDevice/NoSelectIcon.png`
|
||
"
|
||
mode="scaleToFill"
|
||
/>
|
||
</view>
|
||
<text v-if="item2.bindFlag === 1" class="bind_text">{{ item2.bindText }}</text>
|
||
</view>
|
||
</view>
|
||
<view v-for="(itCont, itIndex) in contList" :key="itIndex" class="contList">
|
||
<text>·</text>
|
||
<view>{{ itCont }}</view>
|
||
</view>
|
||
<!-- 确认 -->
|
||
<view class="confirm" @click="determine">确定</view>
|
||
</view>
|
||
</wd-popup>
|
||
<!-- 设备、孩子账号已绑定 -->
|
||
<wd-popup v-model="showAllBindPopup" custom-style="border-radius: 10px;">
|
||
<view class="all_bind">
|
||
<text class="title">您已绑定当前设备和账号,无需重复操作</text>
|
||
<!-- 确认 -->
|
||
<view class="confirm" @click="showAllBindPopup = false">确定</view>
|
||
</view>
|
||
</wd-popup>
|
||
<TipPopup
|
||
v-model="showSuccessPopup"
|
||
showBtn
|
||
:text="bindType === 'success' ? '绑定成功' : '绑定失败'"
|
||
:type="bindType"
|
||
:messageTip="successPopupText"
|
||
:btnText="bindType === 'success' ? '确定' : '好的'"
|
||
@backBtn="successPopupBtn"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 扫码 -->
|
||
<!-- #ifdef H5 -->
|
||
<cshaptx4869-scancode
|
||
v-if="h5ScanCode"
|
||
@success="handleSuccess"
|
||
@fail="handleFail"
|
||
@close="handleClose"
|
||
></cshaptx4869-scancode>
|
||
<!-- #endif -->
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue'
|
||
import { getCurInfo, parentBindAdmin } from '@/api'
|
||
import { userStore, shareConfigStore } from '@/store'
|
||
import { storeToRefs } from 'pinia'
|
||
import TipPopup from '@/components/TipPopup/index.vue'
|
||
import router from '@/router/router'
|
||
import jWeixin from 'weixin-js-sdk'
|
||
const { initWeixinShareConfig } = shareConfigStore()
|
||
|
||
const { userInfo } = storeToRefs(userStore())
|
||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||
const show = ref(false)
|
||
|
||
const showAllBindPopup = ref(false)
|
||
const QRCode = ref() // 扫码结果
|
||
const childUserIds = ref()
|
||
const h5ScanCode = ref(false)
|
||
const resData = ref()
|
||
|
||
const showSuccessPopup = ref(false)
|
||
const bindType = ref('success')
|
||
const successPopupText = ref('')
|
||
|
||
const stepList = ref([
|
||
{
|
||
num: '01',
|
||
title: '第一步',
|
||
content: '打开学习机,来到「设置」界面;',
|
||
},
|
||
{
|
||
num: '02',
|
||
title: '第二步',
|
||
content: '点击「设备」,获取二维码,先扫码关注公众号;',
|
||
},
|
||
{
|
||
num: '03',
|
||
title: '第三步',
|
||
content: '进入公众号,点击「家长助手」扫码绑定,扫描二维码选择绑定设备/账号。',
|
||
},
|
||
])
|
||
|
||
// 绑定项目
|
||
const bindProject = ref([
|
||
{
|
||
name: '当前设备',
|
||
show: true,
|
||
icon: `${OSS_URL}/urm/bindDevice/bindIcon1.png`,
|
||
bindFlag: 0, // 0-未绑定 1-已绑定
|
||
adminFlag: false, // 是否已有管理员
|
||
bindText: '已绑定当前设备',
|
||
},
|
||
{
|
||
name: '孩子账号',
|
||
show: true,
|
||
icon: `${OSS_URL}/urm/bindDevice/bindIcon2.png`,
|
||
bindFlag: 0, // 0-未绑定 1-已绑定
|
||
adminFlag: false, // 是否已有管理员
|
||
bindText: '已绑定当前孩子账号',
|
||
},
|
||
])
|
||
|
||
const contList = ref([
|
||
'第一个绑定设备/帐号的用户自动成为管理员',
|
||
'绑定账号可以查看孩子的学情报告;',
|
||
'绑定设备可以对设备进行管控。',
|
||
])
|
||
|
||
async function queryBinding() {
|
||
const ua = navigator?.userAgent?.toLowerCase()
|
||
const isWechatBrowser = ua?.indexOf('micromessenger') !== -1
|
||
if (!isWechatBrowser) {
|
||
// 非微信环境
|
||
h5ScanCode.value = true
|
||
return
|
||
}
|
||
jWeixin.scanQRCode({
|
||
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
|
||
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
|
||
success: async function (res) {
|
||
let result = res.resultStr
|
||
resData.value = JSON.parse(result)
|
||
QRCode.value = resData.value.simSerialNumber
|
||
childUserIds.value = resData.value.userId
|
||
await fetchCurBindInfo()
|
||
},
|
||
fail: function (response) {
|
||
uni.showToast({
|
||
title: '扫码失败',
|
||
icon: 'none',
|
||
})
|
||
},
|
||
})
|
||
}
|
||
|
||
function SelectProject(e: any) {
|
||
// 无管理员必选
|
||
if (!e.adminFlag) return
|
||
// 已绑定
|
||
if (e.bindFlag === 1) return
|
||
e.show = !e.show
|
||
}
|
||
// 只绑定设备-弹窗
|
||
function successPopupBtn() {
|
||
showSuccessPopup.value = false
|
||
router.navigateTo('/pages/home/index')
|
||
}
|
||
async function determine() {
|
||
// 暂时
|
||
// QRCode.value = 'AADXM1010061';
|
||
// childUserIds.value = '1753596310747975684';
|
||
// fetchCurBindInfo();
|
||
// ------
|
||
if (!bindProject.value[0].show && !bindProject.value[1].show) return
|
||
let obj = {
|
||
childDto: {},
|
||
deviceDto: {},
|
||
simSerialNumber: '',
|
||
childUserId: '',
|
||
}
|
||
if (bindProject.value[0].show) {
|
||
obj.deviceDto = bindProject.value[0]
|
||
obj.simSerialNumber = QRCode.value
|
||
}
|
||
if (bindProject.value[1].show) {
|
||
obj.childDto = bindProject.value[1]
|
||
obj.childUserId = childUserIds.value
|
||
}
|
||
show.value = false
|
||
if (obj.simSerialNumber && !obj.childUserId) {
|
||
let _obj: any
|
||
if (bindProject.value[0].adminFlag) {
|
||
// 设备已有管理员
|
||
_obj = {
|
||
simSerialNumber: obj.simSerialNumber,
|
||
type: 1,
|
||
}
|
||
router.navigateTo({
|
||
path: '/pages/home/bindDevice/applyForBinding',
|
||
query: { parameter: JSON.stringify(_obj) },
|
||
})
|
||
} else {
|
||
_obj = {
|
||
deviceDto: {
|
||
simSerialNumber: obj.simSerialNumber,
|
||
},
|
||
}
|
||
const res = await parentBindAdmin(_obj)
|
||
showSuccessPopup.value = true
|
||
successPopupText.value = res === 6 ? '您已成为设备管理员' : '请稍后再进行尝试~'
|
||
bindType.value = res === 6 ? 'success' : 'fail'
|
||
}
|
||
} else {
|
||
router.navigateTo({
|
||
path: './familyRelationships',
|
||
query: { parameter: JSON.stringify(obj) },
|
||
})
|
||
}
|
||
}
|
||
|
||
// 扫码部分
|
||
async function handleSuccess(res: string) {
|
||
h5ScanCode.value = false
|
||
resData.value = JSON.parse(res)
|
||
QRCode.value = resData.value.simSerialNumber
|
||
childUserIds.value = resData.value.userId
|
||
await fetchCurBindInfo()
|
||
}
|
||
function handleFail(err: any) {
|
||
uni.showModal({
|
||
title: err.errName,
|
||
content: err.errMsg,
|
||
complete: () => {
|
||
h5ScanCode.value = false
|
||
},
|
||
})
|
||
}
|
||
|
||
function handleClose() {
|
||
h5ScanCode.value = false
|
||
}
|
||
// 绑定前获取当前绑定情况
|
||
async function fetchCurBindInfo() {
|
||
try {
|
||
uni.showLoading({
|
||
title: '加载中...',
|
||
mask: true,
|
||
})
|
||
const data = await getCurInfo({
|
||
parentUerId: userInfo.value.id,
|
||
simSerialNumber: QRCode.value, // 设备序列号
|
||
childUserId: childUserIds.value, // 孩子账号
|
||
})
|
||
bindProject.value[0].bindFlag = data.device.bindFlag
|
||
bindProject.value[0].adminFlag = data.deviceAdminFlag
|
||
bindProject.value[0].show = data.device.bindFlag === 0
|
||
bindProject.value[1].bindFlag = data.child.bindFlag
|
||
bindProject.value[1].adminFlag = data.childAdminFlag
|
||
bindProject.value[1].show = data.child.bindFlag === 0
|
||
if (Number(data.device.bindFlag) === 1 && Number(data.child.bindFlag) === 1) {
|
||
// 两者都绑定了
|
||
showAllBindPopup.value = true
|
||
show.value = false
|
||
} else {
|
||
showAllBindPopup.value = false
|
||
show.value = true
|
||
}
|
||
} finally {
|
||
uni.hideLoading()
|
||
}
|
||
}
|
||
onMounted(async () => {
|
||
uni.showLoading({
|
||
title: '加载中...',
|
||
icon: 'none',
|
||
mask: true,
|
||
})
|
||
await initWeixinShareConfig()
|
||
uni.hideLoading()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page {
|
||
height: 100vh;
|
||
box-sizing: border-box;
|
||
}
|
||
.content {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: calc(100vh - 44rpx);
|
||
background-image: url('https://xuexiaole-1313840333.cos.ap-guangzhou.myqcloud.com/xuexiaoleClient/urm/bindDevice/bindDeviceBgImg.png');
|
||
background-size: cover;
|
||
box-sizing: border-box;
|
||
|
||
.robotCont {
|
||
width: 100%;
|
||
// margin-top: 40upx;
|
||
display: flex;
|
||
z-index: 1;
|
||
|
||
.robot {
|
||
width: 250upx;
|
||
height: 312upx;
|
||
}
|
||
.robotMsg {
|
||
width: 486upx;
|
||
height: 220upx;
|
||
margin-top: 30upx;
|
||
margin-left: -30upx;
|
||
}
|
||
}
|
||
.process {
|
||
width: 690upx;
|
||
height: 1016upx;
|
||
margin-left: 30upx;
|
||
display: flex;
|
||
z-index: 0;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
border-radius: 20upx;
|
||
border: 1upx rgba(255, 255, 255, 0.3);
|
||
background: rgba(255, 255, 255, 0.5);
|
||
backdrop-filter: blur(2.9000000953674316upx);
|
||
margin-top: -77upx;
|
||
padding: 40upx 30upx;
|
||
box-sizing: border-box;
|
||
|
||
.title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20upx;
|
||
.UnionLeft {
|
||
width: 35upx;
|
||
height: 8upx;
|
||
}
|
||
|
||
text {
|
||
font-size: 36upx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.UnionRight {
|
||
width: 35upx;
|
||
height: 8upx;
|
||
transform: rotate(180deg);
|
||
}
|
||
}
|
||
|
||
.list {
|
||
width: 630upx;
|
||
// height: 157upx;
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
margin-top: 40upx;
|
||
|
||
.num {
|
||
width: 125upx;
|
||
height: 60upx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 48upx;
|
||
color: #fff;
|
||
background: #615dff;
|
||
border-radius: 0 50upx 50upx 0;
|
||
position: absolute;
|
||
left: 0upx;
|
||
top: 20upx;
|
||
}
|
||
.cont {
|
||
width: 610upx;
|
||
// height: 157upx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
border-radius: 20upx;
|
||
background: rgba(255, 255, 255, 0.8);
|
||
margin-left: 20upx;
|
||
padding: 30upx;
|
||
box-sizing: border-box;
|
||
|
||
.contentRight {
|
||
width: 450upx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
margin-left: 90upx;
|
||
.lest {
|
||
font-size: 32upx;
|
||
height: 48upx;
|
||
}
|
||
.lestCont {
|
||
color: #666;
|
||
font-size: 30upx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.QRbutton {
|
||
width: 610upx;
|
||
height: 90upx;
|
||
background: #615dff;
|
||
border-radius: 20upx;
|
||
margin-top: 60upx;
|
||
color: #fff;
|
||
font-size: 30upx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.QRbuttonText {
|
||
margin-left: 10upx;
|
||
font-size: 30upx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.all_bind {
|
||
display: flex;
|
||
justify-content: center;
|
||
height: 330rpx;
|
||
width: 594upx;
|
||
background: #fff;
|
||
border-radius: 20upx;
|
||
.title {
|
||
margin-top: 66rpx;
|
||
display: inline-block;
|
||
width: 448rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 400;
|
||
line-height: 44rpx;
|
||
}
|
||
.confirm {
|
||
position: absolute;
|
||
bottom: 0upx;
|
||
width: 100%;
|
||
height: 108upx;
|
||
border-top: solid 1upx rgba(238, 238, 238, 1);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 34upx;
|
||
color: rgba(51, 51, 51, 1);
|
||
}
|
||
}
|
||
.popuCont {
|
||
width: 594upx;
|
||
height: 592upx;
|
||
background: #fff;
|
||
border-radius: 20upx;
|
||
padding: 50upx;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
// justify-content: center;
|
||
|
||
.title {
|
||
font-size: 34upx;
|
||
color: #333;
|
||
}
|
||
|
||
.option {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 30upx;
|
||
margin-top: 50upx;
|
||
margin-bottom: 20upx;
|
||
.bind_info {
|
||
flex: 1;
|
||
border-radius: 20rpx;
|
||
border: 2rpx solid transparent;
|
||
.item {
|
||
height: 120upx;
|
||
background-image: url('https://xuexiaole-1313840333.cos.ap-guangzhou.myqcloud.com/xuexiaoleClient/urm/bindDevice/bindPorjectBgimg.png');
|
||
background-size: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: rgba(65, 78, 145, 1);
|
||
font-size: 26upx;
|
||
border-radius: 20upx;
|
||
position: relative;
|
||
|
||
.icons {
|
||
width: 54upx;
|
||
height: 54upx;
|
||
margin-left: 20upx;
|
||
}
|
||
|
||
.SelectIcon {
|
||
width: 40upx;
|
||
height: 40upx;
|
||
position: absolute;
|
||
bottom: 0;
|
||
right: 0;
|
||
}
|
||
}
|
||
.bind_text {
|
||
margin-top: 20rpx;
|
||
display: inline-block;
|
||
width: 100%;
|
||
color: #a9aab5;
|
||
font-size: 24rpx;
|
||
line-height: 36rpx;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
.Select {
|
||
border: 2rpx solid #615dff;
|
||
}
|
||
}
|
||
.contList {
|
||
width: 100%;
|
||
display: flex;
|
||
font-size: 26upx;
|
||
color: rgba(51, 51, 51, 1);
|
||
line-height: 39upx;
|
||
}
|
||
|
||
.confirm {
|
||
position: absolute;
|
||
bottom: 0upx;
|
||
width: 100%;
|
||
height: 108upx;
|
||
border-top: solid 1upx rgba(238, 238, 238, 1);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 34upx;
|
||
color: rgba(51, 51, 51, 1);
|
||
}
|
||
}
|
||
</style>
|