SEC_Warehouse/pages/device/config.vue

305 lines
5.7 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.

<template>
<view class="page">
<view class="top-nav top-nav-base">
<text class="back" @click="goBack"></text>
<text class="title">设备配置</text>
</view>
<view class="search-wrap">
<view class="search-btn" :class="{ 'is-searching': isSearching }" @click="toggleSearch">
<text>{{ searchBtnText }}</text>
</view>
</view>
<view class="tip-row">
*手机需开启蓝牙功能Android手机还需开启定位功能
</view>
<view class="list-header">
<text class="list-title">搜索到的设备列表</text>
</view>
<view class="list-body">
<view v-if="!deviceList.length" class="empty-row">暂无搜索结果</view>
<view v-for="device in deviceList" :key="device.deviceId" class="device-card">
<view class="device-icon"></view>
<view class="device-main">
<view class="device-name-row">
<text class="device-name">{{ device.showName }}</text>
<text v-if="device.hasTargetService" class="device-tag">00F4</text>
<text v-else-if="device.matchedByName || device.matchedByPayload" class="device-tag name-tag">名称匹配</text>
</view>
<text class="device-id">{{ device.deviceId }}</text>
<view class="device-actions">
<view class="action-btn">网络配置</view>
<view class="action-btn">参数配置</view>
<view class="action-btn">服务器配置</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { createBluetoothDiscovery } from '@/hooks/useBluetoothDiscovery'
import { navigateBack } from '@/utils/navigation'
export default {
data() {
return {
isSearching: false,
deviceList: [],
deviceMap: {},
discoveryController: null
}
},
computed: {
searchBtnText() {
return this.isSearching ? '搜索中' : '搜索'
}
},
created() {
/**
* 蓝牙搜索控制器:统一处理设备发现、排序、清理逻辑。
*/
this.discoveryController = createBluetoothDiscovery({
onSearchingChange: (value) => {
this.isSearching = value
},
onDeviceMapChange: (value) => {
this.deviceMap = value
},
onDeviceListChange: (value) => {
this.deviceList = value
}
})
},
onHide() {
this.cleanupDiscovery()
},
onUnload() {
this.cleanupDiscovery()
},
methods: {
cleanupDiscovery() {
if (!this.discoveryController) {
return
}
this.discoveryController.cleanupDiscovery()
},
goBack() {
this.cleanupDiscovery()
navigateBack(1)
},
async toggleSearch() {
if (!this.discoveryController) {
return
}
if (this.isSearching) {
await this.discoveryController.stopSearch(false)
return
}
try {
await this.discoveryController.startSearch()
} catch (error) {
}
}
}
}
</script>
<style>
@import '@/styles/common.css';
.page {
min-height: 100vh;
background: #e9eaed;
}
.top-nav {
border-bottom: 1rpx solid #ececec;
}
.back {
position: absolute;
left: 24rpx;
top: 30rpx;
font-size: 64rpx;
color: #111111;
width: 64rpx;
line-height: 64rpx;
text-align: center;
}
.title {
font-size: 50rpx;
font-weight: 700;
color: #2a2d33;
}
.search-wrap {
height: 500rpx;
background: #ffffff;
display: flex;
justify-content: center;
align-items: center;
}
.search-btn {
width: 260rpx;
height: 260rpx;
border-radius: 130rpx;
background: #43c996;
color: #ffffff;
font-size: 56rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s ease;
}
.search-btn:active {
transform: scale(0.97);
}
.search-btn.is-searching {
animation: searchPulse 1.2s ease-in-out infinite;
}
@keyframes searchPulse {
0% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(67, 201, 150, 0.42);
}
70% {
transform: scale(1.04);
box-shadow: 0 0 0 30rpx rgba(67, 201, 150, 0);
}
100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(67, 201, 150, 0);
}
}
.tip-row {
min-height: 78rpx;
padding: 12rpx 16rpx;
background: #efeff1;
color: #ff0000;
font-size: 34rpx;
font-weight: 600;
display: flex;
align-items: center;
}
.list-header {
height: 116rpx;
background: #ffffff;
display: flex;
align-items: center;
padding: 0 38rpx;
}
.list-title {
font-size: 52rpx;
color: #101217;
font-weight: 700;
}
.list-body {
min-height: calc(100vh - 814rpx);
background: #e9eaed;
padding-bottom: 30rpx;
}
.empty-row {
padding: 36rpx;
text-align: center;
color: #8c9097;
font-size: 30rpx;
}
.device-card {
background: #ffffff;
margin-top: 12rpx;
padding: 24rpx;
display: flex;
gap: 20rpx;
}
.device-icon {
width: 92rpx;
height: 92rpx;
border-radius: 46rpx;
border: 2rpx solid #d8d8d8;
box-shadow: inset 0 0 0 10rpx #f1f1f1;
flex-shrink: 0;
}
.device-main {
flex: 1;
min-width: 0;
}
.device-name-row {
display: flex;
align-items: center;
gap: 12rpx;
}
.device-name {
flex: 1;
min-width: 0;
font-size: 38rpx;
color: #30343a;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.device-tag {
font-size: 22rpx;
color: #17b474;
border: 1rpx solid #17b474;
border-radius: 20rpx;
padding: 2rpx 10rpx;
}
.name-tag {
color: #2f7de1;
border-color: #2f7de1;
}
.device-id {
display: block;
margin-top: 8rpx;
font-size: 30rpx;
color: #8a8f98;
word-break: break-all;
}
.device-actions {
display: flex;
gap: 10rpx;
margin-top: 16rpx;
}
.action-btn {
padding: 8rpx 16rpx;
border: 2rpx solid #42c995;
color: #22b47a;
font-size: 30rpx;
border-radius: 6rpx;
background: #f8fffc;
}
</style>