2026-01-15 14:41:50 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<view class="pages">
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<app-top-push-notice />
|
2026-01-15 14:41:50 +08:00
|
|
|
|
<view class="title">
|
|
|
|
|
|
<view class="title_li" style="display: flex;align-items: center;">
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view class="text">{{ $i18n.t('deviceList') }}</view>
|
2026-01-15 14:41:50 +08:00
|
|
|
|
<!-- <view class="btns" @click="toControl()">
|
|
|
|
|
|
控制台
|
|
|
|
|
|
</view> -->
|
|
|
|
|
|
</view>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<image src="https://api.ccttiot.com/smartmeter/img/static/uYsM9Nn95AK9c3JkUqvb" mode="widthFix"></image>
|
|
|
|
|
|
<!-- <u-icon name="grid-fill" color="#2979ff" size="28"></u-icon> -->
|
|
|
|
|
|
<text class="sm" v-if="showBluetoothStatusText && texts">{{texts}}</text>
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<view class="dblist" v-for="(item, index) in devicesList" :key="index" @tap="choose(item)">
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view class="lt device-thumb-wrap">
|
|
|
|
|
|
<image class="device-thumb" :src="getDeviceImageByMacPrefix(item)" mode="aspectFill" />
|
|
|
|
|
|
</view>
|
2026-01-15 14:41:50 +08:00
|
|
|
|
<view class="cen">
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view class="device-line mac-line">
|
|
|
|
|
|
<text class="device-mac-text">{{$i18n.t('macLabel')}}{{item.localName.slice(-12)}}</text>
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</view>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view class="device-line rssi-line">
|
|
|
|
|
|
<text class="rssi-text">{{$i18n.t('bluetoothSignal')}}{{item.RSSI}}</text>
|
|
|
|
|
|
<text v-if="item.isBand" class="sn-text">{{ $i18n.t('snPrefix') }}{{item.sn}}</text>
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</view>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<!-- <view class="device-line status-line">
|
|
|
|
|
|
<text class="status-text" :class="{ 'status-text--registered': item.isBand }">
|
|
|
|
|
|
{{ item.isBand ? $i18n.t('registered') : $i18n.t('notRegistered') }}
|
|
|
|
|
|
</text>
|
|
|
|
|
|
</view> -->
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</view>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view class="rt">
|
|
|
|
|
|
<!-- bindBtnState: 0 不展示 | 1 绑定 | 2 已绑定 -->
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-if="item.bindBtnState === 1"
|
|
|
|
|
|
class="bind-btn"
|
|
|
|
|
|
:id="item.deviceId"
|
|
|
|
|
|
>{{ $i18n.t('bindAction') }}</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-if="item.bindBtnState === 2"
|
|
|
|
|
|
class="bind-btn bind-btn--bound"
|
|
|
|
|
|
:id="item.deviceId"
|
|
|
|
|
|
>{{ $i18n.t('deviceAlreadyBound') }}</view>
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<!-- <view class="" style="width: 400rpx;margin: auto;" v-if="devicesList.length == 0 || devicesList == [] || devicesList == null || devicesList == undefined">
|
|
|
|
|
|
<image src="https://api.ccttiot.com/smartmeter/img/static/VhMNQ3Nf43oSKKbsPPPk" style="margin-top: 300rpx;width: 400rpx;height: 400rpx;" mode="aspectFit"></image>
|
|
|
|
|
|
</view> -->
|
2026-01-15 14:41:50 +08:00
|
|
|
|
<view class="anniu">
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<view style="width: 200rpx;" @click="backPage">{{ $i18n.t('back') }}</view>
|
|
|
|
|
|
<view style="width: 450rpx;" @click="Search">{{ $i18n.t('rescan') }}</view>
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 加载状态 -->
|
|
|
|
|
|
<view class="containers" v-show="statusflag">
|
|
|
|
|
|
<uni-section>
|
2026-04-28 13:55:17 +08:00
|
|
|
|
<uni-load-more :status="loadMoreStatus" />
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</uni-section>
|
|
|
|
|
|
</view>
|
2026-03-26 17:46:35 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-01-15 14:41:50 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
const app = getApp();
|
|
|
|
|
|
var xBlufi = require("@/common/blufi/xBlufi.js")
|
|
|
|
|
|
let _this = null;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
|
|
|
|
|
|
// 设备名中出现的四位厂商前缀 → 产品图(AUYK 等常在名称前部,不能仅用「后 12 位的前 4 位」)
|
|
|
|
|
|
const MAC_PREFIX_DEVICE_IMAGE = {
|
|
|
|
|
|
AUYK: 'https://api.ccttiot.com/image-1765181560094.png',
|
|
|
|
|
|
AUYG: 'https://api.ccttiot.com/203d6d03e1e65ad7410f42148b88b4e1-1758263531361.png',
|
|
|
|
|
|
AUMC: 'https://api.ccttiot.com/image-1761117712383.png',
|
|
|
|
|
|
AUHW: 'https://api.ccttiot.com/image-1765184024743.png',
|
|
|
|
|
|
AUSQ: 'https://api.ccttiot.com/image-1765184056827.png',
|
|
|
|
|
|
AUBL: 'https://api.ccttiot.com/image-1765184040649.png',
|
|
|
|
|
|
AUGW: 'https://api.ccttiot.com/ad93702b02429b8adf394569460b8b2a-1758263546164.png'
|
|
|
|
|
|
}
|
|
|
|
|
|
const KNOWN_MAC_PREFIXES = Object.keys(MAC_PREFIX_DEVICE_IMAGE)
|
|
|
|
|
|
const DEFAULT_MAC_PREFIX_IMAGE = MAC_PREFIX_DEVICE_IMAGE.AUGW
|
2026-01-15 14:41:50 +08:00
|
|
|
|
export default {
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
titleflag: false, //提示隐藏
|
|
|
|
|
|
bgc: {
|
|
|
|
|
|
backgroundColor: "#F7FAFE",
|
|
|
|
|
|
},
|
|
|
|
|
|
devicesList: [],
|
|
|
|
|
|
devicesLists: [],
|
|
|
|
|
|
searching: false,
|
2026-04-28 13:55:17 +08:00
|
|
|
|
// 蓝牙权限未授权时不展示;授权后按真实状态赋值
|
|
|
|
|
|
showBluetoothStatusText: false,
|
|
|
|
|
|
texts: '',
|
2026-01-15 14:41:50 +08:00
|
|
|
|
btnflag: true,
|
|
|
|
|
|
tishiflag: false,
|
|
|
|
|
|
option: '',
|
|
|
|
|
|
bluthlist: [], //蓝牙数组
|
2026-04-28 13:55:17 +08:00
|
|
|
|
loadMoreStatus: 'loading',
|
2026-01-15 14:41:50 +08:00
|
|
|
|
statusflag: false,
|
|
|
|
|
|
Bluetoothmac: '',
|
|
|
|
|
|
gps: {},
|
|
|
|
|
|
mac: '',
|
2026-04-28 13:55:17 +08:00
|
|
|
|
// 首次扫描完成后为 true,「重新扫描」才可用(沿用原逻辑)
|
2026-01-15 14:41:50 +08:00
|
|
|
|
status: false,
|
|
|
|
|
|
deviceinfo: null,
|
2026-03-26 17:46:35 +08:00
|
|
|
|
sn: '',
|
|
|
|
|
|
// 绑定弹窗
|
|
|
|
|
|
showBindModal: false,
|
|
|
|
|
|
bindFormSn: '',
|
|
|
|
|
|
bindFormMac: ''
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onLoad(e) {
|
|
|
|
|
|
if (e.sn) {
|
|
|
|
|
|
this.sn = e.sn
|
|
|
|
|
|
}
|
|
|
|
|
|
xBlufi.initXBlufi(1)
|
|
|
|
|
|
},
|
|
|
|
|
|
onShow: function() {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
this.bluthlist = []
|
|
|
|
|
|
this.devicesList = []
|
|
|
|
|
|
this.devicesLists = []
|
|
|
|
|
|
this.showBluetoothStatusText = false
|
|
|
|
|
|
this.texts = ''
|
|
|
|
|
|
this.$forceUpdate()
|
|
|
|
|
|
// 先检测蓝牙适配器:未授权则不展示下方状态文案;其它错误展示对应状态
|
|
|
|
|
|
uni.openBluetoothAdapter({
|
|
|
|
|
|
success: () => {
|
|
|
|
|
|
this.showBluetoothStatusText = true
|
|
|
|
|
|
this.texts = this.$i18n.t('scanningBluetooth')
|
|
|
|
|
|
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
|
|
|
|
|
|
xBlufi.notifyStartDiscoverBle({ 'isStart': true })
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
xBlufi.notifyStartDiscoverBle({ 'isStart': false })
|
|
|
|
|
|
if (this.devicesList.length == 0) {
|
|
|
|
|
|
this.tishiflag = true
|
|
|
|
|
|
this.texts = this.$i18n.t('scanCompleteNoDevice')
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.texts = this.$i18n.t('devicesFound')
|
|
|
|
|
|
}
|
|
|
|
|
|
this.status = true
|
|
|
|
|
|
this.$forceUpdate()
|
|
|
|
|
|
}, 2000)
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: (err) => {
|
|
|
|
|
|
this.applyBluetoothAdapterFail(err)
|
|
|
|
|
|
this.$forceUpdate()
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2026-01-15 14:41:50 +08:00
|
|
|
|
},
|
|
|
|
|
|
onUnload: function() {
|
|
|
|
|
|
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent)
|
|
|
|
|
|
xBlufi.notifyStartDiscoverBle({
|
|
|
|
|
|
'isStart': false
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
onHide() {
|
|
|
|
|
|
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent)
|
|
|
|
|
|
xBlufi.notifyStartDiscoverBle({
|
|
|
|
|
|
'isStart': false
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
onBeforeUnmount() {
|
|
|
|
|
|
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent)
|
|
|
|
|
|
xBlufi.notifyStartDiscoverBle({
|
|
|
|
|
|
'isStart': false
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
mounted() {
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
/** 接口 userId 有有效值视为已绑定用户(不可再绑) */
|
|
|
|
|
|
hasBoundUserId(userId) {
|
|
|
|
|
|
if (userId === null || userId === undefined) return false
|
|
|
|
|
|
if (typeof userId === 'number') return !isNaN(userId) && userId !== 0
|
|
|
|
|
|
const s = String(userId).trim()
|
|
|
|
|
|
return s !== '' && s !== 'null' && s !== 'undefined'
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 从广播名解析已知四位型号前缀(与配图表一致),用于带入录入页匹配产品 */
|
|
|
|
|
|
resolveKnownMacPrefix(raw) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (raw === undefined || raw === null || raw === '') return ''
|
|
|
|
|
|
const upper = String(raw).toUpperCase()
|
|
|
|
|
|
let hitPrefix = null
|
|
|
|
|
|
let hitIndex = Infinity
|
|
|
|
|
|
for (let i = 0; i < KNOWN_MAC_PREFIXES.length; i++) {
|
|
|
|
|
|
const p = KNOWN_MAC_PREFIXES[i]
|
|
|
|
|
|
const idx = upper.indexOf(p)
|
|
|
|
|
|
if (idx !== -1 && idx < hitIndex) {
|
|
|
|
|
|
hitIndex = idx
|
|
|
|
|
|
hitPrefix = p
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (hitPrefix) return hitPrefix
|
|
|
|
|
|
const hexOnly = String(raw).replace(/[^0-9A-Fa-f]/g, '')
|
|
|
|
|
|
if (hexOnly.length >= 12) {
|
|
|
|
|
|
const tail = hexOnly.slice(-12)
|
|
|
|
|
|
const p2 = tail.substring(0, 4).toUpperCase()
|
|
|
|
|
|
if (MAC_PREFIX_DEVICE_IMAGE[p2]) return p2
|
|
|
|
|
|
}
|
|
|
|
|
|
const s = String(raw)
|
|
|
|
|
|
if (s.length >= 12) {
|
|
|
|
|
|
const p3 = s.slice(-12).substring(0, 4).toUpperCase()
|
|
|
|
|
|
if (MAC_PREFIX_DEVICE_IMAGE[p3]) return p3
|
|
|
|
|
|
}
|
|
|
|
|
|
return ''
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
getMacPrefixFromItem(item) {
|
|
|
|
|
|
const raw = item && (item.localName != null && item.localName !== '' ? item.localName : item.name)
|
|
|
|
|
|
return this.resolveKnownMacPrefix(raw)
|
|
|
|
|
|
},
|
|
|
|
|
|
// 根据设备名中的 MAC(后 12 位)前四位匹配产品图
|
|
|
|
|
|
getDeviceImageByMacPrefix(item) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const raw = item && (item.localName != null && item.localName !== '' ? item.localName : item.name)
|
|
|
|
|
|
const prefix = this.resolveKnownMacPrefix(raw)
|
|
|
|
|
|
return prefix ? MAC_PREFIX_DEVICE_IMAGE[prefix] : DEFAULT_MAC_PREFIX_IMAGE
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
return DEFAULT_MAC_PREFIX_IMAGE
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 是否为「用户未授予蓝牙权限」(此时不展示标题下状态文案)
|
|
|
|
|
|
isBluetoothPermissionDenied(err) {
|
|
|
|
|
|
const msg = (err && err.errMsg ? String(err.errMsg) : '').toLowerCase()
|
|
|
|
|
|
return msg.includes('auth deny') || msg.includes('authorize') || msg.includes('system permission denied')
|
|
|
|
|
|
},
|
|
|
|
|
|
// 根据 openBluetoothAdapter 失败结果设置展示文案(非权限问题时展示具体状态)
|
|
|
|
|
|
applyBluetoothAdapterFail(err) {
|
|
|
|
|
|
if (this.isBluetoothPermissionDenied(err)) {
|
|
|
|
|
|
this.showBluetoothStatusText = false
|
|
|
|
|
|
this.texts = ''
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this.showBluetoothStatusText = true
|
|
|
|
|
|
const errMsg = err && err.errMsg ? err.errMsg : ''
|
|
|
|
|
|
const t = this.$i18n && this.$i18n.t ? this.$i18n.t.bind(this.$i18n) : (k) => k
|
|
|
|
|
|
if (errMsg.includes('not available') || errMsg.includes('unavailable')) {
|
|
|
|
|
|
this.texts = t('bluetoothUnavailable')
|
|
|
|
|
|
} else if (errMsg.includes('open fail')) {
|
|
|
|
|
|
this.texts = t('bluetoothOpenFailed')
|
|
|
|
|
|
} else if (errMsg.includes('bluetooth service unavailable')) {
|
|
|
|
|
|
this.texts = t('bluetoothServiceUnavailable')
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.texts = (t('bluetoothInitFailed') || '') + (errMsg || '')
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-01-15 14:41:50 +08:00
|
|
|
|
replay(){
|
|
|
|
|
|
uni.reLaunch({
|
|
|
|
|
|
url:'/pages/luru/index'
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
backPage(){
|
|
|
|
|
|
uni.navigateBack()
|
|
|
|
|
|
},
|
|
|
|
|
|
toControl(){
|
|
|
|
|
|
uni.redirectTo({
|
|
|
|
|
|
url:'/pages/luru/controlDevice'
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
fetchDevicesBoundStatus() {
|
|
|
|
|
|
// 提取所有设备的 MAC 地址,并通过 Set 去重
|
2026-03-26 17:46:35 +08:00
|
|
|
|
let uniqueDevices = Array.from(new Set(this.devicesList.map(item => item.localName.slice(-12))))
|
2026-01-15 14:41:50 +08:00
|
|
|
|
// 重新构建去重后的 devicesList
|
|
|
|
|
|
this.devicesList = uniqueDevices.map(mac => {
|
2026-03-26 17:46:35 +08:00
|
|
|
|
return this.devicesList.find(item => item.localName.slice(-12) === mac)
|
2026-01-15 14:41:50 +08:00
|
|
|
|
})
|
|
|
|
|
|
// 拼接成字符串
|
|
|
|
|
|
const macs = uniqueDevices
|
|
|
|
|
|
// 向批量接口请求录入状态
|
2026-03-26 17:46:35 +08:00
|
|
|
|
let array = macs
|
|
|
|
|
|
this.$http.post(`/app/device/simpleListByMacList`,array).then((res) => {
|
2026-01-15 14:41:50 +08:00
|
|
|
|
const resultList = res.data // 获取接口返回的数据数组
|
|
|
|
|
|
console.log(res,'请求')
|
|
|
|
|
|
// 遍历 devicesList 并对比 mac 地址
|
|
|
|
|
|
this.devicesList.forEach(device => {
|
2026-03-26 17:46:35 +08:00
|
|
|
|
const mac = device.localName.slice(-12)
|
2026-01-15 14:41:50 +08:00
|
|
|
|
const matchingResult = resultList.find(result => result.mac === mac)
|
2026-04-28 13:55:17 +08:00
|
|
|
|
device.boundByUser = false
|
2026-01-15 14:41:50 +08:00
|
|
|
|
if (matchingResult) {
|
|
|
|
|
|
device.sn = matchingResult.sn
|
|
|
|
|
|
device.isBand = true
|
2026-04-28 13:55:17 +08:00
|
|
|
|
const uid = matchingResult.userId !== undefined && matchingResult.userId !== null ? matchingResult.userId : matchingResult.user_id
|
|
|
|
|
|
device.boundByUser = this.hasBoundUserId(uid)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
device.isBand = false
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
2026-04-28 13:55:17 +08:00
|
|
|
|
device.bindBtnState = device.boundByUser ? 2 : 1
|
2026-01-15 14:41:50 +08:00
|
|
|
|
})
|
|
|
|
|
|
// 对 devicesList 进行排序,将 isBand 为 false 的设备排在前面
|
|
|
|
|
|
this.devicesList.sort((a, b) => {
|
|
|
|
|
|
return (a.isBand === false ? -1 : 1) - (b.isBand === false ? -1 : 1)
|
|
|
|
|
|
})
|
|
|
|
|
|
this.$forceUpdate() // 强制更新视图
|
|
|
|
|
|
console.log(this.devicesList, 'Updated devicesList')
|
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
|
console.error('批量获取设备录入状态失败', error)
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
choose(e) {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
if (e.bindBtnState === 0) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
if (e.bindBtnState === 2) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: this.$i18n.t('deviceAlreadyBound'),
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const nm = e.name || e.localName || ''
|
|
|
|
|
|
let Bluetoothmac = nm.slice(-12)
|
2026-03-26 17:46:35 +08:00
|
|
|
|
this.bindFormMac = Bluetoothmac
|
|
|
|
|
|
this.bindFormSn = ''
|
2026-04-28 13:55:17 +08:00
|
|
|
|
const prefix = this.getMacPrefixFromItem(e)
|
|
|
|
|
|
const prefixQs = prefix ? ('&prefix=' + encodeURIComponent(prefix)) : ''
|
2026-03-26 17:46:35 +08:00
|
|
|
|
this.$http.get(`/app/device/detailByMac?mac=${Bluetoothmac}`).then(res => {
|
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
|
if (res.data) {
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: '/subpackage/device/deviceaddroom?deviceId=' + e.sn
|
|
|
|
|
|
})
|
|
|
|
|
|
} else {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: '/pages/luru/bind_mac?mac=' + Bluetoothmac + prefixQs
|
2026-03-26 17:46:35 +08:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
// 关闭绑定弹窗
|
|
|
|
|
|
closeBindModal() {
|
|
|
|
|
|
this.showBindModal = false
|
|
|
|
|
|
this.bindFormSn = ''
|
|
|
|
|
|
this.bindFormMac = ''
|
|
|
|
|
|
},
|
|
|
|
|
|
// 确认绑定
|
|
|
|
|
|
getbangd() {
|
|
|
|
|
|
if (!this.bindFormMac) {
|
|
|
|
|
|
uni.showToast({
|
2026-04-28 13:55:17 +08:00
|
|
|
|
title: this.$i18n.t('macInvalid'),
|
2026-03-26 17:46:35 +08:00
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-04-28 13:55:17 +08:00
|
|
|
|
this.$http.put(`/bst/device/bind`, {
|
|
|
|
|
|
mac: this.bindFormMac,
|
|
|
|
|
|
sn: this.bindFormSn,
|
|
|
|
|
|
spaceId: uni.getStorageSync('kjid')
|
|
|
|
|
|
}).then(res => {
|
2026-03-26 17:46:35 +08:00
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
|
uni.showToast({
|
2026-04-28 13:55:17 +08:00
|
|
|
|
title: this.$i18n.t('bindSucceeded'),
|
2026-03-26 17:46:35 +08:00
|
|
|
|
icon: 'success',
|
|
|
|
|
|
duration: 2000
|
|
|
|
|
|
})
|
|
|
|
|
|
this.showBindModal = false
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
uni.reLaunch({
|
|
|
|
|
|
url: '/pages/index/index'
|
|
|
|
|
|
})
|
|
|
|
|
|
}, 1500)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uni.showToast({
|
2026-04-28 13:55:17 +08:00
|
|
|
|
title: res.msg || this.$i18n.t('bindFailed'),
|
2026-03-26 17:46:35 +08:00
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 3000
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2026-01-15 14:41:50 +08:00
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
funListenDeviceMsgEvent: function(options) {
|
|
|
|
|
|
switch (options.type) {
|
|
|
|
|
|
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS:
|
|
|
|
|
|
if (options.result) {
|
|
|
|
|
|
this.devicesLists = options.data
|
2026-04-28 13:55:17 +08:00
|
|
|
|
console.log('搜索的设备',options);
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
break
|
|
|
|
|
|
case xBlufi.XBLUFI_TYPE.TYPE_CONNECTED:
|
|
|
|
|
|
console.log("连接回调:" + JSON.stringify(options))
|
|
|
|
|
|
if (options.result) {
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
uni.showToast({
|
2026-01-17 17:34:06 +08:00
|
|
|
|
title: this.$i18n.t('connectionSuccess'),
|
2026-01-15 14:41:50 +08:00
|
|
|
|
icon: 'none'
|
|
|
|
|
|
}); {
|
|
|
|
|
|
console.log("连接回调options.data.deviceId:" + options.data.deviceId,
|
|
|
|
|
|
"连接回调options.data.name:" + options.data.name);
|
|
|
|
|
|
xBlufi.notifyInitBleEsp32({
|
|
|
|
|
|
deviceId: options.data.deviceId
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START:
|
|
|
|
|
|
if (!options.result) {
|
|
|
|
|
|
console.log("蓝牙未开启", options);
|
|
|
|
|
|
uni.showToast({
|
2026-01-17 17:34:06 +08:00
|
|
|
|
title: this.$i18n.t('bluetoothNotEnabled'),
|
2026-01-15 14:41:50 +08:00
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 3000
|
|
|
|
|
|
});
|
2026-04-28 13:55:17 +08:00
|
|
|
|
if (this.showBluetoothStatusText) {
|
|
|
|
|
|
this.texts = this.$i18n.t('bluetoothNotEnabled')
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
2026-04-28 13:55:17 +08:00
|
|
|
|
this.tishiflag = true
|
2026-01-15 14:41:50 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.searching = true
|
2026-04-28 13:55:17 +08:00
|
|
|
|
if (this.showBluetoothStatusText) {
|
|
|
|
|
|
this.texts = this.$i18n.t('scanningBluetooth')
|
|
|
|
|
|
}
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP:
|
|
|
|
|
|
if (options.result) {
|
|
|
|
|
|
let uniqueDevicesList = Array.from(new Set(this.devicesLists))
|
|
|
|
|
|
// 将去重后的数组重新赋值给 this.devicesList
|
|
|
|
|
|
this.devicesLists = uniqueDevicesList
|
|
|
|
|
|
let list = []
|
|
|
|
|
|
uniqueDevicesList.forEach(device => {
|
|
|
|
|
|
// 从设备名称中提取 MAC 地址(假设 MAC 地址是设备名称的后6个字符)
|
|
|
|
|
|
let macFromName = device.name.substring(device.name.length - 12)
|
|
|
|
|
|
// console.log(macFromName)
|
|
|
|
|
|
// 与 this.mac 进行比较
|
2026-04-28 13:55:17 +08:00
|
|
|
|
device.bindBtnState = 0
|
2026-01-15 14:41:50 +08:00
|
|
|
|
list.push(device)
|
|
|
|
|
|
});
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this.devicesList = list
|
|
|
|
|
|
let uniqueDevicesList = Array.from(new Set(this.devicesList))
|
|
|
|
|
|
// 将去重后的数组重新赋值给 this.devicesList
|
|
|
|
|
|
this.devicesList = uniqueDevicesList
|
|
|
|
|
|
this.fetchDevicesBoundStatus()
|
|
|
|
|
|
}, 200)
|
|
|
|
|
|
|
|
|
|
|
|
console.log('蓝牙停止搜索ok')
|
|
|
|
|
|
} else {
|
|
|
|
|
|
//蓝牙停止搜索失败
|
|
|
|
|
|
console.log('蓝牙停止搜索失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
this.searching = false
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 点击重新搜索
|
|
|
|
|
|
Search() {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
if (!this.status) return
|
|
|
|
|
|
uni.openBluetoothAdapter({
|
|
|
|
|
|
success: () => {
|
|
|
|
|
|
this.showBluetoothStatusText = true
|
|
|
|
|
|
xBlufi.notifyStartDiscoverBle({
|
|
|
|
|
|
'isStart': true
|
|
|
|
|
|
})
|
|
|
|
|
|
this.bluthlist = []
|
|
|
|
|
|
this.devicesList = []
|
|
|
|
|
|
this.devicesLists = []
|
|
|
|
|
|
this.statusflag = true
|
|
|
|
|
|
this.loadMoreStatus = 'loading'
|
|
|
|
|
|
this.texts = this.$i18n.t('scanningBluetooth')
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this.statusflag = false
|
|
|
|
|
|
if (this.searching) {
|
|
|
|
|
|
if (this.devicesList.length == 0) {
|
|
|
|
|
|
this.tishiflag = true
|
|
|
|
|
|
this.texts = this.$i18n.t('scanCompleteNoDevice')
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.texts = this.$i18n.t('devicesFound')
|
|
|
|
|
|
}
|
|
|
|
|
|
xBlufi.notifyStartDiscoverBle({
|
|
|
|
|
|
'isStart': false
|
|
|
|
|
|
})
|
2026-01-15 14:41:50 +08:00
|
|
|
|
} else {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
xBlufi.notifyStartDiscoverBle({
|
|
|
|
|
|
'isStart': true
|
|
|
|
|
|
})
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
2026-04-28 13:55:17 +08:00
|
|
|
|
}, 2000)
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: (err) => {
|
|
|
|
|
|
this.applyBluetoothAdapterFail(err)
|
|
|
|
|
|
this.$forceUpdate()
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2026-01-15 14:41:50 +08:00
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
|
page {
|
|
|
|
|
|
background-color: #F7FAFE !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
.tabback{
|
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
|
height: 130rpx;
|
|
|
|
|
|
background: #FCFCFC;
|
|
|
|
|
|
border-radius: 0rpx 0rpx 0rpx 0rpx;
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
padding: 0 28rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
border-bottom: 1px solid #D8D8D8;
|
|
|
|
|
|
padding-top: 52rpx;
|
|
|
|
|
|
z-index: 999;
|
|
|
|
|
|
.name{
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
color: #3D3D3D;
|
|
|
|
|
|
}
|
|
|
|
|
|
.rtjt {
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.containers {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
padding-top: 130rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
z-index: 999 !important;
|
|
|
|
|
|
/* background-color: #fff; */
|
|
|
|
|
|
z-index: 99;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.pages {
|
|
|
|
|
|
padding-top: 136rpx !important;
|
|
|
|
|
|
padding: 0 66rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
padding-bottom: 200rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-overlay {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
background: rgba(0, 0, 0, 0.5);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal {
|
|
|
|
|
|
width: 300px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-content {
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-title {
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-body {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-footer {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-footer button {
|
|
|
|
|
|
width: 80px;
|
|
|
|
|
|
height: 60rpx;
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
background: #8883F0;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
background: #8883F0;
|
|
|
|
|
|
width: 80px;
|
|
|
|
|
|
height: 60rpx;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-footer button:first-of-type {
|
|
|
|
|
|
background: #ccc;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// text{
|
|
|
|
|
|
// display: block;
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
.sm {
|
|
|
|
|
|
color: #77808D;
|
|
|
|
|
|
border-radius: 0rpx 0rpx 0rpx 0rpx;
|
|
|
|
|
|
// margin-top: 48rpx;
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
}
|
|
|
|
|
|
.title {
|
|
|
|
|
|
margin-bottom: 84rpx;
|
|
|
|
|
|
|
|
|
|
|
|
image {
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
width: 48rpx;
|
|
|
|
|
|
height: 48rpx;
|
|
|
|
|
|
vertical-align: bottom;
|
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
.title_li{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: nowrap;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
.text{
|
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
|
font-size: 70rpx;
|
|
|
|
|
|
color: #262B37;
|
|
|
|
|
|
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
font-style: normal;
|
|
|
|
|
|
text-transform: none;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
.btns{
|
|
|
|
|
|
margin-left: 30rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
width: 138rpx;
|
|
|
|
|
|
height: 50rpx;
|
|
|
|
|
|
background: #F14C4C;
|
|
|
|
|
|
border-radius: 31rpx 31rpx 31rpx 31rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #FFFFFF;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.dblist {
|
|
|
|
|
|
display: flex;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
align-items: stretch;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
width: 100%;
|
|
|
|
|
|
margin-top: 34rpx;
|
|
|
|
|
|
background: #FFFFFF;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
box-shadow: 0rpx 8rpx 40rpx 0rpx rgba(0, 0, 0, 0.06);
|
|
|
|
|
|
padding: 24rpx 20rpx 24rpx 18rpx;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
box-sizing: border-box;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
border: 1rpx solid rgba(0, 0, 0, 0.04);
|
|
|
|
|
|
|
2026-01-15 14:41:50 +08:00
|
|
|
|
.lt {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
flex-shrink: 0;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
padding-left: 10rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
|
align-self: center;
|
|
|
|
|
|
|
|
|
|
|
|
&.device-thumb-wrap {
|
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
background: #f3f4f6;
|
|
|
|
|
|
}
|
2026-01-15 14:41:50 +08:00
|
|
|
|
|
2026-04-28 13:55:17 +08:00
|
|
|
|
.device-thumb {
|
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
|
display: block;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.cen {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
flex: 1;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
padding-left: 4rpx;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
box-sizing: border-box;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
text-align: left;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
|
2026-04-28 13:55:17 +08:00
|
|
|
|
.device-line {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.mac-line {
|
|
|
|
|
|
.device-mac-text {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
|
line-height: 1.45;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.rssi-line {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
align-items: baseline;
|
|
|
|
|
|
margin-top: 12rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.rssi-text {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #5c6370;
|
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
|
margin-right: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sn-text {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #8b9199;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 第三行:录入状态,纯文案左对齐 */
|
|
|
|
|
|
.status-line {
|
|
|
|
|
|
margin-top: 14rpx;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
text-align: left;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-28 13:55:17 +08:00
|
|
|
|
.status-text {
|
2026-01-15 14:41:50 +08:00
|
|
|
|
font-size: 24rpx;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
|
color: #2563eb;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.status-text--registered {
|
|
|
|
|
|
color: #6b7280;
|
|
|
|
|
|
font-weight: 400;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.rt {
|
2026-04-28 13:55:17 +08:00
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
margin-left: 16rpx;
|
|
|
|
|
|
padding-right: 4rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
align-self: center;
|
|
|
|
|
|
|
|
|
|
|
|
.bind-btn {
|
|
|
|
|
|
min-width: 112rpx;
|
|
|
|
|
|
padding: 0 26rpx;
|
|
|
|
|
|
height: 64rpx;
|
|
|
|
|
|
line-height: 64rpx;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
text-align: center;
|
2026-04-28 13:55:17 +08:00
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
background: #0f0f0f;
|
|
|
|
|
|
border: 2rpx solid #0f0f0f;
|
|
|
|
|
|
border-radius: 32rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.bind-btn--bound {
|
|
|
|
|
|
color: #6b7280;
|
|
|
|
|
|
background: #e5e7eb;
|
|
|
|
|
|
border-color: #e5e7eb;
|
|
|
|
|
|
font-weight: 500;
|
2026-01-15 14:41:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.anniu {
|
|
|
|
|
|
padding: 0 40rpx;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
bottom: 60rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
view {
|
|
|
|
|
|
background: #000;
|
|
|
|
|
|
border-radius: 52rpx 52rpx 52rpx 52rpx;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
|
line-height: 80rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.mask {
|
|
|
|
|
|
width: 622rpx;
|
|
|
|
|
|
height: 710rpx;
|
|
|
|
|
|
background: #FFFFFF;
|
|
|
|
|
|
filter: blur(0px);
|
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 475rpx;
|
|
|
|
|
|
left: 50%;
|
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
|
padding-top: 38rpx;
|
|
|
|
|
|
padding-left: 60rpx;
|
|
|
|
|
|
padding-right: 60rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
|
|
|
|
.titles {
|
|
|
|
|
|
font-size: 48rpx;
|
|
|
|
|
|
color: #262B37;
|
|
|
|
|
|
line-height: 70rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
text {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
color: #262B37;
|
|
|
|
|
|
line-height: 56rpx;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
button {
|
|
|
|
|
|
margin-top: 46rpx;
|
|
|
|
|
|
width: 266rpx;
|
|
|
|
|
|
height: 96rpx;
|
|
|
|
|
|
background: #8883F0;
|
|
|
|
|
|
border-radius: 52rpx 52rpx 52rpx 52rpx;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 96rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|