|
|
@@ -25,7 +25,7 @@
|
|
|
<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'}"/>
|
|
|
+ <u-input v-model="deviceName" type="text" maxlength="15" placeholder="设备名称" input-align="right" :custom-style="{'font-size':'24rpx'}"/>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="device-detail-viewImage">
|
|
|
@@ -60,7 +60,7 @@
|
|
|
<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>
|
|
|
+ <text>{{ item.deviceId || 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">
|
|
|
@@ -105,21 +105,21 @@
|
|
|
<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')"/>
|
|
|
+ <u-input v-model="item.photoSettings.burstPhoto" type="number" :maxlength="4" placeholder="连拍(1-9)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.photoSettings, 'burstPhoto', 9)"/>
|
|
|
<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')"/>
|
|
|
+ <u-input v-model="item.photoSettings.videoLength" type="number" :maxlength="4" placeholder="视频长度(1-300)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.photoSettings, 'videoLength', 300)"/>
|
|
|
<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')" />
|
|
|
+ <u-input v-model="item.photoSettings.photoInterval" type="number" :maxlength="4" placeholder="拍摄限制(0-255)" input-align="right" :custom-style="{'font-size':'24rpx'}" @blur="handlePositiveIntBlur(item.photoSettings, 'photoInterval', 255, 0)" />
|
|
|
<text class="unit-text">次</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -127,15 +127,15 @@
|
|
|
<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 class="device-detail-value">
|
|
|
+ <u-switch v-model="item.timeSettings.timePhoto" size="36" />
|
|
|
+ </view>
|
|
|
</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 class="device-detail-value" @click="openIntervalPicker(item)">
|
|
|
+ <text class="week-text">{{ item.timeSettings.photoTime || '00:01' }}</text>
|
|
|
+ <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="device-detail-viewImage">
|
|
|
@@ -173,42 +173,42 @@
|
|
|
<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 class="device-detail-value">
|
|
|
+ <u-switch v-model="item.warning.pirOpenOrClose" size="36" />
|
|
|
+ </view>
|
|
|
</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>
|
|
|
+ <text class="week-text">{{ formatPirSensitivity(item.warning.pirSensitivity) }}</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 class="device-detail-value" @click="setDeviceItemContorl(item, 'pirInterval')">
|
|
|
+ <text class="week-text">{{ item.warning.triggerTimeInterval || '00:00' }}</text>
|
|
|
+ <u-icon name="arrow-right" color="#999999" size="24"></u-icon>
|
|
|
</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 class="device-detail-value">
|
|
|
+ <u-switch v-model="item.other.informationStamp" size="36" />
|
|
|
+ </view>
|
|
|
</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 class="device-detail-value">
|
|
|
+ <u-switch v-model="item.other.autoOverWrite" size="36" />
|
|
|
+ </view>
|
|
|
</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'}" />
|
|
|
+ <u-input v-model="item.other.photoName" :maxlength="15" placeholder="相机名称(最多15字)" input-align="right" :custom-style="{'font-size':'24rpx'}" />
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -220,9 +220,10 @@
|
|
|
<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="showImageTypeContorl" :list="currentSizeList" @confirm="confirmDeviceItemContorl"></u-select>
|
|
|
+ <u-select v-model="showVideoTypeContorl" :list="currentSizeList" @confirm="confirmDeviceItemContorl"></u-select>
|
|
|
<u-select v-model="showPirTypeContorl" :list="pirList" @confirm="confirmDeviceItemContorl"></u-select>
|
|
|
+ <u-select v-model="showPirIntervalContorl" :list="pirIntervalList" @confirm="confirmDeviceItemContorl"></u-select>
|
|
|
<u-picker
|
|
|
v-model="showDateTime"
|
|
|
mode="time"
|
|
|
@@ -245,7 +246,7 @@
|
|
|
<view class="week-picker__btn" @click="confirmWeekPicker">确定</view>
|
|
|
</view>
|
|
|
</u-popup>
|
|
|
- <u-select v-model="showCameraSelect" :list="cameraList" @confirm="confirmCameraSelect"></u-select>
|
|
|
+ <u-select v-model="showCameraSelect" :list="cameraSelectList" @confirm="confirmCameraSelect"></u-select>
|
|
|
</view>
|
|
|
</template>
|
|
|
<script>
|
|
|
@@ -265,36 +266,23 @@ export default {
|
|
|
minute: true,
|
|
|
second: false
|
|
|
},
|
|
|
+ // 拍照模式可选项(value 与协议 CAM_Mode 对应)
|
|
|
list: [
|
|
|
{
|
|
|
- label: '自动',
|
|
|
- value: 'takephoto'
|
|
|
- },
|
|
|
- {
|
|
|
- label: '手动',
|
|
|
- value: 'manual'
|
|
|
- }
|
|
|
- ],
|
|
|
- imageList: [
|
|
|
- {
|
|
|
- label: '1280',
|
|
|
- value: '1280'
|
|
|
+ label: '拍照',
|
|
|
+ value: '0'
|
|
|
},
|
|
|
{
|
|
|
- label: '720',
|
|
|
- value: '720'
|
|
|
- }
|
|
|
- ],
|
|
|
- videoList: [
|
|
|
- {
|
|
|
- label: '1280',
|
|
|
- value: '1280'
|
|
|
+ label: '录像',
|
|
|
+ value: '1'
|
|
|
},
|
|
|
{
|
|
|
- label: '720',
|
|
|
- value: '720'
|
|
|
+ label: '拍照+录像',
|
|
|
+ value: '2'
|
|
|
}
|
|
|
],
|
|
|
+ // 图片/视频大小可选项:点击时由当前相机的 options 动态生成
|
|
|
+ currentSizeList: [],
|
|
|
actionChildItem: 0,
|
|
|
equipContrlForm: {},
|
|
|
time: '',
|
|
|
@@ -303,127 +291,50 @@ export default {
|
|
|
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',
|
|
|
- }
|
|
|
- }],
|
|
|
+ deviceList: [],
|
|
|
d_id: '',
|
|
|
+ // 双摄主设备 id(相机配置接口入参)
|
|
|
+ device_id: '',
|
|
|
show: false,
|
|
|
checked: false,
|
|
|
showContorl: false,
|
|
|
showPirTypeContorl: false,
|
|
|
+ showPirIntervalContorl: false,
|
|
|
+ // 触发时间间隔可选项:小时 00~60、分钟 00~50 步长 10(与 PC 端一致)
|
|
|
+ pirIntervalList: (() => {
|
|
|
+ const list = []
|
|
|
+ for (let hour = 0; hour <= 60; hour++) {
|
|
|
+ for (let minute = 0; minute <= 50; minute += 10) {
|
|
|
+ const hh = ('0' + hour).slice(-2)
|
|
|
+ const mm = ('0' + minute).slice(-2)
|
|
|
+ list.push({ label: hh + ':' + mm, value: hh + ':' + mm })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list
|
|
|
+ })(),
|
|
|
pirList: [
|
|
|
{
|
|
|
label: '自动',
|
|
|
- value: 'auto'
|
|
|
+ value: '0'
|
|
|
},
|
|
|
{
|
|
|
- label: '高',
|
|
|
- value: 'high'
|
|
|
+ label: '低',
|
|
|
+ value: '1'
|
|
|
},
|
|
|
{
|
|
|
label: '中',
|
|
|
- value: 'middle'
|
|
|
+ value: '2'
|
|
|
},
|
|
|
{
|
|
|
- label: '低',
|
|
|
- value: 'low'
|
|
|
+ label: '高',
|
|
|
+ value: '3'
|
|
|
}
|
|
|
],
|
|
|
showDateTime: false,
|
|
|
currentTimeItem: null,
|
|
|
currentTimeField: '',
|
|
|
currentTimeIndex: 0,
|
|
|
+ currentIntervalItem: null,
|
|
|
currentDefaultTime: '08:00',
|
|
|
showImageTypeContorl: false,
|
|
|
showVideoTypeContorl: false,
|
|
|
@@ -440,45 +351,21 @@ export default {
|
|
|
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'
|
|
|
- }
|
|
|
- ]
|
|
|
+ // 相机选择弹层的可选项(打开时按互斥规则过滤)
|
|
|
+ cameraSelectList: [],
|
|
|
+ // 主设备下的相机列表(接口获取,作为相机选择弹层可选项)
|
|
|
+ cameraList: []
|
|
|
}
|
|
|
},
|
|
|
onLoad(options){
|
|
|
this.d_id = options.d_id
|
|
|
- this.getControlDeviceConfigInfo()
|
|
|
+ this.device_id = options.deviceId || ''
|
|
|
+ // 管理员 tab 回显
|
|
|
+ this.deviceID = this.device_id
|
|
|
+ this.deviceName = options.name ? decodeURIComponent(options.name) : ''
|
|
|
+ this.getCameraConfig()
|
|
|
+ this.getCameraDeviceList()
|
|
|
+ // this.getControlDeviceConfigInfo()
|
|
|
uni.getStorage({
|
|
|
key:"myuser_type",
|
|
|
success:(res)=>{
|
|
|
@@ -500,14 +387,20 @@ export default {
|
|
|
this.showContorl = true
|
|
|
break;
|
|
|
case 'imageSize':
|
|
|
+ // 可选项来自当前相机配置返回的 options
|
|
|
+ this.currentSizeList = (item.photoSettings.imageSizeOptions || []).map(label => ({ label: label, value: label }))
|
|
|
this.showImageTypeContorl = true
|
|
|
break;
|
|
|
case 'videoSize':
|
|
|
+ this.currentSizeList = (item.photoSettings.videoSizeOptions || []).map(label => ({ label: label, value: label }))
|
|
|
this.showVideoTypeContorl = true
|
|
|
break;
|
|
|
case 'pirSensitivity':
|
|
|
this.showPirTypeContorl = true
|
|
|
break;
|
|
|
+ case 'pirInterval':
|
|
|
+ this.showPirIntervalContorl = true
|
|
|
+ break;
|
|
|
}
|
|
|
},
|
|
|
confirmDeviceItemContorl(e){
|
|
|
@@ -515,24 +408,28 @@ export default {
|
|
|
takephoto: ['photoSettings', 'photoModel'],
|
|
|
imageSize: ['photoSettings', 'imageSize'],
|
|
|
videoSize: ['photoSettings', 'videoSize'],
|
|
|
- pirSensitivity: ['warning', 'pirSensitivity']
|
|
|
+ pirSensitivity: ['warning', 'pirSensitivity'],
|
|
|
+ pirInterval: ['warning', 'triggerTimeInterval']
|
|
|
}
|
|
|
const target = fieldMap[this.currentFieldType]
|
|
|
if (this.currentItem && target) {
|
|
|
- this.$set(this.currentItem[target[0]], target[1], e[0].label)
|
|
|
+ // 统一写入 value(协议编码或选项串),显示由 formatXxx 转文案
|
|
|
+ this.$set(this.currentItem[target[0]], target[1], e[0].value)
|
|
|
}
|
|
|
},
|
|
|
- // photoModel编码转文案(与后台约定:0=自动,1=手动),已是文案的直接返回
|
|
|
+ // 拍照模式编码转文案(与PC端一致:0=拍照,1=录像,2=拍照+录像)
|
|
|
formatPhotoModel(value){
|
|
|
- if (value === '0') return '自动'
|
|
|
- if (value === '1') return '手动'
|
|
|
- return value || '自动'
|
|
|
+ const map = { '0': '拍照', '1': '录像', '2': '拍照+录像' }
|
|
|
+ return map[value] || value || '--'
|
|
|
},
|
|
|
- // 图片/视频大小:兼容mock编码(0=1280,1=720)与选择后存入的文案
|
|
|
+ // 图片/视频大小:直接显示选项串(如 4M/2560*1440)
|
|
|
formatImageSize(value){
|
|
|
- if (value == 0 || value === '1280') return '1280'
|
|
|
- if (value == 1 || value === '720') return '720'
|
|
|
- return value || '1280'
|
|
|
+ return value === '' || value === null || value === undefined ? '--' : value
|
|
|
+ },
|
|
|
+ // PIR灵敏度编码转文案(0=自动,1=低,2=中,3=高)
|
|
|
+ formatPirSensitivity(value){
|
|
|
+ const map = { '0': '自动', '1': '低', '2': '中', '3': '高' }
|
|
|
+ return map[value] || value || '--'
|
|
|
},
|
|
|
handleTabChildClick(item, tab){
|
|
|
item.activeTab = tab;
|
|
|
@@ -541,21 +438,26 @@ export default {
|
|
|
toggleChildItem(index){
|
|
|
this.actionChildItem = this.actionChildItem == index ? -1 : index
|
|
|
},
|
|
|
- // 失焦时校验:只保留正整数,范围1-1000(空/非法/小于1置为1,大于1000置为1000)
|
|
|
+ // 失焦时校验:只保留数字并按上下限截断(min 缺省为 1,传 0 表示允许 0,如拍摄限制的不限)
|
|
|
// 小程序上@input回传参数拿不到输入值,且边输入边改值会引发输入框错乱,所以统一在失焦时校正
|
|
|
- handlePositiveIntBlur(item, field){
|
|
|
+ handlePositiveIntBlur(item, field, max, min){
|
|
|
+ max = max || 1000
|
|
|
+ min = min === undefined ? 1 : min
|
|
|
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'
|
|
|
+ if (value === '') {
|
|
|
+ value = String(min)
|
|
|
+ } else {
|
|
|
+ value = String(Math.min(Math.max(Number(value), min), max))
|
|
|
}
|
|
|
this.$set(item, field, value)
|
|
|
},
|
|
|
openCameraIdPicker(field) {
|
|
|
this.currentCameraField = field
|
|
|
+ // 互斥:过滤掉已被其他相机项选中的选项
|
|
|
+ const fields = ['camera1ID', 'camera2ID', 'camera3ID']
|
|
|
+ this.cameraSelectList = this.cameraList.filter(c =>
|
|
|
+ fields.every(f => f === field || this[f] !== c.value)
|
|
|
+ )
|
|
|
this.showCameraSelect = true
|
|
|
},
|
|
|
confirmCameraSelect(e) {
|
|
|
@@ -569,7 +471,14 @@ export default {
|
|
|
}
|
|
|
this[this.currentCameraField] = value
|
|
|
},
|
|
|
+ // 循环拍摄间隔:时:分选择器(协议 Timer_Interval,00:00~23:59)
|
|
|
+ openIntervalPicker(item) {
|
|
|
+ this.currentIntervalItem = item
|
|
|
+ this.currentDefaultTime = item.timeSettings.photoTime || '00:01'
|
|
|
+ this.showDateTime = true
|
|
|
+ },
|
|
|
openTimePicker(item, field, index) {
|
|
|
+ this.currentIntervalItem = null
|
|
|
this.currentTimeItem = item
|
|
|
this.currentTimeField = field
|
|
|
this.currentTimeIndex = index
|
|
|
@@ -578,11 +487,18 @@ export default {
|
|
|
this.showDateTime = true
|
|
|
},
|
|
|
confirmTimePicker(e) {
|
|
|
+ const pad = (n) => ('0' + Number(n)).slice(-2)
|
|
|
+ const value = pad(e.hour) + ':' + pad(e.minute)
|
|
|
+ // 循环拍摄间隔:直接写入 HH:MM
|
|
|
+ if (this.currentIntervalItem) {
|
|
|
+ this.currentIntervalItem.timeSettings.photoTime = value
|
|
|
+ this.currentIntervalItem = null
|
|
|
+ return
|
|
|
+ }
|
|
|
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] || []
|
|
|
@@ -590,24 +506,24 @@ export default {
|
|
|
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' })
|
|
|
+ // 开始==结束视为未配置(如默认回显的 00:00-00:00),不参与校验
|
|
|
+ const configured = slots.filter(s => s.start && s.end && s.start !== s.end)
|
|
|
+ for (let i = 0; i < configured.length; i++) {
|
|
|
+ if (configured[i].start >= configured[i].end) {
|
|
|
+ uni.showToast({ title: configured[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
|
|
|
- }
|
|
|
+ for (let i = 0; i < configured.length - 1; i++) {
|
|
|
+ const a = configured[i]
|
|
|
+ const b = configured[i + 1]
|
|
|
+ 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) {
|
|
|
@@ -729,45 +645,98 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
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] + ''
|
|
|
- }
|
|
|
+ // 管理员 tab:保存设备名称与相机绑定;设置 tab:下发相机配置
|
|
|
+ if (this.activeTab === 'pestAnalysis') {
|
|
|
+ this.saveAdminInfo()
|
|
|
+ return
|
|
|
}
|
|
|
- newForm.st = newForm.st.replace(':00', '')
|
|
|
- this.$myRequest({
|
|
|
- url: '/api/api_gateway?method=forecast.send_control.device_control',
|
|
|
+ this.saveCameraConfig()
|
|
|
+ },
|
|
|
+ // 设置 tab:整包下发相机配置(未改动字段原样透传)
|
|
|
+ async saveCameraConfig(){
|
|
|
+ const device_config_data = this.deviceList.map(item => {
|
|
|
+ // 以回显时的原始配置为底,写回用户改动
|
|
|
+ const cfg = JSON.parse(JSON.stringify(item.rawConfig || {}));
|
|
|
+ const p = item.photoSettings;
|
|
|
+ const t = item.timeSettings;
|
|
|
+ const w = item.warning;
|
|
|
+ const o = item.other;
|
|
|
+ cfg.CAM_Mode = Number(p.photoModel);
|
|
|
+ if (p.imageSize && p.imageSizeOptions.length) {
|
|
|
+ cfg.CAM_ImageSize = { options: p.imageSizeOptions, Selected: Math.max(0, p.imageSizeOptions.indexOf(p.imageSize)) };
|
|
|
+ }
|
|
|
+ if (p.videoSize && p.videoSizeOptions.length) {
|
|
|
+ cfg.CAM_VideoSize = { options: p.videoSizeOptions, Selected: Math.max(0, p.videoSizeOptions.indexOf(p.videoSize)) };
|
|
|
+ }
|
|
|
+ cfg.CAM_Shooting = String(p.burstPhoto);
|
|
|
+ cfg.CAM_VideoLength = Number(p.videoLength);
|
|
|
+ cfg.CAM_MaxShooting = Number(p.photoInterval);
|
|
|
+ cfg.PIR_Enable = w.pirOpenOrClose ? 1 : 0;
|
|
|
+ cfg.PIR_Sensitivity = Number(w.pirSensitivity);
|
|
|
+ cfg.PIR_Interval = w.triggerTimeInterval;
|
|
|
+ cfg.Timer_Enable = t.timePhoto ? 1 : 0;
|
|
|
+ cfg.Timer_Interval = t.photoTime;
|
|
|
+ cfg.Timer_1Start = t.time1[0] || '00:00';
|
|
|
+ cfg.Timer_1End = t.time1[1] || '00:00';
|
|
|
+ cfg.Timer_2Start = t.time2[0] || '00:00';
|
|
|
+ cfg.Timer_2End = t.time2[1] || '00:00';
|
|
|
+ cfg.Timer_3Start = t.time3[0] || '00:00';
|
|
|
+ cfg.Timer_3End = t.time3[1] || '00:00';
|
|
|
+ cfg.Timer_Repeats = this.weeksToRepeats(t.weekLoop);
|
|
|
+ cfg.Other_Stamp = o.informationStamp ? 1 : 0;
|
|
|
+ cfg.Other_Cycle = o.autoOverWrite ? 1 : 0;
|
|
|
+ cfg.Other_DevName = o.photoName;
|
|
|
+ return { device_id: item.deviceId, device_config: cfg };
|
|
|
+ });
|
|
|
+ const res = await this.$myRequest({
|
|
|
+ url: '/api/api_gateway?method=forecast.shuhai.shuhai_two_camera_update_config',
|
|
|
method: 'POST',
|
|
|
data: {
|
|
|
- device_type_id: 3,
|
|
|
- d_id: this.d_id,
|
|
|
- config: JSON.stringify(newForm)
|
|
|
+ device_id: this.device_id,
|
|
|
+ device_config_data: JSON.stringify(device_config_data)
|
|
|
}
|
|
|
- }).then(res => {
|
|
|
- if (res) {
|
|
|
- // 设备控制修改成功
|
|
|
- uni.showToast({
|
|
|
- title: '设备控制修改成功!',
|
|
|
- icon: 'success',
|
|
|
- });
|
|
|
- } else {
|
|
|
- uni.showToast({
|
|
|
- title: '设备控制修改失败',
|
|
|
- icon: 'error',
|
|
|
- });
|
|
|
+ });
|
|
|
+ if (res) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存成功',
|
|
|
+ icon: 'success',
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存失败',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // ['周日','周一'...] → 按周日~周六位序的 7 位串
|
|
|
+ weeksToRepeats(weeks) {
|
|
|
+ const weekOrder = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
|
|
+ return weekOrder.map(name => ((weeks || []).indexOf(name) > -1 ? '1' : '0')).join('');
|
|
|
+ },
|
|
|
+ // 管理员 tab:保存设备名称与相机1/2/3绑定
|
|
|
+ async saveAdminInfo(){
|
|
|
+ const res = await this.$myRequest({
|
|
|
+ url: '/api/api_gateway?method=forecast.shuhai.shuhai_two_device_info_update',
|
|
|
+ method: 'POST',
|
|
|
+ data: {
|
|
|
+ device_id: this.device_id,
|
|
|
+ device_name: this.deviceName,
|
|
|
+ ding_one_device_id: this.camera1ID,
|
|
|
+ ding_two_device_id: this.camera2ID,
|
|
|
+ ding_three_device_id: this.camera3ID
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
+ if (res) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存成功',
|
|
|
+ icon: 'success',
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存失败',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
async getControlDeviceConfigInfo(){
|
|
|
const res = await this.$myRequest({
|
|
|
@@ -780,6 +749,98 @@ export default {
|
|
|
});
|
|
|
this.equipContrlForm = res
|
|
|
},
|
|
|
+ // 拉取相机配置并回显:按 camera_config 动态生成相机列表(返回几台显示几台)
|
|
|
+ async getCameraConfig(){
|
|
|
+ const res = await this.$myRequest({
|
|
|
+ url: '/api/api_gateway?method=forecast.shuhai.shuhai_two_camera_config',
|
|
|
+ method: 'POST',
|
|
|
+ data: {
|
|
|
+ device_id: this.device_id
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const configList = (res && res.camera_config) || [];
|
|
|
+ if (!configList.length) return;
|
|
|
+ // 相机编号回显(管理员 tab 的相机选择)
|
|
|
+ this.camera1ID = (configList[0] && configList[0].device_id) || ''
|
|
|
+ this.camera2ID = (configList[1] && configList[1].device_id) || ''
|
|
|
+ this.camera3ID = (configList[2] && configList[2].device_id) || ''
|
|
|
+ this.deviceList = configList.map((camera, index) => {
|
|
|
+ const cfg = (camera && camera.device_config) || {};
|
|
|
+ return {
|
|
|
+ label: '相机' + (index + 1),
|
|
|
+ content: '',
|
|
|
+ show: false,
|
|
|
+ activeTab: 'settings',
|
|
|
+ deviceId: (camera && camera.device_id) || '',
|
|
|
+ // 保存时以原始配置为底回传,未改动字段透传
|
|
|
+ rawConfig: cfg,
|
|
|
+ // 拍摄设置
|
|
|
+ photoSettings: {
|
|
|
+ photoModel: cfg.CAM_Mode !== undefined ? String(cfg.CAM_Mode) : '',
|
|
|
+ imageSize: this.sizeOf(cfg.CAM_ImageSize),
|
|
|
+ videoSize: this.sizeOf(cfg.CAM_VideoSize),
|
|
|
+ burstPhoto: cfg.CAM_Shooting !== undefined ? cfg.CAM_Shooting : '',
|
|
|
+ videoLength: cfg.CAM_VideoLength !== undefined ? cfg.CAM_VideoLength : '',
|
|
|
+ photoInterval: cfg.CAM_MaxShooting !== undefined ? cfg.CAM_MaxShooting : '',
|
|
|
+ // 大小可选项,供下拉选择用
|
|
|
+ imageSizeOptions: (cfg.CAM_ImageSize && cfg.CAM_ImageSize.options) || [],
|
|
|
+ videoSizeOptions: (cfg.CAM_VideoSize && cfg.CAM_VideoSize.options) || []
|
|
|
+ },
|
|
|
+ // 定时设置
|
|
|
+ timeSettings: {
|
|
|
+ // 开关绑布尔值:u-switch 外观只认 value 的布尔真假,字符串 "0" 会被当成开
|
|
|
+ timePhoto: cfg.Timer_Enable !== undefined ? Number(cfg.Timer_Enable) === 1 : false,
|
|
|
+ photoTime: cfg.Timer_Interval !== undefined ? cfg.Timer_Interval : '',
|
|
|
+ time1: [cfg.Timer_1Start || '', cfg.Timer_1End || ''],
|
|
|
+ time2: [cfg.Timer_2Start || '', cfg.Timer_2End || ''],
|
|
|
+ time3: [cfg.Timer_3Start || '', cfg.Timer_3End || ''],
|
|
|
+ weekLoop: this.repeatsToWeeks(cfg.Timer_Repeats)
|
|
|
+ },
|
|
|
+ // 触发报警设置
|
|
|
+ warning: {
|
|
|
+ pirOpenOrClose: cfg.PIR_Enable !== undefined ? Number(cfg.PIR_Enable) === 1 : false,
|
|
|
+ pirSensitivity: cfg.PIR_Sensitivity !== undefined ? String(cfg.PIR_Sensitivity) : '',
|
|
|
+ triggerTimeInterval: cfg.PIR_Interval !== undefined ? cfg.PIR_Interval : ''
|
|
|
+ },
|
|
|
+ // 其他设置
|
|
|
+ other: {
|
|
|
+ informationStamp: cfg.Other_Stamp !== undefined ? Number(cfg.Other_Stamp) === 1 : false,
|
|
|
+ autoOverWrite: cfg.Other_Cycle !== undefined ? Number(cfg.Other_Cycle) === 1 : false,
|
|
|
+ photoName: cfg.Other_DevName !== undefined ? cfg.Other_DevName : ''
|
|
|
+ }
|
|
|
+ };
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // {options, Selected} → 选中的选项文案
|
|
|
+ sizeOf(obj) {
|
|
|
+ return ((obj && obj.options) || [])[(obj && obj.Selected)] || ''
|
|
|
+ },
|
|
|
+ // 拉取主设备下的相机列表,作为相机1/2/3选择弹层的可选项
|
|
|
+ async getCameraDeviceList(){
|
|
|
+ const res = await this.$myRequest({
|
|
|
+ url: '/api/api_gateway?method=forecast.shuhai.get_shuhai_two_camera_device_list',
|
|
|
+ method: 'POST',
|
|
|
+ data: {
|
|
|
+ device_id: this.device_id
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const devices = (res && res.device) || [];
|
|
|
+ this.cameraList = devices
|
|
|
+ .map(d => d.camera_id)
|
|
|
+ .filter(Boolean)
|
|
|
+ .map(id => ({ label: id, value: id }));
|
|
|
+ },
|
|
|
+ // '1111111'(位序:周日~周六)→ 按周一~周日顺序的文案数组
|
|
|
+ repeatsToWeeks(repeats) {
|
|
|
+ const weekOrder = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
|
|
+ if (typeof repeats !== 'string' || repeats.length !== 7) return []
|
|
|
+ const selected = []
|
|
|
+ weekOrder.forEach((name, i) => {
|
|
|
+ if (repeats.charAt(i) === '1') selected.push(name)
|
|
|
+ })
|
|
|
+ // 按页面上周一~周日的展示顺序重排
|
|
|
+ return this.weekList.filter(day => selected.indexOf(day) > -1)
|
|
|
+ },
|
|
|
}
|
|
|
}
|
|
|
</script>
|