-
423src/components/site/order_modal/order_modal.vue
-
17src/js/api.js
-
84src/pages.json
-
5src/pages/index/index.vue
-
95src/pages/site/confirm/confirm.vue
-
330src/pages/site/manage/manage.vue
-
134src/pages/site/occupy_share/occupy_share.vue
-
118src/pages/site/occupy_success/occupy_success.vue
-
23src/pages/write_off/search_result/search_result.vue
-
BINsrc/static/images/icon/share_arrow_cff.png
-
29src/subpackage/device/components/store_name/store_name.vue
-
13src/subpackage/device/js/device_api.js
-
172src/subpackage/device/js/ouxuanac.md
-
967src/subpackage/device/pages/audio_manage/audio_manage.vue
-
8src/subpackage/device/pages/index/airC_manage.vue
-
169src/subpackage/device/pages/index/index.vue
-
292src/subpackage/device/pages/index/lease_ball_box_manage.vue
-
470src/subpackage/device/pages/index/lot_manage.vue
-
427src/subpackage/device/pages/index/router_manage.vue
-
404src/subpackage/device/pages/index/sunblind_manage.vue
-
292src/subpackage/device/pages/monitor_manage/monitor_acount_add.vue
-
245src/subpackage/device/pages/monitor_manage/monitor_acount_list.vue
-
178src/subpackage/device/pages/monitor_manage/monitor_manage.vue
-
185src/subpackage/device/pages/switch_manage/switch_manage.vue
-
336src/subpackage/device/pages/timing/timing_list.vue
-
701src/subpackage/device/pages/timing/timing_setting.vue
-
BINsrc/subpackage/device/static/images/arrow_b2_light.png
-
BINsrc/subpackage/device/static/images/arrow_back.png
-
BINsrc/subpackage/device/static/images/devices/16.png
-
BINsrc/subpackage/device/static/images/devices/17.png
-
BINsrc/subpackage/device/static/images/devices/18.png
-
BINsrc/subpackage/device/static/images/devices/19.png
-
BINsrc/subpackage/device/static/images/i_txt.png
-
BINsrc/subpackage/device/static/images/i_voice_1.png
-
BINsrc/subpackage/device/static/images/i_voice_2.png
-
BINsrc/subpackage/device/static/images/i_voice_3.png
-
BINsrc/subpackage/device/static/images/i_voice_4.png
-
BINsrc/subpackage/device/static/images/icon_clock.png
-
BINsrc/subpackage/device/static/images/index_bg.png
-
BINsrc/subpackage/device/static/images/longOpen.png
-
BINsrc/subpackage/device/static/images/no-info.png
-
BINsrc/subpackage/device/static/images/sunblind.png
-
BINsrc/subpackage/device/static/images/sunblind_close.png
-
BINsrc/subpackage/device/static/images/sunblind_open.png
-
BINsrc/subpackage/device/static/images/timing.png
-
BINsrc/subpackage/device/static/images/windows.png
@ -0,0 +1,423 @@ |
|||
<template> |
|||
<view class="fixed-mask" @click="modalClose"> |
|||
<view class="order-modal" @click.stop="_=>false"> |
|||
<view class="om-title">{{ getTitle(queryInfo.venueInfo.type) }}</view> |
|||
<image class="om-close" @click="modalClose" mode="aspectFit" src="/static/images/icon/x_close.png"></image> |
|||
<view class="om-name-line"> |
|||
<view class="onl-view">{{ orderInfo.stadium_name || '-' }}</view> |
|||
<!-- 0、1、2、8 --> |
|||
<view class="onl-view" v-if="isShowStatus">{{ getStatusTxt(orderInfo.pay_status) }}</view> |
|||
</view> |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">订单编号:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.order_no || '' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line" v-if="orderInfo.type != 'take_up_venue'"> |
|||
<view class="oil-view">创建时间:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.created_at || ' ' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line" v-if="orderInfo.type != 'take_up_venue'"> |
|||
<view class="oil-view">验证码:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.verifyt_code || ' ' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line" v-if="orderInfo.type == 'mini_program'"> |
|||
<view class="oil-view">手机号码:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.mobile || ' ' }}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<block v-if="orderInfo.type == 'take_up_venue'" > |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">是否联动开灯:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.light_up?'是':'否'}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">收取金额:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.amount || '0' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">占用原因:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.reason || ' ' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">操作人:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.operator || ' ' }}</view> |
|||
</view> |
|||
</view> |
|||
</block> |
|||
|
|||
|
|||
<view class="om-border"></view> |
|||
|
|||
<view class="om-name-line"> |
|||
<view class="onl-view">预订信息</view> |
|||
</view> |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">预订项目:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.stadium_name || ' ' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">预订日期:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view">{{ orderInfo.date || ' ' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-info-line"> |
|||
<view class="oil-view">预订场次:</view> |
|||
<view class="oil-view"> |
|||
<view class="ov-view" v-for="(e, i) in orderInfo.sessions" :key="i"> |
|||
{{ e.venue_name || '' }} {{ e.duration || '' }} (¥{{ e.price || '' }} ) |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="om-total" v-if="isShowTotalAmoutn" >实付款 ¥{{ orderInfo.amount || '0' }}</view> |
|||
<!-- 管理员占用 --> |
|||
<view class="om-btns" v-if="orderInfo.type == 'take_up_venue'"> |
|||
<view class="ob-view" @click="toShare">分享给朋友</view> |
|||
<view class="ob-view red" @click="cancelOccupy">取消占用</view> |
|||
</view> |
|||
<!-- 小程序预定 --> |
|||
<view class="om-btns" v-if="orderInfo.type == 'mini_program'"> |
|||
<view class="ob-view" @click="toOrderInfo">订单详情</view> |
|||
<!-- <view class="ob-view red" @click="refundBtn">退款</view> --> |
|||
</view> |
|||
<!-- 课程预定 --> |
|||
<view class="om-btns" v-if="orderInfo.type == 'course_venue'"> |
|||
<view class="ob-view" @click="toCouseInfo">约课详情</view> |
|||
</view> |
|||
<!-- 固定场 --> |
|||
<view class="om-btns" v-if="orderInfo.type == 'fixed_venue'"> |
|||
<!-- 测试:固定场地没有详情 --> |
|||
<view class="ob-view" v-if="orderInfo.pay_status != 0" @click="toOrderInfo">订单详情</view> |
|||
<view class="ob-view red" @click="fixedCancelOccupy" v-if="orderInfo.pay_status!=2">取消订场</view> |
|||
<!-- <view class="ob-view red">退款</view> --> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
import { API } from '../../../js/api' |
|||
import { servers } from '../../../js/server' |
|||
import util from '../../../utils/util' |
|||
export default { |
|||
computed: { |
|||
// 是否显示使用状态 |
|||
isShowStatus(){ |
|||
let { orderInfo } = this; |
|||
// 测试: 固定场地没有状态 |
|||
return orderInfo.type == 'mini_program' || orderInfo.type == 'fixed_venue' |
|||
}, |
|||
|
|||
isShowTotalAmoutn(){ |
|||
let { orderInfo } = this; |
|||
|
|||
return orderInfo.type == 'mini_program' || orderInfo.type == 'course_venue' || orderInfo.type == 'fixed_venue' |
|||
} |
|||
}, |
|||
props: { |
|||
queryInfo: { |
|||
type: Object, |
|||
default: {} |
|||
} |
|||
}, |
|||
data(){ |
|||
return { |
|||
orderInfo: {} |
|||
} |
|||
}, |
|||
mounted(){ |
|||
this.getOrderInfo(); |
|||
}, |
|||
methods: { |
|||
fixedCancelOccupy: util.debounce(function(){ |
|||
let { orderInfo, queryInfo } = this; |
|||
util.showLoad(); |
|||
servers.get({ |
|||
url: API.venue.FixedOccupyCancel, |
|||
data: { |
|||
id: orderInfo.fix_venue_id, |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res=>{ |
|||
util.hideLoad(); |
|||
if(res.data.code == 0){ |
|||
setTimeout(_=>this.$emit('refresh'), 1200); |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
}else{ |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(util.hideLoad) |
|||
}, 300, true), |
|||
toCouseInfo(){ |
|||
util.showNone('待开放') |
|||
}, |
|||
refundBtn: util.debounce(function(){ |
|||
util.showModal({ |
|||
title: '提示', |
|||
content: '是否确认退款,退款后释放场地', |
|||
showCancel: true, |
|||
success: mRes => { |
|||
if(mRes.confirm)this.refundReq(); |
|||
} |
|||
}) |
|||
|
|||
}, 300, true), |
|||
refundReq(){ |
|||
let { orderInfo, queryInfo } = this; |
|||
servers.post({ |
|||
url: API.venue.orderRefund, |
|||
data: { |
|||
brand_id: queryInfo.brand_id, |
|||
order_no: orderInfo.order_no, |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res=>{ |
|||
if(res.data.code == 0){ |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
setTimeout(_=>this.$emit('refresh'), 1200); |
|||
}else{ |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
}, |
|||
toOrderInfo(){ |
|||
let { orderInfo, queryInfo } = this; |
|||
let _query = {} |
|||
_query["stadium_id"] = queryInfo.stadium_id |
|||
_query["order_no"] = orderInfo.order_no |
|||
_query["order_type"] = 3 |
|||
util.routeTo(`/subpackage/device/pages/order_details/order_details?query=${util.jsonStr(_query)}`,'nT'); |
|||
}, |
|||
toShare(){ |
|||
let { orderInfo, queryInfo } = this; |
|||
let _qyStr = `?brand_id=${queryInfo.brand_id}&order_no=${orderInfo.order_no}` |
|||
util.routeTo(`/pages/site/occupy_share/occupy_share${_qyStr}`, 'nT'); |
|||
}, |
|||
|
|||
getStatusTxt(status){ |
|||
switch(status){ |
|||
case 0: |
|||
return '待扣款' |
|||
case 1: |
|||
return '待使用' |
|||
case 2: |
|||
return '已使用' |
|||
case 3: |
|||
return '已失效' |
|||
case 8: |
|||
return '使用中' |
|||
default: return '-' |
|||
} |
|||
}, |
|||
getTitle(type){ |
|||
switch(type){ |
|||
case 'no_price_venue': |
|||
return '无法订场' |
|||
case 'empty_venue': |
|||
return '-' |
|||
case 'mini_program': |
|||
return '小程序订场' |
|||
case 'take_up_venue': |
|||
return '管理员占用' |
|||
case 'course_venue': |
|||
return '课程预定' |
|||
case 'play_venue': |
|||
return '约玩占用' |
|||
case 'fixed_venue': |
|||
return '固定场锁定' |
|||
default: return '-' |
|||
} |
|||
}, |
|||
cancelOccupy: util.debounce(function(){ |
|||
let { orderInfo, queryInfo } = this; |
|||
servers.get({ |
|||
url: API.venue.takeUpCancel, |
|||
data: { |
|||
brand_id: queryInfo.brand_id, |
|||
order_no: orderInfo.order_no, |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res=>{ |
|||
if(res.data.code == 0){ |
|||
setTimeout(_=>this.$emit('refresh'), 1200); |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
}else{ |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
}, 300, true), |
|||
modalClose(){ |
|||
this.$emit('close'); |
|||
}, |
|||
getOrderInfo(){ |
|||
util.showLoad(); |
|||
let { queryInfo } = this; |
|||
servers.post({ |
|||
url: API.venue.dashboardInfo, |
|||
data: { |
|||
brand_id: queryInfo.brand_id, |
|||
stadium_id: queryInfo.stadium_id, |
|||
venue_id: queryInfo.venue_id, |
|||
date: queryInfo.date, |
|||
duration: queryInfo.duration, |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res=>{ |
|||
util.hideLoad(); |
|||
if(res.data.code == 0){ |
|||
this.orderInfo = res.data.data || {} |
|||
}else{ |
|||
// util.showNone(res.data.message || '加载失败!'); |
|||
this.modalClose(); |
|||
util.showModal({ |
|||
title: '提示', |
|||
content: res.data.message || '加载失败!', |
|||
success: mRes=> { |
|||
|
|||
} |
|||
}) |
|||
} |
|||
}) |
|||
.catch(util.hideLoad) |
|||
|
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
@import '~style/public.scss'; |
|||
.fixed-mask{ |
|||
position: fixed; |
|||
top: 0; |
|||
bottom: 0; |
|||
right: 0; |
|||
left: 0; |
|||
z-index: 10; |
|||
width: 100%; |
|||
background-color: rgba($color: #000000, $alpha: .5); |
|||
} |
|||
.order-modal{ |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: 0; |
|||
width: 100%; |
|||
padding-left: 30upx; |
|||
padding-right: 30upx; |
|||
padding-top: 48upx; |
|||
padding-bottom: 0upx; |
|||
padding-bottom: calc( 0upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ |
|||
padding-bottom: calc( 0upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ |
|||
background-color: #fff; |
|||
.om-close{ |
|||
position: absolute; |
|||
right: 30upx; |
|||
top: 30upx; |
|||
width: 34upx; |
|||
height: 34upx; |
|||
} |
|||
.om-title{ |
|||
margin-bottom: 34upx; |
|||
text-align: center; |
|||
font-size: 32upx; |
|||
line-height: 44upx; |
|||
color: #1a1a1a; |
|||
font-weight: 500; |
|||
} |
|||
.om-name-line{ |
|||
margin-bottom: 12upx; |
|||
@include centerFlex(space-between); |
|||
.onl-view{ |
|||
&:first-child{ |
|||
line-height: 40upx; |
|||
font-size: 28upx; |
|||
color: #1a1a1a; |
|||
} |
|||
&+.onl-view{ |
|||
line-height: 40upx; |
|||
font-size: 28upx; |
|||
color: $themeColor; |
|||
} |
|||
} |
|||
} |
|||
.om-info-line{ |
|||
display: flex; |
|||
align-items: baseline; |
|||
.oil-view{ |
|||
font-size: 28upx; |
|||
line-height: 40upx; |
|||
color: #9C9C9F; |
|||
&:first-child{ |
|||
flex-shrink: 0; |
|||
} |
|||
&+.oil-view{ |
|||
flex-grow: 1; |
|||
.ov-view{ |
|||
font-size: 28upx; |
|||
line-height: 40upx; |
|||
color: #1a1a1a; |
|||
@include textHide(1); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.om-border{ |
|||
margin-top: 20upx; |
|||
margin-bottom: 18upx; |
|||
height: 2upx; |
|||
background-color: #D8D8D8; |
|||
} |
|||
.om-total{ |
|||
margin-top: 20upx; |
|||
margin-bottom: 40upx; |
|||
text-align: right; |
|||
line-height: 40upx; |
|||
font-size: 28upx; |
|||
color: #1a1a1a; |
|||
} |
|||
.om-btns{ |
|||
margin-top: 40upx; |
|||
margin-bottom: 10upx; |
|||
@include centerFlex(flex-end); |
|||
.ob-view{ |
|||
margin-left: 20upx; |
|||
width: 210upx; |
|||
height: 80upx; |
|||
border: 2upx solid $themeColor; |
|||
text-align: center; |
|||
line-height: 76upx; |
|||
border-radius: 10upx; |
|||
font-size: 32upx; |
|||
font-weight: 500; |
|||
color: $themeColor; |
|||
&.red{ |
|||
border-color: #EA5061; |
|||
color: #EA5061; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,134 @@ |
|||
<template> |
|||
<view class="occupy-share"> |
|||
<view class="os-address"> |
|||
<view class="oa-name"> |
|||
<image mode="aspectFit" :src="shareInfo.stadium_logo"></image> |
|||
<view>{{ shareInfo.stadium_name || '-' }}</view> |
|||
</view> |
|||
<view class="oa-info"> |
|||
<view>地址:</view> |
|||
<view>{{ shareInfo.stadium_address || '-' }}</view> |
|||
</view> |
|||
</view> |
|||
<view class="os-section"> |
|||
<view class="os-des"> |
|||
<view>①<text>截图</text>该页面后,发此图给朋友 </view> |
|||
<view>② 朋友<text>长按此图</text>识别下面的二维码<text>关注公众号</text> </view> |
|||
<view>③ 接收微信消息,<text>领取入场码</text></view> |
|||
<view>④ 领取成功后<text>仅限本人使用</text></view> |
|||
</view> |
|||
<image class="os-code-img" mode="aspectFit" :src="shareInfo.share_qrcode"></image> |
|||
<view class="os-tip">注:此码非入场码</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { API } from '../../../js/api' |
|||
import { servers } from '../../../js/server' |
|||
export default { |
|||
data(){ |
|||
return { |
|||
shareInfo: {}, |
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
this.getShareCode({ |
|||
brand_id: options.brand_id, |
|||
order_no: options.order_no, |
|||
}) |
|||
}, |
|||
methods: { |
|||
getShareCode({ brand_id, order_no }){ |
|||
servers.get({ |
|||
url: API.venue.takeUpShareQr, |
|||
data: { brand_id, order_no, }, |
|||
failMsg: '加载失败!' |
|||
}) |
|||
.then(res=> { |
|||
console.warn('shareInfo', res) |
|||
this.shareInfo = res || {}; |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
page{ |
|||
background-color: $themeColor; |
|||
} |
|||
.occupy-share{ |
|||
padding-top: 32upx; |
|||
padding-left: 24upx; |
|||
padding-right: 24upx; |
|||
|
|||
} |
|||
.os-address{ |
|||
margin-bottom: 36upx; |
|||
.oa-name{ |
|||
margin-bottom: 20upx; |
|||
@include centerFlex(flex-start); |
|||
>image{ |
|||
flex-shrink: 0; |
|||
margin-right: 10upx; |
|||
width: 34upx; |
|||
height: 34upx; |
|||
} |
|||
>view{ |
|||
line-height: 40upx; |
|||
font-size: 28upx; |
|||
color: #fff; |
|||
@include textHide(1); |
|||
} |
|||
} |
|||
.oa-info{ |
|||
display: flex; |
|||
align-items: baseline; |
|||
>view{ |
|||
line-height: 40upx; |
|||
font-size: 28upx; |
|||
color: #fff; |
|||
&:first-child{ |
|||
flex-shrink: 0; |
|||
} |
|||
&+view{ |
|||
flex-grow: 1; |
|||
word-break: break-all; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.os-section{ |
|||
padding: 30upx 60upx 0; |
|||
height: 640upx; |
|||
overflow: hidden; |
|||
border-radius: 10upx; |
|||
background-color: #fff; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
flex-direction: column; |
|||
.os-des{ |
|||
margin-bottom: 16upx; |
|||
>view{ |
|||
line-height: 52upx; |
|||
font-size: 28upx; |
|||
color: #333; |
|||
>text{ |
|||
color: $themeColor; |
|||
} |
|||
} |
|||
} |
|||
.os-code-img{ |
|||
margin-bottom: 12upx; |
|||
width: 300upx; |
|||
height: 300upx; |
|||
} |
|||
} |
|||
.os-tip{ |
|||
font-size: 24upx; |
|||
color: #9A9A9D; |
|||
} |
|||
</style> |
@ -0,0 +1,118 @@ |
|||
<template> |
|||
<view class="occupy-success"> |
|||
<view class="os-address">{{ qrInfo.stadium_name || '-' }}</view> |
|||
<image class="os-code" mode="aspectFit" :src="qrInfo.verify_qrcode"></image> |
|||
<view class="os-num">验证码:{{ qrInfo.verify_code || '-' }}</view> |
|||
<view class="os-btn" @click="toShare"> |
|||
<view>分享给朋友</view> |
|||
<image mode="aspectFit" src="/static/images/icon/share_arrow_cff.png"></image> |
|||
</view> |
|||
<view class="os-black" @click="backBtn">返回</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { API } from '../../../js/api'; |
|||
import { servers } from '../../../js/server'; |
|||
import util from '../../../utils/util'; |
|||
export default { |
|||
data(){ |
|||
return { |
|||
qrInfo: {}, |
|||
optionsQuery: {}, |
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
this.optionsQuery = options || {}; |
|||
this.getPageInfo({ |
|||
brand_id: options.brand_id, |
|||
order_no: options.order_no, |
|||
}) |
|||
}, |
|||
methods: { |
|||
toShare(){ |
|||
let { optionsQuery } = this; |
|||
let _qrStr = `?brand_id=${optionsQuery.brand_id}&order_no=${optionsQuery.order_no}` |
|||
util.routeTo(`/pages/site/occupy_share/occupy_share${_qrStr}`, 'nT') |
|||
}, |
|||
backBtn(){ |
|||
util.routeTo(); |
|||
util.previousPageFunction({ // 刷新占用列表 |
|||
fnName: 'refreshList', |
|||
query: null |
|||
}) |
|||
}, |
|||
getPageInfo({ |
|||
brand_id, |
|||
order_no, |
|||
}){ |
|||
servers.get({ |
|||
url: API.venue.takeUpVerifyQr, |
|||
data: { |
|||
brand_id, |
|||
order_no, |
|||
}, |
|||
failMsg: '加载失败!' |
|||
}) |
|||
.then(res=>{ |
|||
console.warn('res--->' , res); |
|||
this.qrInfo = res || {}; |
|||
}) |
|||
} |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
.occupy-success{ |
|||
padding: 0 24upx; |
|||
.os-address{ |
|||
margin-bottom: 80upx; |
|||
height: 92upx; |
|||
line-height: 90upx; |
|||
border-bottom: 2upx solid #D8D8D8; |
|||
font-size: 32upx; |
|||
color: #333; |
|||
@include textHide(1); |
|||
} |
|||
.os-code{ |
|||
margin: 0 auto 40upx; |
|||
display: block; |
|||
width: 400upx; |
|||
height: 400upx; |
|||
} |
|||
.os-num{ |
|||
margin-bottom: 128upx; |
|||
text-align: center; |
|||
font-size: 32upx; |
|||
color: #333; |
|||
@include textHide(1); |
|||
} |
|||
.os-btn{ |
|||
margin: 0 auto 92upx; |
|||
width: 320upx; |
|||
height: 112upx; |
|||
background-color: $themeColor; |
|||
border-radius: 10upx; |
|||
@include centerFlex(center); |
|||
>view{ |
|||
font-size: 32upx; |
|||
color: #fff; |
|||
} |
|||
>image{ |
|||
margin-left: 20upx; |
|||
width: 34upx; |
|||
height: 36upx; |
|||
} |
|||
} |
|||
.os-black{ |
|||
font-size: 32upx; |
|||
line-height: 44upx; |
|||
text-align: center; |
|||
color: $themeColor; |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
</style> |
After Width: 68 | Height: 72 | Size: 705 B |
@ -0,0 +1,967 @@ |
|||
<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> |
|||
<!-- <block v-else> |
|||
<view class="si-bottom" v-if="pageInfo.isOpen || pageInfo.isClose"> |
|||
<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> |
|||
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'; |
|||
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: "点击对应音响的麦克风可以进行说话,说话内容将通过音响播放。", |
|||
}, |
|||
|
|||
} |
|||
import { |
|||
mapState |
|||
} from 'vuex'; |
|||
import util from '../../../../utils/util'; |
|||
|
|||
|
|||
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 |
|||
} |
|||
}, |
|||
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 |
|||
} |
|||
}, |
|||
// "token": "f0d5c19b-b87e-11eb-bc7d-5254005df464" |
|||
} |
|||
//发送命令到中控 |
|||
if(_url)this.operateReq({ |
|||
data: _data |
|||
}) |
|||
|
|||
}, |
|||
//试听/播放 语音/录音 |
|||
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 |
|||
}) { |
|||
if (switchInfo.hardware_type === "AudioPlayer") return this.HandleVoiceOperate({ |
|||
switchInfo, |
|||
status |
|||
}); //单独处理音响操作0704 |
|||
|
|||
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 |
|||
}); |
|||
} |
|||
|
|||
this.operateReq({ |
|||
data: _data |
|||
}); |
|||
|
|||
}, 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(); |
|||
console.log("123",data); |
|||
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 等待后续音响设备调试后,再开放更新设备状态功能 |
|||
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', |
|||
}; |
|||
|
|||
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', |
|||
}; |
|||
|
|||
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' |
|||
}; |
|||
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'; |
|||
.slider-box{ |
|||
margin-bottom: 40rpx; |
|||
> text { |
|||
margin-left: 30rpx; |
|||
font-size: 24rpx; |
|||
color: #9C9C9F; |
|||
} |
|||
> view{ |
|||
width: 100%; |
|||
color: #9C9C9F; |
|||
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: #333; |
|||
} |
|||
|
|||
text:last-child { |
|||
width: 466rpx; |
|||
color: #9C9C9F; |
|||
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; |
|||
background-color: #fff; |
|||
|
|||
.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: #333; |
|||
@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: 2upx solid #F2F2F7; |
|||
|
|||
>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> |
@ -0,0 +1,8 @@ |
|||
<template> |
|||
</template> |
|||
|
|||
<script> |
|||
</script> |
|||
|
|||
<style> |
|||
</style> |
@ -0,0 +1,292 @@ |
|||
<template> |
|||
<view class="t-monitor-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title">管理监控平台账户 |
|||
<!-- <view class="t-go-monitor" @click="clickGoMonitorAccount">管理监控平台账户 |
|||
<image src="../../static/images/refresh.png" mode=""></image> |
|||
</view> --> |
|||
</view> |
|||
|
|||
<view class="list-box"> |
|||
<form @submit="formSubmit" @reset="formReset"> |
|||
<view class="f-item"> |
|||
<text>所属平台</text> |
|||
<input name="platform" placeholder="请输入所属平台" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<view class="f-item"> |
|||
<text>名称</text> |
|||
<input name="name" placeholder="请输入名称" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<view class="f-item"> |
|||
<text>appKey</text> |
|||
<input name="appkey" placeholder="请输入appKey" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<view class="f-item"> |
|||
<text>Secret</text> |
|||
<input name="secret" placeholder="请输入Secret" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<button class="add-btn" form-type="submit" submit hover-class="btn-active" >保存</button> |
|||
<view class="l-edit"> |
|||
<view class="add-btn white-style">删除</view> |
|||
<view class="add-btn">保存</view> |
|||
</view> |
|||
</form> |
|||
</view> |
|||
|
|||
<view class="info-box"> |
|||
<view class="t1">上述信息,请前往萤石云开放平台注册并以下步骤获取。<text>https://open.ys7.com/</text> <text class="t-copy" |
|||
@click="copyInfo">复制地址</text></view> |
|||
<view class="t2">1、在控制台内-我的账户-应用信息里面创建应用获得appKey和Secret,并填入上方。</view> |
|||
<view class="t3">2、在我的资源-设备列表内添加您的设备(如有可忽略)。</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
|
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
}, |
|||
data() { |
|||
return { |
|||
update_time: new Date(), |
|||
accountList: false |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
console.log("opts:", opts); |
|||
this.mac = opts.mac; |
|||
this.updateList() |
|||
// try { |
|||
// util.showLoad(); |
|||
// let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
// await this.$store.dispatch('getStoreList'); |
|||
// util.hideLoad(); |
|||
// } catch (err) { |
|||
// util.hideLoad(); |
|||
// } |
|||
|
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
// curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// this.updateList() |
|||
// } |
|||
}, |
|||
methods: { |
|||
clickGoMonitorAccount() { |
|||
util.routeTo(`/subpackage/device/pages/monitor_manage/monitor_acount_list`, 'nT'); |
|||
}, |
|||
formSubmit: function(e) { |
|||
console.log('form发生了submit事件,携带数据为:' + JSON.stringify(e.detail.value)) |
|||
var formdata = e.detail.value |
|||
uni.showModal({ |
|||
content: '表单数据内容:' + JSON.stringify(formdata), |
|||
showCancel: false |
|||
}); |
|||
}, |
|||
formReset: function(e) { |
|||
console.log('清空数据') |
|||
}, |
|||
copyInfo() { |
|||
uni.setClipboardData({ |
|||
data: 'https://open.ys7.com/', |
|||
success: function() { |
|||
console.log('success'); |
|||
uni.showToast({ |
|||
title: "复制成功" |
|||
}) |
|||
} |
|||
}); |
|||
}, |
|||
reboot4G() { |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.reboot4G, |
|||
data: { |
|||
mac: this.mac |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
if (!this.mac) return |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.getLotDetail, |
|||
data: { |
|||
iccid: this.mac, |
|||
is_sync: 1 //是否同步,更新传1 |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
that.filterRouterData(res.data.data) |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
|
|||
}, |
|||
|
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.t-monitor-page { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: column; |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
@include centerFlex(space-between); |
|||
margin: 60rpx auto 0rpx 40rpx; |
|||
|
|||
.t-go-monitor { |
|||
padding-right: 48rpx; |
|||
@include centerFlex(center); |
|||
font-size: 32rpx; |
|||
// color: #009874; |
|||
color: #9C9C9F; |
|||
|
|||
image { |
|||
margin-top: 5rpx; |
|||
margin-left: 15rpx; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.list-box { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: column; |
|||
margin-top: 40rpx; |
|||
font-size: 32rpx; |
|||
color: #9C9C9F; |
|||
>image { |
|||
width: 380rpx; |
|||
height: 380rpx; |
|||
} |
|||
.f-item{ |
|||
margin-top: 20rpx; |
|||
width: 620rpx; |
|||
@include centerFlex(space-between); |
|||
> input{ |
|||
|
|||
width: 434rpx;height: 96rpx; |
|||
padding: 0 15rpx; |
|||
border: 1rpx solid #9C9C9F; |
|||
border-radius: 10rpx; |
|||
} |
|||
.i-class{ |
|||
color: #9C9C9F;font-size: 32rpx; |
|||
} |
|||
} |
|||
.l-edit{ |
|||
@include centerFlex(space-between); |
|||
> view{ |
|||
width: 224rpx;height: 112rpx; |
|||
} |
|||
.white-style{ |
|||
color: #EA5061; |
|||
background-color: white; |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
.t-update { |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
margin-top: 38rpx; |
|||
margin-left: 40rpx; |
|||
} |
|||
|
|||
.add-btn { |
|||
margin-top: 80rpx; |
|||
width: 500rpx; |
|||
height: 112rpx; |
|||
background: #009874; |
|||
color: white; |
|||
font-size: 32rpx; |
|||
border-radius: 10rpx; |
|||
@include centerFlex(center); |
|||
} |
|||
|
|||
.btn-active { |
|||
background: rgba($color: #000000, $alpha: .3); |
|||
} |
|||
|
|||
.info-box { |
|||
margin-top: 114rpx; |
|||
width: 636rpx; |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
|
|||
.t1 { |
|||
>text { |
|||
color: black; |
|||
} |
|||
|
|||
.t-copy { |
|||
color: #009874; |
|||
margin-left: 30rpx; |
|||
} |
|||
} |
|||
|
|||
.t2 { |
|||
margin-top: 60rpx; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,470 @@ |
|||
<template> |
|||
<view class="t-router-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title">物联卡管理 |
|||
<view class="t-reset" @click="updateList">更新 |
|||
<image src="../../static/images/refresh.png" mode=""></image> |
|||
</view> |
|||
</view> |
|||
<view class="t-update"> |
|||
更新时间: {{update_time}} |
|||
</view> |
|||
|
|||
<!-- <view class="t-map" v-if="covers.length>0"> |
|||
<map style="width: 100%; height: 250px;" :latitude="latitude" :longitude="longitude" :markers="covers"> |
|||
</map> |
|||
</view> --> |
|||
|
|||
<view class="t-box"> |
|||
<view class="info-list"> |
|||
<view class="i-item" v-for="(item,index) in infoObj"> |
|||
<view class="i-box">{{item.name}}</view> |
|||
<rich-text class="i-box" :nodes="item.value"></rich-text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
|
|||
// 参数参考: https://support.huaweicloud.com/api-ocgsl/gsl_07_0008.html |
|||
const infoObj = [ |
|||
{ |
|||
key:"act_date", |
|||
value:"", |
|||
name:"在线时间", |
|||
key2:"" |
|||
}, |
|||
{ |
|||
key:"order_id", |
|||
value:"", |
|||
name:"批次号", |
|||
key2:"" |
|||
}, |
|||
{ |
|||
key:"flow_left", |
|||
value:"", |
|||
name:"剩余流量(单位M)", |
|||
key2:"" |
|||
}, |
|||
|
|||
{ |
|||
key:"flow_used", |
|||
value:"", |
|||
name:"已用流量(单位M)", |
|||
key2:"" |
|||
},{ |
|||
key:"sim_type", |
|||
value:"", |
|||
name:"sim卡类型", |
|||
key2:"", //当key2,存在时,value为data[key][key2] |
|||
typeArr:[,"vSIM","eSIM","实体卡"], //当typeArr,value 存在时, value为typeArr[value] |
|||
},{ |
|||
key:"sim_status", |
|||
value:"", |
|||
name:"sim卡状态", |
|||
key2:"", //当key2,存在时,value为data[key][key2] |
|||
typeArr:{ |
|||
"11":"未激活", |
|||
"13":"可激活", |
|||
"14":"已停用", |
|||
"20":"在用" |
|||
}, //当typeArr,value 存在时, value为typeArr[value] |
|||
},{ |
|||
key:"signal_level", |
|||
value:"", |
|||
name:"信号等级", |
|||
key2:"", |
|||
typeArr:["未知","差","良","良","优"] |
|||
},{ |
|||
key:"price_plan_name", |
|||
value:"", |
|||
name:"在用套餐名", |
|||
key2:"", |
|||
},{ |
|||
key:"real_named", |
|||
value:"", |
|||
name:"是否已实名认证", |
|||
key2:"", |
|||
},{ |
|||
key:"sim_price_plan_id", |
|||
value:"", |
|||
name:"套餐订购实例ID", |
|||
key2:"", |
|||
},{ |
|||
key:"tag_names", |
|||
value:"", |
|||
name:"标签名", |
|||
key2:"", |
|||
},{ |
|||
key:"sim_card_id", |
|||
value:"", |
|||
name:"sim卡id", |
|||
key2:"" |
|||
},{ |
|||
key:"cid", |
|||
value:"", |
|||
name:"cid", |
|||
key2:"" |
|||
},{ |
|||
key:"imei", |
|||
value:"", |
|||
name:"imei", |
|||
key2:"" |
|||
},{ |
|||
key:"imsi", |
|||
value:"", |
|||
name:"imsi", |
|||
key2:"" |
|||
},{ |
|||
key:"iccid", |
|||
value:"", |
|||
name:"iccid", |
|||
key2:"" |
|||
},{ |
|||
key:"msisdn", |
|||
value:"", |
|||
name:"msisdn", |
|||
key2:"" |
|||
},{ |
|||
key:"network_type", |
|||
value:"", |
|||
name:"网络类型", |
|||
key2:"" |
|||
},{ |
|||
key:"node_id", |
|||
value:"", |
|||
name:"设备标识", |
|||
key2:"" |
|||
},{ |
|||
key:"operator_status", |
|||
value:"", |
|||
name:"运营商状态", |
|||
key2:"", |
|||
typeArr:["非停机","停机(超流量停机)" ,"停机(超流量阈值停机)" ,"停机(流量池停机)" ,"停机(套餐到期停机)","停机(主动停机)","停机(违规停机)"] |
|||
},{ |
|||
key:"device_status", |
|||
value:"", |
|||
name:"iccid", |
|||
key2:"", |
|||
typeArr:["未知", "注册", "重启", "在线", "离线"] |
|||
},{ |
|||
key:"cut_net_flag", |
|||
value:"", |
|||
name:"是否单独断网", |
|||
key2:"" |
|||
},{ |
|||
key:"exceed_cut_net_flag", |
|||
value:"", |
|||
name:"是否达量断网", |
|||
key2:"" |
|||
},{ |
|||
key:"exceed_cut_net_quota", |
|||
value:"", |
|||
name:"达量断网阈值(单位MB)", |
|||
key2:"" |
|||
},{ |
|||
key:"imei_bind_remain_times", |
|||
value:"", |
|||
name:"本月机卡绑定剩余次数", |
|||
key2:"" |
|||
},{ |
|||
key:"speed_value", |
|||
value:"", |
|||
name:"网络限制速率(单位Kbps)", |
|||
key2:"" |
|||
},{ |
|||
key:"exceed_cut_net_quota", |
|||
value:"", |
|||
name:"达量断网阈值(单位MB)", |
|||
key2:"" |
|||
},{ |
|||
key:"expire_time", |
|||
value:"", |
|||
name:"过期时间", |
|||
key2:"" |
|||
},{ |
|||
key:"dbm", |
|||
value:"", |
|||
name:"信号强度", |
|||
key2:"" |
|||
},{ |
|||
key:"device_model", |
|||
value:"", |
|||
name:"设备模组", |
|||
key2:"" |
|||
} |
|||
]; |
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
isDel() { |
|||
return (item) => { |
|||
return item[2] == "删除" ? "true" : "" |
|||
} |
|||
}, |
|||
|
|||
}, |
|||
data() { |
|||
return { |
|||
infoObj, |
|||
latitude: 23.2174411, |
|||
longitude: 113.3048267, |
|||
update_time:new Date(), |
|||
covers: [ |
|||
], |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
console.log("opts:",opts); |
|||
this.mac = opts.mac; |
|||
this.updateList() |
|||
// try { |
|||
// util.showLoad(); |
|||
// let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
// await this.$store.dispatch('getStoreList'); |
|||
// util.hideLoad(); |
|||
// } catch (err) { |
|||
// util.hideLoad(); |
|||
// } |
|||
|
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
// curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// this.updateList() |
|||
// } |
|||
}, |
|||
methods: { |
|||
clickReboot(){ |
|||
let that = this |
|||
uni.showModal({ |
|||
content: `更新信息 ?`, |
|||
success(res) { |
|||
console.log("确认", res.confirm) |
|||
if(res.confirm){ |
|||
that.reboot4G() |
|||
} |
|||
}, |
|||
}) |
|||
}, |
|||
reboot4G(){ |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.reboot4G, |
|||
data: { |
|||
mac:this.mac |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
if(!this.mac)return |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.getLotDetail, |
|||
data: { |
|||
iccid:this.mac, |
|||
is_sync:1 //是否同步,更新传1 |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
that.filterRouterData(res.data.data) |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
|
|||
}, |
|||
//过滤路由数据 |
|||
filterRouterData(data){ |
|||
console.log("filterRouterData:",data); |
|||
let obj = this.infoObj |
|||
for(var i in obj){ |
|||
let e = obj[i] |
|||
let res = data[e.key] |
|||
if(res==="undefined")res = "未知状态1" |
|||
if(res==="")res = "未知状态2" //写个未知状态({状态值}) 字段没有还是数值没有 |
|||
console.log(888888,res); |
|||
// if(res==="undefined"||res==="") continue |
|||
e.value = (typeof(res)=="object")?data[e.key][e.key2]:res; |
|||
e.value = e.value.toString(); |
|||
if(e.typeArr&&e.value)e.value = e.typeArr[e.value]; |
|||
if(e.value=== "false")e.value = "否"; |
|||
if(e.value=== "true")e.value = "是"; |
|||
// if(e.value===0)e.value = "0"; |
|||
console.log(e.value); |
|||
} |
|||
|
|||
this.update_time = obj[0].value; |
|||
}, |
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.t-router-page { |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
@include centerFlex(space-between); |
|||
margin: 60rpx auto 0rpx 40rpx; |
|||
.t-reset{ |
|||
padding-right: 48rpx; |
|||
@include centerFlex(center); |
|||
font-size: 32rpx; |
|||
color: #009874; |
|||
image{ |
|||
margin-top: 5rpx; |
|||
margin-left: 15rpx; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.t-update{ |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
margin-top: 38rpx; |
|||
margin-left: 40rpx; |
|||
} |
|||
.t-map{ |
|||
@include centerFlex(center); |
|||
width:700rpx; |
|||
// background-color: lightgray; |
|||
// height: 450rpx; |
|||
margin: 25rpx; |
|||
} |
|||
.t-box { |
|||
height: 500rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
width: 100%; |
|||
|
|||
.tab-list { |
|||
width: 100%; |
|||
padding-left: 30rpx; |
|||
@include centerFlex(flex-start); |
|||
flex-wrap: nowrap; |
|||
position: relative; |
|||
|
|||
.t-item { |
|||
margin-right: 50rpx; |
|||
padding: 10rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 900; |
|||
color: #9C9C9F; |
|||
line-height: 40rpx; |
|||
} |
|||
|
|||
.active { |
|||
color: #009874; |
|||
@include centerFlex(center); |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.active:after { |
|||
position: absolute; |
|||
content: ""; |
|||
background-color: #009874; |
|||
color: #009874; |
|||
width: auto; |
|||
display: block; |
|||
width: 30rpx; |
|||
text-align: center; |
|||
height: 6rpx; |
|||
border-radius: 3rpx; |
|||
top: 60rpx; |
|||
} |
|||
} |
|||
|
|||
.info-list { |
|||
margin-top: 30rpx; |
|||
margin-bottom: 50rpx; |
|||
width: 700rpx; |
|||
height: auto; |
|||
background: #FFFFFF; |
|||
border-radius: 10rpx; |
|||
font-size: 28rpx; |
|||
|
|||
.i-item { |
|||
@include centerFlex(flex-start); |
|||
|
|||
.i-box { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: row; |
|||
padding: 26rpx 20rpx; |
|||
height: 100%; |
|||
} |
|||
|
|||
.i-box:first-child { |
|||
@include centerFlex(center); |
|||
width: 300rpx; |
|||
text-align: center; |
|||
border-right: 1rpx solid #F2F2F7; |
|||
} |
|||
|
|||
.i-box:nth-child(2) { |
|||
width: 100%; |
|||
} |
|||
|
|||
} |
|||
|
|||
.i-item:not(:last-child) { |
|||
border-bottom: 1rpx solid #F2F2F7; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,427 @@ |
|||
<template> |
|||
<view class="t-router-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title">路由器管理 |
|||
<view class="t-reset" @click="clickReboot">重启 |
|||
<image src="../../static/images/refresh.png" mode=""></image> |
|||
</view> |
|||
</view> |
|||
<view class="t-update"> |
|||
更新时间: {{update_time}} |
|||
</view> |
|||
|
|||
<view class="t-map" v-if="covers.length>0"> |
|||
<map style="width: 100%; height: 250px;" :latitude="latitude" :longitude="longitude" :markers="covers"> |
|||
</map> |
|||
</view> |
|||
<view class="t-box" v-if="infoObj"> |
|||
<view class="info-list"> |
|||
<view class="i-item" v-for="(item,index) in infoObj"> |
|||
<view class="i-box">{{item.name}}</view> |
|||
<rich-text class="i-box" :nodes="item.value"></rich-text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
|
|||
const infoObj = [ |
|||
{ |
|||
key:"update_time", |
|||
value:"", |
|||
name:"在线时间", |
|||
key2:"" |
|||
},{ |
|||
key:"model", |
|||
value:"00-00-00", |
|||
name:"路由型号", |
|||
key2:"" |
|||
},{ |
|||
key:"mac", |
|||
value:"", |
|||
name:"MAC地址", |
|||
key2:"" |
|||
},{ |
|||
key:"firmware", |
|||
value:"", |
|||
name:"固件版本", |
|||
key2:"" |
|||
},{ |
|||
key:"imei", |
|||
value:"", |
|||
name:"imei", |
|||
key2:"" |
|||
},{ |
|||
key:"imsi", |
|||
value:"", |
|||
name:"imsi", |
|||
key2:"" |
|||
},{ |
|||
key:"iccid", |
|||
value:"", |
|||
name:"iccid", |
|||
key2:"" |
|||
},{ |
|||
key:"mncmcc", |
|||
value:"", |
|||
name:"国家代码", |
|||
key2:"" |
|||
},{ |
|||
key:"lac", |
|||
value:"", |
|||
name:"lac", |
|||
key2:"" |
|||
},{ |
|||
key:"cellid", |
|||
value:"", |
|||
name:"cellid", |
|||
key2:"" |
|||
},{ |
|||
key:"csq", |
|||
value:"", |
|||
name:"信号强度", |
|||
key2:"" |
|||
},{ |
|||
key:"lanip", |
|||
value:"", |
|||
name:"路由IP", |
|||
key2:"ipaddr" |
|||
},{ |
|||
key:"lanip", |
|||
value:"", |
|||
name:"掩码", |
|||
key2:"netmask" |
|||
},{ |
|||
key:"lanip", |
|||
value:"", |
|||
name:"网关", |
|||
key2:"gateway" |
|||
},{ |
|||
key:"lanip", |
|||
value:"", |
|||
name:"dns1", |
|||
key2:"" |
|||
},{ |
|||
key:"lanip", |
|||
value:"", |
|||
name:"dns2", |
|||
key2:"" |
|||
} |
|||
]; |
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
isDel() { |
|||
return (item) => { |
|||
return item[2] == "删除" ? "true" : "" |
|||
} |
|||
}, |
|||
|
|||
}, |
|||
data() { |
|||
return { |
|||
infoObj, |
|||
latitude: 23.2174411, |
|||
longitude: 113.3048267, |
|||
update_time:new Date(), |
|||
covers: [ |
|||
], |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
console.log("opts:",opts); |
|||
this.mac = opts.mac; |
|||
this.updateList() |
|||
// try { |
|||
// util.showLoad(); |
|||
// let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
// await this.$store.dispatch('getStoreList'); |
|||
// util.hideLoad(); |
|||
// } catch (err) { |
|||
// util.hideLoad(); |
|||
// } |
|||
|
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
// curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// this.updateList() |
|||
// } |
|||
}, |
|||
methods: { |
|||
clickReboot(){ |
|||
let that = this |
|||
uni.showModal({ |
|||
content: `确认要重启路由 ?`, |
|||
success(res) { |
|||
console.log("确认", res.confirm) |
|||
if(res.confirm){ |
|||
that.reboot4G() |
|||
} |
|||
}, |
|||
}) |
|||
}, |
|||
reboot4G(){ |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.reboot4G, |
|||
data: { |
|||
mac:this.mac |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
if(!this.mac)return |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.getRouterDetail, |
|||
data: { |
|||
mac:this.mac, |
|||
is_sync:0 |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
that.filterRouterData(res.data.data) |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
that.infoObj = "" |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
|
|||
}, |
|||
//过滤路由数据 |
|||
filterRouterData(data){ |
|||
console.log("filterRouterData:",data); |
|||
let obj = this.infoObj |
|||
for(var i in obj){ |
|||
let e = obj[i] |
|||
let res = data[e.key] |
|||
if(!res) continue |
|||
e.value = (typeof(res)=="object")?data[e.key][e.key2]:res; |
|||
} |
|||
if(data.clientiplist.length>0){ |
|||
data.clientiplist.forEach((e,i)=>{ |
|||
console.log(i,e); |
|||
obj.push({ |
|||
value:e[0], |
|||
name:`终端${i+1} IP` |
|||
}) |
|||
obj.push({ |
|||
value:e[1], |
|||
name:`终端${i+1} MAC` |
|||
}) |
|||
}) |
|||
} |
|||
this.update_time = obj[0].value; |
|||
//填充坐标点到地图 |
|||
let location_arr = data.position.location.split(",") |
|||
this.latitude = location_arr[1]; |
|||
this.longitude = location_arr[0]; |
|||
this.covers.push({ |
|||
latitude: location_arr[1], |
|||
longitude: location_arr[0], |
|||
width:40, |
|||
height:40, |
|||
iconPath: '../../static/images/devices/18.png' |
|||
}) |
|||
}, |
|||
|
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
// 操作接口请求 |
|||
operateReq({ |
|||
data, |
|||
succFun, |
|||
isTip = false, |
|||
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) { |
|||
if (isTip) util.showNone(res.data.message || '操作成功!'); |
|||
succFun(res.data.data) |
|||
} else { |
|||
if (isTip) util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
if (isLoad) util.hideLoad() |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.t-router-page { |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
@include centerFlex(space-between); |
|||
margin: 60rpx auto 0rpx 40rpx; |
|||
.t-reset{ |
|||
padding-right: 48rpx; |
|||
@include centerFlex(center); |
|||
font-size: 32rpx; |
|||
color: #009874; |
|||
image{ |
|||
margin-top: 5rpx; |
|||
margin-left: 15rpx; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.t-update{ |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
margin-top: 38rpx; |
|||
margin-left: 40rpx; |
|||
} |
|||
.t-map{ |
|||
@include centerFlex(center); |
|||
width:700rpx; |
|||
// background-color: lightgray; |
|||
// height: 450rpx; |
|||
margin: 25rpx; |
|||
} |
|||
.t-box { |
|||
height: 500rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
width: 100%; |
|||
|
|||
.tab-list { |
|||
width: 100%; |
|||
padding-left: 30rpx; |
|||
@include centerFlex(flex-start); |
|||
flex-wrap: nowrap; |
|||
position: relative; |
|||
|
|||
.t-item { |
|||
margin-right: 50rpx; |
|||
padding: 10rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 900; |
|||
color: #9C9C9F; |
|||
line-height: 40rpx; |
|||
} |
|||
|
|||
.active { |
|||
color: #009874; |
|||
@include centerFlex(center); |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.active:after { |
|||
position: absolute; |
|||
content: ""; |
|||
background-color: #009874; |
|||
color: #009874; |
|||
width: auto; |
|||
display: block; |
|||
width: 30rpx; |
|||
text-align: center; |
|||
height: 6rpx; |
|||
border-radius: 3rpx; |
|||
top: 60rpx; |
|||
} |
|||
} |
|||
|
|||
.info-list { |
|||
margin-top: 30rpx; |
|||
margin-bottom: 50rpx; |
|||
width: 700rpx; |
|||
height: auto; |
|||
background: #FFFFFF; |
|||
border-radius: 10rpx; |
|||
font-size: 28rpx; |
|||
|
|||
.i-item { |
|||
@include centerFlex(flex-start); |
|||
|
|||
.i-box { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: row; |
|||
padding: 26rpx 20rpx; |
|||
height: 100%; |
|||
} |
|||
|
|||
.i-box:first-child { |
|||
width: 250rpx; |
|||
text-align: center; |
|||
border-right: 1rpx solid #F2F2F7; |
|||
} |
|||
|
|||
.i-box:nth-child(2) { |
|||
width: 100%; |
|||
} |
|||
|
|||
} |
|||
|
|||
.i-item:not(:last-child) { |
|||
border-bottom: 1rpx solid #F2F2F7; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,404 @@ |
|||
<template> |
|||
<view class="t-monitor-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title" @tap="tap">1号窗帘 |
|||
<!-- <view class="t-go-monitor" @click="clickGoMonitorAccount">管理平台账户 |
|||
<image src="../../static/images/refresh.png" mode=""></image> |
|||
</view> --> |
|||
</view> |
|||
|
|||
<view class="image-box"> |
|||
<image src="../../static/images/windows.png" mode=""></image> |
|||
<!-- 窗帘从左到右开关 --> |
|||
<!-- <view class="box-one"> |
|||
<view class="slice-box" > |
|||
<view class="slice-item" v-for="i in sliceLength"></view> |
|||
</view> |
|||
</view> --> |
|||
<!-- 窗帘从两边到中间开关 --> |
|||
<view class="box-two"> |
|||
<view class="slice-box-left" > |
|||
<view class="slice-item" v-for="i in sliceLength"></view> |
|||
</view> |
|||
<view class="slice-box-right" > |
|||
<view class="slice-item" v-for="i in sliceLength"></view> |
|||
</view> |
|||
</view> |
|||
<!-- 触摸窗帘开关 --> |
|||
<!-- <movable-area class="box"> |
|||
<movable-view class="max" :x="x" :y="y" @change="onChange" |
|||
direction="horizontal" inertia> |
|||
</movable-view> |
|||
</movable-area> --> |
|||
</view> |
|||
|
|||
<view class="slider-box"> |
|||
<text>目前状态{{sliderLevel}}%</text> |
|||
<slider :value="sliderLevel" 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="list-box"> |
|||
<view class="l-item" @click="handleClose"> |
|||
<image src="../../static/images/sunblind_close.png" mode=""></image> |
|||
<text>关闭</text> |
|||
</view> |
|||
<view class="l-item"> |
|||
<image src="../../static/images/close.png" mode=""></image> |
|||
<text>暂停</text> |
|||
</view> |
|||
<view class="l-item" @click="handleOpen"> |
|||
<image src="../../static/images/sunblind_open.png" mode=""></image> |
|||
<text>开启</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- <view class="info-box"> |
|||
<view class="t1">上述信息,请前往萤石云开放平台注册并以下步骤获取。<text>https://open.ys7.com/</text> <text class="t-copy" |
|||
@click="copyInfo">复制地址</text></view> |
|||
<view class="t2">1、在控制台内-我的账户-应用信息里面创建应用获得appKey和Secret,并填入上方。</view> |
|||
<view class="t3">2、在我的资源-设备列表内添加您的设备(如有可忽略)。</view> |
|||
</view> --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
|
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
}, |
|||
data() { |
|||
return { |
|||
update_time: new Date(), |
|||
accountList: false, |
|||
sliderLevel:10,//测试回显给10 |
|||
sliceLength:0, |
|||
boxOne:false, //窗帘关闭方式 true: 从左到右, false:从两边到中间 |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
console.log("opts:", opts); |
|||
this.mac = opts.mac; |
|||
this.updateList() |
|||
this.setSliceLength(this.sliderLevel) |
|||
// try { |
|||
// util.showLoad(); |
|||
// let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
// await this.$store.dispatch('getStoreList'); |
|||
// util.hideLoad(); |
|||
// } catch (err) { |
|||
// util.hideLoad(); |
|||
// } |
|||
|
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
const sysInfo = uni.getSystemInfoSync(); |
|||
this.pixelRatio = sysInfo.pixelRatio |
|||
console.log(sysInfo.pixelRatio); |
|||
}, |
|||
watch: { |
|||
// curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// this.updateList() |
|||
// } |
|||
}, |
|||
methods: { |
|||
//滑动更改窗帘状态 |
|||
sliderChange(e) { |
|||
console.log('value 发生变化:' + e.detail.value) |
|||
this.setSliceLength(e.detail.value) |
|||
// this.sliceBoxW = this.sliceLength*30 |
|||
return |
|||
let _data = { |
|||
"device": this.curStoreInfo.device_name, |
|||
"data": { |
|||
"name": "audio-player-volume", |
|||
"value": { |
|||
"volume": e.detail.value.toString() |
|||
} |
|||
}, |
|||
} |
|||
//发送命令到中控 |
|||
this.operateReq({ |
|||
data: _data, |
|||
isTip: true |
|||
}) |
|||
}, |
|||
handleClose(){ |
|||
let val = this.sliderLevel>95 ? 100 : this.sliderLevel+5 |
|||
this.setSliceLength(val) |
|||
}, |
|||
handleOpen(){ |
|||
|
|||
let val = this.sliderLevel<5 ? 0 : this.sliderLevel-5 |
|||
this.setSliceLength(val) |
|||
}, |
|||
setSliceLength(value){ |
|||
// this.level = value |
|||
this.sliderLevel = value |
|||
this.sliceLength = Math.floor(value/(this.boxOne?5:10)) |
|||
}, |
|||
clickGoMonitorAccount() { |
|||
util.routeTo(`/subpackage/device/pages/monitor_manage/monitor_acount_list`, 'nT'); |
|||
}, |
|||
formSubmit: function(e) { |
|||
console.log('form发生了submit事件,携带数据为:' + JSON.stringify(e.detail.value)) |
|||
var formdata = e.detail.value |
|||
uni.showModal({ |
|||
content: '表单数据内容:' + JSON.stringify(formdata), |
|||
showCancel: false |
|||
}); |
|||
}, |
|||
formReset: function(e) { |
|||
console.log('清空数据') |
|||
}, |
|||
copyInfo() { |
|||
uni.setClipboardData({ |
|||
data: 'https://open.ys7.com/', |
|||
success: function() { |
|||
console.log('success'); |
|||
uni.showToast({ |
|||
title: "复制成功" |
|||
}) |
|||
} |
|||
}); |
|||
}, |
|||
reboot4G() { |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.reboot4G, |
|||
data: { |
|||
mac: this.mac |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
if (!this.mac) return |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.getLotDetail, |
|||
data: { |
|||
iccid: this.mac, |
|||
is_sync: 1 //是否同步,更新传1 |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
that.filterRouterData(res.data.data) |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
|
|||
}, |
|||
|
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.slider-box { |
|||
// @include centerFlex(center); |
|||
// flex-direction: column; |
|||
width: 630rpx; |
|||
margin-top: 40rpx; |
|||
>text { |
|||
font-size: 32rpx; |
|||
color: #1A1A1A; |
|||
width: 100%; |
|||
@include centerFlex(center); |
|||
} |
|||
|
|||
>view { |
|||
width: 100%; |
|||
color: #9C9C9F; |
|||
font-size: 28rpx; |
|||
@include centerFlex(space-between); |
|||
padding: 0 34rpx; |
|||
} |
|||
} |
|||
|
|||
.t-monitor-page { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: column; |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
@include centerFlex(space-between); |
|||
margin: 60rpx auto 0rpx 40rpx; |
|||
.t-go-monitor { |
|||
padding-right: 48rpx; |
|||
@include centerFlex(center); |
|||
font-size: 32rpx; |
|||
color: #9C9C9F; |
|||
image { |
|||
margin-top: 5rpx; |
|||
margin-left: 15rpx; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.image-box { |
|||
margin-top: 40rpx; |
|||
|
|||
image { |
|||
width: 690rpx; |
|||
height: 570rpx; |
|||
position: absolute; |
|||
left: 30rpx; |
|||
z-index: -1; |
|||
} |
|||
|
|||
.box-one { |
|||
width: 590rpx; |
|||
height: 570rpx; |
|||
margin-top: 10rpx; |
|||
z-index: 1; |
|||
@include centerFlex(flex-start); |
|||
.slice-box{ |
|||
@include centerFlex(flex-start); |
|||
background-color: lightgray; |
|||
height: 570rpx; |
|||
} |
|||
|
|||
} |
|||
.box-two{ |
|||
width: 560rpx; |
|||
height: 570rpx; |
|||
margin-top: 10rpx; |
|||
z-index: 1; |
|||
@include centerFlex(space-between); |
|||
.slice-box-left{ |
|||
@include centerFlex(flex-start); |
|||
background-color: lightgray; |
|||
height: 570rpx; |
|||
} |
|||
.slice-box-right{ |
|||
@include centerFlex(flex-end); |
|||
background-color: lightgray; |
|||
height: 570rpx; |
|||
|
|||
} |
|||
} |
|||
//窗帘切片 |
|||
.slice-item{ |
|||
flex-grow: 1; |
|||
width: 30rpx; |
|||
height: 570rpx; |
|||
background-color: white; |
|||
border: 1rpx solid #919191; |
|||
border-radius: 5rpx; |
|||
} |
|||
} |
|||
|
|||
.list-box { |
|||
width: 540rpx; |
|||
@include centerFlex(space-between); |
|||
margin-top: 40rpx; |
|||
font-size: 32rpx; |
|||
color: #9C9C9F; |
|||
|
|||
>view { |
|||
@include centerFlex(center); |
|||
flex-direction: column; |
|||
|
|||
>image { |
|||
width: 100rpx; |
|||
height: 100rpx; |
|||
} |
|||
|
|||
>text { |
|||
margin-top: 20rpx; |
|||
font-size: 24rpx; |
|||
color: #9A9A9D; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.add-btn { |
|||
margin-top: 80rpx; |
|||
width: 500rpx; |
|||
height: 112rpx; |
|||
background: #009874; |
|||
color: white; |
|||
font-size: 32rpx; |
|||
border-radius: 10rpx; |
|||
@include centerFlex(center); |
|||
} |
|||
|
|||
.btn-active { |
|||
background: rgba($color: #000000, $alpha: .3); |
|||
} |
|||
.info-box { |
|||
margin-top: 114rpx; |
|||
width: 636rpx; |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
.t1 { |
|||
>text { |
|||
color: black; |
|||
} |
|||
.t-copy { |
|||
color: #009874; |
|||
margin-left: 30rpx; |
|||
} |
|||
} |
|||
.t2 { |
|||
margin-top: 60rpx; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,292 @@ |
|||
<template> |
|||
<view class="t-monitor-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title">管理监控平台账户 |
|||
<!-- <view class="t-go-monitor" @click="clickGoMonitorAccount">管理监控平台账户 |
|||
<image src="../../static/images/refresh.png" mode=""></image> |
|||
</view> --> |
|||
</view> |
|||
|
|||
<view class="list-box"> |
|||
<form @submit="formSubmit" @reset="formReset"> |
|||
<view class="f-item"> |
|||
<text>所属平台</text> |
|||
<input name="platform" placeholder="请输入所属平台" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<view class="f-item"> |
|||
<text>名称</text> |
|||
<input name="name" placeholder="请输入名称" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<view class="f-item"> |
|||
<text>appKey</text> |
|||
<input name="appkey" placeholder="请输入appKey" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<view class="f-item"> |
|||
<text>Secret</text> |
|||
<input name="secret" placeholder="请输入Secret" placeholder-class="i-class" type="text" value="" /> |
|||
</view> |
|||
<button class="add-btn" form-type="submit" submit hover-class="btn-active" >保存</button> |
|||
<view class="l-edit"> |
|||
<view class="add-btn white-style">删除</view> |
|||
<view class="add-btn">保存</view> |
|||
</view> |
|||
</form> |
|||
</view> |
|||
|
|||
<view class="info-box"> |
|||
<view class="t1">上述信息,请前往萤石云开放平台注册并以下步骤获取。<text>https://open.ys7.com/</text> <text class="t-copy" |
|||
@click="copyInfo">复制地址</text></view> |
|||
<view class="t2">1、在控制台内-我的账户-应用信息里面创建应用获得appKey和Secret,并填入上方。</view> |
|||
<view class="t3">2、在我的资源-设备列表内添加您的设备(如有可忽略)。</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
|
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
}, |
|||
data() { |
|||
return { |
|||
update_time: new Date(), |
|||
accountList: false |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
console.log("opts:", opts); |
|||
this.mac = opts.mac; |
|||
this.updateList() |
|||
// try { |
|||
// util.showLoad(); |
|||
// let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
// await this.$store.dispatch('getStoreList'); |
|||
// util.hideLoad(); |
|||
// } catch (err) { |
|||
// util.hideLoad(); |
|||
// } |
|||
|
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
// curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// this.updateList() |
|||
// } |
|||
}, |
|||
methods: { |
|||
clickGoMonitorAccount() { |
|||
util.routeTo(`/subpackage/device/pages/monitor_manage/monitor_acount_list`, 'nT'); |
|||
}, |
|||
formSubmit: function(e) { |
|||
console.log('form发生了submit事件,携带数据为:' + JSON.stringify(e.detail.value)) |
|||
var formdata = e.detail.value |
|||
uni.showModal({ |
|||
content: '表单数据内容:' + JSON.stringify(formdata), |
|||
showCancel: false |
|||
}); |
|||
}, |
|||
formReset: function(e) { |
|||
console.log('清空数据') |
|||
}, |
|||
copyInfo() { |
|||
uni.setClipboardData({ |
|||
data: 'https://open.ys7.com/', |
|||
success: function() { |
|||
console.log('success'); |
|||
uni.showToast({ |
|||
title: "复制成功" |
|||
}) |
|||
} |
|||
}); |
|||
}, |
|||
reboot4G() { |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.reboot4G, |
|||
data: { |
|||
mac: this.mac |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
if (!this.mac) return |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.getLotDetail, |
|||
data: { |
|||
iccid: this.mac, |
|||
is_sync: 1 //是否同步,更新传1 |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
that.filterRouterData(res.data.data) |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
|
|||
}, |
|||
|
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.t-monitor-page { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: column; |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
@include centerFlex(space-between); |
|||
margin: 60rpx auto 0rpx 40rpx; |
|||
|
|||
.t-go-monitor { |
|||
padding-right: 48rpx; |
|||
@include centerFlex(center); |
|||
font-size: 32rpx; |
|||
// color: #009874; |
|||
color: #9C9C9F; |
|||
|
|||
image { |
|||
margin-top: 5rpx; |
|||
margin-left: 15rpx; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.list-box { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: column; |
|||
margin-top: 40rpx; |
|||
font-size: 32rpx; |
|||
color: #9C9C9F; |
|||
>image { |
|||
width: 380rpx; |
|||
height: 380rpx; |
|||
} |
|||
.f-item{ |
|||
margin-top: 20rpx; |
|||
width: 620rpx; |
|||
@include centerFlex(space-between); |
|||
> input{ |
|||
|
|||
width: 434rpx;height: 96rpx; |
|||
padding: 0 15rpx; |
|||
border: 1rpx solid #9C9C9F; |
|||
border-radius: 10rpx; |
|||
} |
|||
.i-class{ |
|||
color: #9C9C9F;font-size: 32rpx; |
|||
} |
|||
} |
|||
.l-edit{ |
|||
@include centerFlex(space-between); |
|||
> view{ |
|||
width: 224rpx;height: 112rpx; |
|||
} |
|||
.white-style{ |
|||
color: #EA5061; |
|||
background-color: white; |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
.t-update { |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
margin-top: 38rpx; |
|||
margin-left: 40rpx; |
|||
} |
|||
|
|||
.add-btn { |
|||
margin-top: 80rpx; |
|||
width: 500rpx; |
|||
height: 112rpx; |
|||
background: #009874; |
|||
color: white; |
|||
font-size: 32rpx; |
|||
border-radius: 10rpx; |
|||
@include centerFlex(center); |
|||
} |
|||
|
|||
.btn-active { |
|||
background: rgba($color: #000000, $alpha: .3); |
|||
} |
|||
|
|||
.info-box { |
|||
margin-top: 114rpx; |
|||
width: 636rpx; |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
|
|||
.t1 { |
|||
>text { |
|||
color: black; |
|||
} |
|||
|
|||
.t-copy { |
|||
color: #009874; |
|||
margin-left: 30rpx; |
|||
} |
|||
} |
|||
|
|||
.t2 { |
|||
margin-top: 60rpx; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,245 @@ |
|||
<template> |
|||
<view class="t-monitor-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title">管理监控平台账户 |
|||
<!-- <view class="t-go-monitor" @click="clickGoMonitorAccount">管理监控平台账户 |
|||
<image src="../../static/images/refresh.png" mode=""></image> |
|||
</view> --> |
|||
</view> |
|||
|
|||
<view class="list-box"> |
|||
<image src="../../static/images/no-info.png" mode="" v-if="!accountList"></image> |
|||
<view class="l-item" v-for=" i in 2" v-else> |
|||
<image src="" mode=""></image> |
|||
<text>店铺名称name</text> |
|||
<view class="opt-box"> |
|||
<view class="o-item"> |
|||
<text @click="addAccount">编辑</text><image src="../../static/images/order/tab_0_8.png" mode=""></image> |
|||
</view> |
|||
<view class="o-item"> |
|||
<text>同步设备</text><image src="../../static/images/order/tab_0_8.png" mode=""></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="add-btn" hover-class="btn-active" @click="accountList = !accountList">添加账户</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
|
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
}, |
|||
data() { |
|||
return { |
|||
update_time: new Date(), |
|||
accountList:false |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
console.log("opts:", opts); |
|||
this.mac = opts.mac; |
|||
this.updateList() |
|||
// try { |
|||
// util.showLoad(); |
|||
// let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
// await this.$store.dispatch('getStoreList'); |
|||
// util.hideLoad(); |
|||
// } catch (err) { |
|||
// util.hideLoad(); |
|||
// } |
|||
|
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
// curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// this.updateList() |
|||
// } |
|||
}, |
|||
methods: { |
|||
clickGoMonitorAccount() { |
|||
util.routeTo(`/subpackage/device/pages/monitor_manage/monitor_acount_list`, 'nT'); |
|||
}, |
|||
statechange(e) { |
|||
console.log('live-player code:', e.detail.code) |
|||
}, |
|||
error(e) { |
|||
console.error('live-player error:', e.detail.errMsg) |
|||
}, |
|||
addAccount(){ |
|||
util.routeTo(`/subpackage/device/pages/monitor_manage/monitor_acount_add`,'nT') |
|||
}, |
|||
reboot4G() { |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.reboot4G, |
|||
data: { |
|||
mac: this.mac |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
if (!this.mac) return |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.getLotDetail, |
|||
data: { |
|||
iccid: this.mac, |
|||
is_sync: 1 //是否同步,更新传1 |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
that.filterRouterData(res.data.data) |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
|
|||
}, |
|||
|
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.t-monitor-page { |
|||
@include centerFlex(flex-start); |
|||
flex-direction: column; |
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
@include centerFlex(space-between); |
|||
margin: 60rpx auto 0rpx 40rpx; |
|||
|
|||
.t-go-monitor { |
|||
padding-right: 48rpx; |
|||
@include centerFlex(center); |
|||
font-size: 32rpx; |
|||
// color: #009874; |
|||
color: #9C9C9F; |
|||
|
|||
image { |
|||
margin-top: 5rpx; |
|||
margin-left: 15rpx; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.list-box{ |
|||
@include centerFlex(flex-start); |
|||
flex-direction: column; |
|||
margin-top: 40rpx; |
|||
> image{ |
|||
width: 380rpx; |
|||
height: 380rpx; |
|||
} |
|||
.l-item{ |
|||
margin-bottom: 30rpx; |
|||
padding: 20rpx; |
|||
background: white; |
|||
border-radius: 10rpx; |
|||
width: 670rpx;height: 170rpx; |
|||
font-size: 32rpx; |
|||
color: #333333; |
|||
@include centerFlex(flex-start); |
|||
> image{ |
|||
width: 108rpx;height: 108rpx; |
|||
background-color: lightgray; |
|||
margin-right: 20rpx; |
|||
} |
|||
.opt-box{ |
|||
position: absolute; |
|||
right: 65rpx; |
|||
.o-item{ |
|||
height: 60rpx; |
|||
@include centerFlex(flex-end); |
|||
> text{ |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
} |
|||
> image{ |
|||
width: 36rpx;height: 36rpx; |
|||
margin-left: 10rpx; |
|||
background-color: lightgray; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
.t-update { |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
margin-top: 38rpx; |
|||
margin-left: 40rpx; |
|||
} |
|||
|
|||
.add-btn{ |
|||
margin-top: 80rpx; |
|||
width: 670rpx; |
|||
height: 112rpx; |
|||
background: #009874; |
|||
color: white; |
|||
font-size: 32rpx; |
|||
border-radius: 10rpx; |
|||
@include centerFlex(center); |
|||
} |
|||
.btn-active{ |
|||
background:rgba($color: #000000, $alpha: .3); |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,178 @@ |
|||
<template> |
|||
<view class="t-monitor-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title">监控管理 |
|||
<view class="t-go-monitor" @click="clickGoMonitorAccount">管理监控平台账户 |
|||
<!-- <image src="../../static/images/refresh.png" mode=""></image> --> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="live-box"> |
|||
<live-player src="https://domain/pull_stream" autoplay @statechange="statechange" @error="error" |
|||
style="width: 300px; height: 225px;" /> |
|||
</view> |
|||
<!-- <view class="t-update"> |
|||
更新时间: {{update_time}} |
|||
</view> |
|||
--> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
|
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
}, |
|||
data() { |
|||
return { |
|||
update_time: new Date(), |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
console.log("opts:", opts); |
|||
this.mac = opts.mac; |
|||
this.updateList() |
|||
// try { |
|||
// util.showLoad(); |
|||
// let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
// await this.$store.dispatch('getStoreList'); |
|||
// util.hideLoad(); |
|||
// } catch (err) { |
|||
// util.hideLoad(); |
|||
// } |
|||
|
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
// curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// this.updateList() |
|||
// } |
|||
}, |
|||
methods: { |
|||
clickGoMonitorAccount() { |
|||
util.routeTo(`/subpackage/device/pages/monitor_manage/monitor_acount_list`, 'nT'); |
|||
}, |
|||
statechange(e) { |
|||
console.log('live-player code:', e.detail.code) |
|||
}, |
|||
error(e) { |
|||
console.error('live-player error:', e.detail.errMsg) |
|||
}, |
|||
reboot4G() { |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.reboot4G, |
|||
data: { |
|||
mac: this.mac |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
util.showNone(res.data.message || '操作成功!'); |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
if (!this.mac) return |
|||
util.showLoad(); |
|||
deviceServer.post({ |
|||
url: deviceApi.getLotDetail, |
|||
data: { |
|||
iccid: this.mac, |
|||
is_sync: 1 //是否同步,更新传1 |
|||
}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
util.hideLoad(); |
|||
if (res.data.code == 0) { |
|||
that.filterRouterData(res.data.data) |
|||
} else { |
|||
util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
util.hideLoad() |
|||
}) |
|||
|
|||
}, |
|||
|
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.t-monitor-page { |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
@include centerFlex(space-between); |
|||
margin: 60rpx auto 0rpx 40rpx; |
|||
|
|||
.t-go-monitor { |
|||
padding-right: 48rpx; |
|||
@include centerFlex(center); |
|||
font-size: 32rpx; |
|||
// color: #009874; |
|||
color: #9C9C9F; |
|||
|
|||
image { |
|||
margin-top: 5rpx; |
|||
margin-left: 15rpx; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.live-box{ |
|||
@include centerFlex(center); |
|||
margin-top: 40rpx; |
|||
} |
|||
.t-update { |
|||
font-size: 28rpx; |
|||
color: #9C9C9F; |
|||
margin-top: 38rpx; |
|||
margin-left: 40rpx; |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,336 @@ |
|||
<template> |
|||
<view class="timing-page"> |
|||
<store-name></store-name> |
|||
<view class="t-title">定时列表</view> |
|||
<view class="t-box"> |
|||
<!-- <view class="tab-list"> |
|||
<view class="t-item " :class="e.on?'active':''" v-for="(e,i) in tabArr" @click="clickTab(i)"> |
|||
{{e.name}} |
|||
</view> |
|||
</view> --> |
|||
<view class="info-list"> |
|||
<view class="i-item" v-for="(item,index) in infoArr"> |
|||
<view class="i-box">{{item[0]}}</view> |
|||
<rich-text class="i-box" :nodes="item[1]"></rich-text> |
|||
<!-- {{item[1]}} --> |
|||
<view class="i-box" v-if="isDel(item)" @click="delItem(item,index)" style="color: red;">{{item[2]}}</view> |
|||
<view class="i-box" v-else>{{item[2]}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
const tabArr = [{ |
|||
id: 0, |
|||
name: '全部', |
|||
path: ``, |
|||
on: true |
|||
}, |
|||
// { |
|||
// id: 1, |
|||
// name: '照明', |
|||
// path: ``, |
|||
// on: false |
|||
// }, |
|||
// { |
|||
// id: 2, |
|||
// name: '风扇', |
|||
// path: ``, |
|||
// on: false |
|||
// }, |
|||
// { |
|||
// id: 3, |
|||
// name: '水阀', |
|||
// path: ``, |
|||
// on: false |
|||
// }, |
|||
]; |
|||
const infoArr = [ |
|||
["标题", "时间", "操作"], |
|||
// ["2号场", "每个星期的 周日6:00 执行 开启 操作", "删除"], |
|||
]; |
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
isDel() { |
|||
return (item) => { |
|||
return item[2] == "删除" ? "true" : "" |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
tabArr, |
|||
infoArr, |
|||
} |
|||
}, |
|||
async onLoad(opts) { |
|||
|
|||
try { |
|||
util.showLoad(); |
|||
let _brandInfo = await this.$store.dispatch('getBrandInfo'); |
|||
await this.$store.dispatch('getStoreList'); |
|||
util.hideLoad(); |
|||
} catch (err) { |
|||
util.hideLoad(); |
|||
} |
|||
|
|||
}, |
|||
onShow() { |
|||
this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
curStoreInfo(newVal, oldVal){ |
|||
this.infoArr.length = 1 |
|||
this.updateList() |
|||
} |
|||
}, |
|||
methods: { |
|||
clickTab(i) { |
|||
this.tabArr.forEach((item) => { |
|||
item.on = false |
|||
}) |
|||
this.tabArr[i].on = true |
|||
}, |
|||
//删除计划任务 |
|||
delItem(e,i) { |
|||
let that = this |
|||
let delData = { |
|||
"device": this.curStoreInfo.device_name, |
|||
"delay": 1, |
|||
"data": { |
|||
"name": "delete-time-select", |
|||
"value": { |
|||
"uuid": e[3] |
|||
} |
|||
} |
|||
} |
|||
uni.showModal({ |
|||
content: `确认要删除: ${e[0]}的计划任务 ?`, |
|||
success(res) { |
|||
console.log("确认删除", res.confirm) |
|||
if(res.confirm){ |
|||
that.operateReq({ |
|||
data: delData, |
|||
succFun: (res) => { |
|||
that.updateList() |
|||
}, |
|||
isTip:true |
|||
}) |
|||
} |
|||
}, |
|||
}) |
|||
}, |
|||
async updateList() { |
|||
let that = this |
|||
let timingData = { |
|||
"device": this.curStoreInfo.device_name, |
|||
"data": { |
|||
"name": "get-time-select", |
|||
"value": {} |
|||
} |
|||
} |
|||
|
|||
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 = `每个星期的 <strong>[${arr} ]</strong> ` |
|||
} |
|||
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] + '号 '; |
|||
} |
|||
timeText = `每个月的 <strong>[ ${arr} ]</strong> ` |
|||
} |
|||
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 += ` 当天<strong>${row.times_on_day[0].substring(0, 5)}</strong>` |
|||
} |
|||
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' ? '<strong style="color:gray;">[关闭]</strong>' : '<strong style="color:#009874;">[开启]</strong>'} 操作`) |
|||
}) |
|||
|
|||
}, |
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
// 操作接口请求 |
|||
operateReq({ |
|||
data, |
|||
succFun, |
|||
isTip = false, |
|||
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) { |
|||
if (isTip) util.showNone(res.data.message || '操作成功!'); |
|||
succFun(res.data.data) |
|||
} else { |
|||
if (isTip) util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
if (isLoad) util.hideLoad() |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.timing-page { |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
margin: 40rpx auto 10rpx 40rpx; |
|||
} |
|||
|
|||
.t-box { |
|||
height: 500rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
width: 100%; |
|||
|
|||
.tab-list { |
|||
width: 100%; |
|||
padding-left: 30rpx; |
|||
@include centerFlex(flex-start); |
|||
flex-wrap: nowrap; |
|||
position: relative; |
|||
|
|||
.t-item { |
|||
margin-right: 50rpx; |
|||
padding: 10rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 900; |
|||
color: #9C9C9F; |
|||
line-height: 40rpx; |
|||
} |
|||
|
|||
.active { |
|||
color: #009874; |
|||
@include centerFlex(center); |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.active:after { |
|||
position: absolute; |
|||
content: ""; |
|||
background-color: #009874; |
|||
color: #009874; |
|||
width: auto; |
|||
display: block; |
|||
width: 30rpx; |
|||
text-align: center; |
|||
height: 6rpx; |
|||
border-radius: 3rpx; |
|||
margin-top: 40rpx; |
|||
// top: 60rpx; |
|||
} |
|||
} |
|||
|
|||
.info-list { |
|||
margin-top: 30rpx; |
|||
margin-bottom: 50rpx; |
|||
width: 700rpx; |
|||
height: auto; |
|||
background: #FFFFFF; |
|||
border-radius: 10rpx; |
|||
font-size: 28rpx; |
|||
|
|||
.i-item { |
|||
@include centerFlex(space-between); |
|||
|
|||
.i-box { |
|||
@include centerFlex(center); |
|||
flex-direction: row; |
|||
padding: 26rpx 10rpx; |
|||
height: 100%; |
|||
} |
|||
|
|||
.i-box:first-child { |
|||
// width: 176rpx; |
|||
width: 300rpx; |
|||
} |
|||
|
|||
.i-box:nth-child(2) { |
|||
width: 100%; |
|||
height: 100%; |
|||
border: 1rpx solid #F2F2F7; |
|||
border-bottom: none; |
|||
border-top: none; |
|||
} |
|||
|
|||
.i-box:last-child { |
|||
width: 144rpx; |
|||
} |
|||
} |
|||
|
|||
.i-item:not(:last-child) { |
|||
border-bottom: 1rpx solid #F2F2F7; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,701 @@ |
|||
<template> |
|||
<view class="timing-page"> |
|||
<!-- <store-name></store-name> --> |
|||
<view class="t-title">{{switchInfo.hardware_name}}定时</view> |
|||
<view class="t-box"> |
|||
|
|||
<view class="info-list"> |
|||
<view class="il-switch"> |
|||
<text class="">时间动作</text> |
|||
<view class="" @click="tapSwitch">开 |
|||
<view class="un-select" v-if="!on"></view> |
|||
<image v-else class="" src="../../../../static/images/icon/retail/choose.png" mode=""></image> |
|||
</view> |
|||
<view class="" @click="tapSwitch">关 |
|||
<view class="un-select" v-if="on"></view> |
|||
<image v-else src="../../../../static/images/icon/retail/choose.png" mode=""></image> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="il-select"> |
|||
<text class="">时间类型</text> |
|||
<picker @change="bindPickerChangeSingle" :value="sIndex" :range="singleArr"> |
|||
<view class="il-input"> |
|||
<text>{{singleArr[sIndex]}}</text><image src="../../../../static/images/icon/arrow_b2.png" mode=""></image> |
|||
</view> |
|||
</picker> |
|||
</view> |
|||
<view class="il-select-week" v-if="sIndex==0"> |
|||
<block v-for="(e,i) in weekArrSelect" :key="i"> |
|||
<view class="" :class="e?'active':''" @click="clickWeekTab(i)">星期{{weekArrCN[i]}}</view> |
|||
</block> |
|||
</view> |
|||
|
|||
<block v-if="sIndex==1"> |
|||
<view class="il-select" > |
|||
<text class="">具体日期</text> |
|||
<!-- <picker @change="bindPickerChangeDay" :value="dIndex" :range="dayArr"> --> |
|||
<view class="il-input" @click="padConfig.show = true"> |
|||
<text>请点击选择</text><image src="../../../../static/images/icon/arrow_b2.png" mode=""></image> |
|||
</view> |
|||
<!-- </picker> --> |
|||
</view> |
|||
<view class="il-select-week"> |
|||
<block v-for="(e,i) in dayArrSelect" :key="i"> |
|||
<view v-if="e" class="" :class="e?'active':''" @click="">{{i+1}} 号</view> |
|||
</block> |
|||
</view> |
|||
</block> |
|||
|
|||
<view class="il-select-double" v-if="sIndex==2"> |
|||
<text class="">具体时间段</text> |
|||
<view class="il-input"> |
|||
<picker mode="date" :value="startTime" :start="startDate" :end="endDate" @change="bindTimeChangeStart"> |
|||
<text>{{startTime?startTime+'起':'请选择开始时间'}}</text> |
|||
</picker> |
|||
<view class="">至</view> |
|||
<picker mode="date" :value="endTime" :start="startDate" :end="endDate" @change="bindTimeChangeEnd"> |
|||
<text>{{endTime?endTime+"止":"请选择结束时间"}}</text> |
|||
</picker> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="il-select"> |
|||
<text class="">时间点</text> |
|||
<picker mode="time" :value="time" start="09:01" end="21:01" @change="bindTimeChange"> |
|||
<view class="il-input"> |
|||
<text>{{time}}</text><image src="../../../../static/images/icon/arrow_b2.png" mode=""></image> |
|||
</view> |
|||
</picker> |
|||
</view> |
|||
|
|||
</view> |
|||
|
|||
<view class="save-btn" @click="saveAdd">保存</view> |
|||
<view class="bottom-tips">保存后发布后将会以最新的定时更新到欧轩智能中控,设备首页<text>定时列表</text>可查看最新发布</view> |
|||
</view> |
|||
|
|||
|
|||
<!-- 日期天多选选择弹框 --> |
|||
<view class="voice_control_pad" v-if="padConfig.show" @touchmove.stop.prevent="(()=>{})"> |
|||
<view class="cover_bg" @click.stop="padConfig.show=false" @touchmove.stop.prevent="(()=>{})"></view> |
|||
<view class="v_box" > |
|||
<scroll-view scroll-y="true" > |
|||
<view class="il-select-week"> |
|||
<block v-for="(e,i) in dayArrSelect" :key="i"> |
|||
<view class="" :class="e?'active':''" @click.stop="clickDaysTab(i)">{{i+1}} 号</view> |
|||
</block> |
|||
</view> |
|||
</scroll-view> |
|||
|
|||
<view class="v_btns"> |
|||
<view class="voice_btn btn_green" @click="padConfig.show=false">确认</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '../../../../utils/util'; |
|||
import store_name from '../../components/store_name/store_name'; |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
|
|||
const rootPage = '/subpackage/device' |
|||
const tabArr = [{ |
|||
id: 0, |
|||
name: '全部', |
|||
path: ``, |
|||
on: true |
|||
}, |
|||
]; |
|||
const weekArrCN = ["日", "一", "二","三","四","五","六"]; |
|||
import { |
|||
mapState |
|||
} from 'vuex' |
|||
export default { |
|||
components: { |
|||
'store-name': store_name |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
storeList: state => state.device.storeList, |
|||
curStoreInfo: state => state.device.curStoreInfo, |
|||
}), |
|||
isDel() { |
|||
return (item) => { |
|||
return item[2] == "删除" ? "true" : "" |
|||
} |
|||
}, |
|||
startDate() { |
|||
return this.getDate('start'); |
|||
}, |
|||
endDate() { |
|||
return this.getDate('end'); |
|||
} |
|||
}, |
|||
data() { |
|||
const currentDate = this.getDate({ |
|||
format: true |
|||
}) |
|||
const dayArrSelect = (()=>{ |
|||
let days = [] |
|||
for(var i=1;i<=31;i++){ |
|||
days.push(false) |
|||
} |
|||
return days |
|||
})() |
|||
return { |
|||
switchInfo:"",//上层页面的选择信息 |
|||
on:false, |
|||
singleArr:["星期","具体日期","具体时间段"], |
|||
sIndex:0, |
|||
dayArrSelect:dayArrSelect,//31天 选择 |
|||
dIndex:0, |
|||
weekArrCN, |
|||
weekArrSelect:[false,false,false,false,false,false,false], |
|||
date: currentDate, |
|||
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) { |
|||
this.handleOpts(option); |
|||
}, |
|||
onShow() { |
|||
// this.updateList() //更新中控信息 |
|||
}, |
|||
watch: { |
|||
curStoreInfo(newVal, oldVal){ |
|||
// this.infoArr.length = 1 |
|||
// 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]) { |
|||
this.$set(this.weekArrSelect,index,false) |
|||
}else{ |
|||
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 = { |
|||
"device": this.curStoreInfo.device_name, |
|||
"delay": 1, |
|||
"data": { |
|||
"name": "delete-time-select", |
|||
"value": { |
|||
"uuid": e[3] |
|||
} |
|||
} |
|||
} |
|||
uni.showModal({ |
|||
content: `确认要删除: ${e[0]}的计划任务 ?`, |
|||
success(res) { |
|||
console.log("确认删除", res.confirm) |
|||
if(res.confirm){ |
|||
that.operateReq({ |
|||
data: delData, |
|||
succFun: (res) => { |
|||
that.updateList() |
|||
}, |
|||
isTip:true |
|||
}) |
|||
} |
|||
}, |
|||
}) |
|||
}, |
|||
getDate(type) { |
|||
const date = new Date(); |
|||
let year = date.getFullYear(); |
|||
let month = date.getMonth() + 1; |
|||
let day = date.getDate(); |
|||
|
|||
if (type === 'start') { |
|||
year = year - 0; |
|||
} else if (type === 'end') { |
|||
year = year + 10;//限制可选10年内 |
|||
} |
|||
month = month > 9 ? month : '0' + month;; |
|||
day = day > 9 ? day : '0' + day; |
|||
return `${year}-${month}-${day}`; |
|||
}, |
|||
async sendDataToVC() { |
|||
let that = this |
|||
let timingData = { |
|||
} |
|||
timingData = this.reqData |
|||
|
|||
this.operateReq({ |
|||
data: timingData, |
|||
succFun: (res) => { |
|||
console.log("操作结果:",res); |
|||
if(res=="ok"){ |
|||
let timing_list = "/subpackage/device/pages/timing/timing_list" |
|||
util.routeTo(`${timing_list}`, 'nT'); |
|||
} |
|||
}, |
|||
isTip:true |
|||
}) |
|||
}, |
|||
goBack() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}) |
|||
}, |
|||
// 操作接口请求 |
|||
operateReq({ |
|||
data, |
|||
succFun, |
|||
isTip = false, |
|||
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) { |
|||
if (isTip) util.showNone(res.data.message || '操作成功!'); |
|||
succFun(res.data.data) |
|||
} else { |
|||
if (isTip) util.showNone(res.data.message || '操作失败!'); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
if (isLoad) util.hideLoad() |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import '~style/public.scss'; |
|||
|
|||
.timing-page { |
|||
|
|||
.t-title { |
|||
font-size: 44rpx; |
|||
color: #1A1A1A; |
|||
font-weight: 900; |
|||
margin: 60rpx auto 72rpx 40rpx; |
|||
} |
|||
|
|||
.t-box { |
|||
height: 500rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
width: 100%; |
|||
|
|||
.info-list { |
|||
margin-bottom: 50rpx; |
|||
padding: 50rpx 30rpx; |
|||
width: 700rpx; |
|||
height: auto; |
|||
background: #FFFFFF; |
|||
border-radius: 10rpx; |
|||
font-size: 32rpx; |
|||
.il-switch{ |
|||
width: 580rpx; |
|||
@include centerFlex(space-between); |
|||
> view{ |
|||
@include centerFlex(center); |
|||
image{ |
|||
margin-left: 20rpx; |
|||
width: 40rpx;height: 40rpx; |
|||
} |
|||
.un-select{ |
|||
margin-left: 20rpx; |
|||
background-color: white; |
|||
width: 40rpx;height: 40rpx; |
|||
border-radius: 50%; |
|||
border: 2rpx solid lightgray; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.il-select{ |
|||
margin-top: 50rpx; |
|||
width: 100%; |
|||
@include centerFlex(space-between); |
|||
.il-input { |
|||
@include centerFlex(space-between); |
|||
padding: 20rpx; |
|||
margin-left: 20rpx; |
|||
width: 480rpx; |
|||
height: 96rpx; |
|||
background: #FFFFFF; |
|||
border: 2rpx solid #D8D8D8; |
|||
border-radius: 10rpx; |
|||
text{ |
|||
color: #9C9C9F; |
|||
} |
|||
image{ |
|||
width: 28rpx; |
|||
height: 28rpx; |
|||
transform: rotate(90deg); |
|||
} |
|||
} |
|||
} |
|||
.il-select-double{ |
|||
margin-top: 50rpx; |
|||
width: 100%; |
|||
@include centerFlex(flex-start); |
|||
align-items: flex-start; |
|||
flex-direction: column; |
|||
.il-input { |
|||
@include centerFlex(space-between); |
|||
padding: 20rpx; |
|||
margin-top: 20rpx; |
|||
width: 648rpx; |
|||
height: 96rpx; |
|||
background: #FFFFFF; |
|||
border: 2rpx solid #D8D8D8; |
|||
border-radius: 10rpx; |
|||
text{ |
|||
color: #9C9C9F; |
|||
} |
|||
> view{ |
|||
padding: 0 10rpx; |
|||
} |
|||
|
|||
} |
|||
} |
|||
.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; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
// 底部css |
|||
.save-btn{ |
|||
width: 700rpx; |
|||
height: 110rpx; |
|||
text-align: center; |
|||
line-height: 110rpx; |
|||
background: #009874; |
|||
border-radius: 10px; |
|||
color: white; |
|||
} |
|||
.bottom-tips{ |
|||
font-size: 28rpx; |
|||
color: #1A1A1A; |
|||
text{ |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
</style> |
After Width: 14 | Height: 14 | Size: 311 B |
After Width: 20 | Height: 20 | Size: 395 B |
After Width: 80 | Height: 80 | Size: 3.0 KiB |
After Width: 80 | Height: 80 | Size: 1.7 KiB |
After Width: 80 | Height: 80 | Size: 4.8 KiB |
After Width: 80 | Height: 80 | Size: 1.3 KiB |
After Width: 200 | Height: 200 | Size: 11 KiB |
After Width: 200 | Height: 200 | Size: 9.9 KiB |
After Width: 103 | Height: 50 | Size: 2.9 KiB |
After Width: 102 | Height: 100 | Size: 2.4 KiB |
After Width: 103 | Height: 50 | Size: 2.9 KiB |
After Width: 14 | Height: 14 | Size: 512 B |
After Width: 187 | Height: 155 | Size: 16 KiB |
After Width: 100 | Height: 100 | Size: 6.3 KiB |
After Width: 380 | Height: 380 | Size: 55 KiB |
After Width: 676 | Height: 570 | Size: 26 KiB |
After Width: 100 | Height: 100 | Size: 5.1 KiB |
After Width: 100 | Height: 100 | Size: 5.2 KiB |
After Width: 100 | Height: 100 | Size: 5.1 KiB |
After Width: 1014 | Height: 696 | Size: 39 KiB |