Files
shoot-miniprograms/src/pages/my-device.vue
2025-07-11 22:21:34 +08:00

301 lines
7.6 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, onMounted } from "vue";
import Container from "@/components/Container.vue";
import ScreenHint from "@/components/ScreenHint.vue";
import SButton from "@/components/SButton.vue";
import { bindDeviceAPI, getMyDevicesAPI, unbindDeviceAPI } from "@/apis";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const showTip = ref(false);
const confirmBindTip = ref(false);
const addDevice = ref();
const store = useStore();
const { updateDevice } = store;
const { user, device } = storeToRefs(store);
const justBind = ref(false);
// 扫描二维码方法
const handleScan = () => {
// 调用扫码API
uni.scanCode({
// 只支持扫码二维码
onlyFromCamera: true,
scanType: ["qrCode"],
success: async (res) => {
const base64Decode = (str) => {
// 将 base64 转换为 utf8 字符串
const bytes = wx.base64ToArrayBuffer(str);
return String.fromCharCode.apply(null, new Uint8Array(bytes));
};
addDevice.value = JSON.parse(base64Decode(res.result));
confirmBindTip.value = true;
},
fail: (err) => {
console.error("扫码失败:", err);
uni.showToast({
title: "扫码失败",
icon: "error",
});
},
});
};
const confirmBind = async () => {
if (!justBind.value && addDevice.value.id) {
await bindDeviceAPI(addDevice.value);
updateDevice(addDevice.value.id, addDevice.value.name);
confirmBindTip.value = false;
justBind.value = true;
uni.showToast({
title: "绑定成功",
icon: "success",
});
}
};
const toFristTryPage = () => {
uni.navigateTo({
url: "/pages/first-try",
});
};
const unbindDevice = async () => {
await unbindDeviceAPI(device.value.deviceId);
uni.showToast({
title: "解绑成功",
icon: "success",
});
device.value = {};
};
const toDeviceIntroPage = () => {
uni.navigateTo({
url: "/pages/device-intro",
});
};
const backToHome = () => {
uni.navigateBack();
};
</script>
<template>
<Container title="弓箭绑定">
<view v-if="!device.deviceId" class="scan-code">
<view @click="handleScan">
<image src="../static/scan.png" mode="widthFix" />
<text>扫码绑定弓箭</text>
</view>
<view>
<view @click="() => (showTip = true)">找不到我的弓箭</view>
<view @click="toDeviceIntroPage">我还没有弓箭</view>
</view>
<ScreenHint
mode="square"
:show="showTip"
:onClose="() => (showTip = false)"
>
<view class="scan-tips">
<text>找不到我的弓箭 </text>
<text>1.确认弓箭是智能弓箭 </text>
<text>2.确认弓箭有电且电源已开启 </text>
<text>3.进入弓箭绑定功能扫描弓箭上的二维码 </text>
<image src="../static/scan-tip.png" mode="widthFix" />
<text>4.连接成功后</text>
<view>联系在线客服</view>
</view>
</ScreenHint>
<ScreenHint
:show="confirmBindTip"
:onClose="() => (confirmBindTip = false)"
>
<view class="confirm-bind">
<text
>智能弓箭和系统账号需一一对应你确定要将<text
:style="{ color: '#fed847' }"
>当前登录用户账号</text
>绑定<text :style="{ color: '#fed847' }">这把弓箭</text>
绑定后不可随意更换</text
>
<view>
<view @click="confirmBind">确认绑定</view>
<view @click="() => (confirmBindTip = false)">取消</view>
</view>
</view>
</ScreenHint>
</view>
<view v-if="justBind" class="just-bind">
<view class="device-binded">
<view @click="toDeviceIntroPage">
<image src="../static/device-icon.png" mode="widthFix" />
<text>{{ device.deviceName }}</text>
</view>
<image src="../static/bind-success.png" mode="widthFix" />
<view>
<image
:src="user.avatar || '../static/user-icon.png'"
mode="widthFix"
:style="{ borderRadius: '50%' }"
/>
<text>{{ user.nickName }}</text>
</view>
</view>
<view>
<text>恭喜你的弓箭和账号已成功绑定</text>
<text :style="{ color: '#fed847' }">已赠送6个月射灵世界会员</text>
<text>赶快进入新手试炼场体验一下吧</text>
</view>
<SButton :onClick="toFristTryPage">进入新手试炼</SButton>
<view :style="{ marginTop: '15px' }">
<SButton :onClick="backToHome" backgroundColor="#fff3" color="#fff"
>返回首页</SButton
>
</view>
</view>
<view v-if="device.deviceId && !justBind" class="has-device">
<view class="device-binded">
<view @click="toDeviceIntroPage">
<image src="../static/device-icon.png" mode="widthFix" />
<text>{{ device.deviceName }}</text>
</view>
<image src="../static/bind.png" mode="widthFix" />
<view>
<image
:src="user.avatar || '../static/user-icon.png'"
mode="widthFix"
:style="{ borderRadius: '50%' }"
/>
<text>{{ user.nickName }}</text>
</view>
</view>
<SButton :onClick="unbindDevice">解绑</SButton>
</view>
</Container>
</template>
<style scoped>
.scan-code,
.just-bind,
.has-device {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
width: 100%;
height: 100%;
}
.scan-code > view:first-child {
display: flex;
flex-direction: column;
align-items: center;
width: 40%;
color: #fff;
font-size: 14px;
margin: 35% 0;
}
.scan-code > view:first-child > image {
width: 100%;
margin-bottom: 20px;
}
.scan-code > view:nth-child(2) {
display: flex;
flex-direction: column;
align-items: center;
}
.scan-code > view:nth-child(2) > view {
color: #39a8ff;
font-size: 14px;
margin: 10px;
}
.scan-tips {
display: flex;
flex-direction: column;
font-size: 14px;
}
.scan-tips > text {
margin-bottom: 2px;
}
.scan-tips > text:first-child {
color: #fed847;
margin-bottom: 10px;
}
.scan-tips > view:last-child {
color: #39a8ff;
margin-top: 5px;
}
.scan-tips > image {
width: 100%;
margin-bottom: 10px;
}
.confirm-bind {
color: #fff9;
font-size: 14px;
}
.confirm-bind > view:last-child {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.confirm-bind > view:last-child > view {
width: 48%;
border-radius: 20px;
background-color: #fed847;
color: #000;
line-height: 40px;
text-align: center;
}
.confirm-bind > view:last-child > view:nth-child(2) {
color: #fff;
background-color: #fff3;
}
.device-binded {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 14px;
margin: 100px 0;
}
.device-binded > view {
display: flex;
flex-direction: column;
align-items: center;
}
.device-binded > view > image {
width: 24vw;
height: 24vw;
margin-bottom: 5px;
border-radius: 10px;
}
.device-binded > view > text {
width: 120px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
}
.device-binded > image {
width: 16vw;
margin: 0 20px;
}
.has-device,
.just-bind {
justify-content: flex-start;
}
.has-device > view:nth-child(2),
.just-bind > view:nth-child(2) {
color: #fff9;
display: flex;
flex-direction: column;
align-items: center;
font-size: 14px;
margin: 75px 0;
}
.has-device > view:nth-child(2) > text,
.just-bind > view:nth-child(2) > text {
margin: 5px;
}
</style>