| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122 |
- <template>
- <view class="device-detail">
- <view class="device-detail__header">
- <u-icon
- size="36"
- class="arrow-left"
- name="arrow-left"
- @click="handleBack"
- ></u-icon>
- {{ title }}
- </view>
- <view class="device-detail__body">
- <view class="tabs">
- <view class="tab-container">
- <view class="tab-item" v-if="myuser_type" :class="activeTab === 'pestAnalysis'?'active':''" @click="handleTabClick('pestAnalysis')">
- 管理员
- </view>
- <view class="tab-item" :class="activeTab === 'viewImage'?'active':''" @click="handleTabClick('viewImage')">
- 设置
- </view>
- </view>
- </view>
- <view class="device-detail-content" v-if="activeTab === 'pestAnalysis'">
- <view class="device-detail-child-settings" style="width:100%">
- <view class="device-detail-viewImage">
- <text class="device-detail-label">设备名称:</text>
- <view class="device-detail-value" >
- <u-input v-model="deviceName" disabled type="text" placeholder="设备名称" input-align="right" :custom-style="{'font-size':'24rpx'}"/>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">设备ID:</text>
- <view class="device-detail-value" >
- <u-input v-model="deviceID" disabled type="text" placeholder="设备ID" input-align="right" :custom-style="{'font-size':'24rpx'}"/>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">相机1:</text>
- <view class="device-detail-value" @click="openCameraIdPicker('camera1ID')">
- <text class="week-text">{{ camera1ID || '请选择相机' }}</text>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">相机2:</text>
- <view class="device-detail-value" @click="openCameraIdPicker('camera2ID')">
- <text class="week-text">{{ camera2ID || '请选择相机' }}</text>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">相机3:</text>
- <view class="device-detail-value" @click="openCameraIdPicker('camera3ID')">
- <text class="week-text">{{ camera3ID || '请选择相机' }}</text>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- </view>
- </view>
- <view class="device-detail-content" style="padding-bottom: 50rpx" v-if="activeTab === 'viewImage'">
- <view v-for="(item, index) in deviceList" :key="index" style="width:100%">
- <view class="device-detail-name" @click="toggleChildItem(index)">
- <text>{{ item.label }}</text>
- <u-icon name="arrow-down" size="24" :class="actionChildItem == index ? 'rotate':''"></u-icon>
- </view>
- <view v-show="actionChildItem == index" class="device-detail-child-settings-container">
- <view class="tabs">
- <view class="tab-container">
- <view class="tab-item" :class="item.activeTab === 'settings'?'active':''" @click="handleTabChildClick(item, 'settings')">
- 拍摄设置
- </view>
- <view class="tab-item" :class="item.activeTab === 'schedule'?'active':''" @click="handleTabChildClick(item, 'schedule')">
- 定时设置
- </view>
- <view class="tab-item" :class="item.activeTab === 'warning'?'active':''" @click="handleTabChildClick(item, 'warning')">
- 触发报警设置
- </view>
- <view class="tab-item" :class="item.activeTab === 'other'?'active':''" @click="handleTabChildClick(item, 'other')">
- 其他设置
- </view>
- </view>
- </view>
- <view class="device-detail-child-settings" v-if="item.activeTab === 'settings'">
- <view class="device-detail-viewImage">
- <text class="device-detail-label">拍照模式:</text>
- <view class="device-detail-value" @click="setDeviceItemContorl(item, 'takephoto')">
- <text class="week-text">{{ formatPhotoModel(item.photoSettings.photoModel) }}</text>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">图片大小:</text>
- <view class="device-detail-value" @click="setDeviceItemContorl(item, 'imageSize')">
- <text class="week-text">{{ formatImageSize(item.photoSettings.imageSize) }}</text>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">视频大小:</text>
- <view class="device-detail-value" @click="setDeviceItemContorl(item, 'videoSize')">
- <text class="week-text">{{ formatImageSize(item.photoSettings.videoSize) }}</text>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">连拍:</text>
- <view class="device-detail-value">
- <u-input v-model="item.photoSettings.burstPhoto" type="number" :maxlength="4" placeholder="连拍(1-1000)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.photoSettings, 'burstPhoto')"/>
- <text class="unit-text">次</text>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">视频长度:</text>
- <view class="device-detail-value">
- <u-input v-model="item.photoSettings.videoLength" type="number" :maxlength="4" placeholder="视频长度(1-1000)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.photoSettings, 'videoLength')"/>
- <text class="unit-text">秒</text>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">拍摄限制:</text>
- <view class="device-detail-value">
- <u-input v-model="item.photoSettings.photoInterval" type="number" :maxlength="4" placeholder="拍摄限制(1-1000)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.photoSettings, 'photoInterval')" />
- <text class="unit-text">次</text>
- </view>
- </view>
- </view>
- <view class="device-detail-child-settings" v-if="item.activeTab === 'schedule'">
- <view class="device-detail-viewImage">
- <text class="device-detail-label">定时拍照:</text>
- <text class="device-detail-value">
- <u-switch v-model="item.timeSettings.timePhoto" active-value="1" inactive-value="0" size="36" />
- </text>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">循环拍摄间隔:</text>
- <view class="device-detail-value">
- <u-input v-model="item.timeSettings.photoTime" type="number" :maxlength="4" placeholder="循环拍摄间隔(1-1000)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.timeSettings, 'photoTime')" />
- <text class="unit-text">秒</text>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">时间段1:</text>
- <view class="device-detail-value">
- <text class="time-text" @click="openTimePicker(item, 'time1', 0)">{{ (item.timeSettings.time1 && item.timeSettings.time1[0]) || '开始' }}</text>
- <text class="time-sep">-</text>
- <text class="time-text" @click="openTimePicker(item, 'time1', 1)">{{ (item.timeSettings.time1 && item.timeSettings.time1[1]) || '结束' }}</text>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">时间段2:</text>
- <view class="device-detail-value">
- <text class="time-text" @click="openTimePicker(item, 'time2', 0)">{{ (item.timeSettings.time2 && item.timeSettings.time2[0]) || '开始' }}</text>
- <text class="time-sep">-</text>
- <text class="time-text" @click="openTimePicker(item, 'time2', 1)">{{ (item.timeSettings.time2 && item.timeSettings.time2[1]) || '结束' }}</text>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">时间段3:</text>
- <view class="device-detail-value">
- <text class="time-text" @click="openTimePicker(item, 'time3', 0)">{{ (item.timeSettings.time3 && item.timeSettings.time3[0]) || '开始' }}</text>
- <text class="time-sep">-</text>
- <text class="time-text" @click="openTimePicker(item, 'time3', 1)">{{ (item.timeSettings.time3 && item.timeSettings.time3[1]) || '结束' }}</text>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">周重复:</text>
- <view class="device-detail-value" @click="openWeekPicker(item)">
- <view class="week-text">{{ (item.timeSettings.weekLoop || []).join('、') || '请选择' }}</view>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- </view>
- <view class="device-detail-child-settings" v-if="item.activeTab === 'warning'">
- <view class="device-detail-viewImage">
- <text class="device-detail-label">PIR开关:</text>
- <text class="device-detail-value">
- <u-switch v-model="item.warning.pirOpenOrClose" active-value="1" inactive-value="0" size="36" />
- </text>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">PIR灵敏度:</text>
- <view class="device-detail-value" @click="setDeviceItemContorl(item, 'pirSensitivity')">
- <text class="week-text">{{ item.warning.pirSensitivity == 0 ? '低' : '高' }}</text>
- <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
- </view>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">触发时间间隔:</text>
- <view class="device-detail-value">
- <u-input v-model="item.warning.triggerTimeInterval" type="number" :maxlength="4" placeholder="触发时间间隔(1-1000)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.warning, 'triggerTimeInterval')" />
- <text class="unit-text">秒</text>
- </view>
- </view>
- </view>
- <view class="device-detail-child-settings" v-if="item.activeTab === 'other'">
- <view class="device-detail-viewImage">
- <text class="device-detail-label">信息戳记:</text>
- <text class="device-detail-value">
- <u-switch v-model="item.other.informationStamp" active-value="1" inactive-value="0" size="36" />
- </text>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">自动覆盖:</text>
- <text class="device-detail-value">
- <u-switch v-model="item.other.autoOverWrite" active-value="1" inactive-value="0" size="36" />
- </text>
- </view>
- <view class="device-detail-viewImage">
- <text class="device-detail-label">相机名称:</text>
- <view class="device-detail-value">
- <u-input v-model="item.other.photoName" :maxlength="20" placeholder="相机名称(最多20字)" input-align="right" :custom-style="{'font-size':'24rpx'}" />
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view class="device-detail-btn-footer">
- <view class="device-detail-btn" @click="saveSettings">保存</view>
- </view>
- <u-select v-model="showContorl" :list="list" @confirm="confirmDeviceItemContorl"></u-select>
- <u-select v-model="showImageTypeContorl" :list="imageList" @confirm="confirmDeviceItemContorl"></u-select>
- <u-select v-model="showVideoTypeContorl" :list="videoList" @confirm="confirmDeviceItemContorl"></u-select>
- <u-select v-model="showPirTypeContorl" :list="pirList" @confirm="confirmDeviceItemContorl"></u-select>
- <u-picker
- v-model="showDateTime"
- mode="time"
- :params="timeParams"
- :default-time="currentDefaultTime"
- @confirm="confirmTimePicker"
- ></u-picker>
- <u-popup v-model="showWeekPicker" mode="bottom" border-radius="16">
- <view class="week-picker">
- <view class="week-picker__title">周重复</view>
- <view class="week-picker__list">
- <view
- v-for="day in weekList"
- :key="day"
- class="week-picker__item"
- :class="{ active: selectedWeeks.indexOf(day) > -1 }"
- @click="toggleWeek(day)"
- >{{ day }}</view>
- </view>
- <view class="week-picker__btn" @click="confirmWeekPicker">确定</view>
- </view>
- </u-popup>
- <u-select v-model="showCameraSelect" :list="cameraList" @confirm="confirmCameraSelect"></u-select>
- </view>
- </template>
- <script>
- export default {
- data(){
- return {
- value: 10,
- camera1ID: '123',
- camera2ID: '456',
- camera3ID: '789',
- timeParams: {
- year: false,
- month: false,
- day: false,
- hour: true,
- minute: true,
- second: false
- },
- list: [
- {
- label: '自动',
- value: 'takephoto'
- },
- {
- label: '手动',
- value: 'manual'
- }
- ],
- imageList: [
- {
- label: '1280',
- value: '1280'
- },
- {
- label: '720',
- value: '720'
- }
- ],
- videoList: [
- {
- label: '1280',
- value: '1280'
- },
- {
- label: '720',
- value: '720'
- }
- ],
- actionChildItem: 0,
- equipContrlForm: {},
- time: '',
- activeTab: 'pestAnalysis',
- title: '设置控制',
- myuser_type: false,
- deviceType: '',
- location: '',
- deviceList: [{
- label: '相机1',
- content:'',
- show:false,
- activeTab: 'settings',
- photoSettings:{
- photoModel: '1',
- imageSize: '0',
- videoSize: '0',
- burstPhoto: 1,
- videoLength: 60,
- photoInterval: 1,
- },
- timeSettings:{
- timePhoto: '1',
- photoTime: 60,
- time1: ['08:00','09:00'],
- time2: ['11:00','12:00'],
- time3: ['15:00','16:00'],
- weekLoop:['周一','周二','周三'],
- },
- warning:{
- pirOpenOrClose:'1',
- pirSensitivity:'0',
- triggerTimeInterval:30,
- },
- other:{
- informationStamp:'1',
- autoOverWrite:'1',
- photoName:'相机1',
- }
- },{
- label: '相机2',
- content:'',
- show:false,
- activeTab: 'settings',
- photoSettings:{
- photoModel: '1',
- imageSize: '0',
- videoSize: '0',
- burstPhoto: 1,
- videoLength: 60,
- photoInterval: 1,
- },
- timeSettings:{
- timePhoto: '1',
- photoTime: 60,
- time1: ['08:00','09:00'],
- time2: ['11:00','12:00'],
- time3: ['15:00','16:00'],
- weekLoop:['周一','周二','周三'],
- },
- warning:{
- pirOpenOrClose:'1',
- pirSensitivity:'0',
- triggerTimeInterval:30,
- },
- other:{
- informationStamp:'1',
- autoOverWrite:'1',
- photoName:'相机1',
- }
- },{
- label: '相机3',
- content:'',
- show:false,
- activeTab: 'settings',
- photoSettings:{
- photoModel: '1',
- imageSize: '0',
- videoSize: '0',
- burstPhoto: 1,
- videoLength: 60,
- photoInterval: 1,
- },
- timeSettings:{
- timePhoto: '1',
- photoTime: 60,
- time1: ['08:00','09:00'],
- time2: ['11:00','12:00'],
- time3: ['15:00','16:00'],
- weekLoop:['周一','周二','周三'],
- },
- warning:{
- pirOpenOrClose:'1',
- pirSensitivity:'0',
- triggerTimeInterval:30,
- },
- other:{
- informationStamp:'1',
- autoOverWrite:'1',
- photoName:'相机1',
- }
- }],
- d_id: '',
- show: false,
- checked: false,
- showContorl: false,
- showPirTypeContorl: false,
- pirList: [
- {
- label: '自动',
- value: 'auto'
- },
- {
- label: '高',
- value: 'high'
- },
- {
- label: '中',
- value: 'middle'
- },
- {
- label: '低',
- value: 'low'
- }
- ],
- showDateTime: false,
- currentTimeItem: null,
- currentTimeField: '',
- currentTimeIndex: 0,
- currentDefaultTime: '08:00',
- showImageTypeContorl: false,
- showVideoTypeContorl: false,
- showWeekPicker: false,
- weekList: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
- selectedWeeks: [],
- currentWeekItem: null,
- currentItem: null,
- currentFieldType: '',
- deviceName: '',
- deviceID: '',
- camera1ID: '',
- camera2ID: '',
- camera3ID: '',
- showCameraSelect: false,
- currentCameraField: '',
- cameraList: [
- {
- label: 'CAM-0001',
- value: 'CAM-0001'
- },
- {
- label: 'CAM-0002',
- value: 'CAM-0002'
- },
- {
- label: 'CAM-0003',
- value: 'CAM-0003'
- },
- {
- label: 'CAM-0004',
- value: 'CAM-0004'
- },
- {
- label: 'CAM-0005',
- value: 'CAM-0005'
- },
- {
- label: 'CAM-0006',
- value: 'CAM-0006'
- },
- {
- label: 'CAM-0007',
- value: 'CAM-0007'
- },
- {
- label: 'CAM-0008',
- value: 'CAM-0008'
- }
- ]
- }
- },
- onLoad(options){
- this.d_id = options.d_id
- this.getControlDeviceConfigInfo()
- uni.getStorage({
- key:"myuser_type",
- success:(res)=>{
- if(Number(res.data) == 1){
- this.myuser_type = true
- this.activeTab = 'pestAnalysis'
- }else{
- this.activeTab = 'viewImage'
- }
- }
- })
- },
- methods: {
- setDeviceItemContorl(item, type){
- this.currentItem = item
- this.currentFieldType = type
- switch(type){
- case 'takephoto':
- this.showContorl = true
- break;
- case 'imageSize':
- this.showImageTypeContorl = true
- break;
- case 'videoSize':
- this.showVideoTypeContorl = true
- break;
- case 'pirSensitivity':
- this.showPirTypeContorl = true
- break;
- }
- },
- confirmDeviceItemContorl(e){
- const fieldMap = {
- takephoto: ['photoSettings', 'photoModel'],
- imageSize: ['photoSettings', 'imageSize'],
- videoSize: ['photoSettings', 'videoSize'],
- pirSensitivity: ['warning', 'pirSensitivity']
- }
- const target = fieldMap[this.currentFieldType]
- if (this.currentItem && target) {
- this.$set(this.currentItem[target[0]], target[1], e[0].label)
- }
- },
- // photoModel编码转文案(与后台约定:0=自动,1=手动),已是文案的直接返回
- formatPhotoModel(value){
- if (value === '0') return '自动'
- if (value === '1') return '手动'
- return value || '自动'
- },
- // 图片/视频大小:兼容mock编码(0=1280,1=720)与选择后存入的文案
- formatImageSize(value){
- if (value == 0 || value === '1280') return '1280'
- if (value == 1 || value === '720') return '720'
- return value || '1280'
- },
- handleTabChildClick(item, tab){
- item.activeTab = tab;
- },
- // 展开/收起相机设置面板(同时只展开一个,再点一次收起;-1表示全部收起)
- toggleChildItem(index){
- this.actionChildItem = this.actionChildItem == index ? -1 : index
- },
- // 失焦时校验:只保留正整数,范围1-1000(空/非法/小于1置为1,大于1000置为1000)
- // 小程序上@input回传参数拿不到输入值,且边输入边改值会引发输入框错乱,所以统一在失焦时校正
- handlePositiveIntBlur(item, field){
- let value = (item[field] === null || item[field] === undefined ? '' : item[field] + '').replace(/\D/g, '')
- value = value.replace(/^0+/, '')
- if (value === '' || Number(value) < 1) {
- value = '1'
- }
- if (Number(value) > 1000) {
- value = '1000'
- }
- this.$set(item, field, value)
- },
- openCameraIdPicker(field) {
- this.currentCameraField = field
- this.showCameraSelect = true
- },
- confirmCameraSelect(e) {
- const value = e[0].value
- const fields = ['camera1ID', 'camera2ID', 'camera3ID']
- for (let i = 0; i < fields.length; i++) {
- if (fields[i] !== this.currentCameraField && this[fields[i]] === value) {
- uni.showToast({ title: '该相机已被其他项选择', icon: 'none' })
- return
- }
- }
- this[this.currentCameraField] = value
- },
- openTimePicker(item, field, index) {
- this.currentTimeItem = item
- this.currentTimeField = field
- this.currentTimeIndex = index
- const range = item.timeSettings[field] || []
- this.currentDefaultTime = range[index] || '08:00'
- this.showDateTime = true
- },
- confirmTimePicker(e) {
- const item = this.currentTimeItem
- const field = this.currentTimeField
- const index = this.currentTimeIndex
- if (!item || !field) return
- const value = e.hour + ':' + e.minute
- // 用修改后的临时数据做校验,通过才写入(time1~time3为[开始,结束]数组)
- const slots = ['time1', 'time2', 'time3'].map((key, i) => {
- const source = item.timeSettings[key] || []
- const range = [source[0] || '', source[1] || '']
- if (key === field) range[index] = value
- return { name: '时间段' + (i + 1), start: range[0], end: range[1] }
- })
- for (let i = 0; i < slots.length; i++) {
- if (slots[i].start && slots[i].end && slots[i].start >= slots[i].end) {
- uni.showToast({ title: slots[i].name + '的开始时间需小于结束时间', icon: 'none' })
- return
- }
- }
- for (let i = 0; i < slots.length - 1; i++) {
- const a = slots[i]
- const b = slots[i + 1]
- if (a.start && a.end && b.start && b.end) {
- if (a.start === b.start && a.end === b.end) {
- uni.showToast({ title: a.name + '与' + b.name + '不能重复', icon: 'none' })
- return
- }
- if (a.end > b.start) {
- uni.showToast({ title: a.name + '需早于' + b.name, icon: 'none' })
- return
- }
- }
- }
- if (!item.timeSettings[field] || item.timeSettings[field].length !== 2) {
- this.$set(item.timeSettings, field, ['', ''])
- }
- this.$set(item.timeSettings[field], index, value)
- },
- openWeekPicker(item) {
- this.currentWeekItem = item
- this.selectedWeeks = item.timeSettings.weekLoop ? item.timeSettings.weekLoop.slice() : []
- this.showWeekPicker = true
- },
- toggleWeek(day) {
- const index = this.selectedWeeks.indexOf(day)
- if (index > -1) {
- if (this.selectedWeeks.length === 1) {
- uni.showToast({
- title: '至少保留一个',
- icon: 'none'
- })
- return
- }
- this.selectedWeeks.splice(index, 1)
- } else {
- this.selectedWeeks.push(day)
- }
- },
- confirmWeekPicker() {
- if (this.selectedWeeks.length === 0) {
- uni.showToast({
- title: '请至少选择一个',
- icon: 'none'
- })
- return
- }
- if (this.currentWeekItem) {
- const ordered = this.weekList.filter(day => this.selectedWeeks.indexOf(day) > -1)
- this.$set(this.currentWeekItem.timeSettings, 'weekLoop', ordered)
- }
- this.showWeekPicker = false
- },
- getProgressWidth(value, min, max) {
- if (max === min) return 0
- return ((value - min) / (max - min)) * 100
- },
- onSliderTouchStart(e, field, min, max) {
- this.sliderField = field
- this.sliderMin = min
- this.sliderMax = max
- const query = uni.createSelectorQuery().in(this)
- query.select('.custom-progress').boundingClientRect(rect => {
- this.sliderRect = rect
- }).exec()
- this.updateSliderValue(e.touches[0].clientX, field, min, max)
- },
- onSliderTouchMove(e, min, max) {
- if (!this.sliderField || !this.sliderRect) return
- this.updateSliderValue(e.touches[0].clientX, this.sliderField, min, max)
- },
- onSliderTouchEnd() {
- this.sliderField = ''
- },
- onSliderTap(e, field, min, max) {
- const query = uni.createSelectorQuery().in(this)
- query.select('.custom-progress').boundingClientRect(rect => {
- this.sliderRect = rect
- this.updateSliderValue(e.detail.x + rect.left, field, min, max)
- }).exec()
- },
- updateSliderValue(clientX, field, min, max) {
- if (!this.sliderRect) return
- let ratio = (clientX - this.sliderRect.left) / this.sliderRect.width
- ratio = Math.max(0, Math.min(1, ratio))
- const value = Math.round(min + ratio * (max - min))
- this.$set(this.equipContrlForm, field, value)
- },
- handleBack() {
- uni.navigateBack({
- delta: 1
- });
- },
- handleTabClick(tab) {
- this.activeTab = tab;
- },
- showMqttConfig(){
- this.show = true;
- },
- closeMqttConfig(){
- this.show = false;
- },
- async setDeviceContorl(type){
- const data = {
- device_type_id: 3,
- d_id: this.d_id,
- cmd: type,
- }
- if(type === 'imei'){
- data.imei = this.equipContrlForm.imei
- }else{
- delete data.imei
- }
- this.$myRequest({
- url: '/api/api_gateway?method=forecast.send_control.admin_device_control',
- method: 'POST',
- data
- }).then(res => {
- this.closeMqttConfig()
- if (res) {
- uni.showToast({
- title: '设备控制修改成功!',
- icon: 'success',
- });
- } else {
- uni.showToast({
- title: '设备控制修改失败',
- icon: 'error',
- });
- }
- });
- },
- saveSettings(){
- let newForm = Object.assign({}, this.equipContrlForm) // 深拷贝
- newForm.st = newForm.st + ''
- newForm.et = newForm.et + ''
- newForm.st && newForm.st.slice(0, 2).charAt(0) != '0'
- ? newForm.st.slice(0, 2)
- : newForm.st.slice(1, 2)
- newForm.et =
- newForm.et && newForm.et.slice(0, 2).charAt(0) != '0'
- ? newForm.et.slice(0, 2)
- : newForm.et.slice(1, 2)
- for (let k in newForm) {
- if (typeof newForm[k] === 'number') {
- newForm[k] = newForm[k] + ''
- }
- }
- newForm.st = newForm.st.replace(':00', '')
- this.$myRequest({
- url: '/api/api_gateway?method=forecast.send_control.device_control',
- method: 'POST',
- data: {
- device_type_id: 3,
- d_id: this.d_id,
- config: JSON.stringify(newForm)
- }
- }).then(res => {
- if (res) {
- // 设备控制修改成功
- uni.showToast({
- title: '设备控制修改成功!',
- icon: 'success',
- });
- } else {
- uni.showToast({
- title: '设备控制修改失败',
- icon: 'error',
- });
- }
- })
- },
- async getControlDeviceConfigInfo(){
- const res = await this.$myRequest({
- url: '/api/api_gateway?method=forecast.send_control.device_control_info',
- method: 'POST',
- data: {
- d_id: this.d_id,
- cmd:'paramconf'
- },
- });
- this.equipContrlForm = res
- },
- }
- }
- </script>
- <style scoped lang="scss">
- .device-detail {
- display: flex;
- width: 100%;
- height: calc(100vh - 112rpx);
- padding-top: 112rpx;
- flex-direction: column;
- align-items: center;
- background: linear-gradient(180deg, #ffffff00 0%, #F5F6FA 23.64%, #F5F6FA 100%), linear-gradient(102deg, #BFEADD 6.77%, #B8F1E7 40.15%, #B9EEF5 84.02%);
- .device-detail__header {
- width: 100%;
- font-size: 28rpx;
- color: #999;
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- font-weight: 700;
- position: relative;
- text-align: center;
- .arrow-left {
- position: absolute;
- left: 32rpx;
- margin-right: 12rpx;
- }
- }
- .device-detail__body {
- width: calc(100% - 64rpx);
- margin: 0 auto;
- border-radius: 16rpx;
- overflow-x: hidden;
- overflow-y: auto;
- // 隐藏滚动条
- -ms-overflow-style: none;
- scrollbar-width: none;
- }
- .tabs {
- margin: 24rpx 0;
- border-radius: 16rpx;
- padding: 16rpx 0;
- padding-top: 0;
- .tab-container{
- display: flex;
- width: 100%;
- height: 88rpx;
- line-height: 88rpx;
- text-align: center;
- font-size: 28rpx;
- font-weight: 700;
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- }
- .tab-item {
- margin-right: 40rpx;
- color:#999999;
- }
- .active{
- position: relative;
- color: #303133;
- text-align: center;
- font-family: "Source Han Sans CN VF";
- font-size: 28rpx;
- font-weight: 700;
- &::after {
- content: '';
- position: absolute;
- bottom: 10rpx;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
- height: 36rpx;
- border-bottom: 6rpx solid #303133;
- }
- }
- }
- .device-detail-content{
- display: flex;
- padding: 24rpx 32rpx;
- flex-direction: column;
- align-items: flex-start;
- gap: 20rpx;
- border-radius: 16rpx;
- background: #FFF;
- .device-detail-name{
- flex:1;
- width: 100%;
- display: flex;
- justify-content: space-between;
- .rotate{
- transform: rotate(180deg);
- transition: all 0.3s ease-in-out;
- }
- }
- .device-detail-child-settings-container{
- transition: all 0.3s ease-in-out;
- padding: 0 24rpx;
- }
- .tabs {
- margin: 2rpx 0;
- border-radius: 16rpx;
- padding: 6rpx 0;
- padding-top: 0;
- .tab-container{
- display: flex;
- width: 100%;
- height: 68rpx;
- line-height: 68rpx;
- text-align: center;
- font-size: 24rpx;
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- }
- .tab-item {
- margin-right: 20rpx;
- color:#999999;
- }
- .active{
- position: relative;
- color: #303133;
- text-align: center;
- font-family: "Source Han Sans CN VF";
- font-size: 24rpx;
- &::after {
- content: '';
- position: absolute;
- bottom: 10rpx;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
- height: 36rpx;
- border-bottom: 6rpx solid #303133;
- }
- }
- }
- .device-detail-item{
- .device-detail-btn-container{
- display: flex;
- gap: 24rpx;
- margin-top: 12rpx;
- }
- .device-detail-btn{
- display: flex;
- padding: 10rpx 16rpx;
- justify-content: center;
- align-items: center;
- gap: 16rpx;
- border-radius: 16rpx;
- background: #0BBC58;
- color: #ffffff;
- font-family: "Source Han Sans CN VF";
- font-size: 26rpx;
- font-weight: 400;
- }
- .force-btn{
- background: #FB4E52;
- }
- }
- .device-detail-viewImage{
- width: 100%;
- display: flex;
- justify-content: space-between;
- align-items: center;
- height: 70rpx;
- .device-detail-label{
- color: #303133;
- font-family: "Source Han Sans CN VF";
- font-size: 26rpx;
- flex-shrink: 0;
- }
- .device-detail-value{
- color: #303133;
- font-family: "Source Han Sans CN VF";
- font-size: 26rpx;
- display: flex;
- align-items: center;
- justify-content: space-between;
- .week-text{
- flex: 1;
- min-width: 0;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- text-align: right;
- margin-right: 8rpx;
- }
- .time-text{
- min-width: 96rpx;
- height: 48rpx;
- line-height: 48rpx;
- padding: 0 16rpx;
- text-align: center;
- border-radius: 10rpx;
- background: #F6F8FC;
- color: #303133;
- font-size: 24rpx;
- font-family: "Source Han Sans CN VF";
- }
- .time-sep{
- margin: 0 8rpx;
- color: #999999;
- }
- .unit-text{
- margin-left: 8rpx;
- flex-shrink: 0;
- color: #303133;
- font-size: 24rpx;
- font-family: "Source Han Sans CN VF";
- }
- }
- }
- }
- .slider-container{
- position: relative;
- margin-bottom: 20rpx;
- .slider-min-value{
- position: absolute;
- left: 0;
- top: -50rpx;
- }
- .slider{
- width: 600rpx;
- }
- .slider-max-value{
- position: absolute;
- right: 0;
- top: -50rpx;
- }
- }
- .custom-progress{
- width: 600rpx;
- padding: 0;
- .progress-track{
- position: relative;
- height: 12rpx;
- background-color: #ebedf0;
- border-radius: 6rpx;
- }
- .progress-fill{
- position: absolute;
- left: 0;
- top: 0;
- height: 100%;
- background-color: #0BBC58;
- border-radius: 6rpx;
- transition: width 0.2s;
- }
- .progress-thumb{
- position: absolute;
- top: 50%;
- width: 28rpx;
- height: 28rpx;
- margin-left: -14rpx;
- margin-top: -14rpx;
- border-radius: 50%;
- background-color: #fff;
- box-shadow: 0 1px 4px rgba(0,0,0,0.3);
- transition: left 0.2s;
- }
- }
- .device-detail-btn-footer{
- position: fixed;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 112rpx;
- line-height: 112rpx;
- text-align: center;
- font-size: 28rpx;
- font-weight: 700;
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- background: #ffffff;
- display: flex;
- justify-content: center;
- align-items: center;
- .device-detail-btn{
- display: flex;
- height: 80rpx;
- width: 90%;
- margin: 0 auto;
- padding: 0rpx 20rpx;
- justify-content: center;
- align-items: center;
- gap: 8rpx;
- border-radius: 16rpx;
- background:#0BBC58;
- color: #ffffff;
- text-align: center;
- font-family: "Source Han Sans CN VF";
- font-size: 14px;
- font-style: normal;
- font-weight: 500;
- }
- }
- .week-picker{
- padding: 32rpx 32rpx 40rpx;
- .week-picker__title{
- text-align: center;
- font-size: 30rpx;
- font-weight: 700;
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- margin-bottom: 32rpx;
- }
- .week-picker__list{
- display: flex;
- flex-wrap: wrap;
- gap: 24rpx;
- margin-bottom: 40rpx;
- }
- .week-picker__item{
- width: calc((100% - 72rpx) / 4);
- height: 64rpx;
- line-height: 64rpx;
- text-align: center;
- border-radius: 12rpx;
- background: #F6F8FC;
- color: #666666;
- font-size: 26rpx;
- font-family: 'Source Han Sans CN VF';
- &.active{
- background: #0BBC58;
- color: #ffffff;
- }
- }
- .week-picker__btn{
- height: 80rpx;
- line-height: 80rpx;
- text-align: center;
- border-radius: 16rpx;
- background: #0BBC58;
- color: #ffffff;
- font-size: 28rpx;
- font-family: 'Source Han Sans CN VF';
- font-weight: 500;
- }
- }
- }
- </style>
|