From 179dce665a06cd1e1bfa86f12e764ac0f8c773e6 Mon Sep 17 00:00:00 2001
From: 1 <1>
Date: Wed, 18 Jun 2025 10:18:15 +0800
Subject: [PATCH] =?UTF-8?q?xaznapp=E5=A3=B0=E5=8D=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pagesA/home/device/status/voice.vue | 372 ++++++++++++++++++++++++----
1 file changed, 323 insertions(+), 49 deletions(-)
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 }}
+ handleStatusChange(index, value)" size="22">
@@ -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;