You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
956 lines
25 KiB
956 lines
25 KiB
<template>
|
|
<view class="switch-manage">
|
|
<store-name></store-name>
|
|
<view class="sm-tit">
|
|
<text>{{pageInfo.name || '-'}}</text>
|
|
<text>{{pageInfo.tips || ''}}</text>
|
|
</view>
|
|
|
|
<view class="slider-box">
|
|
<text>音量</text>
|
|
<slider :value="voiceLevel" activeColor="#009874" block-color="#009874" block-size="22" @change="sliderChange" min="0" max="100" />
|
|
<view class="">
|
|
<text>0%</text>
|
|
<text>100%</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="sm-list">
|
|
<view class="sl-item" v-for="(e, i) in deviceList" :key="i">
|
|
<view class="si-top">
|
|
<image mode="aspectFit" :src="getIcon()"></image>
|
|
<view class="st-right">
|
|
<view class="sr-name">{{e.hardware_name || '-'}}</view>
|
|
<!-- 门闸没有状态查询 -->
|
|
<!-- 请求接口自定义字段设备状态 1->在线,0->离线 -->
|
|
<view class="sr-bot" v-if="pageInfo.id !=5">
|
|
<view :class="[e.defineStatusCode == 1?'active':'']">
|
|
<text>{{ e.defineStatusCode == 1 ? '设备在线' : e.defineStatusCode == 0?'设备离线' : '-' }}</text>
|
|
</view>
|
|
<image mode="aspectFit" src="/subpackage/device/static/images/refresh.png"
|
|
@click="refreshStatusBtn({switchInfo:e, index:i})"></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<block v-if="pageInfo.name=='音响管理'">
|
|
<view class="si-bottom">
|
|
<view v-if="pageInfo.isOpen" @click="operateBtn({ switchInfo: e, status: 1 })">
|
|
<image mode="aspectFit" :src="pageInfo.openIcon || ''"></image>
|
|
<view>{{pageInfo.openName || '-'}}</view>
|
|
</view>
|
|
<view v-if="pageInfo.isClose" @click="operateBtn({ switchInfo: e, status: 0 })">
|
|
<image mode="aspectFit" :src="pageInfo.closeIcon || ''"></image>
|
|
<view>{{pageInfo.closeName || '-'}}</view>
|
|
</view>
|
|
</view>
|
|
</block>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 音频控制 -->
|
|
<view class="voice_control_pad" v-if="voicePadConfig.showVoicePad">
|
|
<!-- 文字转语音 -->
|
|
<view class="cover_bg" @click.stop="voicePadConfig.showVoicePad=false">
|
|
</view>
|
|
<view class="v_box" v-if="voicePadConfig.step==0">
|
|
<textarea value="" v-model="voicePadConfig.txt" placeholder="请输您要说的话,输入标点符号,智能语音效果更好哦!" />
|
|
<view class="v_btns">
|
|
<view class="voice_btn btn_white" @click="sendVoice()">发送</view>
|
|
<view class="voice_btn btn_green" @click="listenVoice()">试听</view>
|
|
</view>
|
|
</view>
|
|
<!-- 录音 -->
|
|
<view class="v_box" v-else>
|
|
<view class="voice_title">{{getVoiceTxt(voicePadConfig.step)}}</view>
|
|
<image class="voice_img" src="../../static/images/i_voice.png" :src="getVoiceIcon(voicePadConfig.step)"
|
|
:class="voicePadConfig.step==2||voicePadConfig.step==4?'voice_img_playing':''"></image>
|
|
<view class="voice_btn " @longpress="longPressHandle" @touchend="touchEndHandle"
|
|
hover-class="btn_active" v-if="voicePadConfig.step<3">按住说话</view>
|
|
<view class="v_btns" v-else-if="voicePadConfig.step==3">
|
|
<view class="voice_btn btn_white" @click="sendVoice()">发送</view>
|
|
<view class="voice_btn btn_green" @click="listenVoice()">听取录音</view>
|
|
</view>
|
|
</view>
|
|
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
/**
|
|
* 20231129
|
|
* fix 语音发送云中控参数 AC_filterCloudACData
|
|
* 新增 value.text
|
|
*
|
|
*
|
|
* */
|
|
const recorderManager = uni.getRecorderManager();
|
|
const innerAudioContext = uni.createInnerAudioContext();
|
|
innerAudioContext.autoplay = true;
|
|
|
|
import store_name from '../../components/store_name/store_name';
|
|
import deviceServer from '../../js/device_server';
|
|
import deviceApi from '../../js/device_api';
|
|
import { mapState } from 'vuex';
|
|
import util from '../../../../utils/util';
|
|
import DEVICE_FUN from '../../js/device_fun.js';
|
|
|
|
const showArr = {
|
|
's14': {
|
|
id: 14,
|
|
name: '音响管理',
|
|
isOpen: true,
|
|
isClose: true,
|
|
openIcon: '/subpackage/device/static/images/i_txt.png',
|
|
closeIcon: '/subpackage/device/static/images/i_voice_1.png',
|
|
openName: '文转音',
|
|
closeName: '语音',
|
|
hardware_type: 'AudioPlayer',
|
|
tips: "点击对应音响的麦克风可以进行说话,说话内容将通过音响播放。",
|
|
},
|
|
}
|
|
|
|
export default {
|
|
components: {
|
|
'store-name': store_name
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
curStoreInfo: state => state.device.curStoreInfo,
|
|
}),
|
|
getVoiceIcon() {
|
|
return i => {
|
|
return `../../static/images/i_voice_${i}.png`
|
|
}
|
|
},
|
|
getVoiceTxt() {
|
|
return i => {
|
|
return [,'请按住说话','录音中...','录音已完成','播放中...'][i]
|
|
}
|
|
},
|
|
|
|
},
|
|
watch: {
|
|
curStoreInfo(newVal, oldVal) {
|
|
this.deviceList = [];
|
|
this.getDeviceList({
|
|
stadium_id: newVal.id,
|
|
hardware_type: this.pageInfo.hardware_type
|
|
})
|
|
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
pageInfo: {},
|
|
deviceList: [],
|
|
voicePadConfig: {
|
|
showVoicePad: false,
|
|
step: 1, // 0 文字转语音, 1 未录音, 2 录音中, 3 录音结束, 4 播放录音中,
|
|
txt: "",
|
|
voicePath: "",
|
|
voiceUrl: "",
|
|
},
|
|
voiceLevel:0,
|
|
|
|
// 20231129 fix 云中控判断
|
|
curSwitch: null,
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
this.initAudio();
|
|
this.initPage(options);
|
|
|
|
},
|
|
methods: {
|
|
//初始化音频
|
|
initAudio(){
|
|
let self = this;
|
|
recorderManager.onStop(function(res) {
|
|
console.log('recorder stop' + JSON.stringify(res));
|
|
self.voicePadConfig.voicePath = res.tempFilePath;
|
|
});
|
|
innerAudioContext.onPlay(function(res) {
|
|
console.log('play voice onPlay' + JSON.stringify(res));
|
|
if(self.voicePadConfig.step==3)self.voicePadConfig.step = 4
|
|
});
|
|
innerAudioContext.onEnded(function(res) {
|
|
console.log('play voice onEnded' + JSON.stringify(res));
|
|
if(self.voicePadConfig.step == 4)self.voicePadConfig.step = 3
|
|
});
|
|
},
|
|
initPage(options){
|
|
let _pageInfo = showArr[`s${options.sid}`] || {};
|
|
this.pageInfo = _pageInfo;
|
|
uni.setNavigationBarTitle({
|
|
title: _pageInfo.name
|
|
});
|
|
|
|
this.getDeviceList({
|
|
stadium_id: this.curStoreInfo.id,
|
|
hardware_type: _pageInfo.hardware_type
|
|
})
|
|
this.updateVoiceSlider();
|
|
|
|
},
|
|
//滑动更改音响音量
|
|
sliderChange(e) {
|
|
console.log('value 发生变化:' + e.detail.value)
|
|
let _data = {
|
|
"device": this.curStoreInfo.device_name,
|
|
"data": {
|
|
"name": "audio-player-volume",
|
|
"value": {
|
|
"volume": e.detail.value.toString()
|
|
}
|
|
},
|
|
}
|
|
//发送命令到中控
|
|
this.operateReq({
|
|
data: _data,
|
|
isTip:true
|
|
})
|
|
},
|
|
//更新音响音量
|
|
updateVoiceSlider(){
|
|
let that = this
|
|
let _data = {
|
|
"device": this.curStoreInfo.device_name,
|
|
"data": {
|
|
"name": "audio-player-volume",
|
|
"value": {
|
|
"volume": "-1"
|
|
}
|
|
},
|
|
}
|
|
//发送命令到中控
|
|
this.operateReq({
|
|
data: _data,
|
|
succFun: (res) => {
|
|
console.log("操作结果:",res);
|
|
that.voiceLevel = res.data
|
|
},
|
|
isTip:false
|
|
})
|
|
},
|
|
longPressHandle(e) {
|
|
console.log("长按开始...");
|
|
this.voicePadConfig.step = 2
|
|
console.log('开始录音');
|
|
recorderManager.start({
|
|
format: "wav"
|
|
});
|
|
},
|
|
touchEndHandle(e) {
|
|
console.log("触摸结束...");
|
|
this.voicePadConfig.step = 3
|
|
console.log('录音结束');
|
|
recorderManager.stop();
|
|
},
|
|
//处理音响数据
|
|
HandleVoiceOperate({
|
|
switchInfo,
|
|
status
|
|
}) {
|
|
console.log(switchInfo, status);
|
|
if (status === 1) { //文字转语音
|
|
console.log("文字转语音");
|
|
this.voicePadConfig.showVoicePad = true
|
|
this.voicePadConfig.step = 0
|
|
} else { //语音发送
|
|
console.log("语音发送");
|
|
this.voicePadConfig.showVoicePad = true
|
|
this.voicePadConfig.step = 1
|
|
}
|
|
},
|
|
//发送语音到中控
|
|
async sendVoice() {
|
|
let that = this
|
|
console.log(deviceApi.ORIGIN)
|
|
//文字转语音
|
|
let _url = ""; //需上传给后台的语音地址
|
|
if(this.voicePadConfig.step==0){
|
|
let txt = this.voicePadConfig.txt
|
|
if(!txt)return util.showNone("请先输入您要说的话后重试")
|
|
_url = `${deviceApi.ORIGIN}/ouxuanac/tts/textToVoice.wav?text=${txt}&voice_type=4&speed=-1&volume=10`;
|
|
}
|
|
//已录音
|
|
if(this.voicePadConfig.step==3){
|
|
console.log("本地录音path:",that.voicePadConfig.voicePath);
|
|
let e = await deviceServer.uploadFile({
|
|
url: deviceApi.uploadAudio,
|
|
filePath: that.voicePadConfig.voicePath
|
|
});
|
|
let _res = util.jsonPar(e.data);
|
|
if (_res.code == 0) {
|
|
that.voicePadConfig.voiceUrl = _res.data.url
|
|
console.log("上传成功后path:", that.voicePadConfig.voiceUrl);
|
|
_url = _res.data.url // 上传后地址
|
|
} else {
|
|
console.error('上传录音失败--->', _res);
|
|
util.showNone(_res.message || '上传录音失败,请重试!')
|
|
return
|
|
}
|
|
}
|
|
//组装中控所需data
|
|
let _data = {
|
|
"device": this.curStoreInfo.device_name,
|
|
"data": {
|
|
"name": "audio-player",
|
|
"value": {
|
|
"url": _url,
|
|
"text": this.voicePadConfig?.txt || ''
|
|
}
|
|
},
|
|
// "token": "f0d5c19b-b87e-11eb-bc7d-5254005df464"
|
|
}
|
|
//发送命令到中控
|
|
if(_url)this.operateReq({
|
|
data: DEVICE_FUN.AC_filterCloudACData(_data, that.curSwitch),
|
|
})
|
|
|
|
},
|
|
//试听/播放 语音/录音
|
|
async listenVoice() {
|
|
let self = this
|
|
if(this.voicePadConfig.step==0){
|
|
//需要将语音下载到本地,然后播放
|
|
let txt = this.voicePadConfig.txt;
|
|
if(!txt)return util.showNone("请先输入您要说的话后重试")
|
|
let url =`${deviceApi.ORIGIN}/ouxuanac/tts/textToVoice.wav?text=${txt}&voice_type=4&speed=-1&volume=10`;
|
|
let updated_url = await this.getDownloadUrl(url)
|
|
innerAudioContext.src = updated_url
|
|
}
|
|
if(this.voicePadConfig.step==3){
|
|
innerAudioContext.src = this.voicePadConfig.voicePath;
|
|
}
|
|
console.log('播放录音文件:', innerAudioContext.src);
|
|
if(innerAudioContext.src)innerAudioContext.play();
|
|
},
|
|
getDownloadUrl(url) {
|
|
console.log('下载录音');
|
|
util.showLoad()
|
|
return new Promise((rs,rj)=>{
|
|
uni.downloadFile({
|
|
url: url, //资源路径e
|
|
success: (res) => {
|
|
if (res.statusCode === 200) {
|
|
console.log('下载成功',res);
|
|
util.hideLoad()
|
|
rs(res.tempFilePath)
|
|
}
|
|
},
|
|
fail: (e) => {
|
|
console.log('文字转录音文件下载失败',e);
|
|
util.hideLoad()
|
|
rj(e)
|
|
},
|
|
complete: (e) => {
|
|
util.hideLoad()
|
|
},
|
|
});
|
|
})
|
|
},
|
|
|
|
getDeviceList({
|
|
stadium_id,
|
|
hardware_type,
|
|
limit = 100,
|
|
page = 1
|
|
}) {
|
|
util.showLoad();
|
|
deviceServer.get({
|
|
url: deviceApi.hardwareList,
|
|
data: {
|
|
'filter[hardware_type]': hardware_type,
|
|
'filter[stadium_id]': stadium_id,
|
|
'limit': limit,
|
|
'page': page,
|
|
},
|
|
failMsg: '加载失败!'
|
|
})
|
|
.then(res => {
|
|
util.hideLoad();
|
|
let _list = res.list || [];
|
|
|
|
//直接拿中控在线状态 做下临时处理先用中控状态的数据填一下
|
|
let deviceInfo = uni.getStorageSync("deviceInfo");
|
|
_list = _list.map((e,i)=>{
|
|
e['defineStatusCode'] = deviceInfo.Online==1? 1 : 0;
|
|
return e
|
|
})
|
|
this.deviceList = _list;
|
|
console.log(res)
|
|
|
|
this.updateVoiceSlider();
|
|
})
|
|
.catch(util.hideLoad)
|
|
},
|
|
// 按钮操作, status 0 -> 关(左), 1 -> 开(右)
|
|
operateBtn: util.debounce(function({
|
|
switchInfo,
|
|
status
|
|
}) {
|
|
this.curSwitch = switchInfo || {};
|
|
if (switchInfo.hardware_type === "AudioPlayer") return this.HandleVoiceOperate({
|
|
switchInfo,
|
|
status
|
|
}); //单独处理音响操作0704
|
|
|
|
|
|
}, 300, 300),
|
|
|
|
// 获取接口参数结构
|
|
getOperateReqData({
|
|
switchInfo,
|
|
status
|
|
}) {
|
|
let {
|
|
curStoreInfo
|
|
} = this;
|
|
|
|
let _query = switchInfo.hardware_type === 'GateControl' ?
|
|
this.getGateQuery({
|
|
switchInfo,
|
|
status
|
|
}) :
|
|
this.getSwitchQuery({
|
|
switchInfo,
|
|
status
|
|
});
|
|
let _data = {
|
|
device: curStoreInfo.device_name, // 中控名,
|
|
data: _query, // 后端数据结构, 参考src\subpackage\device\js\ouxuanac.md
|
|
};
|
|
|
|
//针对门禁没有关按钮发两条命令->开&关 20201224 后端: 直接发两条 关的那条这里填5 然后你那边不用管返回
|
|
if (switchInfo.hardware_type === 'AccessControl' && status == 0) _data['delay'] = '5';
|
|
|
|
return _data;
|
|
},
|
|
// 操作接口请求
|
|
operateReq({
|
|
data,
|
|
succFun,
|
|
isTip = true,
|
|
isLoad = true
|
|
}) {
|
|
let that = this
|
|
if (isLoad) util.showLoad();
|
|
|
|
deviceServer.post({
|
|
url: deviceApi.ouxuanac,
|
|
data: data,
|
|
isDefaultGet: false,
|
|
})
|
|
.then(res => {
|
|
if (isLoad) util.hideLoad();
|
|
if (res.data.code == 0) {
|
|
succFun(res.data);
|
|
if (isTip) util.showNone(res.data.message || '操作成功!');
|
|
that.voicePadConfig.showVoicePad = false; //操作成功后关闭voicePad
|
|
} else {
|
|
if (isTip) util.showNone(res.data.message || '操作失败!');
|
|
}
|
|
})
|
|
.catch(err => {
|
|
if (isLoad) util.hideLoad()
|
|
})
|
|
},
|
|
|
|
// 门闸数据结构 // 门闸数据结构不统一
|
|
getGateQuery({
|
|
switchInfo,
|
|
status
|
|
}) {
|
|
let {
|
|
enter_id,
|
|
leave_id,
|
|
hardware_net_addr
|
|
} = switchInfo;
|
|
// 进出控制ID |进入-> enter_id 离开-> leave_id|
|
|
let _cid = status === 1 ? enter_id :
|
|
status === 0 ? leave_id : '';
|
|
return {
|
|
name: 'gate',
|
|
value: {
|
|
tcp: hardware_net_addr + '',
|
|
cid: _cid + ''
|
|
},
|
|
is_delay: true,
|
|
queue_group: 'gate'
|
|
}
|
|
},
|
|
//
|
|
refreshStatusBtn: util.debounce(function({
|
|
switchInfo,
|
|
index
|
|
}) {
|
|
// this.getStatusReq({
|
|
// data: this.getSwitchStatusQuery(switchInfo),
|
|
// index,
|
|
// })
|
|
//TODO 等待后续音响设备调试后,再开放更新设备状态功能
|
|
// _data = DEVICE_FUN.AC_filterCloudACData(data,switchInfo);
|
|
// 后台:就没这个功能...
|
|
util.showLoad();
|
|
setTimeout(()=>util.hideLoad(),1000)
|
|
}, 300, 300),
|
|
// 获取设备状态
|
|
getStatusReq({
|
|
data,
|
|
index
|
|
}) {
|
|
let _deviceList = this.deviceList.slice();
|
|
util.showLoad();
|
|
deviceServer.post({
|
|
url: deviceApi.ouxuanac,
|
|
data: data,
|
|
isDefaultGet: false,
|
|
})
|
|
.then(res => {
|
|
util.hideLoad();
|
|
let _data = res.data || {};
|
|
console.log(this.changeLowerCase(_data.data))
|
|
if (_data.code == 504 || this.changeLowerCase(_data.data).indexOf('timeout') != -1) {
|
|
_deviceList[index]['defineStatusCode'] = 0;
|
|
|
|
} else if (_data.code == 0 && this.changeLowerCase(_data.data).indexOf('timeout') == -1) {
|
|
_deviceList[index]['defineStatusCode'] = 1;
|
|
} else {
|
|
util.showNone(_data.message || '操作失败!');
|
|
}
|
|
this.deviceList = _deviceList;
|
|
// if(res.data.code == 0){
|
|
// if(isTip)util.showNone(res.data.message || '操作成功!');
|
|
// }else{
|
|
// if(isTip)util.showNone(res.data.message || '操作失败!');
|
|
// }
|
|
})
|
|
.catch(util.hideLoad)
|
|
},
|
|
|
|
// 咖啡机和门闸暂时没有状态
|
|
// 设备状态请求参数数据结构
|
|
getSwitchStatusQuery(switchInfo) {
|
|
let {
|
|
curStoreInfo
|
|
} = this;
|
|
let {
|
|
hardware_connect_method,
|
|
hardware_type,
|
|
hardware_id,
|
|
node_id,
|
|
hardware_net_addr
|
|
} = switchInfo;
|
|
|
|
|
|
const _query = {
|
|
name: this.getStatusQueryName(switchInfo),
|
|
value: {
|
|
id: hardware_id + '',
|
|
} // value 内值全为String
|
|
};
|
|
|
|
if (this.changeLowerCase(hardware_connect_method) === 'tcp') _query.value['tcp'] = hardware_net_addr + '';
|
|
let _flag = this.changeLowerCase(hardware_connect_method) === 'serialport485' || this.changeLowerCase(
|
|
hardware_connect_method) === 'tcp';
|
|
if (_flag) {
|
|
if (hardware_type === 'Air') { // 空调开关状态 key为 op
|
|
_query.value['op'] = 'status'
|
|
_query['name'] = this.getAirQueryName(switchInfo)
|
|
} else {
|
|
_query.value['p'] = node_id + ''; // 硬件子id
|
|
// postData.value['o'] = this.getRelayStatus(status); // 开关状态
|
|
}
|
|
}
|
|
|
|
return {
|
|
device: curStoreInfo.device_name, // 中控名,
|
|
data: _query, // 后端数据结构, 参考src\subpackage\device\js\ouxuanac.md
|
|
}
|
|
|
|
// this.getStatusReq({
|
|
// index,
|
|
// data: {
|
|
// device: curStoreInfo.device_name, // 中控名,
|
|
// data: _query, // 后端数据结构, 参考src\subpackage\device\js\ouxuanac.md
|
|
// }
|
|
// })
|
|
},
|
|
// switchInfo -> 当前开关信息
|
|
// status -> 开关状态 0 -> 关(右), 1 -> 开(左)
|
|
// 数据结构参考 src\subpackage\device\js\ouxuanac.md
|
|
// 空调开关数据结构独立判断处理 hardware_type === 'Air'
|
|
getSwitchQuery({
|
|
switchInfo,
|
|
status
|
|
}) {
|
|
let {
|
|
hardware_connect_method,
|
|
hardware_type,
|
|
hardware_id,
|
|
node_id,
|
|
hardware_net_addr
|
|
} = switchInfo;
|
|
|
|
const postData = {
|
|
name: this.getQueryName(switchInfo),
|
|
value: {
|
|
id: hardware_id + '',
|
|
} // value 内值全为String
|
|
};
|
|
|
|
if (this.changeLowerCase(hardware_connect_method) === 'gpio') postData.value['status'] = this
|
|
.getRelayStatus(status);
|
|
|
|
// tcp 连接需要 hardware_net_addr
|
|
if (this.changeLowerCase(hardware_connect_method) === 'tcp') postData.value['tcp'] = hardware_net_addr +
|
|
'';
|
|
let _flag = this.changeLowerCase(hardware_connect_method) === 'serialport485' || this.changeLowerCase(
|
|
hardware_connect_method) === 'tcp';
|
|
if (_flag) {
|
|
if (hardware_type === 'Air') { // 空调开关状态 key为 op
|
|
postData.value['op'] = this.getAirRelayStatus(status);
|
|
postData['name'] = this.getAirQueryName(switchInfo)
|
|
} else {
|
|
// 空调设备不需要以下两个字段
|
|
postData.value['p'] = node_id + ''; // 硬件子id
|
|
postData.value['o'] = this.getRelayStatus(status); // 开关状态
|
|
}
|
|
}
|
|
return postData;
|
|
},
|
|
changeLowerCase(str) {
|
|
return str.toString().toLocaleLowerCase();
|
|
},
|
|
// 常规开关状态
|
|
// Low = "low", // 低电位,为开启
|
|
// High = "high", // 高电位, 为关闭
|
|
getRelayStatus(status) {
|
|
return ['high', 'low'][status] || ''
|
|
},
|
|
|
|
// 空调状态
|
|
// status = "status",
|
|
// on = "on",
|
|
// off = "off",
|
|
getAirRelayStatus(status) {
|
|
return ['off', 'on'][status] || ''
|
|
},
|
|
|
|
// 非空调获取状态name
|
|
getStatusQueryName(switchInfo) {
|
|
let {
|
|
hardware_connect_method
|
|
} = switchInfo;
|
|
let _obj = {
|
|
'Gpio': 'get-rpio', // 全设备
|
|
'SerialPort485': 'zzio404d-gpio-status',
|
|
'Tcp': 'zzio404d-gpio-status-tcp',
|
|
'YZK':'zzio404d-gpio-status'
|
|
};
|
|
|
|
return _obj[hardware_connect_method] || ''
|
|
},
|
|
|
|
// 非空调获取设置name
|
|
getQueryName(switchInfo) {
|
|
let {
|
|
hardware_connect_method
|
|
} = switchInfo;
|
|
let _obj = {
|
|
'Gpio': 'set-rpio', // 全设备
|
|
'SerialPort485': 'zzio404d-gpio',
|
|
'Tcp': 'zzio404d-gpio-tcp',
|
|
'YZK':'zzio404d-gpio'
|
|
};
|
|
|
|
return _obj[hardware_connect_method] || ''
|
|
},
|
|
// 空调name获取
|
|
getAirQueryName(switchInfo) {
|
|
let {
|
|
hardware_connect_method,
|
|
hardware_model
|
|
} = switchInfo;
|
|
let _flag = this.changeLowerCase(hardware_connect_method) === 'tcp' && this.changeLowerCase(
|
|
hardware_model) === 'jianda';
|
|
if (_flag) return 'ray-air-rs-tcp';
|
|
let _obj = {
|
|
'acmelec': 'acmelec',
|
|
'zhongnan': 'zhongnan',
|
|
'jianda': 'ray-air-rs',
|
|
"XiaoHuiXiong":"xhx-lora-air-tcp"
|
|
};
|
|
return _obj[this.changeLowerCase(hardware_model)] || '';
|
|
},
|
|
|
|
getIcon() {
|
|
let {
|
|
pageInfo
|
|
} = this;
|
|
if (!pageInfo.id) return '';
|
|
return `/subpackage/device/static/images/devices/${pageInfo.id}.png`
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import '~style/public.scss';
|
|
page{
|
|
background:url(../../static/images/page_bg.jpg) repeat-y;
|
|
background-size: 100%;
|
|
background-attachment: fixed;
|
|
}
|
|
.slider-box{
|
|
margin-bottom: 40rpx;
|
|
> text {
|
|
margin-left: 30rpx;
|
|
font-size: 24rpx;
|
|
color: #fff;
|
|
}
|
|
> view{
|
|
width: 100%;
|
|
color: #fff;
|
|
font-size: 28rpx;
|
|
@include centerFlex(space-between);
|
|
padding: 0 34rpx;
|
|
}
|
|
}
|
|
.sm-tit {
|
|
padding-left: 40upx;
|
|
padding-top: 52upx;
|
|
padding-bottom: 30upx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
flex-wrap: nowrap;
|
|
|
|
text:first-child {
|
|
line-height: 60upx;
|
|
font-size: 44upx;
|
|
font-weight: 500;
|
|
color: #1A1A1A;
|
|
}
|
|
|
|
text:last-child {
|
|
width: 466rpx;
|
|
color: #fff;
|
|
font-size: 24rpx;
|
|
}
|
|
}
|
|
|
|
.sm-list {
|
|
padding: 0 32upx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
|
|
.sl-item {
|
|
margin-bottom: 30upx;
|
|
width: 328upx;
|
|
border-radius: 10upx;
|
|
border: .5px solid #fff;
|
|
box-shadow: 0 4upx 12upx 0 #00987454, inset 0 0 40upx 0 #ffffff80;
|
|
background-image: linear-gradient(180deg, #eff6f44d 0%, #FFFFFF 100%);
|
|
.si-top {
|
|
padding: 20upx 20upx 30upx;
|
|
display: flex;
|
|
flex-wrap: nowrap;
|
|
|
|
>image {
|
|
flex-shrink: 0;
|
|
flex-grow: 0;
|
|
margin-right: 20upx;
|
|
width: 80upx;
|
|
height: 80upx;
|
|
}
|
|
|
|
.st-right {
|
|
flex-grow: 1;
|
|
|
|
>.sr-name {
|
|
margin-bottom: 8upx;
|
|
line-height: 44upx;
|
|
font-size: 32upx;
|
|
color: #1A1A1A;
|
|
@include textHide(1);
|
|
}
|
|
|
|
.sr-bot {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
>view {
|
|
margin-right: 8upx;
|
|
padding: 0 12upx;
|
|
font-size: 20upx;
|
|
line-height: 28upx;
|
|
border-radius: 28upx;
|
|
border: 2upx solid #9A9A9D;
|
|
color: #9A9A9D;
|
|
|
|
&::before {
|
|
content: '';
|
|
margin-right: 12upx;
|
|
margin-top: -4upx;
|
|
display: inline-block;
|
|
vertical-align: middle;
|
|
width: 8upx;
|
|
height: 8upx;
|
|
border-radius: 50%;
|
|
background-color: #9A9A9D;
|
|
}
|
|
|
|
&.active {
|
|
color: #333333;
|
|
|
|
&::before {
|
|
background-color: $themeColor;
|
|
}
|
|
}
|
|
}
|
|
|
|
>image {
|
|
flex-shrink: 0;
|
|
flex-grow: 0;
|
|
width: 32upx;
|
|
height: 32upx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.si-bottom {
|
|
padding-top: 30upx;
|
|
padding-bottom: 30upx;
|
|
display: flex;
|
|
justify-content: center;
|
|
border-top: .5px solid #fff;
|
|
|
|
>view {
|
|
flex-shrink: 0;
|
|
flex-grow: 0;
|
|
width: 50%;
|
|
|
|
>image {
|
|
display: block;
|
|
margin: 0 auto 20upx;
|
|
width: 100upx;
|
|
height: 100upx;
|
|
}
|
|
|
|
>view {
|
|
font-size: 24upx;
|
|
line-height: 34upx;
|
|
text-align: center;
|
|
color: #9a9a9d;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//语音控制板
|
|
.voice_control_pad {
|
|
position: fixed;
|
|
top: 0;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 1;
|
|
|
|
.cover_bg {
|
|
position: fixed;
|
|
top: 0;
|
|
background: rgba($color: #000000, $alpha: .3);
|
|
z-index: 2;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.v_box {
|
|
z-index: 3;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
border-radius: 5rpx;
|
|
width: 620rpx;
|
|
height: 550rpx;
|
|
background-color: white;
|
|
|
|
textarea {
|
|
margin-top: 50rpx;
|
|
width: 560rpx;
|
|
height: 260rpx;
|
|
}
|
|
|
|
.voice_title {
|
|
max-width: 560rpx;
|
|
color: #1A1A1A;
|
|
font-size: 32rpx;
|
|
font-weight: 800;
|
|
margin-top: 68rpx;
|
|
}
|
|
|
|
.voice_img {
|
|
margin-top: 70rpx;
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
}
|
|
|
|
.voice_img_playing {
|
|
width: 206rpx;
|
|
height: 100rpx;
|
|
}
|
|
|
|
.voice_btn {
|
|
margin-top: 100rpx;
|
|
width: 392rpx;
|
|
height: 112rpx;
|
|
background: #009874;
|
|
border-radius: 5rpx;
|
|
text-align: center;
|
|
line-height: 112rpx;
|
|
color: white;
|
|
font-size: 32rpx;
|
|
}
|
|
|
|
.btn_active {
|
|
color: black;
|
|
background-color: rgba($color: #000000, $alpha: .4);
|
|
}
|
|
|
|
.btn_white {
|
|
width: 204rpx;
|
|
height: 88rpx;
|
|
background-color: white;
|
|
color: #009874;
|
|
border: 1rpx solid #009874;
|
|
line-height: 88rpx;
|
|
}
|
|
|
|
.btn_green {
|
|
width: 204rpx;
|
|
height: 88rpx;
|
|
background-color: #009874;
|
|
color: white;
|
|
line-height: 88rpx;
|
|
}
|
|
|
|
.v_btns {
|
|
width: 470rpx;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
}
|
|
|
|
}
|
|
}
|
|
</style>
|