声卡部分功能完善

This commit is contained in:
1 2025-06-23 09:16:12 +08:00
parent 8c7b69b208
commit 70b0895bf6
5 changed files with 454 additions and 189 deletions

BIN
dist.zip

Binary file not shown.

View File

@ -117,10 +117,6 @@
"device.device-edit.148398-87": "Server domain ",
"device.device-edit.148398-88": "Server ID",
"device.device-edit.148398-89": "Authentication password",
"device.device-edit.148398-90": "Access port number",
"device.device-edit.148398-91": "Type of Certification",
"device.device-edit.148398-92": "Account",
"device.device-edit.148398-93": "password",
"device.device-functionlog.399522-0": "Please Select A Device Slave:",
"device.device-functionlog.399522-1": "Please Select A Device Slave",
"device.device-functionlog.399522-2": "Slave Address:$",
@ -663,6 +659,10 @@
"iot.group.index.637432-25": "New successfully added",
"iot.group.index.637432-26": "Are you sure to delete the data item with device group number {0}?",
"iot.group.index.637432-27": "Delete successful",
"iot.group.index.637432-28": "Are you sure to deploy the playlist to all devices in this group?",
"iot.group.index.637432-29": "Confirm Deployment",
"iot.group.index.637432-30": "Confirm",
"iot.group.index.637432-31": "Cancel",
"iot.group.device-list.849593-0": "Select device",
"iot.group.device-list.849593-1": "Device Name",
"iot.group.device-list.849593-2": "Please enter the device name",

View File

@ -664,6 +664,10 @@
"iot.group.index.637432-25": "新增成功",
"iot.group.index.637432-26": "是否确认删除设备分组编号为{0}的数据项?",
"iot.group.index.637432-27": "删除成功",
"iot.group.index.637432-28": "确认要下发播放列表到该分组下的所有设备吗?将覆盖原设备播放列表!!!",
"iot.group.index.637432-29": "确认下发",
"iot.group.index.637432-30": "确定",
"iot.group.index.637432-31": "取消",
"iot.group.device-list.849593-0": "选择设备",
"iot.group.device-list.849593-1": "设备名称",
"iot.group.device-list.849593-2": "请输入设备名称",

View File

