声卡部分功能完善
This commit is contained in:
parent
8c7b69b208
commit
70b0895bf6
@ -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",
|
||||
|
@ -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": "请输入设备名称",
|
||||
|
@ -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>
|
||||
@ -246,17 +254,17 @@
|
||||
$t('device.running-status.866086-12') }}</el-link>
|
||||
</template>
|
||||
<el-descriptions-item :label="$t('device.running-status.866086-13')">{{ firmware.firmwareName
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.device-edit.148398-4')">{{ firmware.productName
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.device-edit.148398-12')">Version {{ firmware.version
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.running-status.866086-16')">
|
||||
<el-link :href="getDownloadUrl(firmware.filePath)" :underline="false" type="primary">{{
|
||||
getDownloadUrl(firmware.filePath) }}</el-link>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.running-status.866086-17')">{{ firmware.remark
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="success" @click="otaUpgrade"
|
||||
@ -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
|
||||
// 获取未使用的最小ID(从0开始)
|
||||
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) {
|
||||
// 获取所有已使用的ID
|
||||
const usedIds = data.sound_card.mp3_list.map(item => {
|
||||
const id = parseInt(item.split('_')[0]);
|
||||
return isNaN(id) ? 0 : id;
|
||||
});
|
||||
|
||||
// 找到最小的未使用ID
|
||||
let nextId = 1;
|
||||
while (usedIds.includes(nextId)) {
|
||||
nextId++;
|
||||
}
|
||||
return nextId;
|
||||
const mp3List = data.sound_card?.mp3_list || data.mp3_list || [];
|
||||
// 获取所有已使用的ID
|
||||
const usedIds = mp3List.map(item => {
|
||||
const id = parseInt(item.split('_')[0]);
|
||||
return isNaN(id) ? 0 : id;
|
||||
});
|
||||
// 找到最小的未使用ID(从0开始)
|
||||
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
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 更新物模型shadow值
|
||||
@ -1329,32 +1358,27 @@ 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));
|
||||
|
||||
// 更新物模型shadow值
|
||||
const newShadow = 'JSON=' + JSON.stringify(data);
|
||||
mp3ListModel.shadow = newShadow;
|
||||
|
||||
// 发送更新
|
||||
this.mqttPublish(this.deviceInfo, mp3ListModel).then(() => {
|
||||
this.$message.success('删除成功');
|
||||
}).catch(error => {
|
||||
console.error('发送删除命令失败:', error);
|
||||
this.$message.error('删除失败');
|
||||
});
|
||||
// 用 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('删除成功');
|
||||
}).catch(error => {
|
||||
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,30 +1553,35 @@ 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);
|
||||
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) {
|
||||
// 找到对应的播放项
|
||||
const playItem = data.sound_card.play_list[row.id - 1];
|
||||
if (playItem) {
|
||||
// 更新状态
|
||||
playItem.play.en = row.status === '启用' ? 1 : 0;
|
||||
|
||||
// 更新物模型shadow值
|
||||
playListModel.shadow = 'JSON=' + JSON.stringify(data);
|
||||
|
||||
// 发送更新
|
||||
this.mqttPublish(this.deviceInfo, playListModel).then(() => {
|
||||
this.$message.success('状态更新成功');
|
||||
}).catch(error => {
|
||||
console.error('发送状态更新失败:', error);
|
||||
this.$message.error('状态更新失败');
|
||||
});
|
||||
// 兼容 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('状态更新成功');
|
||||
}).catch(error => {
|
||||
console.error('发送状态更新失败:', error);
|
||||
this.$message.error('状态更新失败');
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('解析或更新播放列表状态失败:', 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>
|
@ -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>
|
||||
@ -91,13 +91,13 @@
|
||||
$t('update') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" v-hasPermi="['iot:group:add']" v-show="!form.groupId">{{
|
||||
$t('add')
|
||||
}}</el-button>
|
||||
}}</el-button>
|
||||
<el-button @click="cancel">{{ $t('iot.group.index.637432-19') }}</el-button>
|
||||
</div>
|
||||
</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">
|
||||
</el-slider>
|
||||
<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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user