2025-11-08 11:30:06 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<view class="device-detail">
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<app-top-push-notice />
|
2025-11-08 11:30:06 +08:00
|
|
|
|
<view class="bj">
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 顶部导航 -->
|
|
|
|
|
|
<view class="tabback">
|
|
|
|
|
|
<view class="rtjt" @click="btnback">←</view>
|
|
|
|
|
|
<view class="name">{{$i18n.t('bjsb')}}</view>
|
|
|
|
|
|
<view @click="btnedit">{{$i18n.t('editSpace')}}</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="content-container">
|
|
|
|
|
|
<!-- 设备ID 灰条 -->
|
|
|
|
|
|
<view class="id-strip">
|
|
|
|
|
|
<text class="id-text">{{ $i18n.t('deviceIdLabel') }}:{{deviceId}}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 白色信息卡:设备ID 与 名称输入 -->
|
|
|
|
|
|
<view class="card">
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view class="field" @tap="openDeviceNameModal">
|
2025-11-08 11:30:06 +08:00
|
|
|
|
<text class="field-label">{{ $i18n.t('deviceName') }}</text>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view class="field-value">{{ deviceName || '—' }}</view>
|
2025-11-08 11:30:06 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 提示说明 -->
|
|
|
|
|
|
<view class="tip-box">
|
|
|
|
|
|
<text class="tip-text">{{ $i18n.t('deviceNameTip') }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 列表:添加房间 -->
|
|
|
|
|
|
<view class="list">
|
|
|
|
|
|
<view :class="activeindex == index ? 'active' : ''" @click="onAddRoom(item,index)" v-for="(item,index) in roomlist" :key="index">
|
|
|
|
|
|
<text class="cell-title">{{ item.name }}</text>
|
|
|
|
|
|
<text v-if="activeindex == index">✔</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 底部添加设备按钮 -->
|
|
|
|
|
|
<view class="button-section">
|
|
|
|
|
|
<button class="continue-btn" @click="handleContinue">{{$i18n.t('deldev')}}</button>
|
|
|
|
|
|
</view>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<DeviceNameEditModal
|
|
|
|
|
|
:visible="deviceNameModalVisible"
|
|
|
|
|
|
:value="deviceNameModalDraft"
|
|
|
|
|
|
:title="$i18n.t('deviceName')"
|
|
|
|
|
|
:placeholder="$i18n.t('deviceNamePlaceholder')"
|
|
|
|
|
|
:cancel-text="$i18n.t('cancel')"
|
|
|
|
|
|
:confirm-text="$i18n.t('confirm')"
|
|
|
|
|
|
@close="deviceNameModalVisible = false"
|
|
|
|
|
|
@confirm="onDeviceNameModalConfirm"
|
|
|
|
|
|
/>
|
2025-11-08 11:30:06 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
import { patchDeviceRoomInStorage } from '@/common/utils/deviceRoomOverlay.js'
|
|
|
|
|
|
import DeviceNameEditModal from '@/common/components/DeviceNameEditModal.vue'
|
2025-11-08 11:30:06 +08:00
|
|
|
|
export default {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
components: { DeviceNameEditModal },
|
2025-11-08 11:30:06 +08:00
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
deviceId: '', // 设备ID输入值
|
|
|
|
|
|
deviceName: '',
|
2026-04-28 13:55:17 +08:00
|
|
|
|
deviceNameModalVisible: false,
|
|
|
|
|
|
deviceNameModalDraft: '',
|
2025-11-08 11:30:06 +08:00
|
|
|
|
kjid:'',
|
|
|
|
|
|
roomlist:[],
|
|
|
|
|
|
activeindex:-1,
|
|
|
|
|
|
roomid:'',
|
|
|
|
|
|
id:'',
|
2026-04-28 13:55:17 +08:00
|
|
|
|
fangdouflag:true,
|
|
|
|
|
|
xqobj: {},
|
2025-11-08 11:30:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onLoad(option) {
|
|
|
|
|
|
this.kjid = uni.getStorageSync('kjid');
|
|
|
|
|
|
this.id = option.id
|
|
|
|
|
|
this.getxq()
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
// 进行设备详情请求
|
|
|
|
|
|
getxq(){
|
|
|
|
|
|
this.$http.get(`/bst/device/detail?id=${this.id}`).then(res => {
|
|
|
|
|
|
if(res.code == 200){
|
2026-04-28 13:55:17 +08:00
|
|
|
|
this.xqobj = res.data
|
2025-11-08 11:30:06 +08:00
|
|
|
|
this.deviceId = res.data.sn
|
|
|
|
|
|
this.deviceName = res.data.name
|
|
|
|
|
|
this.roomid = res.data.roomId
|
|
|
|
|
|
this.getlist()
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
// 点击删除设备
|
|
|
|
|
|
handleContinue(){
|
|
|
|
|
|
uni.showModal({
|
|
|
|
|
|
title: this.$i18n.t('confirmDeleteDeviceTitle'),
|
|
|
|
|
|
content: this.$i18n.t('confirmDeleteDeviceContent'),
|
|
|
|
|
|
cancelText: this.$i18n.t('modalCancel'),
|
|
|
|
|
|
confirmText: this.$i18n.t('modalConfirm'),
|
|
|
|
|
|
success: (res) => {
|
|
|
|
|
|
if (res.confirm) {
|
|
|
|
|
|
let data = { deviceId: this.id }
|
|
|
|
|
|
this.$http.put(`/bst/device/unbind`, data).then(res => {
|
|
|
|
|
|
if(res.code == 200){
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: res.msg,
|
|
|
|
|
|
icon: 'success',
|
|
|
|
|
|
duration:3000
|
|
|
|
|
|
})
|
|
|
|
|
|
setTimeout(()=>{
|
|
|
|
|
|
uni.reLaunch({
|
|
|
|
|
|
url:'/pages/index/index'
|
|
|
|
|
|
})
|
|
|
|
|
|
},1500)
|
|
|
|
|
|
}else{
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: res.msg,
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration:3000
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
// 点击修改成功
|
|
|
|
|
|
btnedit(){
|
2026-04-28 13:55:17 +08:00
|
|
|
|
const name = (this.deviceName || '').trim()
|
|
|
|
|
|
if (!name) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: this.$i18n.t('pleaseEnterDeviceName'),
|
|
|
|
|
|
icon: 'none',
|
2025-11-08 11:30:06 +08:00
|
|
|
|
})
|
2026-04-28 13:55:17 +08:00
|
|
|
|
return
|
2025-11-08 11:30:06 +08:00
|
|
|
|
}
|
2026-04-28 13:55:17 +08:00
|
|
|
|
uni.showModal({
|
|
|
|
|
|
title: this.$i18n.t('tip'),
|
|
|
|
|
|
content: this.$i18n.t('confirmSaveDeviceSettings'),
|
|
|
|
|
|
confirmText: this.$i18n.t('confirm'),
|
|
|
|
|
|
cancelText: this.$i18n.t('cancel'),
|
|
|
|
|
|
success: (res) => {
|
|
|
|
|
|
if (!res.confirm) return
|
|
|
|
|
|
const data = {
|
|
|
|
|
|
sn: this.deviceId,
|
|
|
|
|
|
spaceId: this.kjid,
|
|
|
|
|
|
roomId: this.roomid,
|
|
|
|
|
|
name,
|
|
|
|
|
|
id: this.id,
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.fangdouflag !== true) return
|
|
|
|
|
|
this.fangdouflag = false
|
|
|
|
|
|
this.$http.put(`/bst/device`, data).then((r) => {
|
|
|
|
|
|
if (r.code == 200) {
|
|
|
|
|
|
const hit = (this.roomlist || []).find((x) => String(x.id) === String(this.roomid))
|
|
|
|
|
|
patchDeviceRoomInStorage(this.id, this.roomid, hit ? hit.name : '')
|
|
|
|
|
|
uni.$emit('deviceListNeedRefresh')
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: r.msg,
|
|
|
|
|
|
icon: 'success',
|
|
|
|
|
|
duration: 3000,
|
|
|
|
|
|
})
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this.fangdouflag = true
|
|
|
|
|
|
uni.reLaunch({
|
|
|
|
|
|
url: '/pages/index/index',
|
|
|
|
|
|
})
|
|
|
|
|
|
}, 1500)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: r.msg,
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 3000,
|
|
|
|
|
|
})
|
|
|
|
|
|
this.fangdouflag = true
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
2025-11-08 11:30:06 +08:00
|
|
|
|
},
|
|
|
|
|
|
// 请求房间列表
|
|
|
|
|
|
getlist(){
|
|
|
|
|
|
this.$http.get(`/bst/room/list?spaceId=${this.kjid}&pageNum=1&pageSize=999`).then(res =>{
|
|
|
|
|
|
if(res.code == 200){
|
|
|
|
|
|
this.roomlist = res.rows
|
|
|
|
|
|
this.roomlist.forEach((item,index) =>{
|
|
|
|
|
|
console.log(item.id,this.roomid);
|
|
|
|
|
|
if(item.id == this.roomid){
|
|
|
|
|
|
this.activeindex = index
|
|
|
|
|
|
console.log(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
// 返回上一页
|
|
|
|
|
|
btnback() {
|
|
|
|
|
|
uni.navigateBack({
|
|
|
|
|
|
delta: 1
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
// 点击选择房间
|
|
|
|
|
|
onAddRoom(item,index) {
|
|
|
|
|
|
this.activeindex = index
|
|
|
|
|
|
this.roomid = item.id
|
2026-04-28 13:55:17 +08:00
|
|
|
|
},
|
|
|
|
|
|
openDeviceNameModal() {
|
|
|
|
|
|
this.deviceNameModalDraft = this.deviceName || ''
|
|
|
|
|
|
this.deviceNameModalVisible = true
|
|
|
|
|
|
},
|
|
|
|
|
|
onDeviceNameModalConfirm(name) {
|
|
|
|
|
|
const n = (name || '').trim()
|
|
|
|
|
|
if (!n) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: this.$i18n.t('pleaseEnterDeviceName'),
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this.deviceName = n
|
|
|
|
|
|
this.deviceNameModalVisible = false
|
2025-11-08 11:30:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="less">
|
|
|
|
|
|
.active{
|
|
|
|
|
|
background-color: #d8d9da;
|
|
|
|
|
|
color: #000 !important;
|
|
|
|
|
|
.cell-title{
|
|
|
|
|
|
font-weight: 600 !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 底部按钮区域
|
|
|
|
|
|
.button-section {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
|
padding: 0 40rpx 80rpx;
|
|
|
|
|
|
background-color: #F3F5F6;
|
|
|
|
|
|
|
|
|
|
|
|
.continue-btn {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100rpx;
|
|
|
|
|
|
background-color: #000;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 50rpx;
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.bj {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 50vh;
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
z-index: -1;
|
|
|
|
|
|
background-color: #0F0F0F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tabback {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 126rpx;
|
|
|
|
|
|
padding: 0 20rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
border: 1rpx solid #D8D8D8;
|
|
|
|
|
|
margin-top: 102rpx;
|
|
|
|
|
|
border-radius: 30rpx 30rpx 0 0;
|
|
|
|
|
|
|
|
|
|
|
|
.rtjt {
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.name {
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.device-detail {
|
|
|
|
|
|
height: 93vh;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 顶部导航样式(贴近系统样式)
|
|
|
|
|
|
.tabback {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
height: 98rpx;
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-bottom: 2rpx solid #ECECEC;
|
|
|
|
|
|
|
|
|
|
|
|
.name {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.rtjt {
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 页面容器
|
|
|
|
|
|
.content-container {
|
|
|
|
|
|
height: 74vh;
|
|
|
|
|
|
background: #F3F5F6;
|
|
|
|
|
|
padding-bottom: 40rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 顶部设备ID灰条
|
|
|
|
|
|
.id-strip {
|
|
|
|
|
|
height: 142rpx;
|
|
|
|
|
|
line-height: 142rpx;
|
|
|
|
|
|
background: #F3F5F6;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
border-bottom: 2rpx solid #ECECEC;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 卡片
|
|
|
|
|
|
.card {
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.id-text {
|
|
|
|
|
|
color: #9EA3A8;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field {
|
|
|
|
|
|
padding: 24rpx 0 32rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field-label {
|
|
|
|
|
|
color: #9EA3A8;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-28 13:55:17 +08:00
|
|
|
|
.field-value {
|
2025-11-08 11:30:06 +08:00
|
|
|
|
margin-top: 16rpx;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
min-height: 72rpx;
|
|
|
|
|
|
line-height: 72rpx;
|
2025-11-08 11:30:06 +08:00
|
|
|
|
border-bottom: 2rpx solid #E6E6E6;
|
|
|
|
|
|
font-size: 28rpx;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
color: #333;
|
2025-11-08 11:30:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提示
|
|
|
|
|
|
.tip-box {
|
|
|
|
|
|
padding: 20rpx 24rpx;
|
|
|
|
|
|
background: #F3F5F6;
|
|
|
|
|
|
border-top: 2rpx solid #ECECEC;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tip-text {
|
|
|
|
|
|
color: #9EA3A8;
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
line-height: 40rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 列表
|
|
|
|
|
|
.list {
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
margin-top: 12rpx;
|
|
|
|
|
|
max-height: 44vh;
|
|
|
|
|
|
overflow: scroll;
|
|
|
|
|
|
view {
|
|
|
|
|
|
height: 96rpx;
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
border-top: 2rpx solid #ECECEC;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.cell-title {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.arrow {
|
|
|
|
|
|
color: #C0C0C0;
|
|
|
|
|
|
font-size: 44rpx;
|
|
|
|
|
|
line-height: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.scan-tip {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 40rpx 20rpx;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.scan-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
padding: 40rpx 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@keyframes scan {
|
|
|
|
|
|
0% {
|
|
|
|
|
|
top: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
100% {
|
|
|
|
|
|
top: 580rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.flashlight-btn {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
margin: 40rpx 0;
|
|
|
|
|
|
|
|
|
|
|
|
.flashlight-icon {
|
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
|
height: 60rpx;
|
|
|
|
|
|
background-color: #333;
|
|
|
|
|
|
border-radius: 30rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
|
|
background-color: #007aff;
|
|
|
|
|
|
transform: scale(1.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|