From c19e623401496a1124051b24b7208821f020c95e Mon Sep 17 00:00:00 2001 From: zmt Date: Wed, 21 Jul 2021 15:37:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=9A=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E5=8F=8A=E5=9B=9E=E6=98=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/subpackage/device/js/ouxuanac.md | 88 +++- src/subpackage/device/pages/index/lot_manage.vue | 2 +- .../device/pages/index/router_manage.vue | 18 - .../device/pages/switch_manage/switch_manage.vue | 15 +- src/subpackage/device/pages/timing/timing_list.vue | 11 +- .../device/pages/timing/timing_setting.vue | 475 ++++++++++++++++----- 6 files changed, 464 insertions(+), 145 deletions(-) diff --git a/src/subpackage/device/js/ouxuanac.md b/src/subpackage/device/js/ouxuanac.md index 78b4066..44a4e85 100644 --- a/src/subpackage/device/js/ouxuanac.md +++ b/src/subpackage/device/js/ouxuanac.md @@ -325,7 +325,7 @@ https://test.ouxuanzhineng.cn/ouxuanac/tts/textToVoice.wav?text=试试看&voice_ {"code":0,"data":{"DeviceName":"00-de-47-e9-3a-fc","Online":1,"LoginTime":1626126211,"LastUpdateTime":1624102433,"Tags":[{"Tag":"category","Type":2,"Value":"placeholder","Name":""},{"Tag":"note","Type":2,"Value":"锐那东方渔人码头店","Name":""}],"DeviceType":5,"ConnIP":1231216393,"FirstOnlineTime":1602899627,"LastOfflineTime":1626126208,"LastOfflineTimeStr":"2021-07-13 05:43:28","CreateTime":1602899594,"EnableState":1,"ClientIP":"36.113.100.107","RequestId":"fc49e900-2b4c-403b-bf00-d929725d2276"},"message":""} ``` -### 更新定时列表 sendPacket +### 获取定时列表 sendPacket ``` 请求参数 { @@ -363,4 +363,90 @@ https://test.ouxuanzhineng.cn/ouxuanac/tts/textToVoice.wav?text=试试看&voice_ ``` +### 小程序端定时任务设置 sendPacket(reqData) +> switchData(开关命令数据)->postData(后台定时接口数据)->reqData(组成最终小程序端中控定时数据) +1. 接口复用sendPacket [测试集合:sendPacket](http://api.ouxuan.net/project/233/interface/case/1860) +2. 需了解后台接口SetTimeSelect规则 [SetTimeSelect](http://api.ouxuan.net/project/165/interface/api/8194) +3. 需了解参数中group定义由来: [设备管理-硬件设备-连接方式](http://api.ouxuan.net/project/233/interface/api/11397) +4. 区分开关状态需要传输的value +``` +照明,风扇,水阀 +//都是GPIO 其他设备应该也可以用这种方式设置 + { + "name": "继电器", + "value": "Gpio" +}, + +//value区分 +风扇: 水阀: 照明: data.value.status 开:low , 关:high + +``` +> 在sendPacket接口中的传递定时任务参数 reqData +``` +//接口地址 +http://api.ouxuan.net/project/233/interface/api/10012 (原接口地址) +http://api.ouxuan.net/project/233/interface/case/1860 (设置定时任务接口地址: 后台说那边同个接口只能添加一个) + +例子: +{ + "device": "00-10-7a-0f-6d-7a", + "delay": 1, + "data": { + "name": "set-time-select", + "value": { + "data": "传入设置的json格式字符串,例如:{\"time_arrow_id\":\"c8c39f5c-8dd4-11eb-9aad-4e965989bbce\",\"group\":\"RPIO\",\"type\":\"DAY_OF_WEEK\",\"day_of_week\":[0,1,2,3,6,5,4],\"day_of_month\":null,\"date_slice\":[{\"start\":\"\",\"end\":\"\"}],\"times_on_day\":[\"10:13:00-10:13:10\"],\"expand_tags\":null,\"expand_value\":{\"main\":{\"name\":\"set-rpio\",\"title\":\"测试中控照明9\",\"value\":{\"id\":\"9\",\"status\":\"high\"}}},\"weights\":0,\"extension\":null}" + } + } +} +``` +> 定时任务参数参考后台管理端api postData +``` +http://api.ouxuan.net/project/165/interface/api/8194 + +参数规则: +{ + "time_arrow_id": "c8c39f5c-8dd4-11eb-9aad-4e965989bbce", //不用填 留空 + "group": "RPIO", //照明,风扇,空调固定值 + "type": "DAY_OF_WEEK", //DAY_OF_WEEK/DAY_OF_MONTH/DATE_SLICE , 对应 周,月,单独时间. + "day_of_week": [ + 0, + 1, + 2, + 3, + 6, + 5, + 4 + ], + "day_of_month": null, + "date_slice": [ + { + "start": "", + "end": "" + } + ], + "times_on_day": [ + "10:13:00-10:13:10" + ], + "expand_tags": null, + "expand_value": { + "main": { //中控指令 + "name": "set-rpio", + "title": "测试中控照明9", + "value": { + "id": "9", + "status": "high" + } + } + }, + "weights": 0,//权重 + "extension": null +} +``` +> 关于switchData +``` + postData.expand_value.main = switchData + +switchData 为 switch_manage.vue 中的开关指令 +``` +### diff --git a/src/subpackage/device/pages/index/lot_manage.vue b/src/subpackage/device/pages/index/lot_manage.vue index 840a30c..b61867e 100644 --- a/src/subpackage/device/pages/index/lot_manage.vue +++ b/src/subpackage/device/pages/index/lot_manage.vue @@ -296,7 +296,7 @@ url: deviceApi.getLotDetail, data: { iccid:this.mac, - is_sync:0 + is_sync:1 //是否同步,更新传1 }, isDefaultGet: false, }) diff --git a/src/subpackage/device/pages/index/router_manage.vue b/src/subpackage/device/pages/index/router_manage.vue index 347fc75..dd385c8 100644 --- a/src/subpackage/device/pages/index/router_manage.vue +++ b/src/subpackage/device/pages/index/router_manage.vue @@ -227,17 +227,6 @@ util.hideLoad() }) - // this.operateReq({ - // data: timingData, - // succFun: (list) => { - // that.infoArr.length = 1; - // list.forEach(async (item,i)=> { - // if(item.day_of_week)item.day_of_week = item.day_of_week.sort((a,b)=>a-b);//后端数据未排序 - // let timetxt = await that.getTimeTxt(item); - // that.infoArr.push([item.expand_value.main.title||"-",timetxt||"-","删除",item.time_arrow_id]) - // }) - // } - // }) }, //过滤路由数据 filterRouterData(data){ @@ -276,13 +265,6 @@ }) }, - //该函数由后台管理前端提供逻辑, 与后台前端显示逻辑同步 - getTimeTxt(row) { - return new Promise((rs,rj)=>{ - - }) - - }, goBack() { uni.navigateBack({ delta: 1 diff --git a/src/subpackage/device/pages/switch_manage/switch_manage.vue b/src/subpackage/device/pages/switch_manage/switch_manage.vue index 84fb34d..4467ddb 100644 --- a/src/subpackage/device/pages/switch_manage/switch_manage.vue +++ b/src/subpackage/device/pages/switch_manage/switch_manage.vue @@ -202,6 +202,14 @@ export default { // 按钮操作, status 0 -> 关(左), 1 -> 开(右) ,2 -> 长开 ,3 -> 定时, 4 ->详情(自定义) operateBtn: util.debounce(function({ switchInfo, status }){ console.log("icon tap status: ",status,switchInfo) + + + //todo 配置page.json ,写新的setting 页 + + let _data = this.getOperateReqData({ switchInfo, status }) + //针对门禁没有关按钮发两条命令->开&关 20201224 后端: 直接发两条 关的那条这里填5 然后你那边不用管返回 + + //新增定时/长按拦截判断 if(status == 2) return util.showNone("未对接,前端等待接口中...") if(status == 4){ @@ -209,14 +217,12 @@ export default { if(this.pageInfo.hardware_type=='IotSim')return util.routeTo(`/subpackage/device/pages/index/lot_manage?mac=${switchInfo.hardware_standard}`, 'nT'); } if(status == 3) return (()=>{ + switchInfo.switchData = _data;//将中控组合数据传递到下层 let timing_setting = `/subpackage/device/pages/timing/timing_setting?switchInfo=${encodeURIComponent(JSON.stringify(switchInfo))}` util.routeTo(`${timing_setting}`, 'nT'); })() - //todo 配置page.json ,写新的setting 页 - let _data = this.getOperateReqData({ switchInfo, status }) - //针对门禁没有关按钮发两条命令->开&关 20201224 后端: 直接发两条 关的那条这里填5 然后你那边不用管返回 if(switchInfo.hardware_type === 'AccessControl'&&status == 1){ this.operateReq({data: this.getOperateReqData({ switchInfo, status: 0 }), isTip: false, isLoad: false}); } @@ -398,8 +404,9 @@ export default { // 常规开关状态 // Low = "low", // 低电位,为开启 // High = "high", // 高电位, 为关闭 + // status 0 -> 关(左), 1 -> 开(右) ,2 -> 长开 ,3 -> 定时, 4 ->详情(自定义) getRelayStatus(status){ - return [ 'high', 'low' ][status] || '' + return [ 'high', 'low', '', 'high', ''][status] || '' }, // 空调状态 diff --git a/src/subpackage/device/pages/timing/timing_list.vue b/src/subpackage/device/pages/timing/timing_list.vue index ff3541d..242e7da 100644 --- a/src/subpackage/device/pages/timing/timing_list.vue +++ b/src/subpackage/device/pages/timing/timing_list.vue @@ -187,8 +187,9 @@ if (row.times_on_day && row.times_on_day.length) { timeText += ` 当天${row.times_on_day[0].substring(0, 5)}` } - if (!row.expand_value.main) return '历史错误数据'; - rs(` ${timeText} 执行 ${row.expand_value.main.value.status === 'high' ? '[关闭]' : '[开启]'} 操作`) + if (!row.expand_value.main) rs('历史错误结构数据'); + let _status = row.expand_value.main.value.status||row.expand_value.main.data.value.status;//兼容旧数据中的一种情况 + rs(` ${timeText} 执行 ${_status === 'high' ? '[关闭]' : '[开启]'} 操作`) }) }, @@ -307,11 +308,13 @@ } .i-box:first-child { - width: 176rpx; + // width: 176rpx; + width: 300rpx; } .i-box:nth-child(2) { - width: 100%; + width: 100%; + height: 100%; border: 1rpx solid #F2F2F7; border-bottom: none; border-top: none; diff --git a/src/subpackage/device/pages/timing/timing_setting.vue b/src/subpackage/device/pages/timing/timing_setting.vue index beae7d6..22b8b35 100644 --- a/src/subpackage/device/pages/timing/timing_setting.vue +++ b/src/subpackage/device/pages/timing/timing_setting.vue @@ -1,6 +1,6 @@ @@ -114,56 +139,171 @@ const currentDate = this.getDate({ format: true }) - const dayArr = (()=>{ - let day = [] + const dayArrSelect = (()=>{ + let days = [] for(var i=1;i<=31;i++){ - day.push(i) + days.push(false) } - return day + return days })() return { - // tabArr, - // infoArr, - switchInfo:"", + switchInfo:"",//上层页面的选择信息 on:false, singleArr:["星期","具体日期","具体时间段"], sIndex:0, - dayArr:dayArr, + dayArrSelect:dayArrSelect,//31天 选择 dIndex:0, weekArrCN, weekArrSelect:[false,false,false,false,false,false,false], date: currentDate, - time: '00:00', + time: '00:00-', + startTime:"", + endTime:"", + padConfig:{ + show:false, + data:[] + }, + reqData:{//定时请求中控参数 调用sendPacket时传递参数 switchData->postData->reqData(最终请求数据) + "device": "00-10-7a-0f-6d-7a", + "delay": 1, + "data": { + "name": "set-time-select", + "value": { + "data": "传入设置的json格式字符串,例如:{\"time_arrow_id\":\"c8c39f5c-8dd4-11eb-9aad-4e965989bbce\",\"group\":\"RPIO\",\"type\":\"DAY_OF_WEEK\",\"day_of_week\":[0,1,2,3,6,5,4],\"day_of_month\":null,\"date_slice\":[{\"start\":\"\",\"end\":\"\"}],\"times_on_day\":[\"10:13:00-10:13:10\"],\"expand_tags\":null,\"expand_value\":{\"main\":{\"name\":\"set-rpio\",\"title\":\"测试中控照明9\",\"value\":{\"id\":\"9\",\"status\":\"high\"}}},\"weights\":0,\"extension\":null}" + } + } + }, + postData:{//定时参数消息结构 reqData.data.value + "time_arrow_id": "", //不用填 留空 + "group": "RPIO", //照明,风扇,空调固定值,其它不确定 + "type": "DAY_OF_WEEK", //DAY_OF_WEEK/DAY_OF_MONTH/DATE_SLICE , 对应 周,月,单独时间. + "day_of_week": [ + ], + "day_of_month": null, //数组 + "date_slice": [ + { + "start": "", + "end": "" + } + ], + "times_on_day": [//时间点 + // "10:13:00-10:13:10" //后台要求,10s期间 + ], + "expand_tags": null, + "expand_value": { + "main": { //中控指令 + "name": "set-rpio", + "title": "", + "value": { + "id": "",//设备id + "status": "high" //low:开, high:关 + } + } + }, + "weights": 0,//权重 + "extension": null + }, + switchData:"",//开关请求中控参数 postData.expand_value.main } }, async onLoad(option) { - let switchInfo = JSON.parse(decodeURIComponent(option.switchInfo)); - this.switchInfo = switchInfo; - console.log("switchInfo:",switchInfo); - - try { - util.showLoad(); - let _brandInfo = await this.$store.dispatch('getBrandInfo'); - await this.$store.dispatch('getStoreList'); - util.hideLoad(); - } catch (err) { - util.hideLoad(); - } - + this.handleOpts(option); }, onShow() { - this.updateList() //更新中控信息 + // this.updateList() //更新中控信息 }, watch: { curStoreInfo(newVal, oldVal){ // this.infoArr.length = 1 - this.updateList() + // this.updateList() } }, methods: { + //处理参数 + handleOpts(option){ + let switchInfo = JSON.parse(decodeURIComponent(option.switchInfo)); + this.switchInfo = switchInfo //该选择控制设备的所有数据 (目前只使用了hardware_name) + this.switchData = switchInfo.switchData //开关关联数据 + + //去掉店铺切换功能 + // try { + // util.showLoad(); + // let _brandInfo = await this.$store.dispatch('getBrandInfo'); + // await this.$store.dispatch('getStoreList'); + // util.hideLoad(); + // } catch (err) { + // util.hideLoad(); + // } + }, + //点击保存按钮 + saveAdd(){ //switchData(开关命令数据)->postData(后台定时接口数据)->reqData(组成最终小程序端中控定时数据) + let {switchData,postData,reqData,curStoreInfo,sIndex,time,getWeekRes,getMonthDaysRes,getSliceRes,getDayTimeRes,sendDataToVC} = this; + + // ["星期","具体日期","具体时间段"], + if(sIndex==0)postData.day_of_week = getWeekRes(); // + if(sIndex==1)postData.day_of_month = getMonthDaysRes(); //当月的多选某天 + if(sIndex==2)postData.date_slice = getSliceRes(); // + + if(time=="00:00-") return util.showNone("请先选择定时时间点!") + postData.times_on_day = getDayTimeRes(); //时间点,固定要传 + + switchData.data.title = `${this.switchInfo.hardware_name}-${this.singleArr[this.sIndex]}定时`; + postData.expand_value.main = switchData.data; + reqData.device = switchData.device + reqData.data.value.data = JSON.stringify(postData) + + console.log("reqData:",JSON.stringify(reqData)); + + uni.showModal({ + content: `确认要设置${curStoreInfo.venue_name}中 [ ${this.switchInfo.hardware_name} ] 的[ ${this.singleArr[this.sIndex]} ]计划任务 ?`, + success(res) { + console.log("确认执行", res.confirm) + if(res.confirm){ + sendDataToVC(); + } + }, + }) + + }, + getWeekRes(){ + console.log(this.weekArrSelect); + let res = [] + this.weekArrSelect.forEach((e,i)=>{ + if(e)res.push(i) + }) + return res + }, + getMonthDaysRes(){ + let res = [] + this.dayArrSelect.forEach((e,i)=>{ + if(e)res.push(i+1) + }) + return res + }, + getSliceRes(){ + let res = [],{startTime,endTime} = this; + if(startTime&&endTime){ + res.push({ + "start": startTime, + "end": endTime + }) + }else{ + res.push({ + "start": "", + "end": "" + }) + } + return res + }, + getDayTimeRes(){ + let res = [] + res.push( `${this.time}:00-${this.time}:10`) + return res + }, tapSwitch(){ //开关切换 this.on = !this.on + this.switchData.data.value.status = this.on? "low":"high"; }, clickWeekTab(index) { if(this.weekArrSelect[index]) { @@ -172,7 +312,52 @@ this.$set(this.weekArrSelect,index,true) } }, - //删除计划任务 + clickDaysTab(index) { + if(this.dayArrSelect[index]) { + this.$set(this.dayArrSelect,index,false) + }else{ + this.$set(this.dayArrSelect,index,true) + } + }, + bindPickerChangeSingle(e){ + console.log('bindPickerChangeSingle,携带值为', e.target.value) + this.sIndex = e.target.value + // DAY_OF_WEEK/DAY_OF_MONTH/DATE_SLICE + this.postData.type = ['DAY_OF_WEEK','DAY_OF_MONTH','DATE_SLICE'][e.target.value] + this.resetPostData(); + }, + resetPostData(){ //重置选择数据为原始状态 + let _reset = { + "day_of_week": [ + ], + "day_of_month": null, //数组 + "date_slice": [{ + "start": "", + "end": "" + } + ],} + for(var i in _reset){ + console.log("重置:",i); + this.postData[i] = _reset[i] + } + + }, + bindTimeChange(e){ //时间选择 + this.time = e.target.value + }, + bindTimeChangeStart(e){ //日期选择 + if(new Date(this.endTime)-new Date(e.target.value)<0) return util.showNone("开始时间异常") + this.startTime = e.target.value + }, + bindTimeChangeEnd(e){ //日期选择 + if(new Date(e.target.value)-new Date(this.startTime)<0) return util.showNone("结束时间异常") + this.endTime = e.target.value + }, + bindPickerChangeDay(e){ //月选择 + console.log('bindPickerChangeDay,携带值为', e.target.value) + this.dIndex = e.target.value + }, + //删除计划任务 delItem(e,i) { let that = this let delData = { @@ -184,10 +369,10 @@ "uuid": e[3] } } - } - uni.showModal({ - content: `确认要删除: ${e[0]}的计划任务 ?`, - success(res) { + } + uni.showModal({ + content: `确认要删除: ${e[0]}的计划任务 ?`, + success(res) { console.log("确认删除", res.confirm) if(res.confirm){ that.operateReq({ @@ -197,21 +382,9 @@ }, isTip:true }) - } - }, - }) - }, - bindPickerChangeSingle(e){ - console.log('bindPickerChangeSingle,携带值为', e.target.value) - this.sIndex = e.target.value - }, - bindTimeChange(e){ - console.log('bindTimeChange,携带值为', e.target.value) - this.time = e.target.value - }, - bindPickerChangeDay(e){ - console.log('bindPickerChangeDay,携带值为', e.target.value) - this.dIndex = e.target.value + } + }, + }) }, getDate(type) { const date = new Date(); @@ -220,67 +393,31 @@ let day = date.getDate(); if (type === 'start') { - year = year - 60; + year = year - 0; } else if (type === 'end') { - year = year + 2; + year = year + 10;//限制可选10年内 } month = month > 9 ? month : '0' + month;; day = day > 9 ? day : '0' + day; return `${year}-${month}-${day}`; }, - async updateList() { + async sendDataToVC() { let that = this let timingData = { - "device": this.curStoreInfo.device_name, - "data": { - "name": "get-time-select", - "value": {} - } } + timingData = this.reqData this.operateReq({ data: timingData, - succFun: (list) => { - that.infoArr.length = 1; - list.forEach(async (item,i)=> { - if(item.day_of_week)item.day_of_week = item.day_of_week.sort((a,b)=>a-b);//后端数据未排序 - let timetxt = await that.getTimeTxt(item); - that.infoArr.push([item.expand_value.main.title||"-",timetxt||"-","删除",item.time_arrow_id]) - }) - } - }) - }, - //该函数由后台管理前端提供逻辑, 与后台前端显示逻辑同步 - getTimeTxt(row) { - return new Promise((rs,rj)=>{ - let timeText = "" - if (!row.expand_value) { - rj('error') - } - if (row.type === 'DAY_OF_WEEK' && row.day_of_week) { - let arr = [] - for (let i = 0; i < row.day_of_week.length; i++) { - arr += ' 周' + ['日', '一', '二', '三', '四', '五', '六'][row.day_of_week[i]]; - } - timeText = `每个星期的 [${arr} ] ` - } - if (row.type === 'DAY_OF_MONTH' && row.day_of_month) { - let arr = [] - for (let i = 0; i < row.day_of_month.length; i++) { - arr += row.day_of_month[i] + '号 '; + succFun: (res) => { + console.log("操作结果:",res); + if(res=="ok"){ + let timing_list = "/subpackage/device/pages/timing/timing_list" + util.routeTo(`${timing_list}`, 'nT'); } - timeText = `每个月的 [ ${arr} ] ` - } - if (row.type === 'DATE_SLICE' && row.date_slice) { - timeText = ` ${row.date_slice[0].start.substring(0, 10)}~${row.date_slice[0].end.substring(0, 10)}` - } - if (row.times_on_day && row.times_on_day.length) { - timeText += ` 当天${row.times_on_day[0].substring(0, 5)}` - } - if (!row.expand_value.main) return '历史错误数据'; - rs(` ${timeText} 执行 ${row.expand_value.main.value.status === 'high' ? '[关闭]' : '[开启]'} 操作`) - }) - + }, + isTip:true + }) }, goBack() { uni.navigateBack({ @@ -459,5 +596,109 @@ color: #009874; } margin: 40rpx; - } + } + + //弹窗选择 + .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; + width: 630rpx; + background-color: white; + border-radius: 10rpx; + scroll-view{ + margin-top: 30rpx; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: flex-start; + border-radius: 5rpx; + flex-wrap: wrap; + width: 100%; + height: 700rpx; + border-bottom: 1rpx solid #F2F2F7; + + .il-select-week{ + width: 100%; + height: auto; + @include centerFlex(flex-start); + flex-wrap: wrap; + > view{ + @include centerFlex(center); + width: 160rpx; + height: 88rpx; + border: 2rpx solid #979797; + border-radius: 6rpx; + color: #979797; + margin-left: 40rpx; + margin-top: 40rpx; + } + .active{ + background: rgba(0,152,116,0.12); + border: 2rpx solid #009874;color: #009874; + } + } + + } + + .voice_btn { + 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: 100%; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + margin: 50rpx 0; + } + } + } + +