Showing
43 changed files
with
742 additions
and
804 deletions
| ... | ... | @@ -93,50 +93,9 @@ |
| 93 | 93 | onLoad(e) { |
| 94 | 94 | if (e.data !== null) { |
| 95 | 95 | let params = JSON.parse(decodeURIComponent(e.data)); |
| 96 | - const { | |
| 97 | - deviceName, | |
| 98 | - severity, | |
| 99 | - organizationName, | |
| 100 | - details, | |
| 101 | - type, | |
| 102 | - createdTime, | |
| 103 | - status, | |
| 104 | - id | |
| 105 | - } = params | |
| 96 | + const {deviceName,severity,organizationName,details,type,createdTime,status,id} = params | |
| 106 | 97 | this.detailId = id |
| 107 | - this.alarmDetail = [{ | |
| 108 | - label: '告警场景:', | |
| 109 | - value: type | |
| 110 | - }, | |
| 111 | - { | |
| 112 | - label: '告警级别:', | |
| 113 | - value: severity | |
| 114 | - }, | |
| 115 | - { | |
| 116 | - label: '所属组织:', | |
| 117 | - value: organizationName | |
| 118 | - }, | |
| 119 | - { | |
| 120 | - label: '告警设备:', | |
| 121 | - value: '' | |
| 122 | - }, | |
| 123 | - { | |
| 124 | - label: '告警条件:', | |
| 125 | - value: '' | |
| 126 | - }, | |
| 127 | - { | |
| 128 | - label: '告警值:', | |
| 129 | - value: '' | |
| 130 | - }, | |
| 131 | - { | |
| 132 | - label: '告警时间:', | |
| 133 | - value: createdTime | |
| 134 | - }, | |
| 135 | - { | |
| 136 | - label: '告警状态:', | |
| 137 | - value: status | |
| 138 | - }, | |
| 139 | - ] | |
| 98 | + this.alarmDetail = [{label: '告警场景:',value: type},{label: '告警级别:',value: severity},{label: '所属组织:',value: organizationName},{label: '告警设备:',value: ''},{label: '告警条件:',value: ''},{label: '告警值:',value: ''},{label: '告警时间:',value: createdTime},{label: '告警状态:',value: status},] | |
| 140 | 99 | this.formatAlarmDevice(details) |
| 141 | 100 | this.formatAlarmValue(details) |
| 142 | 101 | this.formatAlarmCondition(details) |
| ... | ... | @@ -183,14 +142,14 @@ |
| 183 | 142 | }, 500); |
| 184 | 143 | } |
| 185 | 144 | }, |
| 145 | + //告警值处理 | |
| 186 | 146 | async formatAlarmValue(e) { |
| 187 | 147 | const keys = Object.keys(e) |
| 188 | 148 | const dataFormat = await this.handleAlarmDetailFormat(keys); |
| 189 | 149 | const values = keys.reduce((acc, curr) => { |
| 190 | 150 | dataFormat.forEach((dataItem => { |
| 191 | 151 | if (dataItem.tbDeviceId === curr) { |
| 192 | - const findAttribute = dataItem.attribute.find(findItem => findItem | |
| 193 | - .identifier === e[curr].key) | |
| 152 | + const findAttribute = dataItem.attribute.find(findItem => findItem.identifier === e[curr].key) | |
| 194 | 153 | acc.push( |
| 195 | 154 | `${findAttribute.name}:${e[curr].realValue}${!findAttribute.detail?.dataType?.specs?.unit?.key?'':findAttribute.detail?.dataType?.specs?.unit?.key}` |
| 196 | 155 | ) |
| ... | ... | @@ -200,6 +159,7 @@ |
| 200 | 159 | }, []) |
| 201 | 160 | this.formatAlarmValueText = values.join(',') |
| 202 | 161 | }, |
| 162 | + //告警条件处理 | |
| 203 | 163 | formatAlarmCondition(e) { |
| 204 | 164 | const keys = Object.keys(e) |
| 205 | 165 | const values = keys.reduce((acc, curr) => { |
| ... | ... | @@ -215,8 +175,8 @@ |
| 215 | 175 | return findOperation + item.logicValue |
| 216 | 176 | }) |
| 217 | 177 | this.formatAlarmConditionText = format.filter(Boolean).join(',') |
| 218 | - console.log(this.formatAlarmConditionText); | |
| 219 | 178 | }, |
| 179 | + //告警设备处理 | |
| 220 | 180 | async formatAlarmDevice(e) { |
| 221 | 181 | const keys = Object.keys(e) |
| 222 | 182 | const dataFormat = await this.handleAlarmDetailFormat(keys); |
| ... | ... | @@ -229,9 +189,7 @@ |
| 229 | 189 | for (let item of keys) { |
| 230 | 190 | if (item === 'key' || item === 'data') return; //旧数据则终止 |
| 231 | 191 | const deviceDetailRes = await api.deviceApi.getDeviceDetail(item); |
| 232 | - const { | |
| 233 | - deviceProfileId | |
| 234 | - } = deviceDetailRes; | |
| 192 | + const { deviceProfileId } = deviceDetailRes; | |
| 235 | 193 | if (!deviceProfileId) return; |
| 236 | 194 | const attributeRes = await api.deviceApi.getAttribute(deviceProfileId); |
| 237 | 195 | const dataFormat = this.handleDataFormat(deviceDetailRes, attributeRes); |
| ... | ... | @@ -240,10 +198,7 @@ |
| 240 | 198 | return temp; |
| 241 | 199 | }, |
| 242 | 200 | handleDataFormat(deviceDetail, attributes) { |
| 243 | - const { | |
| 244 | - name, | |
| 245 | - tbDeviceId | |
| 246 | - } = deviceDetail; | |
| 201 | + const { name,tbDeviceId } = deviceDetail; | |
| 247 | 202 | const attribute = attributes.map((item) => ({ |
| 248 | 203 | identifier: item.identifier, |
| 249 | 204 | name: item.name, | ... | ... |
| ... | ... | @@ -20,9 +20,16 @@ const getConfigurationApi = (params = {}) => { |
| 20 | 20 | .get('/yt/configuration/center', params) |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | +//获取组织列表 | |
| 24 | +const getMeOrgListApi = () => { | |
| 25 | + return uni.$u.http | |
| 26 | + .get('/yt/organization/me/list') | |
| 27 | +} | |
| 28 | + | |
| 23 | 29 | export default { |
| 24 | 30 | getHomeStatisticsApi, |
| 25 | 31 | getCameraApi, |
| 26 | 32 | byCameraIdGetDetailApi, |
| 27 | - getConfigurationApi | |
| 33 | + getConfigurationApi, | |
| 34 | + getMeOrgListApi | |
| 28 | 35 | } | ... | ... |
constant/index.js
0 → 100644
| ... | ... | @@ -111,21 +111,13 @@ |
| 111 | 111 | </template> |
| 112 | 112 | |
| 113 | 113 | <script> |
| 114 | - import { | |
| 115 | - formatToDate | |
| 116 | - } from '@/plugins/utils.js'; | |
| 117 | - import { | |
| 118 | - issueCommand | |
| 119 | - } from '../api/index.js'; | |
| 114 | + import {formatToDate} from '@/plugins/utils.js'; | |
| 115 | + import {issueCommand} from '../api/index.js'; | |
| 120 | 116 | import api from '@/api/index.js'; |
| 121 | 117 | import mpCommandIssuance from './mp-command-issuance.vue'; |
| 122 | - import { | |
| 123 | - commandTypeList | |
| 124 | - } from '../config/data.js' | |
| 125 | - import { | |
| 126 | - useShowModal | |
| 127 | - } from '@/plugins/utils.js' | |
| 128 | - | |
| 118 | + import {commandTypeList} from '../config/data.js' | |
| 119 | + import {useShowModal} from '@/plugins/utils.js' | |
| 120 | + | |
| 129 | 121 | export default { |
| 130 | 122 | components: { |
| 131 | 123 | mpCommandIssuance, | ... | ... |
| ... | ... | @@ -91,9 +91,7 @@ |
| 91 | 91 | } |
| 92 | 92 | }, |
| 93 | 93 | onLoad(options) { |
| 94 | - const { | |
| 95 | - data | |
| 96 | - } = options; | |
| 94 | + const { data } = options; | |
| 97 | 95 | this.commandDetail = JSON.parse(decodeURIComponent(data)); |
| 98 | 96 | if (this.commandDetail.response.status === 'SUCCESS') return |
| 99 | 97 | this.failContent = JSON.stringify(this.commandDetail.response.error) |
| ... | ... | @@ -102,50 +100,5 @@ |
| 102 | 100 | </script> |
| 103 | 101 | |
| 104 | 102 | <style lang="scss" scoped> |
| 105 | - .command-detail { | |
| 106 | - padding: 5rpx 30rpx; | |
| 107 | - height: 100vh; | |
| 108 | - background-color: #f8f9fa; | |
| 109 | - | |
| 110 | - .detail-top { | |
| 111 | - height: 118rpx; | |
| 112 | - width: 690rpx; | |
| 113 | - display: flex; | |
| 114 | - align-items: center; | |
| 115 | - background-color: #fff; | |
| 116 | - color: #333; | |
| 117 | - border-radius: 20rpx; | |
| 118 | - font-size: 15px; | |
| 119 | - margin-top: 30rpx; | |
| 120 | - padding: 30rpx; | |
| 121 | - } | |
| 122 | - | |
| 123 | - .detail { | |
| 124 | - background-color: #fff; | |
| 125 | - margin-top: 30rpx; | |
| 126 | - border-radius: 20rpx; | |
| 127 | - width: 690rpx; | |
| 128 | - | |
| 129 | - .detail-item { | |
| 130 | - padding: 30rpx; | |
| 131 | - display: flex; | |
| 132 | - align-items: center; | |
| 133 | - | |
| 134 | - .detail-label { | |
| 135 | - color: #333; | |
| 136 | - font-size: 15px; | |
| 137 | - } | |
| 138 | - | |
| 139 | - .detail-value { | |
| 140 | - color: #666; | |
| 141 | - font-size: 14px; | |
| 142 | - margin-left: 30rpx; | |
| 143 | - } | |
| 144 | - } | |
| 145 | - } | |
| 146 | - | |
| 147 | - .command { | |
| 148 | - margin: 30rpx 0; | |
| 149 | - } | |
| 150 | - } | |
| 103 | + @import "../static/command-detail.scss"; | |
| 151 | 104 | </style> |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -229,109 +229,7 @@ |
| 229 | 229 | }; |
| 230 | 230 | </script> |
| 231 | 231 | |
| 232 | -<style lang="scss" scoped> | |
| 233 | - .command-record { | |
| 234 | - padding: 0 30rpx; | |
| 235 | - background: #f8f9fa; | |
| 236 | - | |
| 237 | - .filter-button { | |
| 238 | - font-size: 12px; | |
| 239 | - width: 160rpx; | |
| 240 | - height: 64rpx; | |
| 241 | - border-radius: 32rpx; | |
| 242 | - display: flex; | |
| 243 | - justify-content: center; | |
| 244 | - align-items: center; | |
| 245 | - background: #f0f1f2; | |
| 246 | - color: #666; | |
| 247 | - | |
| 248 | - image { | |
| 249 | - width: 28rpx; | |
| 250 | - height: 28rpx; | |
| 251 | - margin-left: 4rpx; | |
| 252 | - } | |
| 253 | - } | |
| 254 | - } | |
| 255 | - | |
| 256 | - .list-item { | |
| 257 | - width: 690rpx; | |
| 258 | - background-color: #fff; | |
| 259 | - border-radius: 20rpx; | |
| 260 | - margin: 20rpx auto; | |
| 261 | - color: #333; | |
| 262 | - | |
| 263 | - .item { | |
| 264 | - .delivered-color { | |
| 265 | - color: blue; | |
| 266 | - } | |
| 267 | - | |
| 268 | - padding: 30rpx; | |
| 269 | - | |
| 270 | - view { | |
| 271 | - font-size: 14px; | |
| 272 | - margin-bottom: 10rpx; | |
| 273 | - } | |
| 274 | - | |
| 275 | - .time { | |
| 276 | - margin-top: 20rpx; | |
| 277 | - color: #999; | |
| 278 | - } | |
| 279 | - | |
| 280 | - .item-first { | |
| 281 | - display: flex; | |
| 282 | - justify-content: space-between; | |
| 283 | - align-items: center; | |
| 284 | - font-size: 15px; | |
| 285 | - font-weight: 500; | |
| 286 | - align-items: center; | |
| 287 | - | |
| 288 | - .item-right { | |
| 289 | - display: flex; | |
| 290 | - justify-content: center; | |
| 291 | - align-items: center; | |
| 292 | - width: 104rpx; | |
| 293 | - height: 36rpx; | |
| 294 | - font-size: 10px; | |
| 295 | - border-radius: 20rpx; | |
| 296 | - } | |
| 297 | 232 | |
| 298 | - .item-fail { | |
| 299 | - color: #848383; | |
| 300 | - background-color: #84838325; | |
| 301 | - } | |
| 302 | - | |
| 303 | - .item.success { | |
| 304 | - color: #00c9a7; | |
| 305 | - background-color: #00c9a725; | |
| 306 | - } | |
| 307 | - } | |
| 308 | - } | |
| 309 | - } | |
| 310 | - | |
| 311 | - .filter { | |
| 312 | - padding: 0 30rpx; | |
| 313 | - | |
| 314 | - .filter-title { | |
| 315 | - text-align: center; | |
| 316 | - margin-top: 14px; | |
| 317 | - font-size: 16px; | |
| 318 | - font-weight: 700; | |
| 319 | - } | |
| 320 | - | |
| 321 | - .button-group { | |
| 322 | - display: flex; | |
| 323 | - margin-top: 40rpx; | |
| 324 | - justify-content: space-between; | |
| 325 | - | |
| 326 | - view { | |
| 327 | - width: 330rpx; | |
| 328 | - } | |
| 329 | - } | |
| 330 | - | |
| 331 | - .command-time-text { | |
| 332 | - color: #333; | |
| 333 | - font-size: 14px; | |
| 334 | - font-weight: 700; | |
| 335 | - } | |
| 336 | - } | |
| 233 | +<style lang="scss" scoped> | |
| 234 | + @import "../static/command-record.scss"; | |
| 337 | 235 | </style> |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -12,41 +12,16 @@ |
| 12 | 12 | </template> |
| 13 | 13 | |
| 14 | 14 | <script> |
| 15 | -export default { | |
| 16 | - props: { | |
| 17 | - recordList: { | |
| 18 | - type: Array, | |
| 19 | - default: () => [] | |
| 15 | + export default { | |
| 16 | + props: { | |
| 17 | + recordList: { | |
| 18 | + type: Array, | |
| 19 | + default: () => [] | |
| 20 | + } | |
| 20 | 21 | } |
| 21 | - } | |
| 22 | -}; | |
| 22 | + }; | |
| 23 | 23 | </script> |
| 24 | 24 | |
| 25 | 25 | <style lang="scss" scoped> |
| 26 | -.realtime-page { | |
| 27 | - .item { | |
| 28 | - margin: 30rpx; | |
| 29 | - padding: 30rpx; | |
| 30 | - border-radius: 20rpx; | |
| 31 | - background-color: #fff; | |
| 32 | - height: 160rpx; | |
| 33 | - width: 690rpx; | |
| 34 | - .item-top { | |
| 35 | - display: flex; | |
| 36 | - justify-content: space-between; | |
| 37 | - color: #333; | |
| 38 | - font-size: 16px; | |
| 39 | - font-family: PingFangSC-Medium, PingFang SC; | |
| 40 | - font-weight: bold; | |
| 41 | - .item-value { | |
| 42 | - font-weight: bold; | |
| 43 | - } | |
| 44 | - } | |
| 45 | - .item-time { | |
| 46 | - margin-top: 4rpx; | |
| 47 | - font-size: 13px; | |
| 48 | - color: #999; | |
| 49 | - } | |
| 50 | - } | |
| 51 | -} | |
| 52 | -</style> | |
| 26 | + @import "../static/realtime-data.scss"; | |
| 27 | +</style> | |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -25,19 +25,13 @@ |
| 25 | 25 | import alarmHistory from "./components/alarm-history.vue"; |
| 26 | 26 | import historyData from "./components/history-data.vue"; |
| 27 | 27 | import commondRecord from "./components/command-record.vue"; |
| 28 | - import { | |
| 29 | - getDeviceKeys, | |
| 30 | - getHistoryData | |
| 31 | - } from "./api/index.js"; | |
| 32 | - import { | |
| 33 | - formatToDate | |
| 34 | - } from "@/plugins/utils.js"; | |
| 28 | + import { getDeviceKeys,getHistoryData } from "./api/index.js"; | |
| 29 | + import {formatToDate} from "@/plugins/utils.js"; | |
| 35 | 30 | import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js"; |
| 36 | 31 | import moment from "moment"; |
| 37 | 32 | import base from "@/config/baseUrl.js"; |
| 38 | - import { | |
| 39 | - list | |
| 40 | - } from './config/data.js' | |
| 33 | + import { list } from './config/data.js' | |
| 34 | + import api from '@/api' | |
| 41 | 35 | |
| 42 | 36 | export default { |
| 43 | 37 | mixins: [MescrollCompMixin], |
| ... | ... | @@ -81,16 +75,10 @@ |
| 81 | 75 | uni.closeSocket(); |
| 82 | 76 | }, |
| 83 | 77 | async onLoad(options) { |
| 84 | - const { | |
| 85 | - id, | |
| 86 | - alarmStatus, | |
| 87 | - lastOnlineTime, | |
| 88 | - tbDeviceId, | |
| 89 | - deviceProfileId | |
| 90 | - } = | |
| 91 | - options; | |
| 78 | + const {id,alarmStatus,lastOnlineTime,tbDeviceId,deviceProfileId} = options; | |
| 92 | 79 | this.deviceId = id; |
| 93 | - const res = await uni.$u.http.get(`/yt/device/${id}`); | |
| 80 | + const res = await api.deviceApi.getDeviceDetail(this.deviceId) | |
| 81 | + if(!res) return | |
| 94 | 82 | this.deviceDetail = { |
| 95 | 83 | ...res, |
| 96 | 84 | alarmStatus, |
| ... | ... | @@ -106,9 +94,7 @@ |
| 106 | 94 | } |
| 107 | 95 | this.isScrollable = this.list.length > 4; |
| 108 | 96 | if (res.deviceProfileId) { |
| 109 | - const getAttrList = await uni.$u.http.get( | |
| 110 | - `/yt/device/attributes/${res.deviceProfileId}` | |
| 111 | - ); | |
| 97 | + const getAttrList = await api.deviceApi.getAttribute(res.deviceProfileId) | |
| 112 | 98 | if (Array.isArray(getAttrList)) { |
| 113 | 99 | this.attrList = getAttrList.map(m => { |
| 114 | 100 | return m.identifier |
| ... | ... | @@ -117,8 +103,7 @@ |
| 117 | 103 | } |
| 118 | 104 | // 连接webSockte |
| 119 | 105 | const socketTask = uni.connectSocket({ |
| 120 | - url: `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` + | |
| 121 | - uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。 | |
| 106 | + url: `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` + uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。 | |
| 122 | 107 | complete: () => {}, |
| 123 | 108 | }); |
| 124 | 109 | uni.onSocketOpen((header) => { |
| ... | ... | @@ -144,17 +129,11 @@ |
| 144 | 129 | }); |
| 145 | 130 | }); |
| 146 | 131 | socketTask.onMessage((msg) => { |
| 147 | - const { | |
| 148 | - data | |
| 149 | - } = JSON.parse(msg.data); | |
| 132 | + const { data } = JSON.parse(msg.data); | |
| 150 | 133 | const newArray = []; |
| 151 | 134 | for (const key in data) { |
| 152 | 135 | const [time, value] = data[key].flat(1); |
| 153 | - let obj = { | |
| 154 | - key, | |
| 155 | - time, | |
| 156 | - value, | |
| 157 | - }; | |
| 136 | + let obj = { key,time,value, }; | |
| 158 | 137 | if (this.recordList.length === 0) { |
| 159 | 138 | this.recordList.unshift(obj); |
| 160 | 139 | } else { |
| ... | ... | @@ -192,7 +171,6 @@ |
| 192 | 171 | // 结束时间 |
| 193 | 172 | this.endTs = moment().format("x"); |
| 194 | 173 | this.entityId = tbDeviceId; |
| 195 | - | |
| 196 | 174 | const data = await getHistoryData({ |
| 197 | 175 | entityId: tbDeviceId, |
| 198 | 176 | startTs: this.startTs, | ... | ... |
| 1 | +.command-detail { | |
| 2 | + padding: 5rpx 30rpx; | |
| 3 | + height: 100vh; | |
| 4 | + background-color: #f8f9fa; | |
| 5 | + | |
| 6 | + .detail-top { | |
| 7 | + height: 118rpx; | |
| 8 | + width: 690rpx; | |
| 9 | + display: flex; | |
| 10 | + align-items: center; | |
| 11 | + background-color: #fff; | |
| 12 | + color: #333; | |
| 13 | + border-radius: 20rpx; | |
| 14 | + font-size: 15px; | |
| 15 | + margin-top: 30rpx; | |
| 16 | + padding: 30rpx; | |
| 17 | + } | |
| 18 | + | |
| 19 | + .detail { | |
| 20 | + background-color: #fff; | |
| 21 | + margin-top: 30rpx; | |
| 22 | + border-radius: 20rpx; | |
| 23 | + width: 690rpx; | |
| 24 | + | |
| 25 | + .detail-item { | |
| 26 | + padding: 30rpx; | |
| 27 | + display: flex; | |
| 28 | + align-items: center; | |
| 29 | + | |
| 30 | + .detail-label { | |
| 31 | + color: #333; | |
| 32 | + font-size: 15px; | |
| 33 | + } | |
| 34 | + | |
| 35 | + .detail-value { | |
| 36 | + color: #666; | |
| 37 | + font-size: 14px; | |
| 38 | + margin-left: 30rpx; | |
| 39 | + } | |
| 40 | + } | |
| 41 | + } | |
| 42 | + | |
| 43 | + .command { | |
| 44 | + margin: 30rpx 0; | |
| 45 | + } | |
| 46 | + } | |
| \ No newline at end of file | ... | ... |
| 1 | +.command-record { | |
| 2 | + padding: 0 30rpx; | |
| 3 | + background: #f8f9fa; | |
| 4 | + | |
| 5 | + .filter-button { | |
| 6 | + font-size: 12px; | |
| 7 | + width: 160rpx; | |
| 8 | + height: 64rpx; | |
| 9 | + border-radius: 32rpx; | |
| 10 | + display: flex; | |
| 11 | + justify-content: center; | |
| 12 | + align-items: center; | |
| 13 | + background: #f0f1f2; | |
| 14 | + color: #666; | |
| 15 | + | |
| 16 | + image { | |
| 17 | + width: 28rpx; | |
| 18 | + height: 28rpx; | |
| 19 | + margin-left: 4rpx; | |
| 20 | + } | |
| 21 | + } | |
| 22 | + } | |
| 23 | + | |
| 24 | + .list-item { | |
| 25 | + width: 690rpx; | |
| 26 | + background-color: #fff; | |
| 27 | + border-radius: 20rpx; | |
| 28 | + margin: 20rpx auto; | |
| 29 | + color: #333; | |
| 30 | + | |
| 31 | + .item { | |
| 32 | + .delivered-color { | |
| 33 | + color: blue; | |
| 34 | + } | |
| 35 | + | |
| 36 | + padding: 30rpx; | |
| 37 | + | |
| 38 | + view { | |
| 39 | + font-size: 14px; | |
| 40 | + margin-bottom: 10rpx; | |
| 41 | + } | |
| 42 | + | |
| 43 | + .time { | |
| 44 | + margin-top: 20rpx; | |
| 45 | + color: #999; | |
| 46 | + } | |
| 47 | + | |
| 48 | + .item-first { | |
| 49 | + display: flex; | |
| 50 | + justify-content: space-between; | |
| 51 | + align-items: center; | |
| 52 | + font-size: 15px; | |
| 53 | + font-weight: 500; | |
| 54 | + align-items: center; | |
| 55 | + | |
| 56 | + .item-right { | |
| 57 | + display: flex; | |
| 58 | + justify-content: center; | |
| 59 | + align-items: center; | |
| 60 | + width: 104rpx; | |
| 61 | + height: 36rpx; | |
| 62 | + font-size: 10px; | |
| 63 | + border-radius: 20rpx; | |
| 64 | + } | |
| 65 | + | |
| 66 | + .item-fail { | |
| 67 | + color: #848383; | |
| 68 | + background-color: #84838325; | |
| 69 | + } | |
| 70 | + | |
| 71 | + .item.success { | |
| 72 | + color: #00c9a7; | |
| 73 | + background-color: #00c9a725; | |
| 74 | + } | |
| 75 | + } | |
| 76 | + } | |
| 77 | + } | |
| 78 | + | |
| 79 | + .filter { | |
| 80 | + padding: 0 30rpx; | |
| 81 | + | |
| 82 | + .filter-title { | |
| 83 | + text-align: center; | |
| 84 | + margin-top: 14px; | |
| 85 | + font-size: 16px; | |
| 86 | + font-weight: 700; | |
| 87 | + } | |
| 88 | + | |
| 89 | + .button-group { | |
| 90 | + display: flex; | |
| 91 | + margin-top: 40rpx; | |
| 92 | + justify-content: space-between; | |
| 93 | + | |
| 94 | + view { | |
| 95 | + width: 330rpx; | |
| 96 | + } | |
| 97 | + } | |
| 98 | + | |
| 99 | + .command-time-text { | |
| 100 | + color: #333; | |
| 101 | + font-size: 14px; | |
| 102 | + font-weight: 700; | |
| 103 | + } | |
| 104 | + } | |
| \ No newline at end of file | ... | ... |
| 1 | +.realtime-page { | |
| 2 | + .item { | |
| 3 | + margin: 30rpx; | |
| 4 | + padding: 30rpx; | |
| 5 | + border-radius: 20rpx; | |
| 6 | + background-color: #fff; | |
| 7 | + height: 160rpx; | |
| 8 | + width: 690rpx; | |
| 9 | + .item-top { | |
| 10 | + display: flex; | |
| 11 | + justify-content: space-between; | |
| 12 | + color: #333; | |
| 13 | + font-size: 16px; | |
| 14 | + font-family: PingFangSC-Medium, PingFang SC; | |
| 15 | + font-weight: bold; | |
| 16 | + .item-value { | |
| 17 | + font-weight: bold; | |
| 18 | + } | |
| 19 | + } | |
| 20 | + .item-time { | |
| 21 | + margin-top: 4rpx; | |
| 22 | + font-size: 13px; | |
| 23 | + color: #999; | |
| 24 | + } | |
| 25 | + } | |
| 26 | +} | |
| \ No newline at end of file | ... | ... |
feedback-subpackage/feedback/config/data.js
0 → 100644
| 1 | +const rules = { | |
| 2 | + 'feedbackInfo.title': { | |
| 3 | + type: 'string', | |
| 4 | + required: true, | |
| 5 | + message: '请输入主题', | |
| 6 | + trigger: ['blur', 'change'] | |
| 7 | + }, | |
| 8 | + 'feedbackInfo.name': { | |
| 9 | + type: 'string', | |
| 10 | + required: true, | |
| 11 | + message: '请输入姓名', | |
| 12 | + trigger: ['blur', 'change'] | |
| 13 | + }, | |
| 14 | + 'feedbackInfo.message': { | |
| 15 | + type: 'string', | |
| 16 | + required: true, | |
| 17 | + message: '请输入意见反馈', | |
| 18 | + trigger: ['blur', 'change'] | |
| 19 | + } | |
| 20 | +} | |
| 21 | +export { | |
| 22 | + rules | |
| 23 | +} | |
| \ No newline at end of file | ... | ... |
| 1 | 1 | <template> |
| 2 | 2 | <view class="feedback-page"> |
| 3 | - <view style="overflow-y: scroll;overflow: hidden;height: 1500rpx;"> | |
| 3 | + <view class="feedback-container"> | |
| 4 | 4 | <!-- 公共组件-每个页面必须引入 --> |
| 5 | 5 | <public-module></public-module> |
| 6 | 6 | <view class="form-page"> |
| ... | ... | @@ -55,6 +55,8 @@ |
| 55 | 55 | mapState |
| 56 | 56 | } from 'vuex'; |
| 57 | 57 | import api from '@/api/index.js' |
| 58 | + import { rules } from './config/data.js' | |
| 59 | + import { UPLOAD_FILE_SIZE } from '@/constant/index.js' | |
| 58 | 60 | |
| 59 | 61 | export default { |
| 60 | 62 | data() { |
| ... | ... | @@ -69,27 +71,7 @@ |
| 69 | 71 | } |
| 70 | 72 | }, |
| 71 | 73 | fileList1: [], |
| 72 | - rules: { | |
| 73 | - 'feedbackInfo.title': { | |
| 74 | - type: 'string', | |
| 75 | - required: true, | |
| 76 | - message: '请输入主题', | |
| 77 | - trigger: ['blur', 'change'] | |
| 78 | - }, | |
| 79 | - 'feedbackInfo.name': { | |
| 80 | - type: 'string', | |
| 81 | - required: true, | |
| 82 | - message: '请输入姓名', | |
| 83 | - trigger: ['blur', 'change'] | |
| 84 | - }, | |
| 85 | - 'feedbackInfo.message': { | |
| 86 | - type: 'string', | |
| 87 | - required: true, | |
| 88 | - message: '请输入意见反馈', | |
| 89 | - trigger: ['blur', 'change'] | |
| 90 | - }, | |
| 91 | - | |
| 92 | - }, | |
| 74 | + rules | |
| 93 | 75 | }; |
| 94 | 76 | }, |
| 95 | 77 | onReady() { |
| ... | ... | @@ -113,7 +95,7 @@ |
| 113 | 95 | let lists = [].concat(event.file); |
| 114 | 96 | let fileListLen = this[`fileList${event.name}`].length; |
| 115 | 97 | lists.map(item => { |
| 116 | - if (item.size > 5242880) { | |
| 98 | + if (item.size > UPLOAD_FILE_SIZE) { | |
| 117 | 99 | this[`fileList${event.name}`].push({ |
| 118 | 100 | ...item, |
| 119 | 101 | status: 'error', |
| ... | ... | @@ -129,7 +111,7 @@ |
| 129 | 111 | }); |
| 130 | 112 | for (let i = 0; i < lists.length; i++) { |
| 131 | 113 | const judgeImageSize = lists[0].size |
| 132 | - if (judgeImageSize > 5242880) { | |
| 114 | + if (judgeImageSize > UPLOAD_FILE_SIZE) { | |
| 133 | 115 | return uni.$u.toast('图片限定5M') |
| 134 | 116 | } else { |
| 135 | 117 | const result = await this.uploadFilePromise(lists[i].url); | ... | ... |
| ... | ... | @@ -5,6 +5,11 @@ |
| 5 | 5 | padding-left: 27rpx; |
| 6 | 6 | overflow-y: scroll; |
| 7 | 7 | overflow: hidden; |
| 8 | + .feedback-container{ | |
| 9 | + overflow-y: scroll; | |
| 10 | + overflow: hidden; | |
| 11 | + height: 1500rpx; | |
| 12 | + } | |
| 8 | 13 | } |
| 9 | 14 | |
| 10 | 15 | .form-page { |
| ... | ... | @@ -12,8 +17,7 @@ |
| 12 | 17 | background-color: #ffffff; |
| 13 | 18 | border-radius: 10px; |
| 14 | 19 | margin-top: 20rpx; |
| 15 | - padding-left: 15rpx; | |
| 16 | - padding: 0 20rpx; | |
| 20 | + padding: 0 40rpx; | |
| 17 | 21 | height: 860rpx; |
| 18 | 22 | .upload-text{ |
| 19 | 23 | margin: 15px 0px 0px -16rpx; | ... | ... |
| ... | ... | @@ -29,16 +29,8 @@ |
| 29 | 29 | |
| 30 | 30 | <script> |
| 31 | 31 | var clear; |
| 32 | - import { | |
| 33 | - mapState, | |
| 34 | - mapMutations, | |
| 35 | - mapActions | |
| 36 | - } from 'vuex'; | |
| 37 | - import { | |
| 38 | - useShowToast, | |
| 39 | - useNavigateTo, | |
| 40 | - useReLaunch | |
| 41 | - } from '@/plugins/utils.js' | |
| 32 | + import {mapState,mapMutations,mapActions} from 'vuex'; | |
| 33 | + import {useShowToast,useNavigateTo,useReLaunch} from '@/plugins/utils.js' | |
| 42 | 34 | import api from '@/api' |
| 43 | 35 | |
| 44 | 36 | export default { | ... | ... |
| ... | ... | @@ -83,17 +83,10 @@ |
| 83 | 83 | mapMutations |
| 84 | 84 | } from 'vuex'; |
| 85 | 85 | import baseUrl from '@/config/baseUrl.js'; |
| 86 | - import { | |
| 87 | - mapState | |
| 88 | - } from 'vuex'; | |
| 86 | + import {mapState} from 'vuex'; | |
| 89 | 87 | import api from '@/api/index.js' |
| 90 | 88 | import permission from '@/js_sdk/wa-permission/permission.js' |
| 91 | - import { | |
| 92 | - useShowModal, | |
| 93 | - useUploadFile, | |
| 94 | - useChooseImage, | |
| 95 | - useFileValidate | |
| 96 | - } from '@/plugins/utils.js' | |
| 89 | + import {useShowModal,useUploadFile,useChooseImage,useFileValidate} from '@/plugins/utils.js' | |
| 97 | 90 | |
| 98 | 91 | export default { |
| 99 | 92 | data() { | ... | ... |
| ... | ... | @@ -47,26 +47,16 @@ |
| 47 | 47 | </template> |
| 48 | 48 | |
| 49 | 49 | <script> |
| 50 | - import { | |
| 51 | - mapMutations, | |
| 52 | - mapActions, | |
| 53 | - mapState | |
| 54 | - } from "vuex"; | |
| 50 | + import {mapMutations,mapActions,mapState} from "vuex"; | |
| 55 | 51 | import api from '@/api' |
| 56 | - import { | |
| 57 | - loginPasswordReg, | |
| 58 | - useReLaunch, | |
| 59 | - useShowToast, | |
| 60 | - useShowModal, | |
| 61 | - useNavigateTo | |
| 62 | - } from '@/plugins/utils.js' | |
| 52 | + import {loginPasswordReg,useReLaunch,useShowToast,useShowModal,useNavigateTo} from '@/plugins/utils.js' | |
| 63 | 53 | |
| 64 | 54 | export default { |
| 65 | 55 | data() { |
| 66 | 56 | return { |
| 67 | 57 | loginForm: { |
| 68 | - username: "", | |
| 69 | - password: "", | |
| 58 | + username: "fengtao", | |
| 59 | + password: "Aa123456@", | |
| 70 | 60 | }, |
| 71 | 61 | showPassword: true, |
| 72 | 62 | code: "", | ... | ... |
| ... | ... | @@ -39,19 +39,19 @@ |
| 39 | 39 | } |
| 40 | 40 | }, |
| 41 | 41 | { |
| 42 | - "path": "pages/index/camera/camera", | |
| 42 | + "path": "pages/index/components/camera/camera", | |
| 43 | 43 | "style": { |
| 44 | 44 | "navigationBarTitleText": "查看摄像头" |
| 45 | 45 | } |
| 46 | 46 | }, |
| 47 | 47 | { |
| 48 | - "path": "pages/index/configuration/configuration", | |
| 48 | + "path": "pages/index/components/configuration/configuration", | |
| 49 | 49 | "style": { |
| 50 | 50 | "navigationBarTitleText": "查看组态" |
| 51 | 51 | } |
| 52 | 52 | }, |
| 53 | 53 | { |
| 54 | - "path": "pages/index/configuration/configuration-detail", | |
| 54 | + "path": "pages/index/components/configuration/configuration-detail", | |
| 55 | 55 | "style": { |
| 56 | 56 | "navigationBarTitleText": "组态详情" |
| 57 | 57 | } | ... | ... |
| 1 | 1 | <template> |
| 2 | - <view class="device-list"> | |
| 2 | + <view class="alarm-list"> | |
| 3 | 3 | <view @click="$emit('openAlertDetail',item)" class="list-item" v-for="(item, index) in list" :key="index"> |
| 4 | 4 | <view class="u-flex item"> |
| 5 | 5 | <view class="item-text text-clip"> |
| ... | ... | @@ -69,6 +69,7 @@ |
| 69 | 69 | }, |
| 70 | 70 | formatDetailText(e) { |
| 71 | 71 | const keys = Object.keys(e) |
| 72 | + if(!keys) return | |
| 72 | 73 | const values = keys.reduce((acc, curr) => { |
| 73 | 74 | acc.push(`${!e[curr].key?'暂无数据':e[curr].key}:${!e[curr].realValue?'暂无数据':e[curr].realValue}`) |
| 74 | 75 | return acc |
| ... | ... | @@ -80,7 +81,7 @@ |
| 80 | 81 | </script> |
| 81 | 82 | |
| 82 | 83 | <style lang="scss" scoped> |
| 83 | - .device-list { | |
| 84 | + .alarm-list { | |
| 84 | 85 | display: flex; |
| 85 | 86 | flex-direction: column; |
| 86 | 87 | padding-left: 18rpx; | ... | ... |
| ... | ... | @@ -54,13 +54,8 @@ |
| 54 | 54 | }); |
| 55 | 55 | }, |
| 56 | 56 | resetFilter() { |
| 57 | - const { | |
| 58 | - deviceStatus, | |
| 59 | - alarmStatus, | |
| 60 | - typeStatus | |
| 61 | - } = this; | |
| 62 | - [deviceStatus, alarmStatus, typeStatus].forEach(item => item.map((item, index) => (item.checked = index === | |
| 63 | - 0))); | |
| 57 | + const {deviceStatus,alarmStatus,typeStatus} = this; | |
| 58 | + [deviceStatus, alarmStatus, typeStatus].forEach(item => item.map((item, index) => (item.checked = index ===0))); | |
| 64 | 59 | }, |
| 65 | 60 | confirmFilter() { |
| 66 | 61 | const deviceState = this.deviceStatus.find(item => item.checked); |
| ... | ... | @@ -70,7 +65,6 @@ |
| 70 | 65 | deviceState: deviceState.type ? deviceState.type : undefined, |
| 71 | 66 | deviceType: deviceType.type ? deviceType.type : undefined, |
| 72 | 67 | alarmStatus: alarmStatus.type === 0 || alarmStatus.type === 1 ? alarmStatus.type : undefined |
| 73 | - | |
| 74 | 68 | }) |
| 75 | 69 | }, |
| 76 | 70 | } | ... | ... |
pages/index/components/camera/camera.vue
renamed from
pages/index/camera/camera.vue
| 1 | -<template> | |
| 2 | - <view class="camera-page"> | |
| 3 | - <!-- 公共组件-每个页面必须引入 --> | |
| 4 | - <public-module></public-module> | |
| 5 | - <header-org @openOrg="openOrg" :total="cameraTotal" :imageSrc="imageSrc"></header-org> | |
| 6 | - <view style="height: 150rpx;"></view> | |
| 7 | - <!-- 自带分页组件 --> | |
| 8 | - <mescroll-body ref="mescrollRef" :up="upOption" @init="mescrollInit" :down="downOption" @down="downCallback" | |
| 9 | - @up="upCallback"> | |
| 10 | - <view class="camera-container"> | |
| 11 | - <view class="container-item"> | |
| 12 | - <view v-for="(item, index) in list" :key="item.id" class="item"> | |
| 13 | - <video :data-id="item.id" :data-accessMode="item.accessMode" :key="item.id" preload="none" | |
| 14 | - :id="'video' + item.id" class="video" :src="item.videoUrl" controls :title="item.name" | |
| 15 | - x5-video-player-type="h5" x5-video-orientation="portraint" show-mute-btn | |
| 16 | - :poster="item.avatar" @play="playVideo"></video> | |
| 17 | - <view style="width:300rpx" class="bottom-text text-clip"> | |
| 18 | - <text class="text">{{ item.name }}</text> | |
| 19 | - </view> | |
| 20 | - </view> | |
| 21 | - </view> | |
| 22 | - </view> | |
| 23 | - <mescroll-empty v-if="!list.length" /> | |
| 24 | - </mescroll-body> | |
| 25 | - <!-- 自带分页组件 --> | |
| 26 | - <view style="height: 60rpx;"></view> | |
| 27 | - </view> | |
| 28 | -</template> | |
| 29 | - | |
| 30 | -<script> | |
| 31 | - import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; | |
| 32 | - import api from '@/api/index.js' | |
| 33 | - import { | |
| 34 | - useNavigateTo | |
| 35 | - } from '@/plugins/utils.js' | |
| 36 | - import headerOrg from '@/components/common/header-org.vue' | |
| 37 | - | |
| 38 | - export default { | |
| 39 | - mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件) | |
| 40 | - components:{ | |
| 41 | - headerOrg | |
| 42 | - }, | |
| 43 | - data() { | |
| 44 | - return { | |
| 45 | - imageSrc:'/static/org.png', | |
| 46 | - page: { | |
| 47 | - num: 0, | |
| 48 | - size: 10 | |
| 49 | - }, | |
| 50 | - downOption: { | |
| 51 | - auto: true //是否在初始化后,自动执行downCallback; 默认true | |
| 52 | - }, | |
| 53 | - upOption: { | |
| 54 | - auto: false // 不自动加载 | |
| 55 | - }, | |
| 56 | - current: 0, | |
| 57 | - cameraTotal: 0, | |
| 58 | - list: [], | |
| 59 | - ordId: '', | |
| 60 | - }; | |
| 61 | - }, | |
| 62 | - onShow() { | |
| 63 | - if (this.ordId) { | |
| 64 | - this.loadData(1, this.ordId); | |
| 65 | - } | |
| 66 | - }, | |
| 67 | - onHide() { | |
| 68 | - this.ordId = ''; | |
| 69 | - }, | |
| 70 | - onLoad() { | |
| 71 | - // 隐藏原生的tabbar | |
| 72 | - uni.hideTabBar(); | |
| 73 | - }, | |
| 74 | - methods: { | |
| 75 | - /*下拉刷新的回调 */ | |
| 76 | - downCallback() { | |
| 77 | - //联网加载数据 | |
| 78 | - this.page.num = 1; | |
| 79 | - this.loadData(1); | |
| 80 | - }, | |
| 81 | - /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */ | |
| 82 | - upCallback() { | |
| 83 | - //联网加载数据 | |
| 84 | - this.page.num += 1; | |
| 85 | - this.loadData(this.page.num); | |
| 86 | - }, | |
| 87 | - async loadData(pageNo, organizationV) { | |
| 88 | - let httpData = { | |
| 89 | - page: pageNo, | |
| 90 | - pageSize: 10, | |
| 91 | - organizationId: organizationV | |
| 92 | - }; | |
| 93 | - const res = await api.homeApi.getCameraApi({ | |
| 94 | - params: httpData, | |
| 95 | - custom: { | |
| 96 | - load: false | |
| 97 | - } | |
| 98 | - }) | |
| 99 | - if (res) { | |
| 100 | - uni.stopPullDownRefresh(); | |
| 101 | - this.mescroll.endByPage(res.items.length, res.total); | |
| 102 | - this.cameraTotal = res.total; | |
| 103 | - if (pageNo == 1) { | |
| 104 | - this.list = res.items; | |
| 105 | - } else { | |
| 106 | - this.list = this.list.concat(res.items); | |
| 107 | - } | |
| 108 | - } | |
| 109 | - }, | |
| 110 | - hideImageUrl(item, index) { | |
| 111 | - this.current = index; | |
| 112 | - }, | |
| 113 | - async playVideo(e) { | |
| 114 | - const { | |
| 115 | - currentTarget: { | |
| 116 | - dataset: { | |
| 117 | - accessmode, | |
| 118 | - id | |
| 119 | - } | |
| 120 | - } = {} | |
| 121 | - } = e | |
| 122 | - const isExistVideoUrl = this.list.find(item => item.id == id).videoUrl | |
| 123 | - if (accessmode === 1 && !isExistVideoUrl) { | |
| 124 | - const res = api.homeApi.byCameraIdGetDetailApi(id) | |
| 125 | - if (res) { | |
| 126 | - const { | |
| 127 | - data: { | |
| 128 | - url | |
| 129 | - } = {} | |
| 130 | - } = res | |
| 131 | - const index = this.list.findIndex(item => item.id === id) | |
| 132 | - if (~index && url) { | |
| 133 | - this.list.splice(index, 1, { | |
| 134 | - ...this.list[index], | |
| 135 | - videoUrl: url | |
| 136 | - }) | |
| 137 | - this.$nextTick(() => { | |
| 138 | - let currentId = 'video' + id; | |
| 139 | - const videoContext = uni.createVideoContext(currentId, this); | |
| 140 | - videoContext.play() | |
| 141 | - }) | |
| 142 | - } | |
| 143 | - } | |
| 144 | - } | |
| 145 | - /** | |
| 146 | - * 点击全屏播放当前视频,暂停其余视频 | |
| 147 | - * 兼容APP和MP端 | |
| 148 | - */ | |
| 149 | - let currentId = 'video' + id; | |
| 150 | - this.videoContent = uni.createVideoContext(currentId, this); | |
| 151 | - this.videoContent.requestFullScreen(); | |
| 152 | - // 获取视频列表 | |
| 153 | - let trailer = this.list; | |
| 154 | - trailer.forEach((item, index) => { | |
| 155 | - if (item.videoUrl != null && item.videoUrl != '') { | |
| 156 | - let temp = 'video' + item.id; | |
| 157 | - if (temp != currentId) { | |
| 158 | - //暂停不是当前的视频 | |
| 159 | - uni.createVideoContext(temp, this).pause(); | |
| 160 | - } | |
| 161 | - } | |
| 162 | - }); | |
| 163 | - }, | |
| 164 | - openOrg() { | |
| 165 | - useNavigateTo('/pages/organization/organization') | |
| 166 | - } | |
| 167 | - } | |
| 168 | - }; | |
| 169 | -</script> | |
| 170 | - | |
| 171 | -<style lang="scss" scoped> | |
| 172 | - @import '../static/camera.scss'; | |
| 1 | +<template> | |
| 2 | + <view class="camera-page"> | |
| 3 | + <!-- 公共组件-每个页面必须引入 --> | |
| 4 | + <public-module></public-module> | |
| 5 | + <header-org @openOrg="openOrg" :total="cameraTotal" :imageSrc="imageSrc"></header-org> | |
| 6 | + <view style="height: 150rpx;"></view> | |
| 7 | + <!-- 自带分页组件 --> | |
| 8 | + <mescroll-body ref="mescrollRef" :up="upOption" @init="mescrollInit" :down="downOption" @down="downCallback" | |
| 9 | + @up="upCallback"> | |
| 10 | + <view class="camera-container"> | |
| 11 | + <view class="container-item"> | |
| 12 | + <view v-for="(item, index) in list" :key="item.id" class="item"> | |
| 13 | + <video :data-id="item.id" :data-accessMode="item.accessMode" :key="item.id" preload="none" | |
| 14 | + :id="'video' + item.id" class="video" :src="item.videoUrl" controls :title="item.name" | |
| 15 | + x5-video-player-type="h5" x5-video-orientation="portraint" show-mute-btn | |
| 16 | + :poster="item.avatar" @play="playVideo"></video> | |
| 17 | + <view class="bottom-text text-clip w-300"> | |
| 18 | + <text class="text">{{ item.name }}</text> | |
| 19 | + </view> | |
| 20 | + </view> | |
| 21 | + </view> | |
| 22 | + </view> | |
| 23 | + <mescroll-empty v-if="!list.length" /> | |
| 24 | + </mescroll-body> | |
| 25 | + <!-- 自带分页组件 --> | |
| 26 | + <view style="height: 60rpx;"></view> | |
| 27 | + </view> | |
| 28 | +</template> | |
| 29 | + | |
| 30 | +<script> | |
| 31 | + import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; | |
| 32 | + import api from '@/api/index.js' | |
| 33 | + import { | |
| 34 | + useNavigateTo | |
| 35 | + } from '@/plugins/utils.js' | |
| 36 | + import headerOrg from '@/components/common/header-org.vue' | |
| 37 | + | |
| 38 | + export default { | |
| 39 | + mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件) | |
| 40 | + components:{ | |
| 41 | + headerOrg | |
| 42 | + }, | |
| 43 | + data() { | |
| 44 | + return { | |
| 45 | + imageSrc:'/static/org.png', | |
| 46 | + page: { | |
| 47 | + num: 0, | |
| 48 | + size: 10 | |
| 49 | + }, | |
| 50 | + downOption: { | |
| 51 | + auto: true //是否在初始化后,自动执行downCallback; 默认true | |
| 52 | + }, | |
| 53 | + upOption: { | |
| 54 | + auto: false // 不自动加载 | |
| 55 | + }, | |
| 56 | + current: 0, | |
| 57 | + cameraTotal: 0, | |
| 58 | + list: [], | |
| 59 | + ordId: '', | |
| 60 | + }; | |
| 61 | + }, | |
| 62 | + onShow() { | |
| 63 | + if (this.ordId) { | |
| 64 | + this.loadData(1, this.ordId); | |
| 65 | + } | |
| 66 | + }, | |
| 67 | + onHide() { | |
| 68 | + this.ordId = ''; | |
| 69 | + }, | |
| 70 | + onLoad() { | |
| 71 | + // 隐藏原生的tabbar | |
| 72 | + uni.hideTabBar(); | |
| 73 | + }, | |
| 74 | + methods: { | |
| 75 | + /*下拉刷新的回调 */ | |
| 76 | + downCallback() { | |
| 77 | + //联网加载数据 | |
| 78 | + this.page.num = 1; | |
| 79 | + this.loadData(1); | |
| 80 | + }, | |
| 81 | + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */ | |
| 82 | + upCallback() { | |
| 83 | + //联网加载数据 | |
| 84 | + this.page.num += 1; | |
| 85 | + this.loadData(this.page.num); | |
| 86 | + }, | |
| 87 | + async loadData(pageNo, organizationId) { | |
| 88 | + let httpData = { | |
| 89 | + page: pageNo, | |
| 90 | + pageSize: 10, | |
| 91 | + organizationId | |
| 92 | + }; | |
| 93 | + const res = await api.homeApi.getCameraApi({ | |
| 94 | + params: httpData, | |
| 95 | + custom: { | |
| 96 | + load: false | |
| 97 | + } | |
| 98 | + }) | |
| 99 | + if (res) { | |
| 100 | + uni.stopPullDownRefresh(); | |
| 101 | + this.mescroll.endByPage(res.items.length, res.total); | |
| 102 | + this.cameraTotal = res.total; | |
| 103 | + if (pageNo == 1) { | |
| 104 | + this.list = res.items; | |
| 105 | + } else { | |
| 106 | + this.list = this.list.concat(res.items); | |
| 107 | + } | |
| 108 | + } | |
| 109 | + }, | |
| 110 | + //播放视频 | |
| 111 | + async playVideo(e) { | |
| 112 | + const {currentTarget: {dataset: {accessmode,id}} = {}} = e | |
| 113 | + const isExistVideoUrl = this.list.find(item => item.id == id).videoUrl | |
| 114 | + if (accessmode === 1 && !isExistVideoUrl) { | |
| 115 | + const res = api.homeApi.byCameraIdGetDetailApi(id) | |
| 116 | + if (res) { | |
| 117 | + const {data: {url} = {}} = res | |
| 118 | + const index = this.list.findIndex(item => item.id === id) | |
| 119 | + if (~index && url) { | |
| 120 | + this.list.splice(index, 1, { | |
| 121 | + ...this.list[index], | |
| 122 | + videoUrl: url | |
| 123 | + }) | |
| 124 | + this.$nextTick(() => { | |
| 125 | + let currentId = 'video' + id; | |
| 126 | + const videoContext = uni.createVideoContext(currentId, this); | |
| 127 | + videoContext.play() | |
| 128 | + }) | |
| 129 | + } | |
| 130 | + } | |
| 131 | + } | |
| 132 | + /** | |
| 133 | + * 点击全屏播放当前视频,暂停其余视频 | |
| 134 | + * 兼容APP和MP端 | |
| 135 | + */ | |
| 136 | + let currentId = 'video' + id; | |
| 137 | + this.videoContent = uni.createVideoContext(currentId, this); | |
| 138 | + this.videoContent.requestFullScreen(); | |
| 139 | + // 获取视频列表 | |
| 140 | + let trailer = this.list; | |
| 141 | + trailer.forEach((item, index) => { | |
| 142 | + if (item.videoUrl != null && item.videoUrl != '') { | |
| 143 | + let temp = 'video' + item.id; | |
| 144 | + if (temp != currentId) { | |
| 145 | + //暂停不是当前的视频 | |
| 146 | + uni.createVideoContext(temp, this).pause(); | |
| 147 | + } | |
| 148 | + } | |
| 149 | + }); | |
| 150 | + }, | |
| 151 | + openOrg() { | |
| 152 | + useNavigateTo('/pages/organization/organization') | |
| 153 | + } | |
| 154 | + } | |
| 155 | + }; | |
| 156 | +</script> | |
| 157 | + | |
| 158 | +<style lang="scss" scoped> | |
| 159 | + @import '../../static/camera.scss'; | |
| 173 | 160 | </style> |
| \ No newline at end of file | ... | ... |
pages/index/components/configuration/configuration-detail.vue
renamed from
pages/index/configuration/configuration-detail.vue
| 1 | 1 | <template> |
| 2 | - <view class="content"> | |
| 2 | + <view class="configuation-detail-page"> | |
| 3 | 3 | <!-- 公共组件-每个页面必须引入 --> |
| 4 | 4 | <public-module></public-module> |
| 5 | - <web-view :src="showConfiguration" bindload="bindload" binderror="binderror"></web-view> | |
| 5 | + <web-view :src="showConfiguration"></web-view> | |
| 6 | 6 | </view> |
| 7 | 7 | </template> |
| 8 | 8 | |
| ... | ... | @@ -38,14 +38,6 @@ |
| 38 | 38 | uni.removeStorageSync('config'); |
| 39 | 39 | }, |
| 40 | 40 | methods: { |
| 41 | - // 网页加载成功时候触发此事件 | |
| 42 | - bindload(res) { | |
| 43 | - console.log(res, res.detail); | |
| 44 | - }, | |
| 45 | - // 网页加载失败的时候触发此事件 | |
| 46 | - binderror(err) { | |
| 47 | - console.log(err, err.detail); | |
| 48 | - }, | |
| 49 | 41 | async requestUrl(e) { |
| 50 | 42 | const httpData = { |
| 51 | 43 | configurationId: e, |
| ... | ... | @@ -59,7 +51,6 @@ |
| 59 | 51 | }); |
| 60 | 52 | const pathUrl = uni.getStorageSync('config'); |
| 61 | 53 | const userInfo = uni.getStorageSync('userInfo') |
| 62 | - console.log(this.params) | |
| 63 | 54 | this.showConfiguration = this.params |
| 64 | 55 | } |
| 65 | 56 | } |
| ... | ... | @@ -67,8 +58,5 @@ |
| 67 | 58 | </script> |
| 68 | 59 | |
| 69 | 60 | <style lang="scss" scoped> |
| 70 | - .content { | |
| 71 | - background: #f8f9fa; | |
| 72 | - min-height: 100vh; | |
| 73 | - } | |
| 74 | -</style> | |
| 61 | + @import '../../static/configuration.scss'; | |
| 62 | +</style> | |
| \ No newline at end of file | ... | ... |
pages/index/components/configuration/configuration.vue
renamed from
pages/index/configuration/configuration.vue
| 1 | 1 | <template> |
| 2 | - <view class="status-page"> | |
| 3 | - <view style="margin-left:15rpx;background-color: #f8f9fa;position:fixed;top:0rpx;z-index: 99999;"> | |
| 4 | - <view style="height:35rpx;background-color: #f8f9fa;"></view> | |
| 5 | - <view class="u-flex search-top"> | |
| 2 | + <view class="configuation-page"> | |
| 3 | + <view class="configuation-header"> | |
| 4 | + <view class="header-gap"></view> | |
| 5 | + <view class="search-top"> | |
| 6 | 6 | <view class="search-main"> |
| 7 | 7 | <u--input @change="inputChanged" prefixIcon="search" placeholder="请输入组态名称" border="surround" |
| 8 | 8 | shape="circle"></u--input> |
| ... | ... | @@ -41,7 +41,7 @@ |
| 41 | 41 | mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件) |
| 42 | 42 | data() { |
| 43 | 43 | return { |
| 44 | - defaultConfigImage: '../../../static/test.png', | |
| 44 | + defaultConfigImage: '../../../../static/test.png', | |
| 45 | 45 | page: { |
| 46 | 46 | num: 0, |
| 47 | 47 | size: 10 |
| ... | ... | @@ -76,7 +76,7 @@ |
| 76 | 76 | openConfigDetail(e) { |
| 77 | 77 | const href = createScadaPageLink(e) |
| 78 | 78 | uni.navigateTo({ |
| 79 | - url: 'configurationDetail?configurationHref=' + href | |
| 79 | + url: 'configuration-detail?configurationHref=' + href | |
| 80 | 80 | }); |
| 81 | 81 | }, |
| 82 | 82 | /*下拉刷新的回调 */ |
| ... | ... | @@ -120,5 +120,5 @@ |
| 120 | 120 | </script> |
| 121 | 121 | |
| 122 | 122 | <style lang="scss" scoped> |
| 123 | - @import '../static/configuration.scss'; | |
| 123 | + @import '../../static/configuration.scss'; | |
| 124 | 124 | </style> |
| \ No newline at end of file | ... | ... |
pages/index/components/configuration/help.js
renamed from
pages/index/configuration/help.js
| 1 | -import config from '../../../config/baseUrl.js' | |
| 2 | -import { | |
| 3 | - atob, | |
| 4 | - btoa | |
| 5 | -} from './weapp.atob.js' | |
| 6 | -const getRandomString = () => Number(Math.random().toString().substring(2)).toString(36); | |
| 7 | - | |
| 8 | -export const ScadaModeEnum = { | |
| 9 | - PRIVATE_VIEW: 'PRIVATE_VIEW', | |
| 10 | - PUBLIC_VIEW: 'PUBLIC_VIEW', | |
| 11 | -} | |
| 12 | - | |
| 13 | -export const encode = (record) => { | |
| 14 | - let hash = JSON.stringify(record); | |
| 15 | - const mixinString = getRandomString() | |
| 16 | - .slice(0, 10) | |
| 17 | - .padEnd(10, getRandomString()) | |
| 18 | - .split('') | |
| 19 | - .map((item) => (Math.random() > 0.5 ? item.toUpperCase() : item)) | |
| 20 | - .join(''); | |
| 21 | - hash = btoa(hash); | |
| 22 | - hash = hash.substring(0, 6) + mixinString + hash.substring(6); | |
| 23 | - hash = btoa(hash); | |
| 24 | - return hash; | |
| 25 | -}; | |
| 26 | - | |
| 27 | - | |
| 28 | -export const createScadaPageLink = ( | |
| 29 | - record, | |
| 30 | - mode = ScadaModeEnum.PRIVATE_VIEW, | |
| 31 | - open = false | |
| 32 | -) => { | |
| 33 | - const userInfo = uni.getStorageSync('userInfo') | |
| 34 | - const params = { | |
| 35 | - configurationId: record?.id, | |
| 36 | - organizationId: record?.organizationId, | |
| 37 | - mode: record?.viewType === ScadaModeEnum.PRIVATE_VIEW ? 'lightbox' : 'share', | |
| 1 | +import config from '../../../../config/baseUrl.js' | |
| 2 | +import { | |
| 3 | + atob, | |
| 4 | + btoa | |
| 5 | +} from './weapp.atob.js' | |
| 6 | +const getRandomString = () => Number(Math.random().toString().substring(2)).toString(36); | |
| 7 | + | |
| 8 | +export const ScadaModeEnum = { | |
| 9 | + PRIVATE_VIEW: 'PRIVATE_VIEW', | |
| 10 | + PUBLIC_VIEW: 'PUBLIC_VIEW', | |
| 11 | +} | |
| 12 | + | |
| 13 | +export const encode = (record) => { | |
| 14 | + let hash = JSON.stringify(record); | |
| 15 | + const mixinString = getRandomString() | |
| 16 | + .slice(0, 10) | |
| 17 | + .padEnd(10, getRandomString()) | |
| 18 | + .split('') | |
| 19 | + .map((item) => (Math.random() > 0.5 ? item.toUpperCase() : item)) | |
| 20 | + .join(''); | |
| 21 | + hash = btoa(hash); | |
| 22 | + hash = hash.substring(0, 6) + mixinString + hash.substring(6); | |
| 23 | + hash = btoa(hash); | |
| 24 | + return hash; | |
| 25 | +}; | |
| 26 | + | |
| 27 | + | |
| 28 | +export const createScadaPageLink = ( | |
| 29 | + record, | |
| 30 | + mode = ScadaModeEnum.PRIVATE_VIEW, | |
| 31 | + open = false | |
| 32 | +) => { | |
| 33 | + const userInfo = uni.getStorageSync('userInfo') | |
| 34 | + const params = { | |
| 35 | + configurationId: record?.id, | |
| 36 | + organizationId: record?.organizationId, | |
| 37 | + mode: record?.viewType === ScadaModeEnum.PRIVATE_VIEW ? 'lightbox' : 'share', | |
| 38 | 38 | platform: record?.platform, |
| 39 | - userId: userInfo.userId | |
| 40 | - }; | |
| 41 | - | |
| 42 | - if (record?.viewType === ScadaModeEnum.PUBLIC_VIEW) { | |
| 43 | - params.publicId = record.publicId; | |
| 44 | - } | |
| 45 | - | |
| 46 | - const hash = encode(params); | |
| 47 | - | |
| 48 | - const href = `${config.baseDrawioUrl}#${hash}` | |
| 49 | - | |
| 50 | - return href | |
| 39 | + userId: userInfo.userId | |
| 40 | + }; | |
| 41 | + | |
| 42 | + if (record?.viewType === ScadaModeEnum.PUBLIC_VIEW) { | |
| 43 | + params.publicId = record.publicId; | |
| 44 | + } | |
| 45 | + | |
| 46 | + const hash = encode(params); | |
| 47 | + | |
| 48 | + const href = `${config.baseDrawioUrl}#${hash}` | |
| 49 | + | |
| 50 | + return href | |
| 51 | 51 | }; |
| \ No newline at end of file | ... | ... |
pages/index/components/configuration/weapp.atob.js
renamed from
pages/index/configuration/weapp.atob.js
| 1 | -var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; | |
| 2 | -var b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; | |
| 3 | -export const btoa = function(string) { | |
| 4 | - string = String(string); | |
| 5 | - var bitmap, a, b, c, result = "", | |
| 6 | - i = 0, | |
| 7 | - rest = string.length % 3; | |
| 8 | - for (; i < string.length;) { | |
| 9 | - if ((a = string.charCodeAt(i++)) > 255 || | |
| 10 | - (b = string.charCodeAt(i++)) > 255 || | |
| 11 | - (c = string.charCodeAt(i++)) > 255) | |
| 12 | - throw new TypeError( | |
| 13 | - "Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range." | |
| 14 | - ); | |
| 15 | - bitmap = (a << 16) | (b << 8) | c; | |
| 16 | - result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) + | |
| 17 | - b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63); | |
| 18 | - } | |
| 19 | - return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result; | |
| 20 | -}; | |
| 21 | - | |
| 22 | -export const atob = function(string) { | |
| 23 | - string = String(string).replace(/[\t\n\f\r ]+/g, ""); | |
| 24 | - if (!b64re.test(string)) | |
| 25 | - throw new TypeError( | |
| 26 | - "Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."); | |
| 27 | - string += "==".slice(2 - (string.length & 3)); | |
| 28 | - var bitmap, result = "", | |
| 29 | - r1, r2, i = 0; | |
| 30 | - for (; i < string.length;) { | |
| 31 | - bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 | | |
| 32 | - (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++))); | |
| 33 | - result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) : | |
| 34 | - r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) : | |
| 35 | - String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); | |
| 36 | - } | |
| 37 | - return result; | |
| 38 | -}; | |
| 39 | - | |
| 40 | -function b64DecodeUnicode(str) { | |
| 41 | - return decodeURIComponent(exports.weAtob(str).replace(/(.)/g, function(p) { | |
| 42 | - var code = p.charCodeAt(0).toString(16).toUpperCase(); | |
| 43 | - if (code.length < 2) { | |
| 44 | - code = "0" + code; | |
| 45 | - } | |
| 46 | - return "%" + code; | |
| 47 | - })); | |
| 48 | -} | |
| 49 | - | |
| 50 | -function base64_url_decode(str) { | |
| 51 | - var output = str.replace(/-/g, "+").replace(/_/g, "/"); | |
| 52 | - switch (output.length % 4) { | |
| 53 | - case 0: | |
| 54 | - break; | |
| 55 | - case 2: | |
| 56 | - output += "=="; | |
| 57 | - break; | |
| 58 | - case 3: | |
| 59 | - output += "="; | |
| 60 | - break; | |
| 61 | - default: | |
| 62 | - throw "Illegal base64url string!"; | |
| 63 | - } | |
| 64 | - try { | |
| 65 | - return b64DecodeUnicode(output); | |
| 66 | - } catch (err) { | |
| 67 | - return exports.weAtob(output); | |
| 68 | - } | |
| 69 | -} | |
| 70 | - | |
| 71 | -function weappJwtDecode(token, options) { | |
| 72 | - if (typeof token !== "string") { | |
| 73 | - throw ("Invalid token specified"); | |
| 74 | - } | |
| 75 | - options = options || {}; | |
| 76 | - var pos = options.header === true ? 0 : 1; | |
| 77 | - try { | |
| 78 | - return JSON.parse(base64_url_decode(token.split(".")[pos])); | |
| 79 | - } catch (e) { | |
| 80 | - throw ("Invalid token specified: " + e.message); | |
| 81 | - } | |
| 1 | +var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; | |
| 2 | +var b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; | |
| 3 | +export const btoa = function(string) { | |
| 4 | + string = String(string); | |
| 5 | + var bitmap, a, b, c, result = "", | |
| 6 | + i = 0, | |
| 7 | + rest = string.length % 3; | |
| 8 | + for (; i < string.length;) { | |
| 9 | + if ((a = string.charCodeAt(i++)) > 255 || | |
| 10 | + (b = string.charCodeAt(i++)) > 255 || | |
| 11 | + (c = string.charCodeAt(i++)) > 255) | |
| 12 | + throw new TypeError( | |
| 13 | + "Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range." | |
| 14 | + ); | |
| 15 | + bitmap = (a << 16) | (b << 8) | c; | |
| 16 | + result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) + | |
| 17 | + b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63); | |
| 18 | + } | |
| 19 | + return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result; | |
| 20 | +}; | |
| 21 | + | |
| 22 | +export const atob = function(string) { | |
| 23 | + string = String(string).replace(/[\t\n\f\r ]+/g, ""); | |
| 24 | + if (!b64re.test(string)) | |
| 25 | + throw new TypeError( | |
| 26 | + "Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."); | |
| 27 | + string += "==".slice(2 - (string.length & 3)); | |
| 28 | + var bitmap, result = "", | |
| 29 | + r1, r2, i = 0; | |
| 30 | + for (; i < string.length;) { | |
| 31 | + bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 | | |
| 32 | + (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++))); | |
| 33 | + result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) : | |
| 34 | + r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) : | |
| 35 | + String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); | |
| 36 | + } | |
| 37 | + return result; | |
| 38 | +}; | |
| 39 | + | |
| 40 | +function b64DecodeUnicode(str) { | |
| 41 | + return decodeURIComponent(exports.weAtob(str).replace(/(.)/g, function(p) { | |
| 42 | + var code = p.charCodeAt(0).toString(16).toUpperCase(); | |
| 43 | + if (code.length < 2) { | |
| 44 | + code = "0" + code; | |
| 45 | + } | |
| 46 | + return "%" + code; | |
| 47 | + })); | |
| 48 | +} | |
| 49 | + | |
| 50 | +function base64_url_decode(str) { | |
| 51 | + var output = str.replace(/-/g, "+").replace(/_/g, "/"); | |
| 52 | + switch (output.length % 4) { | |
| 53 | + case 0: | |
| 54 | + break; | |
| 55 | + case 2: | |
| 56 | + output += "=="; | |
| 57 | + break; | |
| 58 | + case 3: | |
| 59 | + output += "="; | |
| 60 | + break; | |
| 61 | + default: | |
| 62 | + throw "Illegal base64url string!"; | |
| 63 | + } | |
| 64 | + try { | |
| 65 | + return b64DecodeUnicode(output); | |
| 66 | + } catch (err) { | |
| 67 | + return exports.weAtob(output); | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 71 | +function weappJwtDecode(token, options) { | |
| 72 | + if (typeof token !== "string") { | |
| 73 | + throw ("Invalid token specified"); | |
| 74 | + } | |
| 75 | + options = options || {}; | |
| 76 | + var pos = options.header === true ? 0 : 1; | |
| 77 | + try { | |
| 78 | + return JSON.parse(base64_url_decode(token.split(".")[pos])); | |
| 79 | + } catch (e) { | |
| 80 | + throw ("Invalid token specified: " + e.message); | |
| 81 | + } | |
| 82 | 82 | } |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -12,6 +12,7 @@ const basicGridList = [{ |
| 12 | 12 | |
| 13 | 13 | const basicStatistics = [{ |
| 14 | 14 | text: '设备统计', |
| 15 | + key: 'device', | |
| 15 | 16 | icon: '/static/device-total.png', |
| 16 | 17 | leftParam: 'ONLINE', |
| 17 | 18 | centerParam: 'OFFLINE', |
| ... | ... | @@ -19,7 +20,7 @@ const basicStatistics = [{ |
| 19 | 20 | value: { |
| 20 | 21 | leftValue: 0, |
| 21 | 22 | centerValue: 0, |
| 22 | - rightrValue: 0 | |
| 23 | + rightValue: 0 | |
| 23 | 24 | }, |
| 24 | 25 | label: { |
| 25 | 26 | leftText: "在线", |
| ... | ... | @@ -29,6 +30,7 @@ const basicStatistics = [{ |
| 29 | 30 | }, |
| 30 | 31 | { |
| 31 | 32 | text: '告警统计', |
| 33 | + key: 'alarm', | |
| 32 | 34 | icon: '/static/alert.png', |
| 33 | 35 | leftParam: ['ACTIVE_ACK'], |
| 34 | 36 | centerParam: 'CLEARED_ACK', |
| ... | ... | @@ -36,7 +38,7 @@ const basicStatistics = [{ |
| 36 | 38 | value: { |
| 37 | 39 | leftValue: 0, |
| 38 | 40 | centerValue: 0, |
| 39 | - rightrValue: 0 | |
| 41 | + rightValue: 0 | |
| 40 | 42 | }, |
| 41 | 43 | label: { |
| 42 | 44 | leftText: "未处理", | ... | ... |
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | <public-module></public-module> |
| 5 | 5 | <view> |
| 6 | 6 | <!-- 基础统计 --> |
| 7 | - <view class="basic-sty"> | |
| 7 | + <view class="basic-statistics"> | |
| 8 | 8 | <view class="basic-text"><text class="text text-bold">基础统计</text></view> |
| 9 | 9 | <view class="basic"> |
| 10 | 10 | <view class="basic-item" v-for="(item,index) in basicStatistics" :key="index"> |
| ... | ... | @@ -29,7 +29,7 @@ |
| 29 | 29 | </view> |
| 30 | 30 | <view @click="navigatorPage(item,item.rightParam)" class="u-flex sigle-child"> |
| 31 | 31 | <view class="sigle-text"> |
| 32 | - <text class="home-text-total">{{item.value.rightrValue}}</text> | |
| 32 | + <text class="home-text-total">{{item.value.rightValue}}</text> | |
| 33 | 33 | </view> |
| 34 | 34 | <view class="sigle-value"><text |
| 35 | 35 | class="home-text-total-bottom">{{item.label.rightText}}</text></view> |
| ... | ... | @@ -96,33 +96,40 @@ |
| 96 | 96 | setTimeout(function() { |
| 97 | 97 | uni.stopPullDownRefresh(); |
| 98 | 98 | uni.$u.toast('下拉刷新成功...'); |
| 99 | - }, 800); | |
| 99 | + }, 200); | |
| 100 | 100 | }, |
| 101 | 101 | methods: { |
| 102 | 102 | ...mapActions(['updateBadgeTotal']), |
| 103 | 103 | async getDeviceTotalData() { |
| 104 | 104 | const res = await api.homeApi.getHomeStatisticsApi() |
| 105 | 105 | if (res) { |
| 106 | - this.basicStatistics[0].value.leftValue = res.totalDevice.onLine | |
| 107 | - this.basicStatistics[0].value.centerValue = res.totalDevice.offLine | |
| 108 | - this.basicStatistics[0].value.rightrValue = res.totalDevice.inActive | |
| 109 | - this.basicStatistics[1].value.leftValue = res.totalAlarm.activedAlarm | |
| 110 | - this.basicStatistics[1].value.centerValue = res.totalAlarm.clearedAck | |
| 111 | - this.basicStatistics[1].value.rightrValue = res.totalAlarm.clearedUnack | |
| 106 | + const { onLine,offLine,inActive } = res.totalDevice | |
| 107 | + const { activedAlarm,clearedAck,clearedUnack } = res.totalAlarm | |
| 108 | + this.basicStatistics.map(item=>{ | |
| 109 | + const { key, value } = item | |
| 110 | + if(key === 'device'){ | |
| 111 | + value.leftValue = onLine | |
| 112 | + value.centerValue =offLine | |
| 113 | + value.rightValue = inActive | |
| 114 | + }else{ | |
| 115 | + value.leftValue = activedAlarm | |
| 116 | + value.centerValue =clearedAck | |
| 117 | + value.rightValue = clearedUnack | |
| 118 | + } | |
| 119 | + }) | |
| 112 | 120 | //异步实时更新告警徽标数 |
| 113 | 121 | this.updateBadgeTotal(res.totalAlarm?.activedAlarm); |
| 114 | 122 | } |
| 115 | 123 | }, |
| 116 | 124 | openCamera() { |
| 117 | - useNavigateTo('camera/camera') | |
| 125 | + useNavigateTo('components/camera/camera') | |
| 118 | 126 | }, |
| 119 | 127 | openConfiguration() { |
| 120 | - useNavigateTo('configuration/configuration') | |
| 128 | + useNavigateTo('components/configuration/configuration') | |
| 121 | 129 | }, |
| 122 | 130 | handleEvent(event) { |
| 123 | - if (event === 'openCamera') { | |
| 124 | - this.openCamera() | |
| 125 | - } else { | |
| 131 | + if (event === 'openCamera') this.openCamera() | |
| 132 | + else { | |
| 126 | 133 | this.openConfiguration() |
| 127 | 134 | } |
| 128 | 135 | }, |
| ... | ... | @@ -130,9 +137,8 @@ |
| 130 | 137 | const { |
| 131 | 138 | text |
| 132 | 139 | } = item |
| 133 | - if (text === '设备统计') { | |
| 134 | - this.navigatorDeviceStatus(type) | |
| 135 | - } else { | |
| 140 | + if (text === '设备统计') this.navigatorDeviceStatus(type) | |
| 141 | + else { | |
| 136 | 142 | this.navigatorAlarmStatus(type) |
| 137 | 143 | } |
| 138 | 144 | }, | ... | ... |
| 1 | 1 | <template> |
| 2 | - <view class="container"> | |
| 3 | - <view class="container-box"> | |
| 4 | - <image v-if="mpOwnConfig.logo" :src="mpOwnConfig.logo"></image> | |
| 2 | + <view class="splash-container"> | |
| 3 | + <view class="splash-container-box"> | |
| 4 | + <image v-if="initConfig.logo" :src="initConfig.logo"></image> | |
| 5 | 5 | <image v-else :src="staticLogo"></image> |
| 6 | 6 | <text class="splash-text-muted">连接世界 创造价值</text> |
| 7 | 7 | </view> |
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | data() { |
| 22 | 22 | return { |
| 23 | 23 | staticLogo: '/static/logo.png', |
| 24 | - mpOwnConfig: {} | |
| 24 | + initConfig: {} | |
| 25 | 25 | }; |
| 26 | 26 | }, |
| 27 | 27 | onLoad() { |
| ... | ... | @@ -47,7 +47,7 @@ |
| 47 | 47 | methods: { |
| 48 | 48 | async getPlateForm() { |
| 49 | 49 | const res = await api.loginApi.getPlateCustomApi() |
| 50 | - this.mpOwnConfig = { | |
| 50 | + this.initConfig = { | |
| 51 | 51 | bg: res.background, |
| 52 | 52 | logo: res.logo ? res.logo : this.staticLogo, |
| 53 | 53 | name: res.name |
| ... | ... | @@ -57,22 +57,7 @@ |
| 57 | 57 | }; |
| 58 | 58 | </script> |
| 59 | 59 | |
| 60 | -<style lang="scss"> | |
| 61 | - .container { | |
| 62 | - width: 100%; | |
| 63 | - height: 100%; | |
| 64 | - margin-top: 300rpx; | |
| 65 | 60 | |
| 66 | - .container-box { | |
| 67 | - display: flex; | |
| 68 | - align-items: center; | |
| 69 | - justify-content: space-between; | |
| 70 | - flex-direction: column; | |
| 71 | - | |
| 72 | - image { | |
| 73 | - width: 100rpx; | |
| 74 | - height: 100rpx; | |
| 75 | - } | |
| 76 | - } | |
| 77 | - } | |
| 61 | +<style lang="scss" scoped> | |
| 62 | + @import './static/splash.scss'; | |
| 78 | 63 | </style> |
| \ No newline at end of file | ... | ... |
pages/index/static/splash.scss
0 → 100644
| 1 | +.splash-container { | |
| 2 | + width: 100%; | |
| 3 | + height: 100%; | |
| 4 | + margin-top: 300rpx; | |
| 5 | + | |
| 6 | + .splash-container-box { | |
| 7 | + display: flex; | |
| 8 | + align-items: center; | |
| 9 | + justify-content: space-between; | |
| 10 | + flex-direction: column; | |
| 11 | + | |
| 12 | + image { | |
| 13 | + width: 100rpx; | |
| 14 | + height: 100rpx; | |
| 15 | + } | |
| 16 | + } | |
| 17 | + } | |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -17,6 +17,7 @@ |
| 17 | 17 | |
| 18 | 18 | <script> |
| 19 | 19 | import { transOrgFunc } from '@/config/common.js'; |
| 20 | +import api from '@/api/index.js' | |
| 20 | 21 | |
| 21 | 22 | export default { |
| 22 | 23 | data() { |
| ... | ... | @@ -33,16 +34,12 @@ export default { |
| 33 | 34 | this.loadData(); |
| 34 | 35 | }, |
| 35 | 36 | methods: { |
| 36 | - loadData() { | |
| 37 | - uni.$u.http | |
| 38 | - .get('/yt/organization/me/list') | |
| 39 | - .then(res => { | |
| 40 | - if (res) { | |
| 41 | - const list = transOrgFunc(res); | |
| 42 | - this.tree = list; | |
| 43 | - } | |
| 44 | - }) | |
| 45 | - .catch(e => {}); | |
| 37 | + async loadData() { | |
| 38 | + const res = await api.loginApi.getMeOrgListApi() | |
| 39 | + if (res) { | |
| 40 | + const list = transOrgFunc(res); | |
| 41 | + this.tree = list; | |
| 42 | + } | |
| 46 | 43 | }, |
| 47 | 44 | confirm(val) { |
| 48 | 45 | this.id = val[0].id; | ... | ... |
| 1 | +<template> | |
| 2 | + <view> | |
| 3 | + <u-popup bgColor="transparent" :overlay="true" :show="show" mode="bottom"> | |
| 4 | + <view class="u-flex logout-main"> | |
| 5 | + <view class="main"><text style="color: #999999">您确定要退出当前账号吗?</text></view> | |
| 6 | + <view @click="$emit('logoutBtn')" class="main"><text style="color: #f95e5a">退出登录</text></view> | |
| 7 | + <view class="cancel-text"><text @click="$emit('closeLogoutPopup')" style="color: #3478f7">取消</text> | |
| 8 | + </view> | |
| 9 | + </view> | |
| 10 | + </u-popup> | |
| 11 | + </view> | |
| 12 | +</template> | |
| 13 | + | |
| 14 | +<script> | |
| 15 | + export default { | |
| 16 | + props: { | |
| 17 | + show: { | |
| 18 | + type: Boolean, | |
| 19 | + default: false | |
| 20 | + } | |
| 21 | + }, | |
| 22 | + } | |
| 23 | +</script> | |
| 24 | + | |
| 25 | +<style lang="scss" scoped> | |
| 26 | + @import '../static/personal.scss'; | |
| 27 | +</style> | |
| \ No newline at end of file | ... | ... |
pages/personal/config/data.js
0 → 100644
| 1 | +const systemList = [{ | |
| 2 | + url: '/sysnotify-subpackage/sys-notify/system-notify', | |
| 3 | + text: '系统通知', | |
| 4 | + leftIcon: '/static/sys-not.png', | |
| 5 | + rightIcon: '/static/arrow-right.png' | |
| 6 | + }, | |
| 7 | + { | |
| 8 | + url: '/feedback-subpackage/feedback/feedback', | |
| 9 | + text: '意见反馈', | |
| 10 | + leftIcon: '/static/find-sugg.png', | |
| 11 | + rightIcon: '/static/arrow-right.png' | |
| 12 | + } | |
| 13 | +] | |
| 14 | +export { | |
| 15 | + systemList | |
| 16 | +} | |
| \ No newline at end of file | ... | ... |
| 1 | 1 | <template> |
| 2 | - <view class="personal"> | |
| 2 | + <view class="personal-page"> | |
| 3 | 3 | <!-- 公共组件-每个页面必须引入 --> |
| 4 | 4 | <public-module></public-module> |
| 5 | - <view class="head-box"> | |
| 5 | + <view class="header-box"> | |
| 6 | 6 | <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30"> |
| 7 | 7 | <block v-if="userInfo.isToken || userInfo.isThirdLogin"> |
| 8 | 8 | <view @click.top="navigatorPersonal" class="u-m-r-20"> |
| ... | ... | @@ -38,7 +38,7 @@ |
| 38 | 38 | </view> |
| 39 | 39 | <view class="u-flex my-nav"> |
| 40 | 40 | <view class="nav-main"> |
| 41 | - <view v-for="(item,index) in systemList" @click="onTokenJump(item.url)" class="u-flex nav-link"> | |
| 41 | + <view v-for="(item,index) in systemList" :key="index" @click="onTokenJump(item.url)" class="u-flex nav-link"> | |
| 42 | 42 | <view class="nav-image"> |
| 43 | 43 | <image class="image" :src="item.leftIcon"></image> |
| 44 | 44 | </view> |
| ... | ... | @@ -53,21 +53,9 @@ |
| 53 | 53 | </view> |
| 54 | 54 | </view> |
| 55 | 55 | <!-- 绑定账号 --> |
| 56 | - <view> | |
| 57 | - <bind-account-modal ref="bindAccountRef" :show="showBindAccount" | |
| 58 | - @cancelAccountModal="handleCancelAccountModal" /> | |
| 59 | - </view> | |
| 56 | + <bind-account-modal ref="bindAccountRef" :show="showBindAccount" @cancelAccountModal="handleCancelAccountModal" /> | |
| 60 | 57 | <!-- 退出登录 --> |
| 61 | - <view> | |
| 62 | - <u-popup bgColor="transparent" :overlay="true" :show="showLogout" mode="bottom"> | |
| 63 | - <view class="u-flex logout-main"> | |
| 64 | - <view class="main"><text style="color: #999999">您确定要退出当前账号?</text></view> | |
| 65 | - <view @click="logoutBtn" class="main"><text style="color: #f95e5a">退出登录</text></view> | |
| 66 | - <view class="cancel-text"><text @click="closeLogoutPopup" style="color: #3478f7">取消</text> | |
| 67 | - </view> | |
| 68 | - </view> | |
| 69 | - </u-popup> | |
| 70 | - </view> | |
| 58 | + <logout-account-modal ref="logoutAccountRef" :show="showLogout" @logoutBtn="logoutBtn" @closeLogoutPopup="closeLogoutPopup"/> | |
| 71 | 59 | <f-tabbar></f-tabbar> |
| 72 | 60 | </view> |
| 73 | 61 | </template> |
| ... | ... | @@ -76,40 +64,24 @@ |
| 76 | 64 | import fTabbar from '@/components/module/f-tabbar/f-tabbar'; |
| 77 | 65 | import fNavbar from '@/components/module/f-navbar/f-navbar'; |
| 78 | 66 | import bindAccountModal from './components/bind-account-modal.vue' |
| 79 | - import { | |
| 80 | - mapState, | |
| 81 | - mapMutations | |
| 82 | - } from 'vuex'; | |
| 83 | - import { | |
| 84 | - useNavigateTo, | |
| 85 | - useReLaunch, | |
| 86 | - useShowModal | |
| 87 | - } from '@/plugins/utils.js' | |
| 67 | + import logoutAccountModal from './components/logout-account-modal.vue' | |
| 68 | + import { mapState,mapMutations } from 'vuex'; | |
| 69 | + import { useNavigateTo,useReLaunch,useShowModal } from '@/plugins/utils.js' | |
| 70 | + import { systemList } from './config/data.js' | |
| 88 | 71 | |
| 89 | 72 | export default { |
| 90 | 73 | components: { |
| 91 | 74 | fTabbar, |
| 92 | 75 | fNavbar, |
| 93 | - bindAccountModal | |
| 76 | + bindAccountModal, | |
| 77 | + logoutAccountModal, | |
| 94 | 78 | }, |
| 95 | 79 | data() { |
| 96 | 80 | return { |
| 97 | 81 | showBindAccount: false, |
| 98 | 82 | showLogout: false, |
| 99 | 83 | thirdObj: {}, |
| 100 | - systemList: [{ | |
| 101 | - url: '/sysnotify-subpackage/sys-notify/system-notify', | |
| 102 | - text: '系统通知', | |
| 103 | - leftIcon: '/static/sys-not.png', | |
| 104 | - rightIcon: '/static/arrow-right.png' | |
| 105 | - }, | |
| 106 | - { | |
| 107 | - url: '/feedback-subpackage/feedback/feedback', | |
| 108 | - text: '意见反馈', | |
| 109 | - leftIcon: '/static/find-sugg.png', | |
| 110 | - rightIcon: '/static/arrow-right.png' | |
| 111 | - } | |
| 112 | - ] | |
| 84 | + systemList, | |
| 113 | 85 | }; |
| 114 | 86 | }, |
| 115 | 87 | onLoad(e) { |
| ... | ... | @@ -132,11 +104,13 @@ |
| 132 | 104 | }, |
| 133 | 105 | // 跳转前判断登录 |
| 134 | 106 | onTokenJump(url) { |
| 107 | + if(!url) return | |
| 135 | 108 | this.judgeLogin(() => { |
| 136 | 109 | useNavigateTo(url) |
| 137 | 110 | }); |
| 138 | 111 | }, |
| 139 | 112 | onJump(url) { |
| 113 | + if(!url) return | |
| 140 | 114 | useNavigateTo(url) |
| 141 | 115 | }, |
| 142 | 116 | navigatorLogin() { | ... | ... |
| ... | ... | @@ -68,6 +68,9 @@ button { |
| 68 | 68 | .mt-15{ |
| 69 | 69 | margin-top: 15rpx; |
| 70 | 70 | } |
| 71 | +.mt-20{ | |
| 72 | + margin-top: 20rpx; | |
| 73 | +} | |
| 71 | 74 | .mr-1{ |
| 72 | 75 | margin-right: 10rpx; |
| 73 | 76 | } |
| ... | ... | @@ -86,10 +89,21 @@ button { |
| 86 | 89 | .w-100{ |
| 87 | 90 | width: 100%; |
| 88 | 91 | } |
| 92 | +.w-300{ | |
| 93 | + width:300rpx; | |
| 94 | +} | |
| 95 | +.w-500{ | |
| 96 | + width:500rpx; | |
| 97 | +} | |
| 98 | +.h-25{ | |
| 99 | + height:25rpx; | |
| 100 | +} | |
| 89 | 101 | .h-30{ |
| 90 | 102 | height:30rpx; |
| 91 | 103 | } |
| 92 | - | |
| 104 | +.h-140{ | |
| 105 | + height:140rpx; | |
| 106 | +} | |
| 93 | 107 | //通用(设备、告警、摄像头分页头部组织和设备数和设备、告警里面的详情(左边的文本) |
| 94 | 108 | .ml-10{ |
| 95 | 109 | margin-left: 10rpx; | ... | ... |
| 1 | +const actions = [{ | |
| 2 | + url: '/sysnotify-subpackage/sys-notify/system-notify', | |
| 3 | + text: '系统通知', | |
| 4 | + leftIcon: '/static/sys-not.png', | |
| 5 | + rightIcon: '/static/arrow-right.png' | |
| 6 | + }, | |
| 7 | + { | |
| 8 | + url: '/feedback-subpackage/feedback/feedback', | |
| 9 | + text: '意见反馈', | |
| 10 | + leftIcon: '/static/find-sugg.png', | |
| 11 | + rightIcon: '/static/arrow-right.png' | |
| 12 | + } | |
| 13 | +] | |
| 14 | +export { | |
| 15 | + actions | |
| 16 | +} | |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -5,11 +5,11 @@ |
| 5 | 5 | <view class="notify-column"> |
| 6 | 6 | <view class="column-list"> |
| 7 | 7 | <view class="column-title"> |
| 8 | - <view class="text-clip" style="width:500rpx"> | |
| 8 | + <view class="text-clip w-500"> | |
| 9 | 9 | <text class="notify-detail-text ">{{ notifyList.title }}</text> |
| 10 | 10 | </view> |
| 11 | 11 | </view> |
| 12 | - <view style="height: 25rpx;"></view> | |
| 12 | + <view class="h-25"></view> | |
| 13 | 13 | <u-list height="140rpx"> |
| 14 | 14 | <u-list-item> |
| 15 | 15 | <u-cell :value="`${notifyList.senderDate}`" :title="`${notifyList.senderName}`"> |
| ... | ... | @@ -19,10 +19,9 @@ |
| 19 | 19 | </u-list> |
| 20 | 20 | <view class="bottom-text"> |
| 21 | 21 | <view class="u-flex column"></view> |
| 22 | - <view style="margin-top: 21rpx;"> | |
| 22 | + <view class="mt-20"> | |
| 23 | 23 | <!-- 富文本解析 --> |
| 24 | 24 | <u-parse :content="notifyList.content"></u-parse> |
| 25 | - <!-- 富文本解析 --> | |
| 26 | 25 | </view> |
| 27 | 26 | </view> |
| 28 | 27 | </view> | ... | ... |
| ... | ... | @@ -44,6 +44,7 @@ |
| 44 | 44 | import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; |
| 45 | 45 | import api from '@/api/index.js' |
| 46 | 46 | import { useNavigateTo } from '@/plugins/utils.js' |
| 47 | + import { actions } from './config/data.js' | |
| 47 | 48 | |
| 48 | 49 | export default { |
| 49 | 50 | mixins: [MescrollMixin], |
| ... | ... | @@ -51,23 +52,7 @@ |
| 51 | 52 | return { |
| 52 | 53 | notifyType:'', |
| 53 | 54 | showType: false, |
| 54 | - actions: [{ | |
| 55 | - name: '全部', | |
| 56 | - value: '' | |
| 57 | - }, | |
| 58 | - { | |
| 59 | - name: '会议', | |
| 60 | - value: 'MEETING' | |
| 61 | - }, | |
| 62 | - { | |
| 63 | - name: '公告', | |
| 64 | - value: 'NOTICE' | |
| 65 | - }, | |
| 66 | - { | |
| 67 | - name: '其他', | |
| 68 | - value: 'OTHER' | |
| 69 | - } | |
| 70 | - ], | |
| 55 | + actions, | |
| 71 | 56 | page: { |
| 72 | 57 | page: 0, |
| 73 | 58 | pageSize: 10 |
| ... | ... | @@ -86,7 +71,9 @@ |
| 86 | 71 | }, |
| 87 | 72 | methods: { |
| 88 | 73 | formatType(e) { |
| 89 | - return this.actions.find((item)=>item.value===e && item.value!=='').name | |
| 74 | + const findName = this.actions.find((item)=>item.value===e && item.value!=='') | |
| 75 | + if(!findName) return | |
| 76 | + return findName.name | |
| 90 | 77 | }, |
| 91 | 78 | handleTypeClick() { |
| 92 | 79 | this.showType = true; | ... | ... |