fix: 倒计时到25秒时刻,显示为25/60

This commit is contained in:
tianyongbao
2026-01-09 00:00:57 +08:00
parent 04827c9344
commit 75e1b9ca9b

View File

@@ -89,7 +89,10 @@
<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">Timer:</text> <text class="timer-label">Timer:</text>
<text class="timer-value">{{ channel.timerValue }}</text> <text class="timer-value" v-if="channel.status === 'timing' && channel.remainingTime > 0">
{{ channel.remainingTime }}/{{ channel.timerSeconds }}
</text>
<text class="timer-value" v-else>{{ channel.timerValue }}</text>
</view> </view>
<!-- Start/Stop Buttons --> <!-- Start/Stop Buttons -->
@@ -228,7 +231,7 @@ const channels = ref([
timerMode: 'Timer', timerMode: 'Timer',
timerValue: 'Not Set', timerValue: 'Not Set',
remainingTime: 0, // 剩余秒数 remainingTime: 0, // 剩余秒数
timerMinutes: 0 // 设置的分钟 timerSeconds: 0 // 设置的
}, },
{ {
id: 'CH2', id: 'CH2',
@@ -241,7 +244,7 @@ const channels = ref([
timerMode: 'Timer', timerMode: 'Timer',
timerValue: 'Not Set', timerValue: 'Not Set',
remainingTime: 0, remainingTime: 0,
timerMinutes: 0 timerSeconds: 0
}, },
{ {
id: 'CH3', id: 'CH3',
@@ -254,7 +257,7 @@ const channels = ref([
timerMode: 'Timer', timerMode: 'Timer',
timerValue: 'Not Set', timerValue: 'Not Set',
remainingTime: 0, remainingTime: 0,
timerMinutes: 0 timerSeconds: 0
}, },
{ {
id: 'CH4', id: 'CH4',
@@ -267,7 +270,7 @@ const channels = ref([
timerMode: 'Timer', timerMode: 'Timer',
timerValue: 'Not Set', timerValue: 'Not Set',
remainingTime: 0, remainingTime: 0,
timerMinutes: 0 timerSeconds: 0
}, },
{ {
id: 'CH5', id: 'CH5',
@@ -280,7 +283,7 @@ const channels = ref([
timerMode: 'Timer', timerMode: 'Timer',
timerValue: 'Not Set', timerValue: 'Not Set',
remainingTime: 0, remainingTime: 0,
timerMinutes: 0 timerSeconds: 0
}, },
{ {
id: 'CH6', id: 'CH6',
@@ -293,7 +296,7 @@ const channels = ref([
timerMode: 'Timer', timerMode: 'Timer',
timerValue: 'Not Set', timerValue: 'Not Set',
remainingTime: 0, remainingTime: 0,
timerMinutes: 0 timerSeconds: 0
} }
]) ])
@@ -424,12 +427,12 @@ const loadChannelData = (channelId) => {
if (channel) { if (channel) {
// 恢复保存的数据,但状态默认为停止 // 恢复保存的数据,但状态默认为停止
channel.runValue = data.runValue || channel.runValue channel.runValue = data.runValue || channel.runValue
channel.timerMinutes = data.timerMinutes || 0 channel.timerSeconds = data.timerSeconds || 0
channel.remainingTime = 0 channel.remainingTime = 0
channel.status = 'stopped' channel.status = 'stopped'
if (channel.timerMinutes > 0) { if (channel.timerSeconds > 0) {
channel.timerValue = `Set ${channel.timerMinutes} min` channel.timerValue = `${channel.timerSeconds}s`
} }
} }
} }
@@ -445,7 +448,7 @@ const saveChannelData = (channelId) => {
if (channel) { if (channel) {
const data = { const data = {
runValue: channel.runValue, runValue: channel.runValue,
timerMinutes: channel.timerMinutes timerSeconds: channel.timerSeconds
} }
uni.setStorageSync(STORAGE_KEY_PREFIX + channelId, JSON.stringify(data)) uni.setStorageSync(STORAGE_KEY_PREFIX + channelId, JSON.stringify(data))
} }
@@ -582,14 +585,14 @@ const setTimer = (channelId) => {
uni.showModal({ uni.showModal({
title: 'Timer Setting', title: 'Timer Setting',
editable: true, editable: true,
placeholderText: 'Enter minutes (0-9999)', placeholderText: 'Enter seconds (0-9999)',
content: channel.timerMinutes > 0 ? String(channel.timerMinutes) : '', content: channel.timerSeconds > 0 ? String(channel.timerSeconds) : '',
cancelText: 'Cancel', cancelText: 'Cancel',
confirmText: 'OK', confirmText: 'OK',
success: (res) => { success: (res) => {
if (res.confirm && res.content) { if (res.confirm && res.content) {
const minutes = parseInt(res.content) const seconds = parseInt(res.content)
if (isNaN(minutes) || minutes < 0 || minutes > 9999) { if (isNaN(seconds) || seconds < 0 || seconds > 9999) {
uni.showToast({ uni.showToast({
title: 'Please enter 0-9999', title: 'Please enter 0-9999',
icon: 'none' icon: 'none'
@@ -597,12 +600,12 @@ const setTimer = (channelId) => {
return return
} }
console.log(`${channel.name} 设置定时: ${channel.timerMinutes} -> ${minutes}分钟`) console.log(`${channel.name} 设置定时: ${channel.timerSeconds} -> ${seconds}s`)
addDebugLog(`${channel.name} 设置定时: ${minutes}分钟`, 'info') addDebugLog(`${channel.name} 设置定时: ${seconds}s`, 'info')
// ✅ 不立即修改状态,只发送命令 // ✅ 不立即修改状态,只发送命令
// 等待蓝牙设备反馈后,通过 onBLECharacteristicValueChange 监听器更新定时设置 // 等待蓝牙设备反馈后,通过 onBLECharacteristicValueChange 监听器更新定时设置
sendBluetoothCommand('setTimer', channelId, minutes) sendBluetoothCommand('setTimer', channelId, seconds)
uni.showToast({ uni.showToast({
title: `${channel.name} Timer Command Sent`, title: `${channel.name} Timer Command Sent`,
@@ -765,8 +768,8 @@ const startTimer = (channelId) => {
// 清除旧定时器 // 清除旧定时器
stopTimer(channelId) stopTimer(channelId)
console.log(`⏱️ 启动定时器: ${channel.name}, 剩余时间: ${channel.remainingTime}`) console.log(`⏱️ 启动定时器: ${channel.name}, 剩余时间: ${channel.remainingTime}s`)
addDebugLog(`⏱️ ${channel.name} 启动定时器: ${Math.floor(channel.remainingTime / 60)}分钟`, 'info') addDebugLog(`⏱️ ${channel.name} 启动定时器: ${channel.remainingTime}s`, 'info')
// 创建新定时器(后台倒计时,不显示给用户) // 创建新定时器(后台倒计时,不显示给用户)
timerIntervals.value[channelId] = setInterval(() => { timerIntervals.value[channelId] = setInterval(() => {
@@ -849,8 +852,8 @@ const sendBluetoothCommand = (command, channelId, value) => {
break break
case 'setTimer': case 'setTimer':
// 写入电机定时设置0xFF04单位分钟 // 写入电机定时设置0xFF04单位
writeMotorTimer(channelIndex, value) // 直接使用分钟 writeMotorTimer(channelIndex, value) // 直接使用
break break
case 'query': case 'query':
@@ -939,15 +942,15 @@ const writeMotorSpeed = (channelIndex, speed, isBatch = false, batchChannels = [
} }
// 写入电机定时设置(0xFF04) - 格式:电机序号 + 定时时间(小端序) // 写入电机定时设置(0xFF04) - 格式:电机序号 + 定时时间(小端序)
const writeMotorTimer = (channelIndex, minutes) => { const writeMotorTimer = (channelIndex, seconds) => {
// 写格式长度可变每3个字节表示一组采用电机序号+电机定时时间的方式 // 写格式长度可变每3个字节表示一组采用电机序号+电机定时时间的方式
// 例如:[1, 2, 5] 表示第1个电机定时1282分钟2 + 5*256 = 1282 // 例如:[1, 2, 5] 表示第1个电机定时12822 + 5*256 = 1282
const buffer = new ArrayBuffer(3) const buffer = new ArrayBuffer(3)
const dataView = new Uint8Array(buffer) const dataView = new Uint8Array(buffer)
dataView[0] = channelIndex + 1 // 电机序号1-6 dataView[0] = channelIndex + 1 // 电机序号1-6
dataView[1] = minutes & 0xFF // 定时时间低位 dataView[1] = seconds & 0xFF // 定时时间低位
dataView[2] = (minutes >> 8) & 0xFF // 定时时间高位 dataView[2] = (seconds >> 8) & 0xFF // 定时时间高位
// 📝 使用专用的定时特征值UUID0xFF04 // 📝 使用专用的定时特征值UUID0xFF04
const writeCharId = characteristicIds.value.timer || characteristicIds.value.write || '0xFF04' const writeCharId = characteristicIds.value.timer || characteristicIds.value.write || '0xFF04'
@@ -1218,7 +1221,7 @@ Operation: Read Data
Description: Read timer remaining time Description: Read timer remaining time
Query data: Query data:
- Remaining time of 6 channels (minutes) - Remaining time of 6 channels (seconds)
Expected: 12 bytes Expected: 12 bytes
Format: 2 bytes per channel (little-endian)` Format: 2 bytes per channel (little-endian)`
@@ -1375,8 +1378,8 @@ const initBluetoothCommunication = () => {
addDebugLog(` ${channel.name}: ${channel.status} -> ${newStatus}`, 'warn') addDebugLog(` ${channel.name}: ${channel.status} -> ${newStatus}`, 'warn')
// 如果从非定时状态变为定时状态,启动定时器 // 如果从非定时状态变为定时状态,启动定时器
if (newStatus === 'timing' && channel.timerMinutes > 0) { if (newStatus === 'timing' && channel.timerSeconds > 0) {
channel.remainingTime = channel.timerMinutes * 60 channel.remainingTime = channel.timerSeconds
startTimer(channel.id) startTimer(channel.id)
} }
@@ -1528,8 +1531,8 @@ const parseMotorStatusOrSpeed = (dataView) => {
console.log(`${channel.name} 状态变化: ${channel.status} -> ${newStatus}`) console.log(`${channel.name} 状态变化: ${channel.status} -> ${newStatus}`)
// 如果从非定时状态变为定时状态,启动定时器 // 如果从非定时状态变为定时状态,启动定时器
if (newStatus === 'timing' && channel.timerMinutes > 0) { if (newStatus === 'timing' && channel.timerSeconds > 0) {
channel.remainingTime = channel.timerMinutes * 60 channel.remainingTime = channel.timerSeconds
startTimer(channel.id) startTimer(channel.id)
} }
@@ -1557,40 +1560,40 @@ const parseMotorStatusOrSpeed = (dataView) => {
const parseMotorTimer = (dataView, type = 'unknown') => { const parseMotorTimer = (dataView, type = 'unknown') => {
channels.value.forEach((channel, index) => { channels.value.forEach((channel, index) => {
// 低位在前,高位在后(小端序) // 低位在前,高位在后(小端序)
const minutes = dataView[index * 2] | (dataView[index * 2 + 1] << 8) const seconds = dataView[index * 2] | (dataView[index * 2 + 1] << 8)
if (minutes > 0) { if (seconds > 0) {
if (type === 'remaining') { if (type === 'remaining') {
// 明确是剩余时间0xFF05 // 明确是剩余时间0xFF05
channel.remainingTime = minutes * 60 // 转为秒 channel.remainingTime = seconds
console.log(`${channel.name} 剩余时间:`, minutes, '分钟') console.log(`${channel.name} 剩余时间:`, seconds, 's')
addDebugLog(` ${channel.name}: 剩余 ${minutes}分钟`, 'info') addDebugLog(` ${channel.name}: 剩余 ${seconds}s`, 'info')
} else if (type === 'setup') { } else if (type === 'setup') {
// 明确是定时设置0xFF04- 根据设备反馈更新本地定时设置 // 明确是定时设置0xFF04- 根据设备反馈更新本地定时设置
if (channel.timerMinutes !== minutes) { if (channel.timerSeconds !== seconds) {
console.log(`${channel.name} 定时设置变化: ${channel.timerMinutes} -> ${minutes} 分钟`) console.log(`${channel.name} 定时设置变化: ${channel.timerSeconds} -> ${seconds}s`)
addDebugLog(` ${channel.name}: 定时 ${channel.timerMinutes} -> ${minutes}分钟`, 'warn') addDebugLog(` ${channel.name}: 定时 ${channel.timerSeconds} -> ${seconds}s`, 'warn')
channel.timerMinutes = minutes channel.timerSeconds = seconds
channel.timerValue = minutes > 0 ? `Set ${minutes} min` : 'Not Set' channel.timerValue = seconds > 0 ? `${seconds}s` : 'Not Set'
// 保存到本地存储 // 保存到本地存储
saveChannelData(channel.id) saveChannelData(channel.id)
} else { } else {
console.log(`${channel.name} 定时未变: ${minutes}分钟`) console.log(`${channel.name} 定时未变: ${seconds}s`)
} }
} else { } else {
// 未知类型,根据当前状态智能判断(兼容旧逻辑) // 未知类型,根据当前状态智能判断(兼容旧逻辑)
if (channel.status === 'timing' && channel.remainingTime > 0) { if (channel.status === 'timing' && channel.remainingTime > 0) {
// 如果正在定时中且已有剩余时间,优先更新剩余时间 // 如果正在定时中且已有剩余时间,优先更新剩余时间
channel.remainingTime = minutes * 60 channel.remainingTime = seconds
console.log(`${channel.name} 剩余时间(推测):`, minutes, '分钟') console.log(`${channel.name} 剩余时间(推测):`, seconds, 's')
addDebugLog(` ${channel.name}: 剩余 ${minutes}分钟(推测)`, 'info') addDebugLog(` ${channel.name}: 剩余 ${seconds}s(推测)`, 'info')
} else { } else {
// 否则当作定时设置 - 根据设备反馈更新本地定时设置 // 否则当作定时设置 - 根据设备反馈更新本地定时设置
if (channel.timerMinutes !== minutes) { if (channel.timerSeconds !== seconds) {
console.log(`${channel.name} 定时设置变化(推测): ${channel.timerMinutes} -> ${minutes} 分钟`) console.log(`${channel.name} 定时设置变化(推测): ${channel.timerSeconds} -> ${seconds}s`)
addDebugLog(` ${channel.name}: 定时 ${minutes}分钟(推测)`, 'warn') addDebugLog(` ${channel.name}: 定时 ${seconds}s(推测)`, 'warn')
channel.timerMinutes = minutes channel.timerSeconds = seconds
channel.timerValue = minutes > 0 ? `Set ${minutes} min` : 'Not Set' channel.timerValue = seconds > 0 ? `${seconds}s` : 'Not Set'
// 保存到本地存储 // 保存到本地存储
saveChannelData(channel.id) saveChannelData(channel.id)
} }
@@ -1620,8 +1623,8 @@ const parseMotorAllProperties = (dataView) => {
addDebugLog(` ${channel.name}: ${channel.status} -> ${newStatus}`, 'warn') addDebugLog(` ${channel.name}: ${channel.status} -> ${newStatus}`, 'warn')
// 如果从非定时状态变为定时状态,启动定时器 // 如果从非定时状态变为定时状态,启动定时器
if (newStatus === 'timing' && channel.timerMinutes > 0) { if (newStatus === 'timing' && channel.timerSeconds > 0) {
channel.remainingTime = channel.timerMinutes * 60 channel.remainingTime = channel.timerSeconds
startTimer(channel.id) startTimer(channel.id)
} }
@@ -1648,21 +1651,21 @@ const parseMotorAllProperties = (dataView) => {
// 可以根据需要存储方向信息 // 可以根据需要存储方向信息
// 定时设置18-29字节- 根据设备反馈更新本地定时设置 // 定时设置18-29字节- 根据设备反馈更新本地定时设置
const timerMinutes = dataView[18 + index * 2] | (dataView[18 + index * 2 + 1] << 8) const timerSeconds = dataView[18 + index * 2] | (dataView[18 + index * 2 + 1] << 8)
if (channel.timerMinutes !== timerMinutes) { if (channel.timerSeconds !== timerSeconds) {
console.log(`${channel.name} 定时设置变化: ${channel.timerMinutes} -> ${timerMinutes}分钟`) console.log(`${channel.name} 定时设置变化: ${channel.timerSeconds} -> ${timerSeconds}s`)
addDebugLog(` ${channel.name}: 定时 ${channel.timerMinutes} -> ${timerMinutes}分钟`, 'info') addDebugLog(` ${channel.name}: 定时 ${channel.timerSeconds} -> ${timerSeconds}s`, 'info')
channel.timerMinutes = timerMinutes channel.timerSeconds = timerSeconds
channel.timerValue = timerMinutes > 0 ? `Set ${timerMinutes} min` : 'Not Set' channel.timerValue = timerSeconds > 0 ? `${timerSeconds}s` : 'Not Set'
// 保存到本地存储 // 保存到本地存储
saveChannelData(channel.id) saveChannelData(channel.id)
} }
// 剩余时间30-41字节 // 剩余时间30-41字节
const remainingMinutes = dataView[30 + index * 2] | (dataView[30 + index * 2 + 1] << 8) const remainingSeconds = dataView[30 + index * 2] | (dataView[30 + index * 2 + 1] << 8)
channel.remainingTime = remainingMinutes * 60 // 转为秒 channel.remainingTime = remainingSeconds
console.log(`${channel.name} 完整数据 - 状态:${channel.status}, 速度:${speed}, 方向:${direction}, 定时:${timerMinutes}分钟, 剩余:${remainingMinutes}分钟`) console.log(`${channel.name} 完整数据 - 状态:${channel.status}, 速度:${speed}, 方向:${direction}, 定时:${timerSeconds}s, 剩余:${remainingSeconds}s`)
}) })
} }