diff --git a/pagesA/home/device/status/voice.vue b/pagesA/home/device/status/voice.vue index 5bf8d59..75c10d3 100644 --- a/pagesA/home/device/status/voice.vue +++ b/pagesA/home/device/status/voice.vue @@ -18,7 +18,7 @@ - + 基础信息 @@ -80,7 +80,7 @@ - 默认列表 + 播放列表 @@ -91,11 +91,20 @@ - - {{ item.name }} + + + {{ item.name }} + + {{ item.playTime }} + {{ item.weekdays }} + {{ item.radarSpeed }} + + - {{ item.duration }} + @@ -104,7 +113,6 @@ - 远程喊话 按住按钮开始录音,松开结束录音 - + - + - + - + @@ -163,7 +175,7 @@ - 添加默认音频 + 添加播放列表 @@ -686,7 +698,7 @@ }, async confirmAddAudio() { if (!this.checkOnline()) return; - + try { // 获取当前的 mp3_list 模型 const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === 'mp3_list'); @@ -697,7 +709,7 @@ // 解析当前的 mp3_list 数据 const jsonStr = mp3ListModel.shadow.replace('JSON=', ''); const data = JSON.parse(jsonStr); - + // 获取当前最大的 id let maxId = 0; if (data.sound_card && data.sound_card.mp3_list) { @@ -708,10 +720,10 @@ } }); } - + // 生成新的 id const newId = maxId + 1; - + // 构建 TTS 请求数据 const ttsData = { JSON_id: 1, @@ -757,17 +769,131 @@ }); } }, - confirmAddDefault() { + async confirmAddDefault() { if (!this.checkOnline()) return; - uni.showToast({ - title: '默认音频添加成功', - icon: 'success' - }); - this.showAddDefault = false; + + // 验证必填项 + if (!this.newDefault.startTime || !this.newDefault.endTime || !this.newDefault.audioFile) { + uni.showToast({ + title: '请填写完整信息', + icon: 'none' + }); + return; + } + + // 验证雷达速度范围 + if (this.newDefault.radarEnabled) { + if (!this.newDefault.minSpeed || !this.newDefault.maxSpeed) { + uni.showToast({ + title: '请填写速度范围', + icon: 'none' + }); + return; + } + if (parseInt(this.newDefault.minSpeed) >= parseInt(this.newDefault.maxSpeed)) { + uni.showToast({ + title: '最小速度必须小于最大速度', + icon: 'none' + }); + return; + } + } + + const playListModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_list'); + if (playListModel) { + try { + const jsonStr = playListModel.shadow.replace('JSON=', ''); + const data = JSON.parse(jsonStr); + + // 确保 sound_card 和 play_list 存在 + if (!data.sound_card) { + data.sound_card = {}; + } + if (!data.sound_card.play_list) { + data.sound_card.play_list = []; + } + + // 获取当前最大的序号 + let maxNum = 0; + if (data.sound_card.play_list.length > 0) { + maxNum = Math.max(...data.sound_card.play_list.map(item => item.play.num || 0)); + } + + // 转换时间格式(HH:MM 转为秒数) + const [startHour, startMinute] = this.newDefault.startTime.split(':').map(Number); + const [endHour, endMinute] = this.newDefault.endTime.split(':').map(Number); + const startSeconds = startHour * 3600 + startMinute * 60; + const endSeconds = endHour * 3600 + endMinute * 60; + + // 转换星期格式(数组转为数字) + let weekValue = 0; + this.newDefault.repeatDays.forEach(day => { + weekValue |= (1 << day); + }); + + // 构建新的播放项 + const newPlayItem = { + play: { + num: maxNum + 1, + filename: this.newDefault.audioFile.name, + en: 1 + }, + time: { + begin: startSeconds, + end: endSeconds, + week: weekValue + }, + speed: { + en: this.newDefault.radarEnabled ? 1 : 0, + min: this.newDefault.radarEnabled ? parseInt(this.newDefault.minSpeed) : 0, + max: this.newDefault.radarEnabled ? parseInt(this.newDefault.maxSpeed) : 0 + } + }; + + // 添加到播放列表 + data.sound_card.play_list.push(newPlayItem); + + // 更新物模型shadow值 + playListModel.shadow = 'JSON=' + JSON.stringify(data); + + // 发送更新 + try { + await this.mqttPublish(this.device, playListModel); + uni.showToast({ + title: '添加成功', + icon: 'success' + }); + this.showAddDefault = false; + + // 重置表单 + this.newDefault = { + startTime: '', + endTime: '', + repeatDays: [], + radarEnabled: false, + minSpeed: '', + maxSpeed: '', + audioFile: null + }; + } catch (error) { + console.error('发送添加命令失败:', error); + uni.showToast({ + title: '添加失败', + icon: 'none' + }); + } + } catch (error) { + console.error('解析或更新播放列表失败:', error); + uni.showToast({ + title: '添加失败', + icon: 'none' + }); + } + } }, async deleteAudio(index) { if (!this.checkOnline()) return; - + try { uni.showModal({ title: '提示', @@ -777,26 +903,27 @@ success: async (res) => { if (res.confirm) { // 获取当前的 mp3_list 模型 - const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === 'mp3_list'); + const mp3ListModel = this.deviceInfo.thingsModels.find(model => model + .id === 'mp3_list'); if (mp3ListModel && mp3ListModel.shadow) { try { // 解析当前的 JSON 数据 const jsonStr = mp3ListModel.shadow.replace('JSON=', ''); const data = JSON.parse(jsonStr); - + // 从音频列表中删除指定索引的项 if (data.sound_card && data.sound_card.mp3_list) { data.sound_card.mp3_list.splice(index, 1); - + // 更新 shadow 值 mp3ListModel.shadow = 'JSON=' + JSON.stringify(data); - + // 发送更新到设备 await this.mqttPublish(this.device, mp3ListModel); - + // 更新本地音频列表 this.audioList.splice(index, 1); - + uni.showToast({ title: '删除成功', icon: 'success' @@ -824,12 +951,53 @@ deleteDefault(index) { uni.showModal({ title: '提示', - content: '确定要删除该默认音频吗?', + content: '确认删除该播放项吗?', cancelText: '取消', confirmText: '确定', - success: (res) => { + success: async (res) => { if (res.confirm) { - this.defaultList.splice(index, 1); + const playListModel = this.deviceInfo.thingsModels.find(model => model.id === + 'play_list'); + if (playListModel) { + try { + const jsonStr = playListModel.shadow.replace('JSON=', ''); + const data = JSON.parse(jsonStr); + + if (data.sound_card && data.sound_card.play_list) { + // 删除对应的播放项 + data.sound_card.play_list.splice(index, 1); + + // 更新序号 + data.sound_card.play_list.forEach((item, index) => { + item.play.num = index + 1; + }); + + // 更新物模型shadow值 + playListModel.shadow = 'JSON=' + JSON.stringify(data); + + // 发送更新 + try { + await this.mqttPublish(this.device, playListModel); + uni.showToast({ + title: '删除成功', + icon: 'success' + }); + } catch (error) { + console.error('发送删除命令失败:', error); + uni.showToast({ + title: '删除失败', + icon: 'none' + }); + } + } + } catch (error) { + console.error('解析或更新播放列表失败:', error); + uni.showToast({ + title: '删除失败', + icon: 'none' + }); + } + } } } }); @@ -925,20 +1093,20 @@ // 更新音频列表 const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === 'mp3_list'); console.log('mp3ListModel:', mp3ListModel); - + if (mp3ListModel && mp3ListModel.shadow) { try { // 解析 JSON 字符串 const jsonStr = mp3ListModel.shadow.replace('JSON=', ''); console.log('jsonStr:', jsonStr); - + const data = JSON.parse(jsonStr); console.log('parsed data:', data); // 获取 mp3_list 数组 if (data.sound_card && data.sound_card.mp3_list) { console.log('mp3_list:', data.sound_card.mp3_list); - + // 更新音频列表 this.audioList = data.sound_card.mp3_list.map((item, index) => { // 从 "1_def" 格式中提取名称 @@ -960,6 +1128,99 @@ } else { console.log('no mp3ListModel or shadow is empty'); } + + // 更新播放列表 + const playListModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_list'); + if (playListModel && playListModel.shadow) { + try { + const jsonStr = playListModel.shadow.replace('JSON=', ''); + const data = JSON.parse(jsonStr); + + if (data.sound_card && data.sound_card.play_list) { + this.defaultList = data.sound_card.play_list.map((item, index) => { + // 转换时间格式 + const beginTime = this.formatSecondsToTime(item.time.begin); + const endTime = this.formatSecondsToTime(item.time.end); + + // 转换星期格式 + const weekdays = this.convertWeekToArray(item.time.week); + + return { + id: index + 1, + name: item.play.filename, + playTime: `${beginTime} - ${endTime}`, + weekdays: weekdays.join(', '), + radarEnabled: item.speed.en === 1, + status: item.play.en === 1 ? '启用' : '禁用', + radarSpeed: item.speed.en === 1 ? `${item.speed.min}-${item.speed.max}km/h` : + '' + }; + }); + } + } catch (error) { + console.error('解析播放列表失败:', error); + } + } + }, + + // 将秒数转换为时间格式 (HH:MM) + formatSecondsToTime(seconds) { + const hours = Math.floor(seconds / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`; + }, + + // 将星期数字转换为数组 + convertWeekToArray(week) { + const weekdays = []; + for (let i = 0; i < 7; i++) { + if (week & (1 << i)) { + weekdays.push(this.weekDays[i]); + } + } + return weekdays; + }, + async handleStatusChange(index, value) { + const playListModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_list'); + if (playListModel) { + try { + const jsonStr = playListModel.shadow.replace('JSON=', ''); + const data = JSON.parse(jsonStr); + + if (data.sound_card && data.sound_card.play_list) { + // 更新播放项的启用状态 + data.sound_card.play_list[index].play.en = value === '启用' ? 1 : 0; + + // 更新物模型shadow值 + playListModel.shadow = 'JSON=' + JSON.stringify(data); + + // 发送更新 + try { + await this.mqttPublish(this.device, playListModel); + uni.showToast({ + title: '更新成功', + icon: 'success' + }); + } catch (error) { + console.error('发送状态更新命令失败:', error); + uni.showToast({ + title: '更新失败', + icon: 'none' + }); + // 恢复原状态 + this.defaultList[index].status = value === '启用' ? '禁用' : '启用'; + } + } + } catch (error) { + console.error('解析或更新播放列表失败:', error); + uni.showToast({ + title: '更新失败', + icon: 'none' + }); + // 恢复原状态 + this.defaultList[index].status = value === '启用' ? '禁用' : '启用'; + } + } } }, computed: { @@ -1129,17 +1390,37 @@ .audio-info { display: flex; - align-items: center; + align-items: flex-start; gap: 16rpx; flex: 1; overflow: hidden; - .audio-name { - font-size: 26rpx; - color: #333; + .audio-details { + flex: 1; overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + + .audio-name { + font-size: 26rpx; + color: #333; + margin-bottom: 8rpx; + display: block; + } + + .audio-meta { + display: flex; + flex-wrap: wrap; + gap: 12rpx; + font-size: 22rpx; + color: #666; + + .time-info, + .week-info, + .radar-info { + background-color: #f5f5f5; + padding: 4rpx 12rpx; + border-radius: 4rpx; + } + } } } @@ -1148,13 +1429,6 @@ align-items: center; gap: 24rpx; margin-left: 16rpx; - - .audio-duration { - font-size: 24rpx; - color: #999; - min-width: 72rpx; - text-align: right; - } } } } @@ -1241,13 +1515,13 @@ display: flex; align-items: center; width: 100%; - + .custom-slider { flex: 1; margin-right: 20rpx; } } - + :deep(.u-radio-group) { display: flex; flex-wrap: wrap;