@ -67,7 +67,7 @@
border>
<el-table-column prop="id" label="序号" width="80" align="center">
</el-table-column>
<el-table-column prop="name" label="音频名称" min-width="150">
<el-table-column prop="name" label="音频名称" min-width="150" align="center">
</el-table-column>
<el-table-column label="操作" width="120" align="center">
<template slot-scope="scope">
@ -82,52 +82,6 @@
</template>
</el-table>
</el-card>
<!-- 播放列表 -->
<el-card class="default-list-card" shadow="hover">
<div slot="header" class="default-list-header">
<span class="default-list-title">播放列表</span>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="showAddPlaylistDialog">
添加音频
</el-button>
</div>
<el-table :data="defaultList" style="width: 100%" :header-cell-style="{ background: '#f5f7fa' }"
border>
<el-table-column prop="id" label="序号" width="80" align="center">
</el-table-column>
<el-table-column prop="name" label="音频名称" min-width="150">
</el-table-column>
<el-table-column prop="playTime" label="播放时间" width="120" align="center">
</el-table-column>
<el-table-column prop="weekdays" label="重复" width="200" align="center">
</el-table-column>
<el-table-column label="雷达" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.radarEnabled ? 'success' : 'info'">
{{ scope.row.radarEnabled ? '开启' : '关闭' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" width="120" align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.status" :active-value="'启用'" :inactive-value="'禁用'"
@change="handleStatusChange(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-delete" @click="handleDeletePlaylist(scope.row)">
</el-button>
</template>
</el-table-column>
<template slot="empty">
<div style="padding: 20px 0;">
<el-empty description="暂无播放列表数据"></el-empty>
</div>
</template>
</el-table>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
@ -199,6 +153,60 @@
</el-col>
</el-row>
<!-- 播放列表 - 占据整行宽度 -->
<el-row :gutter="20" style="margin-top: 20px;">
<el-col :xs="22" :sm="22" :md="22" :lg="22" :xl="22">
<el-card class="default-list-card" shadow="hover">
<div slot="header" class="default-list-header">
<span class="default-list-title">播放列表</span>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="showAddPlaylistDialog">
添加音频
</el-button>
</div>
<el-table :data="defaultList" style="width: 100%" :header-cell-style="{ background: '#f5f7fa' }"
border>
<el-table-column prop="id" label="序号" width="80" align="center">
</el-table-column>
<el-table-column prop="name" label="音频名称" min-width="150" align="center">
</el-table-column>
<el-table-column prop="playTime" label="播放时间" width="120" align="center">
</el-table-column>
<el-table-column prop="weekdays" label="重复" width="200" align="center">
</el-table-column>
<el-table-column label="雷达" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.radarEnabled ? 'success' : 'info'">
{{ scope.row.radarEnabled ? '开启' : '关闭' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" width="120" align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.status" :active-value="'启用'" :inactive-value="'禁用'"
@change="handleStatusChange(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-edit" @click="handleEditPlaylist(scope.row)">
编辑
</el-button>
<el-button type="text" icon="el-icon-delete" @click="handleDeletePlaylist(scope.row)">
删除
</el-button>
</template>
</el-table-column>
<template slot="empty">
<div style="padding: 20px 0;">
<el-empty description="暂无播放列表数据"></el-empty>
</div>
</template>
</el-table>
</el-card>
</el-col>
</el-row>
<!-- 固件版本查看对话框 -->
<el-dialog :title="$t('device.running-status.866086-10')" :visible.sync="openVersion" width="550px"
append-to-body>
@ -305,7 +313,8 @@
</el-dialog>
<!-- 添加播放列表对话框 -->
<el-dialog title="添加播放列表" :visible.sync="addPlaylistDialogVisible" width="600px" append-to-body>
<el-dialog :title="isEditPlaylist ? '编辑播放列表' : '添加播放列表'" :visible.sync="addPlaylistDialogVisible" width="600px"
append-to-body>
<el-form :model="newPlaylist" :rules="playlistRules" ref="playlistForm" label-width="120px">
<el-form-item label="音频选择" prop="audioId">
<el-select v-model="newPlaylist.audioId" placeholder="请选择音频" style="width: 100%">
@ -329,6 +338,14 @@
</div>
</div>
</el-form-item>
<el-form-item label="播放时长(秒)" prop="play_time">
<el-input-number v-model="newPlaylist.play_time" :min="1" :max="600" :step="1"
style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item label="停顿时长(秒)" prop="pause_time">
<el-input-number v-model="newPlaylist.pause_time" :min="0" :max="600" :step="1"
style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item label="星期重复" prop="weekdays">
<div class="weekday-select">
<el-checkbox v-model="newPlaylist.isAllWeek" @change="handleAllWeekChange">全选</el-checkbox>
@ -365,7 +382,7 @@
</el-collapse-transition>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addPlaylistDialogVisible = false"> </el-button>
<el-button @click="cancelPlaylistDialog"> </el-button>
<el-button type="primary" @click="submitPlaylistForm"> </el-button>
</div>
</el-dialog>
@ -530,7 +547,9 @@ export default {
radarSpeedMin: 0,
radarSpeedMax: 120,
isAllDay: false,
isAllWeek: false
isAllWeek: false,
play_time: 1,
pause_time: 0
},
playlistRules: {
audioId: [
@ -541,8 +560,6 @@ export default {
validator: (rule, value, callback) => {
if (!this.newPlaylist.playTimeStart || !this.newPlaylist.playTimeEnd) {
callback(new Error('请选择播放时间段'));
} else if (this.newPlaylist.playTimeStart >= this.newPlaylist.playTimeEnd) {
callback(new Error('开始时间必须小于结束时间'));
} else {
callback();
}
@ -570,8 +587,16 @@ export default {
},
trigger: 'change'
}
],
play_time: [
{ required: true, message: '请输入播放时长', trigger: 'blur' }
],
pause_time: [
{ required: true, message: '请输入停顿时长', trigger: 'blur' }
]
},
isEditPlaylist: false,
editingPlaylistIndex: null,
};
},
mounted() {
@ -610,6 +635,7 @@ export default {
};
//线
if (this.device.status !== 3 && this.device.isShadow !== 1) {
let title = '';
if (this.device.status === 1) {
title = this.$t('device.device-variable.930930-0');
} else if (this.device.status === 2) {
@ -678,36 +704,36 @@ export default {
if (!this.deviceInfo.thingsModels) return;
//
const playEnModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_en');
const playEnModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playEn');
if (playEnModel) {
this.basicSettings.audioEnabled = playEnModel.shadow === '1';
}
//
const volumeModel = this.deviceInfo.thingsModels.find(model => model.id === 'volume');
const volumeModel = this.deviceInfo.thingsModels.find(model => model.id === '103#volume');
if (volumeModel) {
this.basicSettings.volume = parseInt(volumeModel.shadow) || 50;
}
//
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === 'mp3_list');
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#mp3List');
if (mp3ListModel && mp3ListModel.shadow) {
try {
// JSON
const jsonStr = mp3ListModel.shadow.replace('JSON=', '');
const data = JSON.parse(jsonStr);
// mp3_list
if (data.sound_card && data.sound_card.mp3_list) {
//
this.audioList = data.sound_card.mp3_list.map((item, index) => {
// "1_def"
const name = item.split('_')[1] || item;
const mp3List = data.sound_card?.mp3_list || data.mp3_list;
if (mp3List) {
this.audioList = mp3List.map((item) => {
const [idStr, name] = item.split('_');
return {
id: index + 1,
name: name
id: parseInt(idStr, 10),
name: name || item,
raw: item
};
});
}).sort((a, b) => a.id - b.id); // id
}
} catch (error) {
console.error('解析音频列表失败:', error);
@ -715,14 +741,16 @@ export default {
}
//
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_list');
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList');
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) => {
// sound_card
const playList = data.sound_card?.play_list || data.play_list;
if (playList) {
this.defaultList = playList.map((item, index) => {
//
const beginTime = this.formatSecondsToTime(item.time.begin);
const endTime = this.formatSecondsToTime(item.time.end);
@ -733,11 +761,14 @@ export default {
return {
id: index + 1,
name: item.play.filename,
playTime: `${beginTime} - ${endTime}`,
playTime: (item.time.begin === 0 && item.time.end === 86400)
? '全天'
: `${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` : ''
radarSpeed: item.speed.en === 1 ? `${item.speed.min}-${item.speed.max}km/h` : '',
rawIndex: index //
};
});
}
@ -761,7 +792,7 @@ export default {
},
handleVolumeChange(val) {
const volumeModel = this.deviceInfo.thingsModels.find(model => model.id === 'volume');
const volumeModel = this.deviceInfo.thingsModels.find(model => model.id === '103#volume');
if (volumeModel) {
volumeModel.shadow = val.toString();
this.mqttPublish(this.deviceInfo, volumeModel);
@ -1229,7 +1260,7 @@ export default {
},
handleAudioSwitchChange(val) {
const playEnModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_en');
const playEnModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playEn');
if (playEnModel) {
playEnModel.shadow = val ? '1' : '0';
this.mqttPublish(this.deviceInfo, playEnModel);
@ -1249,39 +1280,37 @@ export default {
};
},
// 使ID
// 使ID0
getNextAvailableId() {
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === 'mp3_list');
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#mp3List');
if (mp3ListModel) {
try {
const jsonStr = mp3ListModel.shadow.replace('JSON=', '');
const data = JSON.parse(jsonStr);
if (data.sound_card && data.sound_card.mp3_list) {
const mp3List = data.sound_card?.mp3_list || data.mp3_list || [];
// 使ID
const usedIds = data.sound_card.mp3_list.map(item => {
const usedIds = mp3List.map(item => {
const id = parseInt(item.split('_')[0]);
return isNaN(id) ? 0 : id;
});
// 使ID
// 使ID0
let nextId = 1;
while (usedIds.includes(nextId)) {
nextId++;
}
return nextId;
}
} catch (error) {
console.error('解析mp3_list失败:', error);
}
}
return 1; // 1
return 0; // 0
},
submitAudioForm() {
this.$refs.audioForm.validate((valid) => {
if (valid) {
// mp3_list
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === 'mp3_list');
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#mp3List');
if (mp3ListModel) {
try {
// ID
@ -1293,16 +1322,16 @@ export default {
// TTS
const ttsData = {
JSON_id: 1,
sound_card: {
TTS: {
per: this.newAudio.per,
spd: this.newAudio.spd,
pit: this.newAudio.pit,
vol: this.newAudio.vol,
tex_utf8: this.newAudio.tex_utf8,
filename: filename
}
filename: filename,
}
};
// shadow
@ -1329,24 +1358,20 @@ export default {
type: 'warning'
}).then(() => {
// mp3_list
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === 'mp3_list');
const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#mp3List');
if (mp3ListModel) {
try {
// JSON
const jsonStr = mp3ListModel.shadow.replace('JSON=', '');
const data = JSON.parse(jsonStr);
// ID
const audioId = row.name;
// mp3_list
if (data.sound_card && data.sound_card.mp3_list) {
data.sound_card.mp3_list = data.sound_card.mp3_list.filter(item => !item.endsWith(audioId));
// raw
const audioRaw = row.raw;
if (data.mp3_list) {
data.mp3_list = data.mp3_list.filter(item => item !== audioRaw);
}
// shadow
const newShadow = 'JSON=' + JSON.stringify(data);
mp3ListModel.shadow = newShadow;
//
this.mqttPublish(this.deviceInfo, mp3ListModel).then(() => {
this.$message.success('删除成功');
@ -1354,7 +1379,6 @@ export default {
console.error('发送删除命令失败:', error);
this.$message.error('删除失败');
});
}
} catch (error) {
console.error('解析或更新mp3_list失败:', error);
this.$message.error('删除失败');
@ -1364,6 +1388,10 @@ export default {
},
showAddPlaylistDialog() {
//
this.isEditPlaylist = false;
this.editingPlaylistIndex = null;
this.addPlaylistDialogVisible = true;
this.newPlaylist = {
name: '',
@ -1377,7 +1405,9 @@ export default {
radarSpeedMin: 0,
radarSpeedMax: 120,
isAllDay: false,
isAllWeek: false
isAllWeek: false,
play_time: 1,
pause_time: 0
};
},
@ -1385,12 +1415,17 @@ export default {
this.$refs.playlistForm.validate((valid) => {
if (valid) {
// play_list
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_list');
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList');
if (playListModel) {
try {
// JSON
const jsonStr = playListModel.shadow.replace('JSON=', '');
const data = JSON.parse(jsonStr);
// JSON
let jsonStr = playListModel.shadow ? playListModel.shadow.replace('JSON=', '') : '';
let data = {};
if (jsonStr) {
data = JSON.parse(jsonStr);
} else {
data = { play_list: [] };
}
//
const selectedAudio = this.audioList.find(audio => audio.id === this.newPlaylist.audioId);
@ -1399,20 +1434,20 @@ export default {
return;
}
//
const newPlayItem = {
//
const playItem = {
play: {
en: 1,
num: this.defaultList.length + 1,
en: this.newPlaylist.status === '启用' ? 1 : 0,
num: this.isEditPlaylist ? (this.editingPlaylistIndex + 1) : (this.defaultList.length + 1),
sou: 0,
filename: `${selectedAudio.id}_${selectedAudio.name}`,
play_time: 1,
pause_time: 0
play_time: this.newPlaylist.play_time,
pause_time: this.newPlaylist.pause_time
},
time: {
en: 1,
begin: this.newPlaylist.isAllDay ? 0 : this.convertTimeToSeconds(this.newPlaylist.playTimeStart),
end: this.newPlaylist.isAllDay ? 86399 : this.convertTimeToSeconds(this.newPlaylist.playTimeEnd),
end: this.newPlaylist.isAllDay ? 86400 : this.convertTimeToSeconds(this.newPlaylist.playTimeEnd),
week: this.convertWeekArrayToValue(this.newPlaylist.weekdays)
},
speed: {
@ -1422,29 +1457,41 @@ export default {
}
};
//
if (!data.sound_card) {
data.sound_card = {};
// play_list
if (!data.play_list) {
data.play_list = [];
}
if (!data.sound_card.play_list) {
data.sound_card.play_list = [];
if (this.isEditPlaylist) {
//
if (data.play_list[this.editingPlaylistIndex]) {
data.play_list[this.editingPlaylistIndex] = playItem;
} else {
this.$message.error('未找到要编辑的播放项');
return;
}
} else {
//
data.play_list.push(playItem);
}
data.sound_card.play_list.push(newPlayItem);
// shadow
playListModel.shadow = 'JSON=' + JSON.stringify(data);
//
this.mqttPublish(this.deviceInfo, playListModel).then(() => {
const isEdit = this.isEditPlaylist;
this.addPlaylistDialogVisible = false;
this.$message.success('添加成功');
this.isEditPlaylist = false;
this.editingPlaylistIndex = null;
this.$message.success(isEdit ? '编辑成功' : '添加成功');
}).catch(error => {
console.error('发送播放列表更新失败:', error);
this.$message.error('添加失败');
this.$message.error(this.isEditPlaylist ? '编辑失败' : '添加失败');
});
} catch (error) {
console.error('解析或更新播放列表失败:', error);
this.$message.error('添加失败');
this.$message.error(this.isEditPlaylist ? '编辑失败' : '添加失败');
}
}
}
@ -1506,22 +1553,28 @@ export default {
},
handleStatusChange(row) {
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_list');
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList');
if (playListModel) {
try {
const jsonStr = playListModel.shadow.replace('JSON=', '');
const data = JSON.parse(jsonStr);
if (data.sound_card && data.sound_card.play_list) {
//
const playItem = data.sound_card.play_list[row.id - 1];
if (playItem) {
//
playItem.play.en = row.status === '启用' ? 1 : 0;
let jsonStr = playListModel.shadow ? playListModel.shadow.replace('JSON=', '') : '';
let data = {};
if (jsonStr) {
data = JSON.parse(jsonStr);
} else {
data = { play_list: [] };
}
// sound_card
const playListArr = data.sound_card?.play_list || data.play_list;
if (playListArr && playListArr[row.rawIndex]) {
playListArr[row.rawIndex].play.en = row.status === '启用' ? 1 : 0;
// shadow
if (data.sound_card) {
data.sound_card.play_list = playListArr;
} else {
data.play_list = playListArr;
}
playListModel.shadow = 'JSON=' + JSON.stringify(data);
//
this.mqttPublish(this.deviceInfo, playListModel).then(() => {
this.$message.success('状态更新成功');
@ -1530,7 +1583,6 @@ export default {
this.$message.error('状态更新失败');
});
}
}
} catch (error) {
console.error('解析或更新播放列表状态失败:', error);
this.$message.error('状态更新失败');
@ -1538,28 +1590,119 @@ export default {
}
},
handleEditPlaylist(row) {
//
this.isEditPlaylist = true;
this.editingPlaylistIndex = row.rawIndex;
//
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList');
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 && data.sound_card.play_list[row.rawIndex]) ||
(data.play_list && data.play_list[row.rawIndex])) {
const playItem = (data.sound_card?.play_list || data.play_list)[row.rawIndex];
//
this.newPlaylist = {
name: playItem.play.filename,
type: '用户',
status: playItem.play.en === 1 ? '启用' : '禁用',
audioId: this.getAudioIdFromFilename(playItem.play.filename),
playTimeStart: this.convertSecondsToTime(playItem.time.begin),
playTimeEnd: this.convertSecondsToTime(playItem.time.end),
weekdays: this.convertWeekValueToArray(playItem.time.week),
radarEnabled: playItem.speed.en === 1,
radarSpeedMin: playItem.speed.min || 0,
radarSpeedMax: playItem.speed.max || 120,
isAllDay: playItem.time.begin === 0 && playItem.time.end === 86400,
isAllWeek: this.isAllWeekSelected(playItem.time.week),
play_time: playItem.play.play_time || 1,
pause_time: playItem.play.pause_time || 0
};
this.addPlaylistDialogVisible = true;
}
} catch (error) {
console.error('解析播放列表数据失败:', error);
this.$message.error('获取播放列表数据失败');
}
}
},
// ID
getAudioIdFromFilename(filename) {
if (!filename) return '';
const parts = filename.split('_');
if (parts.length >= 2) {
const audioId = parseInt(parts[0]);
return isNaN(audioId) ? '' : audioId;
}
return '';
},
//
convertSecondsToTime(seconds) {
if (seconds === 0) return new Date(2000, 0, 1, 0, 0);
if (seconds === 86400) return new Date(2000, 0, 1, 0, 0);
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
return new Date(2000, 0, 1, hours, minutes);
},
//
convertWeekValueToArray(week) {
const result = [];
for (let i = 0; i < 7; i++) {
if (week & (1 << i)) {
result.push(i.toString());
}
}
return result;
},
//
isAllWeekSelected(week) {
return week === 127; // 127 = 1111111 ()
},
handleDeletePlaylist(row) {
this.$confirm('确认删除该播放项吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === 'play_list');
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList');
if (playListModel) {
try {
const jsonStr = playListModel.shadow.replace('JSON=', '');
const data = JSON.parse(jsonStr);
let jsonStr = playListModel.shadow ? playListModel.shadow.replace('JSON=', '') : '';
let data = {};
if (jsonStr) {
data = JSON.parse(jsonStr);
} else {
data = { play_list: [] };
}
if (data.sound_card && data.sound_card.play_list) {
if ((data.sound_card && data.sound_card.play_list) || data.play_list) {
//
data.sound_card.play_list.splice(row.id - 1, 1);
const playListArr = data.sound_card?.play_list || data.play_list;
playListArr.splice(row.rawIndex, 1);
//
data.sound_card.play_list.forEach((item, index) => {
playListArr.forEach((item, index) => {
item.play.num = index + 1;
});
// shadow
if (data.sound_card) {
data.sound_card.play_list = playListArr;
} else {
data.play_list = playListArr;
}
playListModel.shadow = 'JSON=' + JSON.stringify(data);
//
@ -1583,7 +1726,7 @@ export default {
if (val) {
// 00:00 23:59
this.newPlaylist.playTimeStart = new Date(2000, 0, 1, 0, 0);
this.newPlaylist.playTimeEnd = new Date(2000, 0, 1, 23, 59);
this.newPlaylist.playTimeEnd = new Date(2000, 0, 1, 0, 0);
}
},
@ -1597,6 +1740,12 @@ export default {
this.newPlaylist.weekdays = [];
}
},
cancelPlaylistDialog() {
this.addPlaylistDialogVisible = false;
this.isEditPlaylist = false;
this.editingPlaylistIndex = null;
},
},
};
</script>
@ -1915,4 +2064,70 @@ export default {
flex-direction: column;
gap: 10px;
}
//
.el-table {
//
&::-webkit-scrollbar {
width: 12px;
height: 12px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 6px;
&:hover {
background: #a8a8a8;
}
}
//
.el-table__body-wrapper {
&::-webkit-scrollbar {
width: 12px;
height: 12px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 6px;
&:hover {
background: #a8a8a8;
}
}
}
}
//
::-webkit-scrollbar {
width: 12px;
height: 12px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 6px;
&:hover {
background: #a8a8a8;
}
}
</style>

View File

@ -57,7 +57,7 @@
</el-button>
<el-button size="small" type="text" icon="el-icon-setting" @click="handleAreaControl(scope.row)"
v-hasPermi="['iot:group:query']">
区域控制
批量控制
</el-button>
</template>
</el-table-column>
@ -97,7 +97,7 @@
</el-dialog>
<!-- 添加区域控制对话框 -->
<el-dialog title="区域控制" :visible.sync="areaControlDialogVisible" width="1200px" append-to-body>
<el-dialog title="批量控制" :visible.sync="areaControlDialogVisible" width="1200px" append-to-body>
<el-form :model="areaControlForm" ref="areaControlForm" label-width="120px">
<!-- 基础设置 -->
<el-card class="settings-card" shadow="hover">
@ -111,9 +111,13 @@
</el-switch>
</el-form-item>
<el-form-item label="音量设置">
<el-slider v-model="basicSettings.volume" :min="0" :max="100" :format-tooltip="formatVolume"
@change="handleVolumeChange" style="width: 80%" :disabled="!basicSettings.audioEnabled">
<div class="volume-control">
<el-slider v-model="basicSettings.volume" :min="0" :max="100"
:format-tooltip="formatVolume" @change="handleVolumeChange" style="width: 70%"
:disabled="!basicSettings.audioEnabled">
</el-slider>
<span class="volume-value">{{ basicSettings.volume }}%</span>
</div>
</el-form-item>
</el-form>
</el-card>
@ -169,8 +173,9 @@
</el-card>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="areaControlDialogVisible = false"> </el-button>
<el-button type="primary" @click="submitAreaControlForm"> </el-button>
<el-button type="primary" @click="confirmSubmitAreaControl" style="margin: 0 auto; display: block;">
下发播放列表
</el-button>
</div>
</el-dialog>
@ -515,7 +520,7 @@ export default {
if (runningStatusResponse.code === 200 && runningStatusResponse.data) {
const thingsModels = runningStatusResponse.data.thingsModels;
if (thingsModels) {
const playListModel = thingsModels.find(model => model.id === 'play_list');
const playListModel = thingsModels.find(model => model.id === '103#playList');
console.log("data", JSON.stringify(playListModel));
if (playListModel && playListModel.value) {
@ -583,9 +588,9 @@ export default {
serialNumber: device.serialNumber,
productId: device.productId,
remoteCommand: {
'play_en': val ? 1 : 0
'103#playEn': val ? 1 : 0
},
identifier: 'play_en',
identifier: '103#playEn',
modelName: '音频开关',
isShadow: device.status != 3,
type: 1
@ -616,9 +621,9 @@ export default {
serialNumber: device.serialNumber,
productId: device.productId,
remoteCommand: {
'volume': val
'103#volume': val
},
identifier: 'volume',
identifier: '103#volume',
modelName: '音量设置',
isShadow: device.status != 3,
type: 1
@ -757,9 +762,9 @@ export default {
serialNumber: device.serialNumber,
productId: device.productId,
remoteCommand: {
'play_list': 'JSON=' + JSON.stringify(playListData)
'103#playList': 'JSON=' + JSON.stringify(playListData)
},
identifier: 'play_list',
identifier: '103#playList',
modelName: '播放列表',
isShadow: device.status != 3,
type: 1
@ -768,7 +773,7 @@ export default {
await serviceInvoke(data);
}
this.$message.success('区域控制设置成功');
this.$message.success('批量控制设置成功');
this.areaControlDialogVisible = false;
}
} catch (error) {
@ -810,6 +815,25 @@ export default {
//
this.playlistForm.weekdays = [];
}
},
/** 确认提交区域控制 */
async confirmSubmitAreaControl() {
try {
await this.$confirm(
this.$t('iot.group.index.637432-28'),
this.$t('iot.group.index.637432-29'),
{
confirmButtonText: this.$t('iot.group.index.637432-30'),
cancelButtonText: this.$t('iot.group.index.637432-31'),
type: 'warning'
}
);
await this.submitAreaControlForm();
} catch (error) {
//
}
}
},
};
@ -918,4 +942,26 @@ export default {
::v-deep .el-form-item__label {
font-weight: normal;
}
::v-deep .el-dialog__footer {
text-align: center;
}
::v-deep .el-dialog__footer .el-button {
margin: 0 10px;
}
.volume-control {
display: flex;
align-items: center;
gap: 15px;
}
.volume-value {
font-size: 14px;
color: #606266;
font-weight: 500;
min-width: 40px;
text-align: center;
}
</style>