fix: 中文全部换成英文。
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -10,3 +10,7 @@ docs/_book
|
|||||||
test/
|
test/
|
||||||
|
|
||||||
node_modules
|
node_modules
|
||||||
|
/.idea/.gitignore
|
||||||
|
/.idea/intc-mixer-app.iml
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/vcs.xml
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="bluetooth-page">
|
<view class="bluetooth-page">
|
||||||
<!-- 导航栏 -->
|
<!-- Navigation Bar -->
|
||||||
<uni-navbar title="搅拌器设备连接" :border="false" background-color="rgba(102, 126, 234, 0.9)" color="#fff" />
|
<uni-navbar title="Mixer Device Connection" :border="false" background-color="rgba(102, 126, 234, 0.9)" color="#fff" />
|
||||||
|
|
||||||
<view class="bluetooth-container">
|
<view class="bluetooth-container">
|
||||||
|
|
||||||
<!-- 搜索状态和设置 -->
|
<!-- Search Status and Settings -->
|
||||||
<view class="search-status">
|
<view class="search-status">
|
||||||
<view class="status-row">
|
<view class="status-row">
|
||||||
<view class="status-item">
|
<view class="status-item">
|
||||||
<text class="status-label">蓝牙状态:</text>
|
<text class="status-label">Bluetooth:</text>
|
||||||
<text :class="['status-value', bluetoothEnabled ? 'status-on' : 'status-off']">
|
<text :class="['status-value', bluetoothEnabled ? 'status-on' : 'status-off']">
|
||||||
{{ bluetoothEnabled ? '已开启' : '未开启' }}
|
{{ bluetoothEnabled ? 'On' : 'Off' }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="status-item">
|
<view class="status-item">
|
||||||
<text class="status-label">搜索状态:</text>
|
<text class="status-label">Search:</text>
|
||||||
<text :class="['status-value', isSearching ? 'status-on' : 'status-off']">
|
<text :class="['status-value', isSearching ? 'status-on' : 'status-off']">
|
||||||
{{ isSearching ? '搜索中...' : '未搜索' }}
|
{{ isSearching ? 'Searching...' : 'Idle' }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- Action Buttons -->
|
||||||
<view class="action-buttons">
|
<view class="action-buttons">
|
||||||
<u-button
|
<u-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
@click="startBluetoothSearch"
|
@click="startBluetoothSearch"
|
||||||
:disabled="!bluetoothEnabled"
|
:disabled="!bluetoothEnabled"
|
||||||
>
|
>
|
||||||
{{ isSearching ? '搜索中...' : '开始搜索' }}
|
{{ isSearching ? 'Searching...' : 'Start Search' }}
|
||||||
</u-button>
|
</u-button>
|
||||||
<u-button
|
<u-button
|
||||||
type="warning"
|
type="warning"
|
||||||
@@ -40,11 +40,11 @@
|
|||||||
:disabled="!isSearching"
|
:disabled="!isSearching"
|
||||||
style="margin-left: 20rpx;"
|
style="margin-left: 20rpx;"
|
||||||
>
|
>
|
||||||
停止搜索
|
Stop Search
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 预览按钮 -->
|
<!-- Preview Button -->
|
||||||
<view class="preview-button-wrapper">
|
<view class="preview-button-wrapper">
|
||||||
<u-button
|
<u-button
|
||||||
type="success"
|
type="success"
|
||||||
@@ -52,15 +52,15 @@
|
|||||||
@click="previewMixerPage"
|
@click="previewMixerPage"
|
||||||
>
|
>
|
||||||
<uni-icons type="eye" color="#52c41a" size="20" style="margin-right: 8rpx;"></uni-icons>
|
<uni-icons type="eye" color="#52c41a" size="20" style="margin-right: 8rpx;"></uni-icons>
|
||||||
预览搅拌器页面
|
Preview Mixer Page
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
<!-- 设备列表 -->
|
<!-- Device List -->
|
||||||
<view class="device-list">
|
<view class="device-list">
|
||||||
<view class="list-header">
|
<view class="list-header">
|
||||||
<text class="header-title">附近的设备</text>
|
<text class="header-title">Nearby Devices</text>
|
||||||
<text class="device-count">({{ deviceList.length }})</text>
|
<text class="device-count">({{ deviceList.length }})</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<text class="empty-text">暂无设备,点击上方按钮开始搜索</text>
|
<text class="empty-text">No devices found, click above to start searching</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-else class="device-items">
|
<view v-else class="device-items">
|
||||||
@@ -95,20 +95,20 @@
|
|||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<text class="name-text">
|
<text class="name-text">
|
||||||
{{ device.name || device.localName || `未命名设备 (${device.deviceId.slice(-8)})` }}
|
{{ device.name || device.localName || `Unnamed Device (${device.deviceId.slice(-8)})` }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="device-details">
|
<view class="device-details">
|
||||||
<text class="detail-text">设备ID: {{ device.deviceId }}</text>
|
<text class="detail-text">Device ID: {{ device.deviceId }}</text>
|
||||||
<text class="detail-text">信号强度: {{ device.RSSI }} dBm</text>
|
<text class="detail-text">Signal: {{ device.RSSI }} dBm</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="device-action">
|
<view class="device-action">
|
||||||
<view v-if="device.deviceId === connectedDeviceId" class="connected-badge">
|
<view v-if="device.deviceId === connectedDeviceId" class="connected-badge">
|
||||||
<text class="badge-text">已连接</text>
|
<text class="badge-text">Connected</text>
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="device.deviceId === connectingDeviceId" class="connecting-badge">
|
<view v-else-if="device.deviceId === connectingDeviceId" class="connecting-badge">
|
||||||
<text class="connecting-text">连接中...</text>
|
<text class="connecting-text">Connecting...</text>
|
||||||
</view>
|
</view>
|
||||||
<u-button
|
<u-button
|
||||||
v-else
|
v-else
|
||||||
@@ -116,15 +116,15 @@
|
|||||||
size="small"
|
size="small"
|
||||||
@click.stop="connectDevice(device)"
|
@click.stop="connectDevice(device)"
|
||||||
>
|
>
|
||||||
连接
|
Connect
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 已连接设备的详细信息,显示在对应设备下方 -->
|
<!-- Connected device details, displayed below the corresponding device -->
|
||||||
<view v-if="device.deviceId === connectedDeviceId && connectedDevice" class="device-connected-detail">
|
<view v-if="device.deviceId === connectedDeviceId && connectedDevice" class="device-connected-detail">
|
||||||
<view class="detail-header">
|
<view class="detail-header">
|
||||||
<text class="detail-title">连接成功,准备跳转...</text>
|
<text class="detail-title">Connected successfully, preparing to navigate...</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -366,22 +366,22 @@ const guideToEnableGPS = () => {
|
|||||||
let content = ''
|
let content = ''
|
||||||
|
|
||||||
if (androidVersion >= 12) {
|
if (androidVersion >= 12) {
|
||||||
content = '检测到您使用的是 Android 12+,不需要开启GPS即可使用蓝牙功能。'
|
content = 'You are using Android 12+, GPS is not required for Bluetooth.'
|
||||||
} else if (androidVersion >= 10) {
|
} else if (androidVersion >= 10) {
|
||||||
content = `检测到您使用的是 Android ${androidVersion},系统要求必须开启位置服务(GPS)才能搜索蓝牙设备。
|
content = `You are using Android ${androidVersion}. The system requires location service (GPS) to be enabled for Bluetooth device scanning.
|
||||||
|
|
||||||
这是 Android 系统的强制要求,即使不会真正定位您的位置。
|
This is a mandatory Android system requirement, even though it won't actually track your location.
|
||||||
|
|
||||||
是否前往设置开启?`
|
Go to settings to enable?`
|
||||||
} else {
|
} else {
|
||||||
content = '建议开启位置服务(GPS)以确保蓝牙搜索功能正常使用。\n\n是否前往设置开启?'
|
content = 'It is recommended to enable location service (GPS) to ensure Bluetooth search function works properly.\n\nGo to settings to enable?'
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: androidVersion >= 12 ? '提示' : '需要开启GPS',
|
title: androidVersion >= 12 ? 'Notice' : 'GPS Required',
|
||||||
content: content,
|
content: content,
|
||||||
showCancel: androidVersion < 12,
|
showCancel: androidVersion < 12,
|
||||||
confirmText: androidVersion >= 12 ? '知道了' : '去设置',
|
confirmText: androidVersion >= 12 ? 'OK' : 'Go to Settings',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm && androidVersion < 12) {
|
if (res.confirm && androidVersion < 12) {
|
||||||
// 跳转到位置设置页面
|
// 跳转到位置设置页面
|
||||||
@@ -395,7 +395,7 @@ const guideToEnableGPS = () => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('跳转设置失败:', e)
|
console.error('跳转设置失败:', e)
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '请手动前往设置开启GPS',
|
title: 'Please go to settings manually to enable GPS',
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
@@ -411,14 +411,14 @@ const saveLastDevice = (device) => {
|
|||||||
try {
|
try {
|
||||||
const deviceInfo = {
|
const deviceInfo = {
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
name: device.name || device.localName || '未命名设备',
|
name: device.name || device.localName || 'Unnamed Device',
|
||||||
localName: device.localName,
|
localName: device.localName,
|
||||||
RSSI: device.RSSI
|
RSSI: device.RSSI
|
||||||
}
|
}
|
||||||
uni.setStorageSync(LAST_DEVICE_KEY, JSON.stringify(deviceInfo))
|
uni.setStorageSync(LAST_DEVICE_KEY, JSON.stringify(deviceInfo))
|
||||||
console.log('已保存上次连接的设备:', deviceInfo)
|
console.log('Saved last connected device:', deviceInfo)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('保存设备信息失败:', e)
|
console.error('Failed to save device info:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,11 +428,11 @@ const getLastDevice = () => {
|
|||||||
const deviceStr = uni.getStorageSync(LAST_DEVICE_KEY)
|
const deviceStr = uni.getStorageSync(LAST_DEVICE_KEY)
|
||||||
if (deviceStr) {
|
if (deviceStr) {
|
||||||
const device = JSON.parse(deviceStr)
|
const device = JSON.parse(deviceStr)
|
||||||
console.log('读取到上次连接的设备:', device)
|
console.log('Read last connected device:', device)
|
||||||
return device
|
return device
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('读取设备信息失败:', e)
|
console.error('Failed to read device info:', e)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -441,7 +441,7 @@ const getLastDevice = () => {
|
|||||||
const tryAutoReconnectLastDevice = async () => {
|
const tryAutoReconnectLastDevice = async () => {
|
||||||
// 防止重复尝试
|
// 防止重复尝试
|
||||||
if (hasTriedAutoReconnect) {
|
if (hasTriedAutoReconnect) {
|
||||||
console.log('已经尝试过自动重连,跳过')
|
console.log('Already tried auto-reconnect, skipping')
|
||||||
startBluetoothSearch()
|
startBluetoothSearch()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -451,15 +451,15 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
// 获取上次连接的设备
|
// 获取上次连接的设备
|
||||||
const lastDevice = getLastDevice()
|
const lastDevice = getLastDevice()
|
||||||
if (!lastDevice) {
|
if (!lastDevice) {
|
||||||
console.log('没有上次连接的设备记录,开始正常搜索')
|
console.log('No last connected device record, starting normal search')
|
||||||
startBluetoothSearch()
|
startBluetoothSearch()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('尝试自动重连上次的设备:', lastDevice.name)
|
console.log('Trying to auto-reconnect to last device:', lastDevice.name)
|
||||||
|
|
||||||
uni.showLoading({
|
uni.showLoading({
|
||||||
title: `正在连接 ${lastDevice.name}...`,
|
title: `Connecting ${lastDevice.name}...`,
|
||||||
mask: true
|
mask: true
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -468,7 +468,7 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
await checkLocationService()
|
await checkLocationService()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
console.log('GPS未开启,无法自动重连')
|
console.log('GPS not enabled, cannot auto-reconnect')
|
||||||
guideToEnableGPS()
|
guideToEnableGPS()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -483,7 +483,7 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('开始搜索上次连接的设备...')
|
console.log('Starting to search for last connected device...')
|
||||||
|
|
||||||
// 等待3秒搜索设备
|
// 等待3秒搜索设备
|
||||||
await new Promise(resolve => setTimeout(resolve, 3000))
|
await new Promise(resolve => setTimeout(resolve, 3000))
|
||||||
@@ -500,7 +500,7 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
const targetDevice = devices.find(d => d.deviceId === lastDevice.deviceId)
|
const targetDevice = devices.find(d => d.deviceId === lastDevice.deviceId)
|
||||||
|
|
||||||
if (targetDevice) {
|
if (targetDevice) {
|
||||||
console.log('找到上次连接的设备,尝试连接:', targetDevice)
|
console.log('Found last connected device, trying to connect:', targetDevice)
|
||||||
|
|
||||||
// 尝试连接
|
// 尝试连接
|
||||||
try {
|
try {
|
||||||
@@ -514,7 +514,7 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 连接成功
|
// 连接成功
|
||||||
console.log('自动重连成功')
|
console.log('Auto-reconnect successful')
|
||||||
connectingDeviceId.value = ''
|
connectingDeviceId.value = ''
|
||||||
connectedDeviceId.value = targetDevice.deviceId
|
connectedDeviceId.value = targetDevice.deviceId
|
||||||
connectedDevice.value = targetDevice
|
connectedDevice.value = targetDevice
|
||||||
@@ -528,7 +528,7 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '自动连接成功',
|
title: 'Auto-connect successful',
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
duration: 1500
|
duration: 1500
|
||||||
})
|
})
|
||||||
@@ -536,16 +536,16 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
// 自动跳转到控制页面
|
// 自动跳转到控制页面
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const url = buildMixerPageUrl(targetDevice, bleInfo)
|
const url = buildMixerPageUrl(targetDevice, bleInfo)
|
||||||
console.log('🚀 跳转到搅拌器页面:', url)
|
console.log('🚀 Navigating to mixer page:', url)
|
||||||
uni.navigateTo({ url })
|
uni.navigateTo({ url })
|
||||||
}, 1500)
|
}, 1500)
|
||||||
|
|
||||||
} catch (connectErr) {
|
} catch (connectErr) {
|
||||||
console.error('自动重连失败:', connectErr)
|
console.error('Auto-reconnect failed:', connectErr)
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '自动连接失败,请手动选择',
|
title: 'Auto-connect failed, please select manually',
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
@@ -558,11 +558,11 @@ const tryAutoReconnectLastDevice = async () => {
|
|||||||
}, 2000)
|
}, 2000)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('未找到上次连接的设备,继续正常搜索')
|
console.log('Last device not found, continuing normal search')
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '未找到上次设备',
|
title: 'Last device not found',
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
duration: 1500
|
duration: 1500
|
||||||
})
|
})
|
||||||
@@ -722,11 +722,13 @@ const connectDevice = (device) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果已经连接了其他设备,先提示用户
|
// If already connected to another device, prompt user first
|
||||||
if (connectedDeviceId.value && connectedDeviceId.value !== device.deviceId) {
|
if (connectedDeviceId.value && connectedDeviceId.value !== device.deviceId) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: 'Notice',
|
||||||
content: '已连接其他设备,是否断开并连接新设备?',
|
content: 'Already connected to another device. Disconnect and connect to new device?',
|
||||||
|
confirmText: 'Confirm',
|
||||||
|
cancelText: 'Cancel',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
// 先断开当前连接
|
// 先断开当前连接
|
||||||
@@ -754,19 +756,19 @@ const connectDevice = (device) => {
|
|||||||
const doConnect = (device) => {
|
const doConnect = (device) => {
|
||||||
connectingDeviceId.value = device.deviceId
|
connectingDeviceId.value = device.deviceId
|
||||||
|
|
||||||
console.log('开始连接设备:', device)
|
console.log('Starting to connect device:', device)
|
||||||
|
|
||||||
uni.createBLEConnection({
|
uni.createBLEConnection({
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
timeout: 10000, // 设置10秒超时
|
timeout: 10000, // 10 seconds timeout
|
||||||
success: async (res) => {
|
success: async (res) => {
|
||||||
console.log('连接成功', res)
|
console.log('Connection successful', res)
|
||||||
connectingDeviceId.value = ''
|
connectingDeviceId.value = ''
|
||||||
connectedDeviceId.value = device.deviceId
|
connectedDeviceId.value = device.deviceId
|
||||||
connectedDevice.value = device
|
connectedDevice.value = device
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '连接成功',
|
title: 'Connected',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -782,41 +784,41 @@ const doConnect = (device) => {
|
|||||||
// 连接成功后跳转到控制页面
|
// 连接成功后跳转到控制页面
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const url = buildMixerPageUrl(device, bleInfo)
|
const url = buildMixerPageUrl(device, bleInfo)
|
||||||
console.log('🚀 跳转到搅拌器页面:', url)
|
console.log('🚀 Navigating to mixer page:', url)
|
||||||
uni.navigateTo({ url })
|
uni.navigateTo({ url })
|
||||||
}, 800)
|
}, 800)
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('连接失败', err)
|
console.error('Connection failed', err)
|
||||||
connectingDeviceId.value = ''
|
connectingDeviceId.value = ''
|
||||||
|
|
||||||
// 根据错误码提供更详细的错误信息
|
// Provide detailed error information based on error code
|
||||||
let errorMsg = '无法连接到该设备'
|
let errorMsg = 'Unable to connect to this device'
|
||||||
|
|
||||||
if (err.errCode === 10003) {
|
if (err.errCode === 10003) {
|
||||||
errorMsg = '连接失败:设备未找到或已关闭'
|
errorMsg = 'Connection failed: Device not found or turned off'
|
||||||
} else if (err.errCode === 10012) {
|
} else if (err.errCode === 10012) {
|
||||||
errorMsg = '连接失败:连接超时,设备可能距离太远'
|
errorMsg = 'Connection failed: Connection timeout, device may be too far away'
|
||||||
} else if (err.errCode === 10004) {
|
} else if (err.errCode === 10004) {
|
||||||
errorMsg = '连接失败:设备不支持连接'
|
errorMsg = 'Connection failed: Device does not support connection'
|
||||||
} else if (err.errCode === -1) {
|
} else if (err.errCode === -1) {
|
||||||
errorMsg = '连接失败:系统错误,请重启蓝牙后重试'
|
errorMsg = 'Connection failed: System error, please restart Bluetooth and retry'
|
||||||
} else if (err.errMsg) {
|
} else if (err.errMsg) {
|
||||||
errorMsg = `连接失败:${err.errMsg}`
|
errorMsg = `Connection failed: ${err.errMsg}`
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '连接失败',
|
title: 'Connection Failed',
|
||||||
content: `${errorMsg}
|
content: `${errorMsg}
|
||||||
|
|
||||||
错误码: ${err.errCode || '未知'}
|
Error Code: ${err.errCode || 'Unknown'}
|
||||||
|
|
||||||
提示:
|
Tips:
|
||||||
1. 确保设备在可连接范围内
|
1. Ensure device is within connection range
|
||||||
2. 确保设备未被其他应用连接
|
2. Ensure device is not connected by other apps
|
||||||
3. 尝试重启设备蓝牙`,
|
3. Try restarting device Bluetooth`,
|
||||||
showCancel: false,
|
showCancel: false,
|
||||||
confirmText: '知道了'
|
confirmText: 'OK'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -826,7 +828,7 @@ const doConnect = (device) => {
|
|||||||
const disconnectDevice = () => {
|
const disconnectDevice = () => {
|
||||||
if (!connectedDeviceId.value) {
|
if (!connectedDeviceId.value) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '没有已连接的设备',
|
title: 'No connected device',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -844,14 +846,14 @@ const disconnectDevice = () => {
|
|||||||
characteristicId: char.uuid,
|
characteristicId: char.uuid,
|
||||||
state: false,
|
state: false,
|
||||||
success: () => {
|
success: () => {
|
||||||
console.log('关闭notify成功:', char.uuid)
|
console.log('Notify disabled successfully:', char.uuid)
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('关闭notify失败:', char.uuid, err)
|
console.error('Failed to disable notify:', char.uuid, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('关闭notify异常:', err)
|
console.error('Notify exception:', err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -859,20 +861,20 @@ const disconnectDevice = () => {
|
|||||||
uni.closeBLEConnection({
|
uni.closeBLEConnection({
|
||||||
deviceId: deviceId,
|
deviceId: deviceId,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log('断开连接成功', res)
|
console.log('Disconnected successfully', res)
|
||||||
// 清空连接状态和服务信息
|
// Clear connection status and service info
|
||||||
cleanupConnection()
|
cleanupConnection()
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '已断开连接',
|
title: 'Disconnected',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('断开连接失败', err)
|
console.error('Failed to disconnect', err)
|
||||||
// 即使断开失败,也清空状态(可能设备已经离线)
|
// Clear status even if disconnection fails (device may already be offline)
|
||||||
cleanupConnection()
|
cleanupConnection()
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '断开连接',
|
title: 'Disconnected',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -901,7 +903,7 @@ const getBLEDeviceServices = async (deviceId) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('获取到的服务列表', res.services)
|
console.log('Retrieved service list', res.services)
|
||||||
services.value = res.services
|
services.value = res.services
|
||||||
|
|
||||||
// 计算所有服务的特征值总数
|
// 计算所有服务的特征值总数
|
||||||
@@ -1530,7 +1532,7 @@ const addToHistory = (type, data, hex, characteristicId = '') => {
|
|||||||
const toggleHistory = () => {
|
const toggleHistory = () => {
|
||||||
if (dataHistory.value.length === 0) {
|
if (dataHistory.value.length === 0) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '暂无历史记录',
|
title: 'No history records',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -1538,18 +1540,20 @@ const toggleHistory = () => {
|
|||||||
showHistory.value = !showHistory.value
|
showHistory.value = !showHistory.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空历史记录
|
// Clear history
|
||||||
const clearHistory = () => {
|
const clearHistory = () => {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '确认',
|
title: 'Confirm',
|
||||||
content: '确定要清空所有历史记录吗?',
|
content: 'Are you sure to clear all history records?',
|
||||||
|
confirmText: 'Confirm',
|
||||||
|
cancelText: 'Cancel',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
sendHistory.value = []
|
sendHistory.value = []
|
||||||
receiveHistory.value = []
|
receiveHistory.value = []
|
||||||
showHistory.value = false
|
showHistory.value = false
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '已清空',
|
title: 'Cleared',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1560,12 +1564,12 @@ const clearHistory = () => {
|
|||||||
// 监听蓝牙适配器状态变化
|
// 监听蓝牙适配器状态变化
|
||||||
const onBluetoothAdapterStateChange = () => {
|
const onBluetoothAdapterStateChange = () => {
|
||||||
uni.onBluetoothAdapterStateChange((res) => {
|
uni.onBluetoothAdapterStateChange((res) => {
|
||||||
console.log('蓝牙适配器状态变化', res)
|
console.log('Bluetooth adapter state changed', res)
|
||||||
bluetoothEnabled.value = res.available
|
bluetoothEnabled.value = res.available
|
||||||
if (!res.available) {
|
if (!res.available) {
|
||||||
isSearching.value = false
|
isSearching.value = false
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '蓝牙已关闭',
|
title: 'Bluetooth turned off',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1577,10 +1581,10 @@ onMounted(() => {
|
|||||||
// 判断是否为H5环境
|
// 判断是否为H5环境
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: 'Notice',
|
||||||
content: 'H5平台不支持蓝牙功能,请使用App或小程序版本',
|
content: 'Bluetooth is not supported on H5 platform, please use App or Mini Program version',
|
||||||
showCancel: false,
|
showCancel: false,
|
||||||
confirmText: '我知道了'
|
confirmText: 'OK'
|
||||||
})
|
})
|
||||||
bluetoothEnabled.value = false
|
bluetoothEnabled.value = false
|
||||||
// #endif
|
// #endif
|
||||||
@@ -1620,10 +1624,10 @@ const cleanup = () => {
|
|||||||
// 关闭蓝牙适配器
|
// 关闭蓝牙适配器
|
||||||
uni.closeBluetoothAdapter({
|
uni.closeBluetoothAdapter({
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log('关闭蓝牙适配器成功', res)
|
console.log('Bluetooth adapter closed successfully', res)
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('关闭蓝牙适配器失败', err)
|
console.error('Failed to close Bluetooth adapter', err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,17 +12,17 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 标题 -->
|
<!-- Title -->
|
||||||
<view class="title-section">
|
<view class="title-section">
|
||||||
<text class="main-title">搅拌器控制连接</text>
|
<text class="main-title">Mixer Control Connection</text>
|
||||||
<text class="sub-title">快速搜索并连接附近搅拌器蓝牙设备</text>
|
<text class="sub-title">Quickly search and connect to nearby mixer Bluetooth devices</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 登录按钮 -->
|
<!-- 登录按钮 -->
|
||||||
<view class="btn-section">
|
<view class="btn-section">
|
||||||
<button @click="handleLogin" class="login-btn">
|
<button @click="handleLogin" class="login-btn">
|
||||||
<uni-icons type="right" size="24" color="#667eea" style="margin-right: 12rpx;"></uni-icons>
|
<uni-icons type="right" size="24" color="#667eea" style="margin-right: 12rpx;"></uni-icons>
|
||||||
<text class="btn-text">进入</text>
|
<text class="btn-text">Enter</text>
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="mixer-page">
|
<view class="mixer-page">
|
||||||
<!-- 顶部蓝牙状态栏 -->
|
<!-- Top Bluetooth Status Bar -->
|
||||||
<view class="custom-navbar">
|
<view class="custom-navbar">
|
||||||
<view class="navbar-content">
|
<view class="navbar-content">
|
||||||
<view class="nav-left" @click="goBack">
|
<view class="nav-left" @click="goBack">
|
||||||
<uni-icons type="back" color="#fff" size="20"></uni-icons>
|
<uni-icons type="back" color="#fff" size="20"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
<view class="nav-center">
|
<view class="nav-center">
|
||||||
<text class="nav-title">{{ deviceName || '六通道搅拌器' }}</text>
|
<text class="nav-title">{{ deviceName || 'Six-Channel Mixer' }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="nav-right">
|
<view class="nav-right">
|
||||||
<view class="bluetooth-status" @click="showDeviceInfo">
|
<view class="bluetooth-status" @click="showDeviceInfo">
|
||||||
<uni-icons type="bluetooth-filled" color="#fff" size="20"></uni-icons>
|
<uni-icons type="bluetooth-filled" color="#fff" size="20"></uni-icons>
|
||||||
<text class="status-text">{{ connected ? '已连接' : '未连接' }}</text>
|
<text class="status-text">{{ connected ? 'Connected' : 'Disconnected' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="mixer-container">
|
<view class="mixer-container">
|
||||||
<!-- 选择状态栏 -->
|
<!-- Selection Status Bar -->
|
||||||
<view class="selection-status">
|
<view class="selection-status">
|
||||||
<view class="status-row">
|
<view class="status-row">
|
||||||
<view class="status-item">
|
<view class="status-item">
|
||||||
<text class="status-label">已选择:</text>
|
<text class="status-label">Selected:</text>
|
||||||
<text :class="['status-value', selectedChannels.length > 0 ? 'status-on' : 'status-off']">
|
<text :class="['status-value', selectedChannels.length > 0 ? 'status-on' : 'status-off']">
|
||||||
{{ selectedChannels.length }}/{{ channels.length }} 通道
|
{{ selectedChannels.length }}/{{ channels.length }} Channels
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="select-actions">
|
<view class="select-actions">
|
||||||
<text class="action-link" @click="selectAll">全选</text>
|
<text class="action-link" @click="selectAll">Select All</text>
|
||||||
<text class="action-divider">|</text>
|
<text class="action-divider">|</text>
|
||||||
<text class="action-link" @click="clearSelection">清空</text>
|
<text class="action-link" @click="clearSelection">Clear</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 通道卡片网格 -->
|
<!-- Channel Cards Grid -->
|
||||||
<view class="channel-grid">
|
<view class="channel-grid">
|
||||||
<view
|
<view
|
||||||
v-for="channel in channels"
|
v-for="channel in channels"
|
||||||
:key="channel.id"
|
:key="channel.id"
|
||||||
:class="['channel-card', { 'selected': isChannelSelected(channel.id) }]"
|
:class="['channel-card', { 'selected': isChannelSelected(channel.id) }]"
|
||||||
>
|
>
|
||||||
<!-- 通道标题 -->
|
<!-- Channel Title -->
|
||||||
<view class="card-header">
|
<view class="card-header">
|
||||||
<!-- 选择复选框(内联在标题左侧) -->
|
<!-- Selection Checkbox (Inline on the left side of title) -->
|
||||||
<view class="channel-checkbox-inline" @click.stop="toggleChannelSelection(channel.id)">
|
<view class="channel-checkbox-inline" @click.stop="toggleChannelSelection(channel.id)">
|
||||||
<view :class="['checkbox-icon', { 'checked': isChannelSelected(channel.id) }]">
|
<view :class="['checkbox-icon', { 'checked': isChannelSelected(channel.id) }]">
|
||||||
<text v-if="isChannelSelected(channel.id)" class="check-mark">✓</text>
|
<text v-if="isChannelSelected(channel.id)" class="check-mark">✓</text>
|
||||||
@@ -59,11 +59,11 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 运行模式控制 -->
|
<!-- Run Mode Control -->
|
||||||
<view class="mode-controls">
|
<view class="mode-controls">
|
||||||
<!-- 转速调节滑块 -->
|
<!-- Speed Adjustment Slider -->
|
||||||
<view class="slider-group" @click.stop>
|
<view class="slider-group" @click.stop>
|
||||||
<text class="slider-label">转速</text>
|
<text class="slider-label">Speed</text>
|
||||||
<text class="slider-min-value">0</text>
|
<text class="slider-min-value">0</text>
|
||||||
<slider
|
<slider
|
||||||
:value="channel.runValue"
|
:value="channel.runValue"
|
||||||
@@ -78,43 +78,43 @@
|
|||||||
<text class="slider-max-value">400</text>
|
<text class="slider-max-value">400</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 转速数值显示 -->
|
<!-- Speed Value Display -->
|
||||||
<view class="speed-display">
|
<view class="speed-display">
|
||||||
<text class="speed-value">{{ calculateSpeed(channel.runValue) }}</text>
|
<text class="speed-value">{{ calculateSpeed(channel.runValue) }}</text>
|
||||||
<text class="speed-unit">转/分</text>
|
<text class="speed-unit">RPM</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 定时设置 -->
|
<!-- Timer Setting -->
|
||||||
<view class="timer-setting" @click.stop="setTimer(channel.id)">
|
<view class="timer-setting" @click.stop="setTimer(channel.id)">
|
||||||
<text class="timer-emoji">⏱</text>
|
<text class="timer-emoji">⏱</text>
|
||||||
<text class="timer-label">{{ channel.timerMode }}:</text>
|
<text class="timer-label">Timer:</text>
|
||||||
<text class="timer-value">{{ channel.timerValue }}</text>
|
<text class="timer-value">{{ channel.timerValue }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 启停按钮 -->
|
<!-- Start/Stop Buttons -->
|
||||||
<view class="card-footer">
|
<view class="card-footer">
|
||||||
<view
|
<view
|
||||||
v-if="channel.status === 'stopped'"
|
v-if="channel.status === 'stopped'"
|
||||||
class="start-btn"
|
class="start-btn"
|
||||||
@click.stop="handleChannelStart(channel.id)"
|
@click.stop="handleChannelStart(channel.id)"
|
||||||
>
|
>
|
||||||
<text class="btn-text">启动</text>
|
<text class="btn-text">Start</text>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
v-else
|
v-else
|
||||||
class="stop-btn"
|
class="stop-btn"
|
||||||
@click.stop="handleChannelStop(channel.id)"
|
@click.stop="handleChannelStop(channel.id)"
|
||||||
>
|
>
|
||||||
<text class="btn-text">停止</text>
|
<text class="btn-text">Stop</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 底部控制区 -->
|
<!-- Bottom Control Area -->
|
||||||
<view class="bottom-controls">
|
<view class="bottom-controls">
|
||||||
<!-- 批量操作按钮 -->
|
<!-- Batch Operation Buttons -->
|
||||||
<view class="batch-buttons">
|
<view class="batch-buttons">
|
||||||
<u-button
|
<u-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
:custom-style="{flex: 1, height: '88rpx', fontSize: '28rpx', fontWeight: '600', borderRadius: '16rpx'}"
|
:custom-style="{flex: 1, height: '88rpx', fontSize: '28rpx', fontWeight: '600', borderRadius: '16rpx'}"
|
||||||
>
|
>
|
||||||
<uni-icons type="checkmarkempty" color="#fff" size="24" style="margin-right: 8rpx;"></uni-icons>
|
<uni-icons type="checkmarkempty" color="#fff" size="24" style="margin-right: 8rpx;"></uni-icons>
|
||||||
启动选中({{ selectedChannels.length }})
|
Start Selected({{ selectedChannels.length }})
|
||||||
</u-button>
|
</u-button>
|
||||||
<u-button
|
<u-button
|
||||||
type="error"
|
type="error"
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
:custom-style="{flex: 1, height: '88rpx', fontSize: '28rpx', fontWeight: '600', borderRadius: '16rpx', marginLeft: '20rpx'}"
|
:custom-style="{flex: 1, height: '88rpx', fontSize: '28rpx', fontWeight: '600', borderRadius: '16rpx', marginLeft: '20rpx'}"
|
||||||
>
|
>
|
||||||
<uni-icons type="closeempty" color="#fff" size="24" style="margin-right: 8rpx;"></uni-icons>
|
<uni-icons type="closeempty" color="#fff" size="24" style="margin-right: 8rpx;"></uni-icons>
|
||||||
停止选中({{ selectedChannels.length }})
|
Stop Selected({{ selectedChannels.length }})
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -178,8 +178,8 @@ const channels = ref([
|
|||||||
currentValue: '0-400',
|
currentValue: '0-400',
|
||||||
runValue: 60,
|
runValue: 60,
|
||||||
controlType: 'speed', // speed, status
|
controlType: 'speed', // speed, status
|
||||||
timerMode: '定时', // 定时, 格式
|
timerMode: 'Timer',
|
||||||
timerValue: '未设置',
|
timerValue: 'Not Set',
|
||||||
remainingTime: 0, // 剩余秒数
|
remainingTime: 0, // 剩余秒数
|
||||||
timerHours: 0 // 设置的小时数
|
timerHours: 0 // 设置的小时数
|
||||||
},
|
},
|
||||||
@@ -191,8 +191,8 @@ const channels = ref([
|
|||||||
currentValue: '0-400',
|
currentValue: '0-400',
|
||||||
runValue: 65,
|
runValue: 65,
|
||||||
controlType: 'speed',
|
controlType: 'speed',
|
||||||
timerMode: '定时',
|
timerMode: 'Timer',
|
||||||
timerValue: '未设置',
|
timerValue: 'Not Set',
|
||||||
remainingTime: 0,
|
remainingTime: 0,
|
||||||
timerHours: 0
|
timerHours: 0
|
||||||
},
|
},
|
||||||
@@ -204,8 +204,8 @@ const channels = ref([
|
|||||||
currentValue: '0-400',
|
currentValue: '0-400',
|
||||||
runValue: 70,
|
runValue: 70,
|
||||||
controlType: 'speed',
|
controlType: 'speed',
|
||||||
timerMode: '定时',
|
timerMode: 'Timer',
|
||||||
timerValue: '未设置',
|
timerValue: 'Not Set',
|
||||||
remainingTime: 0,
|
remainingTime: 0,
|
||||||
timerHours: 0
|
timerHours: 0
|
||||||
},
|
},
|
||||||
@@ -217,8 +217,8 @@ const channels = ref([
|
|||||||
currentValue: '0-400',
|
currentValue: '0-400',
|
||||||
runValue: 75,
|
runValue: 75,
|
||||||
controlType: 'speed',
|
controlType: 'speed',
|
||||||
timerMode: '定时',
|
timerMode: 'Timer',
|
||||||
timerValue: '未设置',
|
timerValue: 'Not Set',
|
||||||
remainingTime: 0,
|
remainingTime: 0,
|
||||||
timerHours: 0
|
timerHours: 0
|
||||||
},
|
},
|
||||||
@@ -230,8 +230,8 @@ const channels = ref([
|
|||||||
currentValue: '0-400',
|
currentValue: '0-400',
|
||||||
runValue: 80,
|
runValue: 80,
|
||||||
controlType: 'speed',
|
controlType: 'speed',
|
||||||
timerMode: '定时',
|
timerMode: 'Timer',
|
||||||
timerValue: '未设置',
|
timerValue: 'Not Set',
|
||||||
remainingTime: 0,
|
remainingTime: 0,
|
||||||
timerHours: 0
|
timerHours: 0
|
||||||
},
|
},
|
||||||
@@ -243,8 +243,8 @@ const channels = ref([
|
|||||||
currentValue: '0-400',
|
currentValue: '0-400',
|
||||||
runValue: 50,
|
runValue: 50,
|
||||||
controlType: 'speed',
|
controlType: 'speed',
|
||||||
timerMode: '定时',
|
timerMode: 'Timer',
|
||||||
timerValue: '未设置',
|
timerValue: 'Not Set',
|
||||||
remainingTime: 0,
|
remainingTime: 0,
|
||||||
timerHours: 0
|
timerHours: 0
|
||||||
}
|
}
|
||||||
@@ -254,7 +254,7 @@ const channels = ref([
|
|||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
if (options.deviceId) {
|
if (options.deviceId) {
|
||||||
deviceId.value = options.deviceId
|
deviceId.value = options.deviceId
|
||||||
deviceName.value = decodeURIComponent(options.deviceName || '') || '六通道搅拌器'
|
deviceName.value = decodeURIComponent(options.deviceName || '') || 'Six-Channel Mixer'
|
||||||
connected.value = true
|
connected.value = true
|
||||||
|
|
||||||
// 获取蓝牙服务和特征值信息
|
// 获取蓝牙服务和特征值信息
|
||||||
@@ -300,12 +300,12 @@ const loadChannelData = (channelId) => {
|
|||||||
channel.status = 'stopped'
|
channel.status = 'stopped'
|
||||||
|
|
||||||
if (channel.timerHours > 0) {
|
if (channel.timerHours > 0) {
|
||||||
channel.timerValue = `设置 ${channel.timerHours} 小时`
|
channel.timerValue = `Set ${channel.timerHours} hours`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('加载通道数据失败:', e)
|
console.error('Failed to load channel data:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ const saveChannelData = (channelId) => {
|
|||||||
uni.setStorageSync(STORAGE_KEY_PREFIX + channelId, JSON.stringify(data))
|
uni.setStorageSync(STORAGE_KEY_PREFIX + channelId, JSON.stringify(data))
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('保存通道数据失败:', e)
|
console.error('Failed to save channel data:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ const isChannelSelected = (channelId) => {
|
|||||||
const selectAll = () => {
|
const selectAll = () => {
|
||||||
selectedChannels.value = channels.value.map(c => c.id)
|
selectedChannels.value = channels.value.map(c => c.id)
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '已全选',
|
title: 'All Selected',
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
duration: 1000
|
duration: 1000
|
||||||
})
|
})
|
||||||
@@ -354,7 +354,7 @@ const selectAll = () => {
|
|||||||
const clearSelection = () => {
|
const clearSelection = () => {
|
||||||
selectedChannels.value = []
|
selectedChannels.value = []
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '已清空选择',
|
title: 'Selection Cleared',
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
duration: 1000
|
duration: 1000
|
||||||
})
|
})
|
||||||
@@ -363,11 +363,11 @@ const clearSelection = () => {
|
|||||||
// 获取状态文本
|
// 获取状态文本
|
||||||
const getStatusText = (status) => {
|
const getStatusText = (status) => {
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
running: '运行中',
|
running: 'Running',
|
||||||
stopped: '已停止',
|
stopped: 'Stopped',
|
||||||
timing: '定时中'
|
timing: 'Timing'
|
||||||
}
|
}
|
||||||
return statusMap[status] || '未知'
|
return statusMap[status] || 'Unknown'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回
|
// 返回
|
||||||
@@ -378,9 +378,10 @@ const goBack = () => {
|
|||||||
// 显示设备信息
|
// 显示设备信息
|
||||||
const showDeviceInfo = () => {
|
const showDeviceInfo = () => {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '设备信息',
|
title: 'Device Info',
|
||||||
content: `设备名称:${deviceName.value}\n设备ID:${deviceId.value}\n连接状态:${connected.value ? '已连接' : '未连接'}`,
|
content: `Device Name: ${deviceName.value}\nDevice ID: ${deviceId.value}\nConnection: ${connected.value ? 'Connected' : 'Disconnected'}`,
|
||||||
showCancel: false
|
showCancel: false,
|
||||||
|
confirmText: 'OK'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,35 +406,37 @@ const setTimer = (channelId) => {
|
|||||||
if (!channel) return
|
if (!channel) return
|
||||||
|
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '定时设置',
|
title: 'Timer Setting',
|
||||||
editable: true,
|
editable: true,
|
||||||
placeholderText: '请输入小时数(0-99)',
|
placeholderText: 'Enter hours (0-99)',
|
||||||
content: channel.timerHours > 0 ? String(channel.timerHours) : '',
|
content: channel.timerHours > 0 ? String(channel.timerHours) : '',
|
||||||
|
cancelText: 'Cancel',
|
||||||
|
confirmText: 'OK',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm && res.content) {
|
if (res.confirm && res.content) {
|
||||||
const hours = parseInt(res.content)
|
const hours = parseInt(res.content)
|
||||||
if (isNaN(hours) || hours < 0 || hours > 99) {
|
if (isNaN(hours) || hours < 0 || hours > 99) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '请输入0-99的数字',
|
title: 'Please enter 0-99',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.timerHours = hours
|
channel.timerHours = hours
|
||||||
channel.remainingTime = hours * 3600 // 转为秒(小时*3600)
|
channel.remainingTime = hours * 3600 // Convert to seconds (hours*3600)
|
||||||
|
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
channel.timerValue = `设置 ${hours} 小时`
|
channel.timerValue = `Set ${hours} hours`
|
||||||
} else {
|
} else {
|
||||||
channel.timerValue = '未设置'
|
channel.timerValue = 'Not Set'
|
||||||
}
|
}
|
||||||
|
|
||||||
saveChannelData(channelId)
|
saveChannelData(channelId)
|
||||||
sendBluetoothCommand('setTimer', channelId, hours)
|
sendBluetoothCommand('setTimer', channelId, hours)
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `定时设置成功`,
|
title: `Timer Set Successfully`,
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -467,7 +470,7 @@ const startChannel = (channelId) => {
|
|||||||
|
|
||||||
sendBluetoothCommand('start', channelId)
|
sendBluetoothCommand('start', channelId)
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `${channel.name} 已启动`,
|
title: `${channel.name} Started`,
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -481,7 +484,7 @@ const stopChannel = (channelId) => {
|
|||||||
stopTimer(channelId)
|
stopTimer(channelId)
|
||||||
sendBluetoothCommand('stop', channelId)
|
sendBluetoothCommand('stop', channelId)
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `${channel.name} 已停止`,
|
title: `${channel.name} Stopped`,
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -491,22 +494,24 @@ const stopChannel = (channelId) => {
|
|||||||
const batchStart = () => {
|
const batchStart = () => {
|
||||||
if (selectedChannels.value.length === 0) {
|
if (selectedChannels.value.length === 0) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '请先选择通道',
|
title: 'Please select channels first',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '确认启动',
|
title: 'Confirm Start',
|
||||||
content: `是否启动选中的 ${selectedChannels.value.length} 个通道?`,
|
content: `Start ${selectedChannels.value.length} selected channels?`,
|
||||||
|
confirmText: 'Confirm',
|
||||||
|
cancelText: 'Cancel',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
selectedChannels.value.forEach(channelId => {
|
selectedChannels.value.forEach(channelId => {
|
||||||
startChannel(channelId)
|
startChannel(channelId)
|
||||||
})
|
})
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `已启动 ${selectedChannels.value.length} 个通道`,
|
title: `Started ${selectedChannels.value.length} channels`,
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -518,22 +523,24 @@ const batchStart = () => {
|
|||||||
const batchStop = () => {
|
const batchStop = () => {
|
||||||
if (selectedChannels.value.length === 0) {
|
if (selectedChannels.value.length === 0) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '请先选择通道',
|
title: 'Please select channels first',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '确认停止',
|
title: 'Confirm Stop',
|
||||||
content: `是否停止选中的 ${selectedChannels.value.length} 个通道?`,
|
content: `Stop ${selectedChannels.value.length} selected channels?`,
|
||||||
|
confirmText: 'Confirm',
|
||||||
|
cancelText: 'Cancel',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
selectedChannels.value.forEach(channelId => {
|
selectedChannels.value.forEach(channelId => {
|
||||||
stopChannel(channelId)
|
stopChannel(channelId)
|
||||||
})
|
})
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `已停止 ${selectedChannels.value.length} 个通道`,
|
title: `Stopped ${selectedChannels.value.length} channels`,
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -563,7 +570,7 @@ const startTimer = (channelId) => {
|
|||||||
sendBluetoothCommand('stop', channelId)
|
sendBluetoothCommand('stop', channelId)
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `${channel.name} 定时已到,自动停止`,
|
title: `${channel.name} Timer expired, auto-stopped`,
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
@@ -584,14 +591,14 @@ const stopTimer = (channelId) => {
|
|||||||
const sendBluetoothCommand = (command, channelId, value) => {
|
const sendBluetoothCommand = (command, channelId, value) => {
|
||||||
if (!connected.value) {
|
if (!connected.value) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '蓝牙未连接',
|
title: 'Bluetooth Disconnected',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!characteristicId.value) {
|
if (!characteristicId.value) {
|
||||||
console.error('未找到可写入的特征值')
|
console.error('Characteristic not found for writing')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,7 +611,7 @@ const sendBluetoothCommand = (command, channelId, value) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const jsonStr = JSON.stringify(commandData)
|
const jsonStr = JSON.stringify(commandData)
|
||||||
console.log('发送蓝牙命令:', jsonStr, `(${jsonStr.length} 字节)`)
|
console.log('Sending Bluetooth command:', jsonStr, `(${jsonStr.length} bytes)`)
|
||||||
|
|
||||||
// 检查是否需要分包
|
// 检查是否需要分包
|
||||||
if (jsonStr.length <= 20) {
|
if (jsonStr.length <= 20) {
|
||||||
@@ -615,7 +622,7 @@ const sendBluetoothCommand = (command, channelId, value) => {
|
|||||||
sendMultiplePackets(jsonStr)
|
sendMultiplePackets(jsonStr)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('构造蓝牙命令失败:', error)
|
console.error('Failed to construct Bluetooth command:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,12 +636,12 @@ const sendSinglePacket = (data) => {
|
|||||||
characteristicId: characteristicId.value,
|
characteristicId: characteristicId.value,
|
||||||
value: buffer,
|
value: buffer,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log('✅ 蓝牙数据发送成功')
|
console.log('✅ Bluetooth data sent successfully')
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('❌ 蓝牙数据发送失败:', err)
|
console.error('❌ Bluetooth data send failed:', err)
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '发送失败',
|
title: 'Send Failed',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -651,7 +658,7 @@ const sendMultiplePackets = (data) => {
|
|||||||
packets.push(data.slice(i, i + maxPacketSize))
|
packets.push(data.slice(i, i + maxPacketSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`📦 数据需要分 ${packets.length} 包发送`)
|
console.log(`📦 Data needs to be sent in ${packets.length} packets`)
|
||||||
|
|
||||||
// 依次发送每个包(间隔 100ms)
|
// 依次发送每个包(间隔 100ms)
|
||||||
packets.forEach((packet, index) => {
|
packets.forEach((packet, index) => {
|
||||||
@@ -664,10 +671,10 @@ const sendMultiplePackets = (data) => {
|
|||||||
characteristicId: characteristicId.value,
|
characteristicId: characteristicId.value,
|
||||||
value: buffer,
|
value: buffer,
|
||||||
success: () => {
|
success: () => {
|
||||||
console.log(`✅ 第 ${index + 1}/${packets.length} 包发送成功`)
|
console.log(`✅ Packet ${index + 1}/${packets.length} sent successfully`)
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error(`❌ 第 ${index + 1}/${packets.length} 包发送失败:`, err)
|
console.error(`❌ Packet ${index + 1}/${packets.length} send failed:`, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, index * 100)
|
}, index * 100)
|
||||||
@@ -705,7 +712,7 @@ const initBluetoothCommunication = () => {
|
|||||||
|
|
||||||
if (!res.connected) {
|
if (!res.connected) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '蓝牙已断开',
|
title: 'Bluetooth Disconnected',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
// 停止数据查询
|
// 停止数据查询
|
||||||
|
|||||||
Reference in New Issue
Block a user