Files
shoot-miniprograms/src/pages/my-device.vue

301 lines
7.6 KiB
Vue
Raw Normal View History

2025-05-29 15:48:38 +08:00
<script setup>
2025-05-31 14:17:56 +08:00
import { ref, onMounted } from "vue";
2025-05-29 15:48:38 +08:00
import Container from "@/components/Container.vue";
2025-06-19 21:03:33 +08:00
import ScreenHint from "@/components/ScreenHint.vue";
2025-05-29 15:48:38 +08:00
import SButton from "@/components/SButton.vue";
2025-05-31 14:17:56 +08:00
import { bindDeviceAPI, getMyDevicesAPI, unbindDeviceAPI } from "@/apis";
2025-05-29 15:48:38 +08:00
import useStore from "@/store";
import { storeToRefs } from "pinia";
const showTip = ref(false);
const confirmBindTip = ref(false);
2025-05-31 14:17:56 +08:00
const addDevice = ref();
2025-05-29 15:48:38 +08:00
const store = useStore();
2025-06-16 00:30:56 +08:00
const { updateDevice } = store;
const { user, device } = storeToRefs(store);
2025-05-31 14:17:56 +08:00
const justBind = ref(false);
2025-05-29 15:48:38 +08:00
// 扫描二维码方法
const handleScan = () => {
// 调用扫码API
uni.scanCode({
// 只支持扫码二维码
onlyFromCamera: true,
scanType: ["qrCode"],
success: async (res) => {
2025-06-16 00:30:56 +08:00
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;
2025-05-29 15:48:38 +08:00
},
fail: (err) => {
console.error("扫码失败:", err);
uni.showToast({
title: "扫码失败",
icon: "error",
});
},
});
};
const confirmBind = async () => {
2025-06-22 15:04:10 +08:00
if (!justBind.value && addDevice.value.id) {
2025-05-31 14:17:56 +08:00
await bindDeviceAPI(addDevice.value);
2025-06-16 00:30:56 +08:00
updateDevice(addDevice.value.id, addDevice.value.name);
confirmBindTip.value = false;
2025-05-31 14:17:56 +08:00
justBind.value = true;
2025-05-29 15:48:38 +08:00
uni.showToast({
title: "绑定成功",
icon: "success",
});
}
};
const toFristTryPage = () => {
uni.navigateTo({
url: "/pages/first-try",
});
};
2025-05-31 14:17:56 +08:00
const unbindDevice = async () => {
await unbindDeviceAPI(device.value.deviceId);
uni.showToast({
title: "解绑成功",
icon: "success",
});
device.value = {};
};
const toDeviceIntroPage = () => {
uni.navigateTo({
url: "/pages/device-intro",
});
};
2025-06-16 00:30:56 +08:00
const backToHome = () => {
uni.navigateBack();
};
2025-05-29 15:48:38 +08:00
</script>
<template>
<Container title="弓箭绑定">
2025-06-16 00:30:56 +08:00
<view v-if="!device.deviceId" class="scan-code">
2025-05-29 15:48:38 +08:00
<view @click="handleScan">
<image src="../static/scan.png" mode="widthFix" />
<text>扫码绑定弓箭</text>
</view>
2025-06-19 01:55:40 +08:00
<view>
<view @click="() => (showTip = true)">找不到我的弓箭</view>
<view @click="toDeviceIntroPage">我还没有弓箭</view>
2025-05-29 15:48:38 +08:00
</view>
2025-06-19 21:03:33 +08:00
<ScreenHint
2025-05-29 15:48:38 +08:00
mode="square"
:show="showTip"
:onClose="() => (showTip = false)"
>
<view class="scan-tips">
2025-07-10 15:34:00 +08:00
<text>找不到我的弓箭 </text>
<text>1.确认弓箭是智能弓箭 </text>
<text>2.确认弓箭有电且电源已开启 </text>
<text>3.进入弓箭绑定功能扫描弓箭上的二维码 </text>
2025-05-29 15:48:38 +08:00
<image src="../static/scan-tip.png" mode="widthFix" />
2025-07-10 15:34:00 +08:00
<text>4.连接成功后</text>
2025-05-29 15:48:38 +08:00
<view>联系在线客服</view>
</view>
2025-06-19 21:03:33 +08:00
</ScreenHint>
<ScreenHint
2025-05-29 15:48:38 +08:00
: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>
2025-06-19 21:03:33 +08:00
</ScreenHint>
2025-05-29 15:48:38 +08:00
</view>
2025-05-31 14:17:56 +08:00
<view v-if="justBind" class="just-bind">
<view class="device-binded">
<view @click="toDeviceIntroPage">
2025-05-29 15:48:38 +08:00
<image src="../static/device-icon.png" mode="widthFix" />
<text>{{ device.deviceName }}</text>
</view>
2025-05-31 14:17:56 +08:00
<image src="../static/bind-success.png" mode="widthFix" />
2025-05-29 15:48:38 +08:00
<view>
2025-05-31 14:17:56 +08:00
<image
2025-07-11 22:21:34 +08:00
:src="user.avatar || '../static/user-icon.png'"
2025-05-31 14:17:56 +08:00
mode="widthFix"
:style="{ borderRadius: '50%' }"
/>
2025-05-29 15:48:38 +08:00
<text>{{ user.nickName }}</text>
</view>
</view>
<view>
<text>恭喜你的弓箭和账号已成功绑定</text>
<text :style="{ color: '#fed847' }">已赠送6个月射灵世界会员</text>
<text>赶快进入新手试炼场体验一下吧</text>
</view>
<SButton :onClick="toFristTryPage">进入新手试炼</SButton>
2025-06-16 00:30:56 +08:00
<view :style="{ marginTop: '15px' }">
<SButton :onClick="backToHome" backgroundColor="#fff3" color="#fff"
>返回首页</SButton
>
</view>
2025-05-29 15:48:38 +08:00
</view>
2025-06-16 00:30:56 +08:00
<view v-if="device.deviceId && !justBind" class="has-device">
2025-05-31 14:17:56 +08:00
<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
2025-07-11 22:21:34 +08:00
:src="user.avatar || '../static/user-icon.png'"
2025-05-31 14:17:56 +08:00
mode="widthFix"
:style="{ borderRadius: '50%' }"
/>
<text>{{ user.nickName }}</text>
</view>
</view>
<SButton :onClick="unbindDevice">解绑</SButton>
</view>
2025-05-29 15:48:38 +08:00
</Container>
</template>
<style scoped>
2025-05-31 14:17:56 +08:00
.scan-code,
.just-bind,
.has-device {
2025-05-29 15:48:38 +08:00
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
width: 100%;
height: 100%;
}
2025-05-31 14:17:56 +08:00
.scan-code > view:first-child {
2025-05-29 15:48:38 +08:00
display: flex;
flex-direction: column;
align-items: center;
width: 40%;
color: #fff;
font-size: 14px;
2025-06-16 11:26:57 +08:00
margin: 35% 0;
2025-05-29 15:48:38 +08:00
}
2025-05-31 14:17:56 +08:00
.scan-code > view:first-child > image {
2025-05-29 15:48:38 +08:00
width: 100%;
margin-bottom: 20px;
}
2025-05-31 14:17:56 +08:00
.scan-code > view:nth-child(2) {
2025-05-29 15:48:38 +08:00
display: flex;
flex-direction: column;
align-items: center;
}
2025-05-31 14:17:56 +08:00
.scan-code > view:nth-child(2) > view {
2025-05-29 15:48:38 +08:00
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 {
2025-06-16 00:30:56 +08:00
color: #fff9;
font-size: 14px;
2025-05-29 15:48:38 +08:00
}
.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;
}
2025-05-31 14:17:56 +08:00
.device-binded {
2025-05-29 15:48:38 +08:00
width: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 14px;
2025-06-16 00:30:56 +08:00
margin: 100px 0;
2025-05-29 15:48:38 +08:00
}
2025-05-31 14:17:56 +08:00
.device-binded > view {
2025-05-29 15:48:38 +08:00
display: flex;
flex-direction: column;
align-items: center;
}
2025-05-31 14:17:56 +08:00
.device-binded > view > image {
2025-05-29 15:48:38 +08:00
width: 24vw;
2025-06-16 00:30:56 +08:00
height: 24vw;
2025-05-29 15:48:38 +08:00
margin-bottom: 5px;
border-radius: 10px;
}
2025-06-16 11:26:57 +08:00
.device-binded > view > text {
width: 120px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
}
2025-05-31 14:17:56 +08:00
.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) {
2025-05-29 15:48:38 +08:00
color: #fff9;
display: flex;
flex-direction: column;
align-items: center;
font-size: 14px;
2025-05-31 14:17:56 +08:00
margin: 75px 0;
2025-05-29 15:48:38 +08:00
}
2025-05-31 14:17:56 +08:00
.has-device > view:nth-child(2) > text,
.just-bind > view:nth-child(2) > text {
2025-05-29 15:48:38 +08:00
margin: 5px;
}
</style>