Commit 1c2f21524b460b5e618280b89e13e7e507efc89a
Committed by
xp.Huang
1 parent
fe27c91c
feat: 设备命令下发添加服务调用
Showing
5 changed files
with
1048 additions
and
384 deletions
| @@ -4,37 +4,47 @@ | @@ -4,37 +4,47 @@ | ||
| 4 | * data ((deviceProfileIds)) | 4 | * data ((deviceProfileIds)) |
| 5 | */ | 5 | */ |
| 6 | const getDeviceApi = (urlParams, data) => { | 6 | const getDeviceApi = (urlParams, data) => { |
| 7 | - const { | ||
| 8 | - page, | ||
| 9 | - pageSize, | ||
| 10 | - } = urlParams | ||
| 11 | - return uni.$u.http.post(`/yt/device?page=${page}&pageSize=${pageSize}`, data); | ||
| 12 | -}; | 7 | + const { page, pageSize } = urlParams |
| 8 | + return uni.$u.http.post(`/yt/device?page=${page}&pageSize=${pageSize}`, data) | ||
| 9 | +} | ||
| 13 | 10 | ||
| 14 | // 设备详情 | 11 | // 设备详情 |
| 15 | const getDeviceDetail = (id) => { | 12 | const getDeviceDetail = (id) => { |
| 16 | - return uni.$u.http.get(`/yt/device/${id}`); | ||
| 17 | -}; | 13 | + return uni.$u.http.get(`/yt/device/${id}`) |
| 14 | +} | ||
| 18 | 15 | ||
| 19 | //设备属性 | 16 | //设备属性 |
| 20 | const getAttribute = (deviceProfileId) => { | 17 | const getAttribute = (deviceProfileId) => { |
| 21 | - return uni.$u.http.get(`/yt/device/attributes/${deviceProfileId}`); | ||
| 22 | -}; | 18 | + return uni.$u.http.get(`/yt/device/attributes/${deviceProfileId}`) |
| 19 | +} | ||
| 23 | 20 | ||
| 24 | //命令下发 | 21 | //命令下发 |
| 25 | const issueCommand = (type, tbDeviceId, data) => { | 22 | const issueCommand = (type, tbDeviceId, data) => { |
| 26 | - return uni.$u.http.post(`/rpc/${type==='OneWay'?'oneway':'twoway'}/${tbDeviceId}`, data) | 23 | + return uni.$u.http.post(`/rpc/${type === 'OneWay' ? 'oneway' : 'twoway'}/${tbDeviceId}`, data) |
| 27 | } | 24 | } |
| 28 | 25 | ||
| 29 | //获取命令下发记录 | 26 | //获取命令下发记录 |
| 30 | const getRpcRecord = (params) => { | 27 | const getRpcRecord = (params) => { |
| 31 | - return uni.$u.http.get('/yt/rpc', params); | ||
| 32 | -}; | 28 | + return uni.$u.http.get('/yt/rpc', params) |
| 29 | +} | ||
| 30 | + | ||
| 31 | +// 获取设备状态 在线or离线 | ||
| 32 | +const getDeviceActiveTime = (entityId) => { | ||
| 33 | + return uni.$u.http.get(`/plugins/telemetry/DEVICE/${entityId}/values/attributes?keys=active`) | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +// 获取服务调用 | ||
| 37 | +const getModelServices = (params) => { | ||
| 38 | + const { deviceProfileId } = params | ||
| 39 | + return uni.$u.http.get(`/yt/things_model/get_services/${deviceProfileId}`) | ||
| 40 | +} | ||
| 33 | 41 | ||
| 34 | export default { | 42 | export default { |
| 35 | - getDeviceApi, | ||
| 36 | - getDeviceDetail, | ||
| 37 | - getAttribute, | ||
| 38 | - issueCommand, | ||
| 39 | - getRpcRecord | ||
| 40 | -} | ||
| 43 | + getDeviceApi, | ||
| 44 | + getDeviceDetail, | ||
| 45 | + getAttribute, | ||
| 46 | + issueCommand, | ||
| 47 | + getRpcRecord, | ||
| 48 | + getModelServices, | ||
| 49 | + getDeviceActiveTime, | ||
| 50 | +} |
| @@ -6,8 +6,7 @@ | @@ -6,8 +6,7 @@ | ||
| 6 | <view class="basic-header"> | 6 | <view class="basic-header"> |
| 7 | <view class="u-flex"> | 7 | <view class="u-flex"> |
| 8 | <view class="pl-3"> | 8 | <view class="pl-3"> |
| 9 | - <u-icon v-if="deviceDetail.deviceInfo.longitude !== ''" @click="handleClick" | ||
| 10 | - name="map-fill"></u-icon> | 9 | + <u-icon v-if="deviceDetail.deviceInfo.longitude !== ''" @click="handleClick" name="map-fill"></u-icon> |
| 11 | </view> | 10 | </view> |
| 12 | <view class="basic-text text-clip ml-2"> | 11 | <view class="basic-text text-clip ml-2"> |
| 13 | {{ deviceDetail.alias ? deviceDetail.alias : deviceDetail.name }} | 12 | {{ deviceDetail.alias ? deviceDetail.alias : deviceDetail.name }} |
| @@ -17,13 +16,13 @@ | @@ -17,13 +16,13 @@ | ||
| 17 | </view> | 16 | </view> |
| 18 | </view> | 17 | </view> |
| 19 | <!-- 命令下发 设备在线并且不是网关子设备 --> | 18 | <!-- 命令下发 设备在线并且不是网关子设备 --> |
| 20 | - <view class="mr-2" v-if="deviceDetail.deviceState === 'ONLINE' && deviceDetail.transportType!==deviceTypeNum.GBT"> | 19 | + <view class="mr-2" v-if="deviceDetail.deviceState === 'ONLINE' && deviceDetail.transportType !== deviceTypeNum.GBT"> |
| 21 | <!-- #ifdef MP --> | 20 | <!-- #ifdef MP --> |
| 22 | - <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="handleMpShowModal" /> | 21 | + <u-button type="primary" shape="circle" size="mini" text="命令下发" @click="handleMpShowModal" /> |
| 23 | <!-- #endif --> | 22 | <!-- #endif --> |
| 24 | <!-- #ifdef APP-PLUS --> | 23 | <!-- #ifdef APP-PLUS --> |
| 25 | <view class="cu-item" @tap="handleAppShowModal" data-target="Modal"> | 24 | <view class="cu-item" @tap="handleAppShowModal" data-target="Modal"> |
| 26 | - <text>下发命令</text> | 25 | + <text>命令下发</text> |
| 27 | </view> | 26 | </view> |
| 28 | <!-- #endif --> | 27 | <!-- #endif --> |
| 29 | </view> | 28 | </view> |
| @@ -79,7 +78,7 @@ | @@ -79,7 +78,7 @@ | ||
| 79 | <radio :value="item.value" :checked="index === current" /> | 78 | <radio :value="item.value" :checked="index === current" /> |
| 80 | </view> | 79 | </view> |
| 81 | <view style="width:10rpx"></view> | 80 | <view style="width:10rpx"></view> |
| 82 | - <view class="ml-1">{{item.name}}</view> | 81 | + <view class="ml-1">{{ item.name }}</view> |
| 83 | </view> | 82 | </view> |
| 84 | </label> | 83 | </label> |
| 85 | </radio-group> | 84 | </radio-group> |
| @@ -87,9 +86,9 @@ | @@ -87,9 +86,9 @@ | ||
| 87 | </view> | 86 | </view> |
| 88 | <view class="app-command-body"> | 87 | <view class="app-command-body"> |
| 89 | <textarea class="app-command-textarea" v-model="inputCommandContent" | 88 | <textarea class="app-command-textarea" v-model="inputCommandContent" |
| 90 | - :placeholder="`请输入下发内容${isShowTCP?'(字符串格式)':'(json格式)'}`" /> | ||
| 91 | - <u-icon @click="handleCopy(copyTextValue)" v-if="!isShowTCP" name="question-circle" | ||
| 92 | - color="#2979ff" size="28" class="ml-10"> | 89 | + :placeholder="`请输入下发内容${isShowTCP ? '(字符串格式)' : '(json格式)'}`" /> |
| 90 | + <u-icon @click="handleCopy(copyTextValue)" v-if="!isShowTCP" name="question-circle" color="#2979ff" | ||
| 91 | + size="28" class="ml-10"> | ||
| 93 | </u-icon> | 92 | </u-icon> |
| 94 | </view> | 93 | </view> |
| 95 | <view class="app-command-buttons"> | 94 | <view class="app-command-buttons"> |
| @@ -104,315 +103,326 @@ | @@ -104,315 +103,326 @@ | ||
| 104 | <!-- #ifdef MP --> | 103 | <!-- #ifdef MP --> |
| 105 | <!-- u-modal在app端弹窗层级无法覆盖背景色 --> | 104 | <!-- u-modal在app端弹窗层级无法覆盖背景色 --> |
| 106 | <mp-command-issuance ref="mpCommandIssuanceRef" :isShowTCP="isShowTCP" :showModal="mpShowModal" | 105 | <mp-command-issuance ref="mpCommandIssuanceRef" :isShowTCP="isShowTCP" :showModal="mpShowModal" |
| 107 | - @hideModal="hideMpModal" @cancelCommand="cancelCommand" | 106 | + :deviceDetail="deviceDetail" @hideModal="hideMpModal" @cancelCommand="cancelCommand" |
| 108 | @confirmCommand="confirmCommand"></mp-command-issuance> | 107 | @confirmCommand="confirmCommand"></mp-command-issuance> |
| 109 | <!-- #endif --> | 108 | <!-- #endif --> |
| 110 | </view> | 109 | </view> |
| 111 | </template> | 110 | </template> |
| 112 | 111 | ||
| 113 | <script> | 112 | <script> |
| 114 | - import {formatToDate} from '@/plugins/utils.js'; | ||
| 115 | - import api from '@/api/index.js'; | ||
| 116 | - import mpCommandIssuance from './mp-command-issuance.vue'; | ||
| 117 | - import {commandTypeList} from '../config/data.js' | ||
| 118 | - import {useShowModal} from '@/plugins/utils.js' | ||
| 119 | - import {deviceTypeNum} from '../config/data' | ||
| 120 | - | ||
| 121 | - export default { | ||
| 122 | - components: { | ||
| 123 | - mpCommandIssuance, | ||
| 124 | - }, | ||
| 125 | - props: { | ||
| 126 | - deviceDetail: { | ||
| 127 | - type: Object, | ||
| 128 | - default: () => ({}) | 113 | +import { formatToDate } from '@/plugins/utils.js'; |
| 114 | +import api from '@/api/index.js'; | ||
| 115 | +import mpCommandIssuance from './mp-command-issuance.vue'; | ||
| 116 | +import { commandTypeList } from '../config/data.js' | ||
| 117 | +import { useShowModal } from '@/plugins/utils.js' | ||
| 118 | +import { deviceTypeNum } from '../config/data' | ||
| 119 | +import deviceDetail from '../device-detail.vue'; | ||
| 120 | + | ||
| 121 | +export default { | ||
| 122 | + components: { | ||
| 123 | + mpCommandIssuance, | ||
| 124 | + }, | ||
| 125 | + props: { | ||
| 126 | + deviceDetail: { | ||
| 127 | + type: Object, | ||
| 128 | + default: () => ({}) | ||
| 129 | + } | ||
| 130 | + }, | ||
| 131 | + data() { | ||
| 132 | + return { | ||
| 133 | + showNativeModal: false, | ||
| 134 | + current: 0, | ||
| 135 | + commandTypeList, | ||
| 136 | + deviceTypeNum: deviceTypeNum, | ||
| 137 | + commandTypeStr: 'OneWay', | ||
| 138 | + inputCommandContent: '', | ||
| 139 | + mpShowModal: false, | ||
| 140 | + commandValue: {}, | ||
| 141 | + isShowTCP: false, //用于下发命令时判断是否是TCP/UDP | ||
| 142 | + modalName: null, | ||
| 143 | + copyTextValue: { | ||
| 144 | + "method": "methodThingskit", | ||
| 145 | + "params": { | ||
| 146 | + "pin": 7, | ||
| 147 | + "value": 1 | ||
| 148 | + } | ||
| 129 | } | 149 | } |
| 150 | + }; | ||
| 151 | + }, | ||
| 152 | + computed: { | ||
| 153 | + deviceStatus() { | ||
| 154 | + return this.deviceDetail.deviceState === 'INACTIVE' ? '待激活' : this.deviceDetail.deviceState === 'ONLINE' ? | ||
| 155 | + '在线' : '离线'; | ||
| 130 | }, | 156 | }, |
| 131 | - data() { | ||
| 132 | - return { | ||
| 133 | - showNativeModal: false, | ||
| 134 | - current: 0, | ||
| 135 | - commandTypeList, | ||
| 136 | - deviceTypeNum:deviceTypeNum, | ||
| 137 | - commandTypeStr: 'OneWay', | ||
| 138 | - inputCommandContent: '', | ||
| 139 | - mpShowModal: false, | ||
| 140 | - commandValue: {}, | ||
| 141 | - isShowTCP: false, //用于下发命令时判断是否是TCP/UDP | ||
| 142 | - modalName: null, | ||
| 143 | - copyTextValue: { | ||
| 144 | - "method": "methodThingskit", | ||
| 145 | - "params": { | ||
| 146 | - "pin": 7, | ||
| 147 | - "value": 1 | 157 | + deviceType() { |
| 158 | + return this.deviceDetail.deviceType === 'DIRECT_CONNECTION' ? | ||
| 159 | + '直连设备' : | ||
| 160 | + this.deviceDetail.deviceType === 'GATEWAY' ? | ||
| 161 | + '网关设备' : | ||
| 162 | + this.deviceDetail.deviceType === 'SENSOR' ? | ||
| 163 | + '网关子设备' : | ||
| 164 | + ''; | ||
| 165 | + }, | ||
| 166 | + alarmStatus() { | ||
| 167 | + return this.deviceDetail.alarmStatus === '0' ? '否' : '是'; | ||
| 168 | + }, | ||
| 169 | + formatLastOnlineTime() { | ||
| 170 | + return formatToDate(Number(this.deviceDetail.lastOnlineTime), 'YYYY-MM-DD HH:mm:ss'); | ||
| 171 | + } | ||
| 172 | + }, | ||
| 173 | + beforeCreate() { | ||
| 174 | + this.modalName = null | ||
| 175 | + }, | ||
| 176 | + onLoad() { | ||
| 177 | + // 隐藏原生的tabbar | ||
| 178 | + uni.hideTabBar(); | ||
| 179 | + this.modalName = null | ||
| 180 | + }, | ||
| 181 | + methods: { | ||
| 182 | + handleCopy(value) { | ||
| 183 | + useShowModal(JSON.stringify(value), '命令下发', '复制内容').then(res => { | ||
| 184 | + uni.setClipboardData({ | ||
| 185 | + data: JSON.stringify(value), | ||
| 186 | + success: () => { | ||
| 187 | + uni.showToast({ | ||
| 188 | + title: '复制成功' | ||
| 189 | + }) | ||
| 148 | } | 190 | } |
| 191 | + }); | ||
| 192 | + }) | ||
| 193 | + }, | ||
| 194 | + radioChange: function (evt) { | ||
| 195 | + for (let i = 0; i < this.commandTypeList.length; i++) { | ||
| 196 | + if (this.items[i].value === evt.detail.value) { | ||
| 197 | + this.current = i; | ||
| 198 | + break; | ||
| 149 | } | 199 | } |
| 200 | + } | ||
| 201 | + this.commandTypeStr = evt.detail.value | ||
| 202 | + }, | ||
| 203 | + formatTextStatus(deviceState) { | ||
| 204 | + return deviceState === 'INACTIVE' ? '#666' : deviceState === 'ONLINE' ? '#377DFF' : '#DE4437'; | ||
| 205 | + }, | ||
| 206 | + handleClick() { | ||
| 207 | + const data = { | ||
| 208 | + longitude: this.deviceDetail.deviceInfo.longitude || 0, | ||
| 209 | + latitude: this.deviceDetail.deviceInfo.latitude || 0 | ||
| 150 | }; | 210 | }; |
| 211 | + uni.navigateTo({ | ||
| 212 | + url: '/device-subpackage/device-detail/device-position?data=' + JSON.stringify(data) | ||
| 213 | + }); | ||
| 151 | }, | 214 | }, |
| 152 | - computed: { | ||
| 153 | - deviceStatus() { | ||
| 154 | - return this.deviceDetail.deviceState === 'INACTIVE' ? '待激活' : this.deviceDetail.deviceState === 'ONLINE' ? | ||
| 155 | - '在线' : '离线'; | ||
| 156 | - }, | ||
| 157 | - deviceType() { | ||
| 158 | - return this.deviceDetail.deviceType === 'DIRECT_CONNECTION' ? | ||
| 159 | - '直连设备' : | ||
| 160 | - this.deviceDetail.deviceType === 'GATEWAY' ? | ||
| 161 | - '网关设备' : | ||
| 162 | - this.deviceDetail.deviceType === 'SENSOR' ? | ||
| 163 | - '网关子设备' : | ||
| 164 | - ''; | ||
| 165 | - }, | ||
| 166 | - alarmStatus() { | ||
| 167 | - return this.deviceDetail.alarmStatus === '0' ? '否' : '是'; | ||
| 168 | - }, | ||
| 169 | - formatLastOnlineTime() { | ||
| 170 | - return formatToDate(Number(this.deviceDetail.lastOnlineTime), 'YYYY-MM-DD HH:mm:ss'); | ||
| 171 | - } | 215 | + disabledScroll() { |
| 216 | + return; | ||
| 172 | }, | 217 | }, |
| 173 | - beforeCreate() { | ||
| 174 | - this.modalName = null | 218 | + handleAppShowModal(e) { |
| 219 | + this.modalName = e.currentTarget.dataset.target; | ||
| 220 | + this.showNativeModal = true | ||
| 175 | }, | 221 | }, |
| 176 | - onLoad() { | ||
| 177 | - // 隐藏原生的tabbar | ||
| 178 | - uni.hideTabBar(); | ||
| 179 | - this.modalName = null | 222 | + handleMpShowModal() { |
| 223 | + const { | ||
| 224 | + transportType | ||
| 225 | + } = this.deviceDetail.deviceProfile; | ||
| 226 | + this.isShowTCP = transportType == 'TCP' ? true : false; | ||
| 227 | + this.mpShowModal = true; | ||
| 180 | }, | 228 | }, |
| 181 | - methods: { | ||
| 182 | - handleCopy(value) { | ||
| 183 | - useShowModal(JSON.stringify(value), '命令下发', '复制内容').then(res => { | ||
| 184 | - uni.setClipboardData({ | ||
| 185 | - data: JSON.stringify(value), | ||
| 186 | - success: () => { | ||
| 187 | - uni.showToast({ | ||
| 188 | - title: '复制成功' | ||
| 189 | - }) | ||
| 190 | - } | ||
| 191 | - }); | ||
| 192 | - }) | ||
| 193 | - }, | ||
| 194 | - radioChange: function(evt) { | ||
| 195 | - for (let i = 0; i < this.commandTypeList.length; i++) { | ||
| 196 | - if (this.items[i].value === evt.detail.value) { | ||
| 197 | - this.current = i; | ||
| 198 | - break; | ||
| 199 | - } | 229 | + hideMpModal() { |
| 230 | + this.mpShowModal = false; | ||
| 231 | + }, | ||
| 232 | + hideAppModal() { | ||
| 233 | + this.modalName = null; | ||
| 234 | + this.showNativeModal = false | ||
| 235 | + }, | ||
| 236 | + confirmCommand(commandType, callType, values) { | ||
| 237 | + this.handleCommand(commandType, callType, values) | ||
| 238 | + }, | ||
| 239 | + cancelCommand() { | ||
| 240 | + this.hideMpModal(); | ||
| 241 | + this.hideAppModal(); | ||
| 242 | + this.commandTypeStr = 'OneWay' | ||
| 243 | + this.inputCommandContent = '' | ||
| 244 | + this.$nextTick(() => { | ||
| 245 | + this.$refs.mpCommandIssuanceRef.reset() | ||
| 246 | + }) | ||
| 247 | + }, | ||
| 248 | + handleAppCommand() { | ||
| 249 | + this.handleCommand(this.commandTypeStr, this.inputCommandContent) | ||
| 250 | + }, | ||
| 251 | + async handleCommand(commandType, callType, values) { | ||
| 252 | + if (!values) return uni.$u.toast('请输入下发内容~'); | ||
| 253 | + if(callType=='TwoWay'){ | ||
| 254 | + const result = await api.deviceApi.getDeviceActiveTime(this.deviceDetail.tbDeviceId) | ||
| 255 | + const [firsetItem] = result || [] | ||
| 256 | + if (!firsetItem.value) { | ||
| 257 | + return uni.$u.toast('当前设备不在线~') | ||
| 200 | } | 258 | } |
| 201 | - this.commandTypeStr = evt.detail.value | ||
| 202 | - }, | ||
| 203 | - formatTextStatus(deviceState) { | ||
| 204 | - return deviceState === 'INACTIVE' ? '#666' : deviceState === 'ONLINE' ? '#377DFF' : '#DE4437'; | ||
| 205 | - }, | ||
| 206 | - handleClick() { | ||
| 207 | - const data = { | ||
| 208 | - longitude: this.deviceDetail.deviceInfo.longitude || 0, | ||
| 209 | - latitude: this.deviceDetail.deviceInfo.latitude || 0 | ||
| 210 | - }; | ||
| 211 | - uni.navigateTo({ | ||
| 212 | - url: '/device-subpackage/device-detail/device-position?data=' + JSON.stringify(data) | ||
| 213 | - }); | ||
| 214 | - }, | ||
| 215 | - disabledScroll() { | ||
| 216 | - return; | ||
| 217 | - }, | ||
| 218 | - handleAppShowModal(e) { | ||
| 219 | - this.modalName = e.currentTarget.dataset.target; | ||
| 220 | - this.showNativeModal = true | ||
| 221 | - }, | ||
| 222 | - handleMpShowModal() { | ||
| 223 | - const { | ||
| 224 | - transportType | ||
| 225 | - } = this.deviceDetail.deviceProfile; | ||
| 226 | - this.isShowTCP = transportType == 'TCP' ? true : false; | ||
| 227 | - this.mpShowModal = true; | ||
| 228 | - }, | ||
| 229 | - hideMpModal() { | ||
| 230 | - this.mpShowModal = false; | ||
| 231 | - }, | ||
| 232 | - hideAppModal() { | ||
| 233 | - this.modalName = null; | ||
| 234 | - this.showNativeModal = false | ||
| 235 | - }, | ||
| 236 | - confirmCommand(commandType, inputCommandVal) { | ||
| 237 | - this.handleCommand(commandType, inputCommandVal) | ||
| 238 | - }, | ||
| 239 | - cancelCommand() { | ||
| 240 | - this.hideMpModal(); | ||
| 241 | - this.hideAppModal(); | ||
| 242 | - this.commandTypeStr = 'OneWay' | ||
| 243 | - this.inputCommandContent = '' | ||
| 244 | - this.$nextTick(() => { | ||
| 245 | - this.$refs.mpCommandIssuanceRef.reset() | ||
| 246 | - }) | ||
| 247 | - }, | ||
| 248 | - handleAppCommand() { | ||
| 249 | - this.handleCommand(this.commandTypeStr, this.inputCommandContent) | ||
| 250 | - }, | ||
| 251 | - async handleCommand(commandType, inputCommandVal) { | ||
| 252 | - if (!inputCommandVal) return uni.$u.toast('请输入下发内容~'); | 259 | + } |
| 260 | + | ||
| 261 | + this.commandValue.persistent = true; | ||
| 262 | + this.commandValue.additionalInfo = { | ||
| 263 | + cmdType: commandType == 0 ? 0 : 1 | ||
| 264 | + }; | ||
| 265 | + this.commandValue.method = 'methodThingskit'; | ||
| 266 | + this.commandValue.params = values; | ||
| 267 | + if (commandType == 0) {//下发类型是自定义时 | ||
| 253 | if (this.isShowTCP) { | 268 | if (this.isShowTCP) { |
| 254 | //TCP的格式只能是字符串 | 269 | //TCP的格式只能是字符串 |
| 255 | const zg = /^[0-9a-zA-Z]*$/; | 270 | const zg = /^[0-9a-zA-Z]*$/; |
| 256 | - if (!zg.test(inputCommandVal)) { | 271 | + if (!zg.test(values)) { |
| 257 | uni.$u.toast('输入的内容只能是字母和数字的组合'); | 272 | uni.$u.toast('输入的内容只能是字母和数字的组合'); |
| 258 | return; | 273 | return; |
| 259 | } | 274 | } |
| 260 | - this.commandValue.params = inputCommandVal; | 275 | + this.commandValue.params = values; |
| 261 | } else { | 276 | } else { |
| 262 | - this.commandValue.params = JSON.parse(inputCommandVal); | 277 | + this.commandValue.params = JSON.parse(values); |
| 263 | } | 278 | } |
| 264 | - this.commandValue.persistent = true; | ||
| 265 | - this.commandValue.additionalInfo = { | ||
| 266 | - cmdType: 'API' | ||
| 267 | - }; | ||
| 268 | - this.commandValue.method = 'methodThingskit'; | ||
| 269 | - this.commandValue.params = inputCommandVal; | ||
| 270 | - await api.deviceApi.issueCommand(commandType, this.deviceDetail.tbDeviceId, this.commandValue); | ||
| 271 | - this.cancelCommand(); | ||
| 272 | - uni.$u.toast('下发成功~'); | ||
| 273 | - | ||
| 274 | - }, | 279 | + } |
| 280 | + | ||
| 281 | + await api.deviceApi.issueCommand(callType, this.deviceDetail.tbDeviceId, this.commandValue); | ||
| 282 | + this.cancelCommand(); | ||
| 283 | + uni.$u.toast('下发成功~'); | ||
| 284 | + }, | ||
| 275 | 285 | ||
| 276 | - } | ||
| 277 | - }; | 286 | + } |
| 287 | +}; | ||
| 278 | </script> | 288 | </script> |
| 279 | 289 | ||
| 280 | <style lang="scss" scoped> | 290 | <style lang="scss" scoped> |
| 281 | - @import url('../static/modal.css'); | 291 | +@import url('../static/modal.css'); |
| 282 | 292 | ||
| 283 | - .app-command-content { | ||
| 284 | - .app-command-text { | ||
| 285 | - display: flex; | ||
| 286 | - justify-content: center; | ||
| 287 | - align-items: center; | 293 | +.app-command-content { |
| 294 | + .app-command-text { | ||
| 295 | + display: flex; | ||
| 296 | + justify-content: center; | ||
| 297 | + align-items: center; | ||
| 288 | 298 | ||
| 289 | - text { | ||
| 290 | - font-weight: 700; | ||
| 291 | - } | 299 | + text { |
| 300 | + font-weight: 700; | ||
| 292 | } | 301 | } |
| 302 | + } | ||
| 293 | 303 | ||
| 294 | - .app-command-type { | ||
| 295 | - display: flex; | ||
| 296 | - margin-top: 20rpx; | ||
| 297 | - margin-left: 20rpx; | 304 | + .app-command-type { |
| 305 | + display: flex; | ||
| 306 | + margin-top: 20rpx; | ||
| 307 | + margin-left: 20rpx; | ||
| 298 | 308 | ||
| 299 | - text { | ||
| 300 | - font-weight: 700; | ||
| 301 | - } | 309 | + text { |
| 310 | + font-weight: 700; | ||
| 302 | } | 311 | } |
| 312 | + } | ||
| 303 | 313 | ||
| 304 | - .app-command-body { | ||
| 305 | - display: flex; | ||
| 306 | - align-items: center; | ||
| 307 | - justify-content: space-between; | ||
| 308 | - margin-top: 20rpx; | ||
| 309 | - margin-left: 20rpx; | 314 | + .app-command-body { |
| 315 | + display: flex; | ||
| 316 | + align-items: center; | ||
| 317 | + justify-content: space-between; | ||
| 318 | + margin-top: 20rpx; | ||
| 319 | + margin-left: 20rpx; | ||
| 310 | 320 | ||
| 311 | - .app-command-textarea { | ||
| 312 | - width: 625rpx; | ||
| 313 | - height: 400rpx; | ||
| 314 | - background: #FFFFFF; | ||
| 315 | - box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.03); | ||
| 316 | - border-radius: 10px; | ||
| 317 | - } | 321 | + .app-command-textarea { |
| 322 | + width: 625rpx; | ||
| 323 | + height: 400rpx; | ||
| 324 | + background: #FFFFFF; | ||
| 325 | + box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.03); | ||
| 326 | + border-radius: 10px; | ||
| 318 | } | 327 | } |
| 328 | + } | ||
| 319 | 329 | ||
| 320 | - .app-command-buttons { | ||
| 321 | - display: flex; | ||
| 322 | - align-items: center; | ||
| 323 | - justify-content: space-evenly; | ||
| 324 | - height: 85rpx; | ||
| 325 | - margin-top: 20rpx; | ||
| 326 | - margin-bottom: 20rpx; | 330 | + .app-command-buttons { |
| 331 | + display: flex; | ||
| 332 | + align-items: center; | ||
| 333 | + justify-content: space-evenly; | ||
| 334 | + height: 85rpx; | ||
| 335 | + margin-top: 20rpx; | ||
| 336 | + margin-bottom: 20rpx; | ||
| 327 | 337 | ||
| 328 | - .cancel-button { | ||
| 329 | - width: 300rpx; | ||
| 330 | - background: #e3e3e5; | ||
| 331 | - height: 85rpx; | ||
| 332 | - border-radius: 38rpx; | ||
| 333 | - line-height: 85rpx; | 338 | + .cancel-button { |
| 339 | + width: 300rpx; | ||
| 340 | + background: #e3e3e5; | ||
| 341 | + height: 85rpx; | ||
| 342 | + border-radius: 38rpx; | ||
| 343 | + line-height: 85rpx; | ||
| 334 | 344 | ||
| 335 | - .cancel-text { | ||
| 336 | - color: #333333 | ||
| 337 | - } | 345 | + .cancel-text { |
| 346 | + color: #333333 | ||
| 338 | } | 347 | } |
| 348 | + } | ||
| 339 | 349 | ||
| 340 | - .confrim-button { | ||
| 341 | - width: 300rpx; | ||
| 342 | - background: #3388ff; | ||
| 343 | - border-radius: 38rpx; | ||
| 344 | - height: 85rpx; | ||
| 345 | - line-height: 85rpx; | 350 | + .confrim-button { |
| 351 | + width: 300rpx; | ||
| 352 | + background: #3388ff; | ||
| 353 | + border-radius: 38rpx; | ||
| 354 | + height: 85rpx; | ||
| 355 | + line-height: 85rpx; | ||
| 346 | 356 | ||
| 347 | - .confrim-text { | ||
| 348 | - color: white | ||
| 349 | - } | 357 | + .confrim-text { |
| 358 | + color: white | ||
| 350 | } | 359 | } |
| 351 | } | 360 | } |
| 352 | } | 361 | } |
| 362 | +} | ||
| 353 | 363 | ||
| 354 | - .basic-page { | ||
| 355 | - padding: 0 30rpx; | 364 | +.basic-page { |
| 365 | + padding: 0 30rpx; | ||
| 356 | 366 | ||
| 357 | - .basic-header { | ||
| 358 | - display: flex; | ||
| 359 | - justify-content: space-between; | ||
| 360 | - align-items: center; | ||
| 361 | - height: 140rpx; | ||
| 362 | - background-color: #fff; | ||
| 363 | - border-radius: 20rpx; | 367 | + .basic-header { |
| 368 | + display: flex; | ||
| 369 | + justify-content: space-between; | ||
| 370 | + align-items: center; | ||
| 371 | + height: 140rpx; | ||
| 372 | + background-color: #fff; | ||
| 373 | + border-radius: 20rpx; | ||
| 364 | 374 | ||
| 365 | - .basic-text { | ||
| 366 | - width: 370rpx; | ||
| 367 | - } | 375 | + .basic-text { |
| 376 | + width: 370rpx; | ||
| 377 | + } | ||
| 368 | 378 | ||
| 369 | - .cu-item { | ||
| 370 | - background: #3388ff; | ||
| 371 | - border-radius: 12px; | ||
| 372 | - width: 120rpx; | ||
| 373 | - height: 48rpx; | ||
| 374 | - text-align: center; | ||
| 375 | - line-height: 40rpx; | 379 | + .cu-item { |
| 380 | + background: #3388ff; | ||
| 381 | + border-radius: 12px; | ||
| 382 | + width: 120rpx; | ||
| 383 | + height: 48rpx; | ||
| 384 | + text-align: center; | ||
| 385 | + line-height: 40rpx; | ||
| 376 | 386 | ||
| 377 | - text { | ||
| 378 | - font-size: 12px; | ||
| 379 | - font-family: PingFangSC-Regular, PingFang SC; | ||
| 380 | - font-weight: 400; | ||
| 381 | - color: #ffffff; | ||
| 382 | - } | 387 | + text { |
| 388 | + font-size: 12px; | ||
| 389 | + font-family: PingFangSC-Regular, PingFang SC; | ||
| 390 | + font-weight: 400; | ||
| 391 | + color: #ffffff; | ||
| 383 | } | 392 | } |
| 393 | + } | ||
| 384 | 394 | ||
| 385 | - .basic-text-status { | ||
| 386 | - font-size: 14px; | ||
| 387 | - } | 395 | + .basic-text-status { |
| 396 | + font-size: 14px; | ||
| 388 | } | 397 | } |
| 398 | + } | ||
| 389 | 399 | ||
| 390 | - .detail { | ||
| 391 | - background-color: #fff; | ||
| 392 | - margin-top: 30rpx; | ||
| 393 | - border-radius: 20rpx; | ||
| 394 | - width: 690rpx; | 400 | + .detail { |
| 401 | + background-color: #fff; | ||
| 402 | + margin-top: 30rpx; | ||
| 403 | + border-radius: 20rpx; | ||
| 404 | + width: 690rpx; | ||
| 395 | 405 | ||
| 396 | - .detail-item { | ||
| 397 | - padding: 30rpx; | ||
| 398 | - display: flex; | ||
| 399 | - align-items: center; | 406 | + .detail-item { |
| 407 | + padding: 30rpx; | ||
| 408 | + display: flex; | ||
| 409 | + align-items: center; | ||
| 400 | 410 | ||
| 401 | - .detail-label { | ||
| 402 | - color: #333; | ||
| 403 | - font-size: 15px; | ||
| 404 | - } | 411 | + .detail-label { |
| 412 | + color: #333; | ||
| 413 | + font-size: 15px; | ||
| 414 | + } | ||
| 405 | 415 | ||
| 406 | - .detail-value { | ||
| 407 | - color: #666; | ||
| 408 | - font-size: 14px; | ||
| 409 | - margin-left: 30rpx; | ||
| 410 | - } | 416 | + .detail-value { |
| 417 | + color: #666; | ||
| 418 | + font-size: 14px; | ||
| 419 | + margin-left: 30rpx; | ||
| 411 | } | 420 | } |
| 412 | } | 421 | } |
| 413 | } | 422 | } |
| 423 | +} | ||
| 414 | 424 | ||
| 415 | - /deep/ .u-modal__content { | ||
| 416 | - padding: 30rpx 0 !important; | ||
| 417 | - } | 425 | +/deep/ .u-modal__content { |
| 426 | + padding: 30rpx 0 !important; | ||
| 427 | +} | ||
| 418 | </style> | 428 | </style> |
| 1 | <template> | 1 | <template> |
| 2 | - <view class="mp-u-modal"> | ||
| 3 | - <u-modal :mask-close-able="true" :show="showModal" closeOnClickOverlay :showConfirmButton="false" | ||
| 4 | - @close="$emit('hideModal')" @touchmove.stop.prevent="disabledScroll" z-index="99999"> | ||
| 5 | - <view class="w-100 modal-content"> | ||
| 6 | - <view class="header-title">命令下发</view> | ||
| 7 | - <view class="u-flex"> | ||
| 8 | - <text class="type-text">下发类型:</text> | ||
| 9 | - <u-radio-group v-model="commandType" placement="row"> | ||
| 10 | - <u-radio activeColor="#3388FF" label="单向" name="OneWay"></u-radio> | ||
| 11 | - <view style="margin: 0 20rpx;"></view> | ||
| 12 | - <u-radio activeColor="#3388FF" label="双向" name="TwoWay"></u-radio> | ||
| 13 | - </u-radio-group> | ||
| 14 | - </view> | ||
| 15 | - <view class="content-body"> | ||
| 16 | - <div class="u-flex u-row-between"> | ||
| 17 | - <u--textarea :placeholder="`请输入下发内容${isShowTCP?'(字符串格式)':'(json格式)'}`" | ||
| 18 | - v-model="inputCommandVal" /> | ||
| 19 | - <u-icon v-if="!isShowTCP" @click="handleCopy(copyTextValue)" name="question-circle" | ||
| 20 | - color="#2979ff" size="28" class="ml-10"> | ||
| 21 | - </u-icon> | ||
| 22 | - </div> | ||
| 23 | - </view> | ||
| 24 | - <view class="button-group"> | ||
| 25 | - <view> | ||
| 26 | - <u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="取消" | ||
| 27 | - @click="cancelCommand"></u-button> | ||
| 28 | - </view> | ||
| 29 | - <view> | ||
| 30 | - <u-button color="#3388ff" shape="circle" text="确认" @click="confirmCommand"></u-button> | ||
| 31 | - </view> | ||
| 32 | - </view> | ||
| 33 | - </view> | ||
| 34 | - </u-modal> | ||
| 35 | - </view> | 2 | + <view class="mp-u-modal"> |
| 3 | + <u-modal :mask-close-able="true" :show="showModal" closeOnClickOverlay :showConfirmButton="false" @close="$emit('hideModal')" z-index="99999"> | ||
| 4 | + <view class="w-100 modal-content"> | ||
| 5 | + <view style="max-height:560rpx;overflow-y: scroll;"> | ||
| 6 | + <view class="header-title">命令下发</view> | ||
| 7 | + <view class="u-flex"> | ||
| 8 | + <text class="type-text">下发类型:</text> | ||
| 9 | + <u-radio-group v-model="commandType" placement="row" @change="handleCommand"> | ||
| 10 | + <u-radio :customStyle="{marginRight: '20rpx'}" v-for="item in commandTypeList" activeColor="#3388FF" :label="item.label" :name="item.value" :key="item.value"></u-radio> | ||
| 11 | + </u-radio-group> | ||
| 12 | + </view> | ||
| 13 | + <view class="u-flex" style="margin-top: 28rpx" v-if="commandType == 0"> | ||
| 14 | + <text class="type-text">单向/双向:</text> | ||
| 15 | + <u-radio-group v-model="callType" placement="row"> | ||
| 16 | + <u-radio activeColor="#3388FF" label="单向" name="OneWay"></u-radio> | ||
| 17 | + <view style="margin: 0 20rpx"></view> | ||
| 18 | + <u-radio activeColor="#3388FF" label="双向" name="TwoWay"></u-radio> | ||
| 19 | + </u-radio-group> | ||
| 20 | + </view> | ||
| 21 | + <view class="u-flex" style="margin-top: 28rpx" v-else> | ||
| 22 | + <text class="type-text">服务:</text> | ||
| 23 | + <view @click="openService"> | ||
| 24 | + <u-input shape="circle" v-model="serviceName" placeholder="请选择服务" disabled disabledColor="#fff" suffixIcon="arrow-down" /> | ||
| 25 | + </view> | ||
| 26 | + </view> | ||
| 27 | + <view class="u-flex" style="margin-top: 28rpx; flex-direction: column; align-items: flex-start" v-if="isShowServiceFunctionName && commandType == 1"> | ||
| 28 | + <text class="type-text">输入参数:</text> | ||
| 29 | + <seriesForm ref="seriesFormRef" :seriesInputData="seriesInputData" :isTCPTransport="isTCPTransport"></seriesForm> | ||
| 30 | + </view> | ||
| 31 | + <view class="content-body" v-if="commandType == 0"> | ||
| 32 | + <div class="u-flex u-row-between"> | ||
| 33 | + <u--textarea :placeholder="`请输入下发内容${isShowTCP ? '(字符串格式)' : '(json格式)'}`" v-model="inputCommandVal" /> | ||
| 34 | + <u-icon v-if="!isShowTCP" @click="handleCopy(copyTextValue)" name="question-circle" color="#2979ff" size="28" class="ml-10"> </u-icon> | ||
| 35 | + </div> | ||
| 36 | + </view> | ||
| 37 | + </view> | ||
| 38 | + <view class="button-group"> | ||
| 39 | + <view> | ||
| 40 | + <u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="取消" @click="cancelCommand"></u-button> | ||
| 41 | + </view> | ||
| 42 | + <view> | ||
| 43 | + <u-button color="#3388ff" shape="circle" text="确认" @click="confirmCommand"></u-button> | ||
| 44 | + </view> | ||
| 45 | + </view> | ||
| 46 | + </view> | ||
| 47 | + <u-picker | ||
| 48 | + :show="isShowService" | ||
| 49 | + :columns="[seriesList.map((item) => ({ label: item.functionName, value: item.identifier,callType:item.callType }))]" | ||
| 50 | + keyName="label" | ||
| 51 | + closeOnClickOverlay | ||
| 52 | + @cancel="cancelTypeGap" | ||
| 53 | + @close="cancelTypeGap" | ||
| 54 | + @confirm="handleSelect" | ||
| 55 | + ></u-picker> | ||
| 56 | + </u-modal> | ||
| 57 | + </view> | ||
| 36 | </template> | 58 | </template> |
| 37 | 59 | ||
| 38 | <script> | 60 | <script> |
| 39 | - import { | ||
| 40 | - useShowModal | ||
| 41 | - } from '@/plugins/utils.js' | 61 | +import { useShowModal } from '@/plugins/utils.js' |
| 62 | +import seriesForm from './seriesForm.vue' | ||
| 42 | 63 | ||
| 43 | - export default { | ||
| 44 | - props: { | ||
| 45 | - showModal: Boolean, | ||
| 46 | - isShowTCP: Boolean | ||
| 47 | - }, | ||
| 48 | - data() { | ||
| 49 | - return { | ||
| 50 | - current: 0, | ||
| 51 | - commandType: 'OneWay', | ||
| 52 | - inputCommandVal: '', | ||
| 53 | - copyTextValue: { | ||
| 54 | - "method": "methodThingskit", | ||
| 55 | - "params": { | ||
| 56 | - "pin": 7, | ||
| 57 | - "value": 1 | ||
| 58 | - } | 64 | +import api from '@/api/index.js' |
| 65 | + | ||
| 66 | +export default { | ||
| 67 | + components: { | ||
| 68 | + seriesForm, | ||
| 69 | + }, | ||
| 70 | + props: { | ||
| 71 | + showModal: Boolean, | ||
| 72 | + isShowTCP: Boolean, | ||
| 73 | + deviceDetail: Object, | ||
| 74 | + }, | ||
| 75 | + data() { | ||
| 76 | + return { | ||
| 77 | + current: 0, | ||
| 78 | + commandType: 0, //下发类型 | ||
| 79 | + callType: 'OneWay', //单双向 | ||
| 80 | + serviceName: '', //服务 | ||
| 81 | + service: null, //服务 | ||
| 82 | + inputCommandVal: '',//自定义命令 | ||
| 83 | + isShowService: false, //服务下拉框 | ||
| 84 | + isShowServiceFunctionName: false, //选择服务过后的输入参数 | ||
| 85 | + copyTextValue: { | ||
| 86 | + method: 'methodThingskit', | ||
| 87 | + params: { | ||
| 88 | + pin: 7, | ||
| 89 | + value: 1, | ||
| 90 | + }, | ||
| 91 | + }, | ||
| 92 | + commandTypeList: [{ label: '自定义', value: 0 }], | ||
| 93 | + seriesList: [], //服务下拉框的数据 | ||
| 94 | + boolList: [], | ||
| 95 | + enumList: [], | ||
| 96 | + seriesInputData: [], | ||
| 97 | + isTCPTransport:false | ||
| 98 | + } | ||
| 99 | + }, | ||
| 100 | + mounted() { | ||
| 101 | + this.getFormInfo() | ||
| 102 | + }, | ||
| 103 | + watch: { | ||
| 104 | + showModal: { | ||
| 105 | + deep: true, | ||
| 106 | + handler() { | ||
| 107 | + this.commandType = 0 | ||
| 108 | + this.serviceName = '' | ||
| 109 | + this.isShowServiceFunctionName = false | ||
| 110 | + }, | ||
| 111 | + }, | ||
| 112 | + }, | ||
| 113 | + methods: { | ||
| 114 | + cancelCommand() { | ||
| 115 | + this.commandType = 0 | ||
| 116 | + this.$emit('cancelCommand') | ||
| 117 | + }, | ||
| 118 | + async confirmCommand() { | ||
| 119 | + if(this.commandType==0){ | ||
| 120 | + this.$emit('confirmCommand',this.commandType, this.callType, this.inputCommandVal) | ||
| 121 | + }else{ | ||
| 122 | + const result = this.$refs.seriesFormRef.handleValidate() | ||
| 123 | + if(!result){ | ||
| 124 | + return | ||
| 125 | + } | ||
| 126 | + const value = this.$refs.seriesFormRef.getFormField() | ||
| 127 | + const values =this.isTCPTransport?value.serviceCommand: { | ||
| 128 | + [this.service]:value | ||
| 59 | } | 129 | } |
| 130 | + this.$emit('confirmCommand',this.commandType, this.callType, values) | ||
| 60 | } | 131 | } |
| 61 | - }, | ||
| 62 | - methods: { | ||
| 63 | - cancelCommand() { | ||
| 64 | - this.$emit('cancelCommand') | ||
| 65 | - }, | ||
| 66 | - confirmCommand() { | ||
| 67 | - this.$emit('confirmCommand', this.commandType, this.inputCommandVal) | ||
| 68 | - }, | ||
| 69 | - handleCopy(value) { | ||
| 70 | - useShowModal(JSON.stringify(value), '命令下发', '复制内容').then(res => { | ||
| 71 | - uni.setClipboardData({ | ||
| 72 | - data: JSON.stringify(value), | ||
| 73 | - success: () => { | ||
| 74 | - uni.showToast({ | ||
| 75 | - title: '复制成功' | ||
| 76 | - }) | ||
| 77 | - } | ||
| 78 | - }); | ||
| 79 | - }) | ||
| 80 | - }, | ||
| 81 | - reset() { | ||
| 82 | - this.commandType = 'OneWay' | ||
| 83 | - this.inputCommandVal = '' | 132 | + }, |
| 133 | + handleCopy(value) { | ||
| 134 | + useShowModal(JSON.stringify(value), '命令下发', '复制内容').then((res) => { | ||
| 135 | + uni.setClipboardData({ | ||
| 136 | + data: JSON.stringify(value), | ||
| 137 | + success: () => { | ||
| 138 | + uni.showToast({ | ||
| 139 | + title: '复制成功', | ||
| 140 | + }) | ||
| 141 | + }, | ||
| 142 | + }) | ||
| 143 | + }) | ||
| 144 | + }, | ||
| 145 | + | ||
| 146 | + async getFormInfo() { | ||
| 147 | + const { transportType, deviceType, deviceProfile } = this.deviceDetail || {} | ||
| 148 | + const { | ||
| 149 | + profileData: { | ||
| 150 | + transportConfiguration: { protocol }, | ||
| 151 | + }, | ||
| 152 | + } = deviceProfile || {} | ||
| 153 | + this.isTCPTransport = transportType === 'TCP' | ||
| 154 | + const isTCPModbus = this.isTCPTransport && protocol === 'MODBUS_RTU' | ||
| 155 | + if (isTCPModbus || (this.isTCPTransport && deviceType === 'SENSOR')) { | ||
| 156 | + this.commandTypeList = this.commandTypeList.length==2?this.commandTypeList.pop():this.commandTypeList | ||
| 157 | + } else { | ||
| 158 | + this.commandTypeList.push({ label: '服务', value: 1 }) | ||
| 159 | + this.seriesList = await api.deviceApi.getModelServices(this.deviceDetail) | ||
| 160 | + } | ||
| 161 | + }, | ||
| 162 | + | ||
| 163 | + openService() { | ||
| 164 | + this.isShowService = true | ||
| 165 | + }, | ||
| 166 | + handleSelect(e) { | ||
| 167 | + this.isShowService = false | ||
| 168 | + const { value } = e || {} | ||
| 169 | + this.serviceName = value[0].label | ||
| 170 | + this.service = value[0].value | ||
| 171 | + if (this.service) { | ||
| 172 | + this.isShowServiceFunctionName = true | ||
| 173 | + const { functionJson } = this.seriesList.filter((item) => item.identifier === this.service)[0] || {} | ||
| 174 | + const { inputData } = functionJson || {} | ||
| 175 | + this.seriesInputData = inputData || [] | ||
| 176 | + this.callType = value[0].callType==='ASYNC'?'OneWay':'TwoWay' | ||
| 177 | + } | ||
| 178 | + }, | ||
| 179 | + | ||
| 180 | + cancelModel() { | ||
| 181 | + this.isShowService = false | ||
| 182 | + this.seriesInputData = [] | ||
| 183 | + this.seriesList = [] | ||
| 184 | + }, | ||
| 185 | + | ||
| 186 | + handleCommand(name){ | ||
| 187 | + this.seriesInputData = [] | ||
| 188 | + this.serviceName = '' | ||
| 189 | + this.isShowServiceFunctionName = false | ||
| 190 | + if(this.commandType==0){ | ||
| 191 | + this.callType = 'OneWay' | ||
| 84 | } | 192 | } |
| 85 | - } | ||
| 86 | - } | 193 | + }, |
| 194 | + | ||
| 195 | + cancelTypeGap() { | ||
| 196 | + this.isShowService = false | ||
| 197 | + }, | ||
| 198 | + | ||
| 199 | + reset() { | ||
| 200 | + this.callType = 'OneWay' | ||
| 201 | + this.inputCommandVal = '' | ||
| 202 | + }, | ||
| 203 | + }, | ||
| 204 | +} | ||
| 87 | </script> | 205 | </script> |
| 88 | 206 | ||
| 89 | <style lang="scss" scoped> | 207 | <style lang="scss" scoped> |
| 90 | - .modal-content { | ||
| 91 | - width: 720rpx; | ||
| 92 | - padding: 0 30rpx; | ||
| 93 | - background-color: white; | 208 | +.modal-content { |
| 209 | + width: 720rpx; | ||
| 210 | + padding: 0 30rpx; | ||
| 211 | + background-color: white; | ||
| 94 | 212 | ||
| 95 | - .header-title { | ||
| 96 | - text-align: center; | ||
| 97 | - font-weight: 700; | ||
| 98 | - margin-bottom: 40rpx; | ||
| 99 | - } | 213 | + .header-title { |
| 214 | + text-align: center; | ||
| 215 | + font-weight: 700; | ||
| 216 | + margin-bottom: 40rpx; | ||
| 217 | + } | ||
| 100 | 218 | ||
| 101 | - .type-text { | ||
| 102 | - color: #333; | ||
| 103 | - font-size: 14px; | ||
| 104 | - font-weight: 700; | ||
| 105 | - margin-right: 30rpx; | ||
| 106 | - } | 219 | + .type-text { |
| 220 | + color: #333; | ||
| 221 | + font-size: 14px; | ||
| 222 | + font-weight: 700; | ||
| 223 | + margin-right: 30rpx; | ||
| 224 | + } | ||
| 107 | 225 | ||
| 108 | - .content-body { | ||
| 109 | - margin-top: 28rpx; | ||
| 110 | - width: 100%; | ||
| 111 | - } | 226 | + .content-body { |
| 227 | + margin-top: 28rpx; | ||
| 228 | + width: 100%; | ||
| 229 | + } | ||
| 112 | 230 | ||
| 113 | - .button-group { | ||
| 114 | - display: flex; | ||
| 115 | - margin-top: 40rpx; | ||
| 116 | - justify-content: space-between; | 231 | + .button-group { |
| 232 | + display: flex; | ||
| 233 | + margin-top: 40rpx; | ||
| 234 | + justify-content: space-between; | ||
| 117 | 235 | ||
| 118 | - view { | ||
| 119 | - width: 300rpx; | ||
| 120 | - } | ||
| 121 | - } | ||
| 122 | - } | ||
| 123 | -</style> | ||
| 236 | + view { | ||
| 237 | + width: 300rpx; | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | +} | ||
| 241 | +</style> |
| 1 | +<template> | ||
| 2 | + <view> | ||
| 3 | + <!-- :label-style="{'width':'120rpx','overflow':'hidden','text-overflow':'ellipsis','white-space':'nowrap',display:'block'}" label-width="120rpx" --> | ||
| 4 | + <u-form :model="seriesForm" ref="seriesRef"> | ||
| 5 | + <u-form-item style="display: flex" v-for="(item, index) in seriesFunctionList" label-position="left" :key="item.identifier" :prop="item.identifier"> | ||
| 6 | + <view v-if="!isTCPTransport"" :class="Array.isArray(item.dataType.specs)?'positionTop':'positionLeft'"> | ||
| 7 | + <view class="text">{{ item.functionName }}</view> | ||
| 8 | + <u-input | ||
| 9 | + v-if="item.dataType.type == 'INT' || item.dataType.type == 'DOUBLE'" | ||
| 10 | + shape="circle" | ||
| 11 | + type="number" | ||
| 12 | + v-model.number="seriesForm[item.identifier]" | ||
| 13 | + :placeholder="`请输入${item.functionName}`" | ||
| 14 | + @blur="(e)=>handleBlur(e,item.identifier)" | ||
| 15 | + /> | ||
| 16 | + <u-input v-if="item.dataType.type == 'TEXT'" shape="circle" type="text" v-model="seriesForm[item.identifier]" :placeholder="`请输入${item.functionName}`" /> | ||
| 17 | + <view v-if="item.dataType.type == 'BOOL'" @click="handleBool(item.functionName, item.dataType, index)"> | ||
| 18 | + <u-input | ||
| 19 | + shape="circle" | ||
| 20 | + v-model="seriesForm[item.identifier]" | ||
| 21 | + :placeholder="`请选择${item.functionName}`" | ||
| 22 | + disabled | ||
| 23 | + disabledColor="#fff" | ||
| 24 | + suffixIcon="arrow-down" | ||
| 25 | + /> | ||
| 26 | + <u-picker | ||
| 27 | + :show="item.isShowModel" | ||
| 28 | + :columns="[boolList]" | ||
| 29 | + keyName="label" | ||
| 30 | + @cancel="handleCancelBool(index)" | ||
| 31 | + @close="handleCancelBool(index)" | ||
| 32 | + @confirm="(e) => handleSelectBool(e, item.identifier, index)" | ||
| 33 | + ></u-picker> | ||
| 34 | + </view> | ||
| 35 | + <view v-if="item.dataType.type == 'ENUM'" @click="handleEnum(item.functionName, item.dataType, index)"> | ||
| 36 | + <u-input | ||
| 37 | + shape="circle" | ||
| 38 | + v-model="seriesForm[item.identifier]" | ||
| 39 | + :placeholder="`请选择${item.functionName}`" | ||
| 40 | + disabled | ||
| 41 | + disabledColor="#fff" | ||
| 42 | + suffixIcon="arrow-down" | ||
| 43 | + /> | ||
| 44 | + <u-picker | ||
| 45 | + :show="item.isShowModel" | ||
| 46 | + :columns="[enumList.map((item) => ({ label: item.name, value: item.value }))]" | ||
| 47 | + keyName="label" | ||
| 48 | + @cancel="handleCancelEnum(index)" | ||
| 49 | + @close="handleCancelEnum(index)" | ||
| 50 | + @confirm="(e) => handleSelectEnum(e, item.identifier, index)" | ||
| 51 | + ></u-picker> | ||
| 52 | + </view> | ||
| 53 | + <template v-if="Array.isArray(item.dataType.specs)"> | ||
| 54 | + <structuralForm class="seriesForm" :ref="item.identifier" :seriesInputData="item.dataType.specs || []"></structuralForm> | ||
| 55 | + </template> | ||
| 56 | + </view> | ||
| 57 | + <view v-else class="positionLeft" style=" border: 1px dashed #f0f0f0; padding: 20rpx;"> | ||
| 58 | + <view class="text">服务命令</view> | ||
| 59 | + <u-input v-model="seriesForm.serviceCommand" type="text" shape="circle" :disabled="true"></u-input> | ||
| 60 | + </view> | ||
| 61 | + </u-form-item> | ||
| 62 | + </u-form> | ||
| 63 | + </view> | ||
| 64 | +</template> | ||
| 65 | + | ||
| 66 | +<script> | ||
| 67 | +import structuralForm from './structuralForm.vue' | ||
| 68 | +export default { | ||
| 69 | + name: 'StructForm', | ||
| 70 | + props: { | ||
| 71 | + seriesInputData: { | ||
| 72 | + type: Array, | ||
| 73 | + default: () => [], | ||
| 74 | + }, | ||
| 75 | + isTCPTransport:{ | ||
| 76 | + type:Boolean, | ||
| 77 | + default:false | ||
| 78 | + } | ||
| 79 | + }, | ||
| 80 | + components: { | ||
| 81 | + structuralForm, | ||
| 82 | + }, | ||
| 83 | + data() { | ||
| 84 | + return { | ||
| 85 | + boolInfo: {}, | ||
| 86 | + enumInfo: {}, | ||
| 87 | + seriesForm: {}, | ||
| 88 | + seriesRules: {}, | ||
| 89 | + seriesFunctionList: [], | ||
| 90 | + boolList: [], | ||
| 91 | + enumList: [], | ||
| 92 | + } | ||
| 93 | + }, | ||
| 94 | + async mounted() { | ||
| 95 | + await this.$nextTick(() => { | ||
| 96 | + this.createInit() | ||
| 97 | + }) | ||
| 98 | + }, | ||
| 99 | + watch: { | ||
| 100 | + seriesInputData: { | ||
| 101 | + deep: true, | ||
| 102 | + handler(newVal, oldVal) { | ||
| 103 | + this.createInit() | ||
| 104 | + }, | ||
| 105 | + }, | ||
| 106 | + }, | ||
| 107 | + | ||
| 108 | + methods: { | ||
| 109 | + createInit() { | ||
| 110 | + this.seriesForm = {} | ||
| 111 | + this.boolInfo = {} | ||
| 112 | + this.seriesFunctionList = this.seriesInputData | ||
| 113 | + for(const item of this.seriesInputData){ | ||
| 114 | + this.$set(item, 'isShowModel', false)//动态添加picker的控制变量 | ||
| 115 | + const { | ||
| 116 | + dataType, | ||
| 117 | + identifier, | ||
| 118 | + functionName, | ||
| 119 | + serviceCommand | ||
| 120 | + } = item || {} | ||
| 121 | + const {specs,type} = dataType || {} | ||
| 122 | + if(this.isTCPTransport){ | ||
| 123 | + this.$set(this.seriesForm,'serviceCommand',serviceCommand) | ||
| 124 | + break; | ||
| 125 | + } | ||
| 126 | + if (Array.isArray(specs)) { | ||
| 127 | + specs.forEach((itemSpecs) => { | ||
| 128 | + this.$set(this.seriesForm, identifier, { | ||
| 129 | + [itemSpecs.identifier]: '', | ||
| 130 | + }) | ||
| 131 | + }) | ||
| 132 | + } else { | ||
| 133 | + this.$set(this.seriesForm, identifier, '') | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + //设置验证规则 | ||
| 137 | + const { valueRange, length = 10240 } = specs || {} | ||
| 138 | + const { max = 2147483647, min = -2147483647 } = valueRange || {} | ||
| 139 | + if (type !== 'STRUCT') { | ||
| 140 | + this.seriesRules[identifier] = [ | ||
| 141 | + { required: true, message: type == 'BOOL' || type == 'ENUM' ? '请选择' : '请输入' + functionName }, | ||
| 142 | + type == 'INT' || type == 'DOUBLE' | ||
| 143 | + ? { | ||
| 144 | + type: 'number', | ||
| 145 | + trigger: 'change', | ||
| 146 | + validator: (_rule, value) => { | ||
| 147 | + const reg = /^[0-9]*$/ | ||
| 148 | + if (!reg.test(value)) return Promise.reject(new Error(`${functionName}不是一个有效的数字`)) | ||
| 149 | + if (value < min || value > max) return Promise.reject(new Error(`${functionName}取值范围在${min}~${max}之间`)) | ||
| 150 | + | ||
| 151 | + return Promise.resolve(value) | ||
| 152 | + }, | ||
| 153 | + } | ||
| 154 | + : type == 'TEXT' | ||
| 155 | + ? { | ||
| 156 | + type: 'string', | ||
| 157 | + trigger: 'change', | ||
| 158 | + validator: (_rule, value) => { | ||
| 159 | + if ((value?.length || 0) > length) return Promise.reject(new Error(`${functionName}数据长度应该小于${length}`)) | ||
| 160 | + | ||
| 161 | + return Promise.resolve(value) | ||
| 162 | + }, | ||
| 163 | + } | ||
| 164 | + : {}, | ||
| 165 | + ] | ||
| 166 | + } | ||
| 167 | + } | ||
| 168 | + //设置验证规则 | ||
| 169 | + this.$nextTick(() => { | ||
| 170 | + !this.isTCPTransport && this.$refs.seriesRef.setRules(this.seriesRules) | ||
| 171 | + }) | ||
| 172 | + }, | ||
| 173 | + isEmptyObject(obj) { | ||
| 174 | + return Object.keys(obj).length === 0 && obj.constructor === Object | ||
| 175 | + }, | ||
| 176 | + | ||
| 177 | + //打开Bool的picker | ||
| 178 | + handleBool(name, dataType, num) { | ||
| 179 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 180 | + if (index == num) { | ||
| 181 | + item.isShowModel = true | ||
| 182 | + } | ||
| 183 | + }) | ||
| 184 | + const { specs } = dataType || {} | ||
| 185 | + const { boolClose, boolOpen } = specs || {} | ||
| 186 | + console.log(boolClose, boolOpen,'boolClose, boolOpen') | ||
| 187 | + if(!boolClose&&!boolOpen){ | ||
| 188 | + uni.$u.toast(`暂无可选的${name}`) | ||
| 189 | + this.boolList = [] | ||
| 190 | + return | ||
| 191 | + } | ||
| 192 | + this.boolList = [ | ||
| 193 | + { label: boolClose + '-0', value: 0 }, | ||
| 194 | + { label: boolOpen + '-1', value: 1 }, | ||
| 195 | + ] | ||
| 196 | + }, | ||
| 197 | + handleSelectBool(e, name, num) { | ||
| 198 | + const { value } = e || {} | ||
| 199 | + this.boolInfo[name] = value[0].value | ||
| 200 | + this.$set(this.seriesForm, name, value[0].label) | ||
| 201 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 202 | + if (index == num) { | ||
| 203 | + item.isShowModel = false | ||
| 204 | + } | ||
| 205 | + }) | ||
| 206 | + }, | ||
| 207 | + handleBlur(value,name){ | ||
| 208 | + if(!value) return | ||
| 209 | + this.$set(this.seriesForm,name,Number(value)) | ||
| 210 | + }, | ||
| 211 | + | ||
| 212 | + //打开Enum的picker | ||
| 213 | + handleEnum(name, dataType, num) { | ||
| 214 | + const { specsList } = dataType || {} | ||
| 215 | + this.enumList = specsList || [] | ||
| 216 | + console.log(this.enumList,'enumInfo') | ||
| 217 | + if(!this.enumList.length){ | ||
| 218 | + return uni.$u.toast(`暂无可选的${name}`) | ||
| 219 | + } | ||
| 220 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 221 | + if (index == num) { | ||
| 222 | + item.isShowModel = true | ||
| 223 | + } | ||
| 224 | + }) | ||
| 225 | + }, | ||
| 226 | + //确定选中 | ||
| 227 | + handleSelectEnum(e, name, num) { | ||
| 228 | + const { value } = e || {} | ||
| 229 | + this.enumInfo[name] = value[0].value | ||
| 230 | + this.$set(this.seriesForm, name, value[0].label) | ||
| 231 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 232 | + if (index == num) { | ||
| 233 | + item.isShowModel = false | ||
| 234 | + } | ||
| 235 | + }) | ||
| 236 | + }, | ||
| 237 | + | ||
| 238 | + | ||
| 239 | + //关闭Enum和Bool的picker弹框 | ||
| 240 | + handleCancelEnum(num){ | ||
| 241 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 242 | + if (index == num) { | ||
| 243 | + item.isShowModel = false | ||
| 244 | + } | ||
| 245 | + }) | ||
| 246 | + }, | ||
| 247 | + handleCancelBool(num){ | ||
| 248 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 249 | + if (index == num) { | ||
| 250 | + item.isShowModel = false | ||
| 251 | + } | ||
| 252 | + }) | ||
| 253 | + }, | ||
| 254 | + | ||
| 255 | + // 获取表单数据 | ||
| 256 | + getFormField() { | ||
| 257 | + const keys = Object.keys(this.seriesForm) | ||
| 258 | + for (let i = 0; i < keys.length; i++) { | ||
| 259 | + const key = keys[i] | ||
| 260 | + if (Array.isArray(this.$refs[key])) { | ||
| 261 | + const values = this.$refs[key][0]?.getFormField() | ||
| 262 | + if (!this.isEmptyObject(values)) { | ||
| 263 | + this.seriesForm[key] = values | ||
| 264 | + } | ||
| 265 | + } | ||
| 266 | + } | ||
| 267 | + return { | ||
| 268 | + ...this.seriesForm, | ||
| 269 | + ...this.boolInfo, | ||
| 270 | + ...this.enumInfo, | ||
| 271 | + } | ||
| 272 | + }, | ||
| 273 | + | ||
| 274 | + | ||
| 275 | + handleValidate() { | ||
| 276 | + const keys = Object.keys(this.seriesForm) | ||
| 277 | + for (let i = 0; i < keys.length; i++) { | ||
| 278 | + const key = keys[i] | ||
| 279 | + if (Array.isArray(this.$refs[key])) { | ||
| 280 | + this.$refs[key][0]?.handleValidate(valid=>{ | ||
| 281 | + if(!valid) return false | ||
| 282 | + }) | ||
| 283 | + } else { | ||
| 284 | + this.$refs.seriesRef.validate(valid=>{ | ||
| 285 | + if(!valid) return false | ||
| 286 | + }) | ||
| 287 | + } | ||
| 288 | + return true | ||
| 289 | + } | ||
| 290 | + }, | ||
| 291 | + }, | ||
| 292 | +} | ||
| 293 | +</script> | ||
| 294 | + | ||
| 295 | +<style lang="scss" scoped> | ||
| 296 | +.positionLeft { | ||
| 297 | + display: flex; | ||
| 298 | + align-items: center; | ||
| 299 | + .text{ | ||
| 300 | + | ||
| 301 | + max-width: 190rpx; | ||
| 302 | + overflow: hidden; | ||
| 303 | + text-overflow: ellipsis; | ||
| 304 | + white-space: nowrap; | ||
| 305 | + } | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +.positionTop { | ||
| 309 | + display: flex; | ||
| 310 | + flex-direction: column; | ||
| 311 | + border: 1px dashed #f0f0f0; | ||
| 312 | + padding: 20rpx; | ||
| 313 | + .seriesForm{ | ||
| 314 | + margin-left:30rpx | ||
| 315 | + } | ||
| 316 | +} | ||
| 317 | +</style> |
| 1 | +<template> | ||
| 2 | + <view> | ||
| 3 | + <u-form :model="seriesForm" ref="seriesRef" :label-style="{ width: '160rpx', overflow: 'hidden', 'text-overflow': 'ellipsis', 'white-space': 'nowrap', display: 'block' }" label-width="160rpx"> | ||
| 4 | + <u-form-item v-for="(item, index) in seriesFunctionList" :key="item.identifier" :label="item.functionName" :prop="item.identifier"> | ||
| 5 | + <u-input v-if="item.dataType.type == 'INT' || item.dataType.type == 'DOUBLE'" shape="circle" type="number" v-model="seriesForm[item.identifier]" :placeholder="`请输入${item.functionName}`" /> | ||
| 6 | + <u-input v-if="item.dataType.type == 'TEXT'" shape="circle" type="text" v-model="seriesForm[item.identifier]" :placeholder="`请输入${item.functionName}`" /> | ||
| 7 | + <view @click="handleBool(item.identifier, item.dataType, index)"> | ||
| 8 | + <u-input | ||
| 9 | + v-if="item.dataType.type == 'BOOL'" | ||
| 10 | + shape="circle" | ||
| 11 | + v-model="seriesForm[item.identifier]" | ||
| 12 | + :placeholder="`请选择${item.functionName}`" | ||
| 13 | + disabled | ||
| 14 | + disabledColor="#fff" | ||
| 15 | + suffixIcon="arrow-down" | ||
| 16 | + /> | ||
| 17 | + <u-picker | ||
| 18 | + :show="item.isShowModel" | ||
| 19 | + :columns="[boolList]" | ||
| 20 | + keyName="label" | ||
| 21 | + closeOnClickOverlay | ||
| 22 | + @cancel="handleCancel(index)" | ||
| 23 | + @close="handleCancel(index)" | ||
| 24 | + @confirm="(e) => handleSelectBool(e, item.identifier, index)" | ||
| 25 | + ></u-picker> | ||
| 26 | + </view> | ||
| 27 | + | ||
| 28 | + <view @click="handleEnum(item.identifier, item.dataType, index)"> | ||
| 29 | + <u-input | ||
| 30 | + v-if="item.dataType.type == 'ENUM'" | ||
| 31 | + shape="circle" | ||
| 32 | + v-model="seriesForm[item.identifier]" | ||
| 33 | + :placeholder="`请选择${item.functionName}`" | ||
| 34 | + disabled | ||
| 35 | + disabledColor="#fff" | ||
| 36 | + suffixIcon="arrow-down" | ||
| 37 | + /> | ||
| 38 | + <u-picker | ||
| 39 | + :show="item.isShowModel" | ||
| 40 | + :columns="[enumList.map((item) => ({ label: item.name, value: item.value }))]" | ||
| 41 | + keyName="label" | ||
| 42 | + closeOnClickOverlay | ||
| 43 | + @cancel="handleCancel(index)" | ||
| 44 | + @close="handleCancel(index)" | ||
| 45 | + @confirm="(e) => handleSelectEnum(e, item.identifier, index)" | ||
| 46 | + ></u-picker> | ||
| 47 | + </view> | ||
| 48 | + </u-form-item> | ||
| 49 | + </u-form> | ||
| 50 | + </view> | ||
| 51 | +</template> | ||
| 52 | + | ||
| 53 | +<script> | ||
| 54 | +export default { | ||
| 55 | + name: 'StructForm', | ||
| 56 | + props: { | ||
| 57 | + seriesInputData: { | ||
| 58 | + type: Array, | ||
| 59 | + default: () => [], | ||
| 60 | + }, | ||
| 61 | + }, | ||
| 62 | + data() { | ||
| 63 | + return { | ||
| 64 | + boolInfo: {}, | ||
| 65 | + enumInfo: {}, | ||
| 66 | + seriesForm: {}, | ||
| 67 | + seriesRules: {}, | ||
| 68 | + seriesFunctionList: [], | ||
| 69 | + boolList: [], | ||
| 70 | + enumList: [], | ||
| 71 | + } | ||
| 72 | + }, | ||
| 73 | + async mounted() { | ||
| 74 | + await this.$nextTick(() => { | ||
| 75 | + this.createInit() | ||
| 76 | + }) | ||
| 77 | + }, | ||
| 78 | + watch: { | ||
| 79 | + seriesInputData: { | ||
| 80 | + deep: true, | ||
| 81 | + handler(newVal, oldVal) { | ||
| 82 | + this.createInit() | ||
| 83 | + }, | ||
| 84 | + }, | ||
| 85 | + }, | ||
| 86 | + | ||
| 87 | + methods: { | ||
| 88 | + createInit() { | ||
| 89 | + this.seriesFunctionList = this.seriesInputData | ||
| 90 | + this.seriesInputData.forEach((item) => { | ||
| 91 | + this.$set(item, 'isShowModel', false) | ||
| 92 | + const { | ||
| 93 | + dataType: { specs, type }, | ||
| 94 | + identifier, | ||
| 95 | + functionName, | ||
| 96 | + } = item || {} | ||
| 97 | + | ||
| 98 | + this.$set(this.seriesForm, identifier, '') | ||
| 99 | + const { valueRange, length = 10240 } = specs || {} | ||
| 100 | + | ||
| 101 | + const { max = 2147483647, min = -2147483647 } = valueRange || {} | ||
| 102 | + | ||
| 103 | + this.seriesRules[identifier] = [ | ||
| 104 | + { required: true, message: type == 'BOOL' || type == 'ENUM' ? '请选择' : '请输入' + functionName }, | ||
| 105 | + type == 'INT' || type == 'DOUBLE' | ||
| 106 | + ? { | ||
| 107 | + type: 'number', | ||
| 108 | + trigger: 'change', | ||
| 109 | + validator: (_rule, value) => { | ||
| 110 | + const reg = /^[0-9]*$/ | ||
| 111 | + if (!reg.test(value)) return Promise.reject(new Error(`${functionName}不是一个有效的数字`)) | ||
| 112 | + if (value < min || value > max) return Promise.reject(new Error(`${functionName}取值范围在${min}~${max}之间`)) | ||
| 113 | + | ||
| 114 | + return Promise.resolve(value) | ||
| 115 | + }, | ||
| 116 | + } | ||
| 117 | + : type == 'TEXT' | ||
| 118 | + ? { | ||
| 119 | + type: 'string', | ||
| 120 | + trigger: 'change', | ||
| 121 | + validator: (_rule, value) => { | ||
| 122 | + if ((value?.length || 0) > length) return Promise.reject(new Error(`${functionName}数据长度应该小于${length}`)) | ||
| 123 | + | ||
| 124 | + return Promise.resolve(value) | ||
| 125 | + }, | ||
| 126 | + } | ||
| 127 | + : {}, | ||
| 128 | + ] | ||
| 129 | + }) | ||
| 130 | + this.$nextTick(() => { | ||
| 131 | + this.$refs.seriesRef.setRules(this.seriesRules) | ||
| 132 | + }) | ||
| 133 | + }, | ||
| 134 | + | ||
| 135 | + handleBool(name, dataType, num) { | ||
| 136 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 137 | + if (index == num) { | ||
| 138 | + item.isShowModel = true | ||
| 139 | + } | ||
| 140 | + }) | ||
| 141 | + const { specs } = dataType || {} | ||
| 142 | + const { boolClose, boolOpen } = specs || {} | ||
| 143 | + this.boolList = [ | ||
| 144 | + { label: boolClose + '0', value: 0 }, | ||
| 145 | + { label: boolOpen + '0', value: 1 }, | ||
| 146 | + ] | ||
| 147 | + this.isShowBool = true | ||
| 148 | + }, | ||
| 149 | + handleSelectBool(e, name, num) { | ||
| 150 | + this.isShowBool = false | ||
| 151 | + const { value } = e || {} | ||
| 152 | + this.boolInfo[name] = value[0].value | ||
| 153 | + this.$set(this.seriesForm, name, value[0].label) | ||
| 154 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 155 | + if (index == num) { | ||
| 156 | + item.isShowModel = false | ||
| 157 | + } | ||
| 158 | + }) | ||
| 159 | + }, | ||
| 160 | + | ||
| 161 | + getFormField() { | ||
| 162 | + return { | ||
| 163 | + ...this.seriesForm, | ||
| 164 | + ...this.boolInfo, | ||
| 165 | + ...this.enumInfo, | ||
| 166 | + } | ||
| 167 | + }, | ||
| 168 | + | ||
| 169 | + handleEnum(name, dataType, num) { | ||
| 170 | + const { specsList } = dataType || {} | ||
| 171 | + this.isShowEnum = true | ||
| 172 | + this.enumList = specsList || [] | ||
| 173 | + if(!this.enumList.length){ | ||
| 174 | + return uni.$u.toast(`暂无可选的${name}`) | ||
| 175 | + } | ||
| 176 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 177 | + if (index == num) { | ||
| 178 | + item.isShowModel = true | ||
| 179 | + } | ||
| 180 | + }) | ||
| 181 | + }, | ||
| 182 | + handleSelectEnum(e, name, num) { | ||
| 183 | + const { value } = e || {} | ||
| 184 | + this.enumInfo[name] = value[0].value | ||
| 185 | + this.$set(this.seriesForm, name, value[0].label) | ||
| 186 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 187 | + if (index == num) { | ||
| 188 | + item.isShowModel = false | ||
| 189 | + } | ||
| 190 | + }) | ||
| 191 | + }, | ||
| 192 | + handleCancel(num){ | ||
| 193 | + this.seriesFunctionList.forEach((item, index) => { | ||
| 194 | + if (index == num) { | ||
| 195 | + item.isShowModel = false | ||
| 196 | + } | ||
| 197 | + }) | ||
| 198 | + }, | ||
| 199 | + | ||
| 200 | + handleValidate() { | ||
| 201 | + return this.$refs.seriesRef?.validate((valid) => { | ||
| 202 | + if (!valid) return | ||
| 203 | + }) | ||
| 204 | + }, | ||
| 205 | + }, | ||
| 206 | +} | ||
| 207 | +</script> | ||
| 208 | + | ||
| 209 | +<style lang="scss" scoped></style> |