From 89334e8f839f04a3c85c9853520570d327f281ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=81=82=E9=BB=8E?= <329261568@qq.com> Date: Tue, 5 Sep 2023 17:01:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20=E7=BD=91=E5=85=B3?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=9B=BA=E4=BB=B6=E5=8D=87=E7=BA=A7=EF=BC=8C?= =?UTF-8?q?=E5=9E=8B=E5=8F=B7=E7=B3=BB=E5=88=97=20=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 4 +- src/api/iot/deviceOta.js | 11 + src/api/iot/model.js | 17 + src/api/iot/modelSeries.js | 53 ++ src/store/modules/attribute.js | 22 +- src/utils/hciot.js | 1 + src/views/iot/model/index.vue | 223 +++++- src/views/iot/modelScries/index.vue | 637 ++++++++++++++++++ .../ESceneAction/src/executeAction.js | 1 + .../profile/BatchFirmwareUpgrade/example.vue | 111 +++ .../profile/BatchFirmwareUpgrade/index.js | 7 + .../BatchFirmwareUpgrade/src/ESelect.vue | 44 ++ .../BatchFirmwareUpgrade/src/firmwareItem.js | 134 ++++ .../BatchFirmwareUpgrade/src/index.css | 47 ++ src/views/profile/DeviceDetailsView/index.vue | 87 ++- src/views/profile/attribute/attributeView.vue | 14 +- src/views/profile/attribute/groupView.vue | 15 +- src/views/profile/attribute/index.vue | 41 +- 18 files changed, 1429 insertions(+), 40 deletions(-) create mode 100644 src/api/iot/modelSeries.js create mode 100644 src/views/iot/modelScries/index.vue create mode 100644 src/views/profile/BatchFirmwareUpgrade/example.vue create mode 100644 src/views/profile/BatchFirmwareUpgrade/index.js create mode 100644 src/views/profile/BatchFirmwareUpgrade/src/ESelect.vue create mode 100644 src/views/profile/BatchFirmwareUpgrade/src/firmwareItem.js create mode 100644 src/views/profile/BatchFirmwareUpgrade/src/index.css diff --git a/.env.development b/.env.development index 69eb1809..5abec8a2 100644 --- a/.env.development +++ b/.env.development @@ -19,6 +19,6 @@ port= 9988 // target = http://192.168.18.136:8899 // 测试端 - target = http://192.168.10.241:32024 +// target = http://192.168.10.241:32024 // 开发端 -// target = http://192.168.10.241:30646 + target = http://192.168.10.241:30646 diff --git a/src/api/iot/deviceOta.js b/src/api/iot/deviceOta.js index 8e193a38..50bc1e76 100644 --- a/src/api/iot/deviceOta.js +++ b/src/api/iot/deviceOta.js @@ -60,3 +60,14 @@ export function upgradeOta(data) { data: data }) } + + +// 新增固件版本 +export function upgradeBatch(data) { + return request({ + url: '/iot/ota/upgradeBatch', + method: 'post', + data: data + }) + } + \ No newline at end of file diff --git a/src/api/iot/model.js b/src/api/iot/model.js index 0eb63872..67eaaabc 100644 --- a/src/api/iot/model.js +++ b/src/api/iot/model.js @@ -68,3 +68,20 @@ export function listModelType() { method: "get" }); } + +// 根据网关设备id 查询 子设备模型列表 +export function getModelListByGatewayDevId(deviceId) { + return request({ + url: "/iot/device/modelList/" + deviceId, + method: "get" + }); +} + +// 根据 型号 产品key 查询固件 +export function getAtoListByModelProdKey(query) { + return request({ + url: "/iot/ota/list", + method: "get", + params: query + }); +} \ No newline at end of file diff --git a/src/api/iot/modelSeries.js b/src/api/iot/modelSeries.js new file mode 100644 index 00000000..35cb1a49 --- /dev/null +++ b/src/api/iot/modelSeries.js @@ -0,0 +1,53 @@ +import request from '@/utils/request' + +// 查询型号系列列表 +export function listModelSeries(query) { + return request({ + url: '/iot/modelSeries/list', + method: 'get', + params: query + }) +} + +// 查询型号系列详细 +export function getModelSeries(seriesId) { + return request({ + url: '/iot/modelSeries/' + seriesId, + method: 'get' + }) +} + +// 新增型号系列 +export function addModelSeries(data) { + return request({ + url: '/iot/modelSeries', + method: 'post', + data: data + }) +} + +// 修改型号系列 +export function updateModelSeries(data) { + return request({ + url: '/iot/modelSeries', + method: 'put', + data: data + }) +} + +// 删除型号系列 +export function delModelSeries(seriesId) { + return request({ + url: '/iot/modelSeries/' + seriesId, + method: 'delete' + }) +} + +// 导出型号系列 +export function exportModelSeries(query) { + return request({ + url: '/iot/modelSeries/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/src/store/modules/attribute.js b/src/store/modules/attribute.js index 04c19fab..20f6371e 100644 --- a/src/store/modules/attribute.js +++ b/src/store/modules/attribute.js @@ -9,6 +9,7 @@ const attribute = { mutations: { SET_ATTRIBUTE_LIST: (state, list) => { + debugger state.attributeList = list }, SET_GROUP_LIST: (state, list) => { @@ -37,15 +38,32 @@ const attribute = { }, GET_GROUP_ITEM: (state, idx) => { return state.groupList[idx] - } + }, + GET_ATTRIBUTE_LIST: (state) => { + return state.attributeList + }, + GET_GROUP_LIST: (state) => { + return state.groupList + }, }, actions: { + GetAttributeList({state}) { + debugger + return new Promise((resolve, reject) => { + resolve(state.attributeList) + }) + }, + GetGroupList({state}) { + return new Promise((resolve, reject) => { + resolve(state.groupList) + }) + }, // 初始化 属性和分组数据 InitAttributeAndGroup({ commit, state }, data) { commit('SET_ATTRIBUTE_LIST', data.attrList) commit('SET_GROUP_LIST', data.groupList) - console.log('res:', state) + console.log('res:', state, data) }, // 新增 属性 AddAttribute({ commit, state }, attr) { diff --git a/src/utils/hciot.js b/src/utils/hciot.js index b05a4fdb..38664cf7 100644 --- a/src/utils/hciot.js +++ b/src/utils/hciot.js @@ -1,3 +1,4 @@ + /** * 通用js方法封装处理 * Copyright (c) 2019 hciot diff --git a/src/views/iot/model/index.vue b/src/views/iot/model/index.vue index a35f5e13..f68d7c0a 100644 --- a/src/views/iot/model/index.vue +++ b/src/views/iot/model/index.vue @@ -248,6 +248,18 @@ + + + 选择型号系列 + + { + this.tableSelectOption.tableList = response.rows; + this.tableSelectOption.queryOpt.page.total = Number(response.total); + } + ); + }, // 点击或者双击数据回调 returnEvent(data) { this.selectResult = {}; if (data.type === "dblclick") { - if (data.otherOption.tableType === "vendor") { - this.form.vendorId = data.value.vendorId; - this.form.vendorName = data.value.vendorName; - } else if (data.otherOption.tableType === "product") { - this.form.prodKey = data.value.prodId; - this.form.prodSecret = data.value.prodSecret; + switch(data.otherOption.tableType) { + case 'vendor': + this.form.vendorId = data.value.vendorId; + this.form.vendorName = data.value.vendorName; + break; + + case 'product': + this.form.prodKey = data.value.prodId; + this.form.prodSecret = data.value.prodSecret; + break; + + case 'scries': + this.form.prodJson = data.value.prodJson; + this.form.remark = data.value.remark; + this.form.deviceType = data.value.deviceType; + try { + this.form.paramList = JSON.parse(data.value.paramJson); + } catch (error) { + this.form.paramList = []; + } + let _this = this; + setTimeout(() => { + _this.$refs.paramWrap.setList(_this.form.paramList || []); + _this.$refs.attributeref.handleInitData(); + _this.$refs.attributeref.forceUpdateList('groupForm'); + _this.$refs.attributeref.forceUpdateList('attributeForm'); + + }, 100); + + break; } this.selectTableShow = false; } else if (data.type === "click") { - if (data.otherOption.tableType === "vendor") { - this.selectResult.vendorId = data.value.vendorId; - this.selectResult.vendorName = data.value.vendorName; - } else if (data.otherOption.tableType === "product") { - this.selectResult.prodKey = data.value.prodId; - this.selectResult.prodSecret = data.value.prodSecret; + + switch(data.otherOption.tableType) { + case 'vendor': + this.selectResult.vendorId = data.value.vendorId; + this.selectResult.vendorName = data.value.vendorName; + break; + + case 'product': + this.selectResult.prodKey = data.value.prodId; + this.selectResult.prodSecret = data.value.prodSecret; + break; + + case 'scries': + this.selectResult.prodJson = data.value.prodJson; + this.selectResult.remark = data.value.remark; + this.selectResult.deviceType = data.value.deviceType; + try { + this.selectResult.paramList = JSON.parse(data.value.paramJson); + } catch (error) { + this.selectResult.paramList = []; + } + console.log('row:', data.value) + break; } + this.selectResult.tableType = data.otherOption.tableType; } }, // 点击确定按钮 resuleClick() { - if (this.selectResult.tableType === "vendor") { - this.form.vendorId = this.selectResult.vendorId; - this.form.vendorName = this.selectResult.vendorName; - } else if (this.selectResult.tableType === "product") { - this.form.prodKey = this.selectResult.prodKey; - this.form.prodSecret = this.selectResult.prodSecret; + switch(this.selectResult.tableType) { + case 'vendor': + this.form.vendorId = this.selectResult.vendorId; + this.form.vendorName = this.selectResult.vendorName; + break; + + case 'product': + this.form.prodKey = this.selectResult.prodKey; + this.form.prodSecret = this.selectResult.prodSecret; + break; + + case 'scries': + this.form.prodJson = this.selectResult.prodJson; + this.form.remark = this.selectResult.remark; + this.form.deviceType = this.selectResult.deviceType; + this.form.paramList = this.selectResult.paramList + let _this = this; + setTimeout(() => { + _this.$refs.paramWrap.setList(_this.form.paramList || []); + _this.$refs.attributeref.handleInitData(); + _this.$refs.attributeref.forceUpdateList('groupForm'); + _this.$refs.attributeref.forceUpdateList('attributeForm'); + }, 100); + + break; } this.selectTableShow = false; }, @@ -854,7 +1031,7 @@ export default { } this.form.paramList = this.$refs.paramWrap.getResult(); - if (this.form.modelId != null) { + if (this.form.seriesId != null) { updateModel(this.form).then((response) => { this.msgSuccess("修改成功"); this.open = false; diff --git a/src/views/iot/modelScries/index.vue b/src/views/iot/modelScries/index.vue new file mode 100644 index 00000000..9aa5c515 --- /dev/null +++ b/src/views/iot/modelScries/index.vue @@ -0,0 +1,637 @@ + + + + + + + + + + + + + 搜索 + 重置 + + + + + + 新增 + + + 修改 + + + 删除 + + + 导出 + + + + + + + + + + + + + + + + + + + 启用 + 禁用 + + + + + + + + 修改 + 删除 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + *注意:锁定即参数不可修改;未锁则可以修改。 + + + + + + + + + + + + + + + { + AttributeViewShow = false; + } + " + :visible="AttributeViewShow" + width="750px" + > + + + + 确 定 + { + AttributeViewShow = false; + } + " + >取 消 + + + + + + + + diff --git a/src/views/iot/project/profileV2/ESceneManage/ESceneAction/src/executeAction.js b/src/views/iot/project/profileV2/ESceneManage/ESceneAction/src/executeAction.js index ea2140c2..e4969653 100644 --- a/src/views/iot/project/profileV2/ESceneManage/ESceneAction/src/executeAction.js +++ b/src/views/iot/project/profileV2/ESceneManage/ESceneAction/src/executeAction.js @@ -5,6 +5,7 @@ import ESelect from './ESelect' import EDeviceParam from './EDeviceParam' + export default { name: 'EExecuteAction', props: { diff --git a/src/views/profile/BatchFirmwareUpgrade/example.vue b/src/views/profile/BatchFirmwareUpgrade/example.vue new file mode 100644 index 00000000..cca18026 --- /dev/null +++ b/src/views/profile/BatchFirmwareUpgrade/example.vue @@ -0,0 +1,111 @@ + + + 新增 + + + + + + + + + \ No newline at end of file diff --git a/src/views/profile/BatchFirmwareUpgrade/index.js b/src/views/profile/BatchFirmwareUpgrade/index.js new file mode 100644 index 00000000..96fd26df --- /dev/null +++ b/src/views/profile/BatchFirmwareUpgrade/index.js @@ -0,0 +1,7 @@ +import FirmwareItem from "./src/firmwareItem" + +FirmwareItem.install = function install(Vue) { + Vue.component(FirmwareItem.name, FirmwareItem); +}; + +export default FirmwareItem diff --git a/src/views/profile/BatchFirmwareUpgrade/src/ESelect.vue b/src/views/profile/BatchFirmwareUpgrade/src/ESelect.vue new file mode 100644 index 00000000..da097ead --- /dev/null +++ b/src/views/profile/BatchFirmwareUpgrade/src/ESelect.vue @@ -0,0 +1,44 @@ + + + + + + + + diff --git a/src/views/profile/BatchFirmwareUpgrade/src/firmwareItem.js b/src/views/profile/BatchFirmwareUpgrade/src/firmwareItem.js new file mode 100644 index 00000000..4a0bf0d8 --- /dev/null +++ b/src/views/profile/BatchFirmwareUpgrade/src/firmwareItem.js @@ -0,0 +1,134 @@ + +import ESelect from './ESelect' +import "./index.css" + +import { getAtoListByModelProdKey } from "@/api/iot/model" + +export default { + name: 'FirmwareItem', + props: { + addDisabled: { + type: Boolean, + default: false + }, + dataItem: { + type: Object + }, + inputWidth: { + type: String, + default: '200' + }, + modelList: { + type: Array, + default: () => { + return [] + } + }, + options:{ + type: Object, + default: () => { + return { + model_pk: 'prodKey', + ota_pk: 'otaId', + model_label: 'modelName', + ota_label: 'otaVersion', + } + } + } + }, + + data() { + return { + firmwareList: [] + } + }, + + components: { + ESelect + }, + + methods: { + methodChange(val) { + this.dataItem[this.options.model_pk] = val; + this.dataItem[this.options.ota_pk] = ''; + this.getFirmwareListFn(); + this.handlePinChange() + }, + getFirmwareListFn() { + getAtoListByModelProdKey({prodKey: this.dataItem[this.options.model_pk]}).then(res => { + this.firmwareList = res.rows; + if (this.firmwareList && this.firmwareList.length > 0) { + this.dataItem[this.options.ota_pk] = this.firmwareList[0][this.options.ota_pk]; + } + }); + }, + + firmwareChange(value) { + this.dataItem[this.options.ota_pk] = value; + this.handlePinChange() + }, + handlePinChange() { + this.$forceUpdate(); + this.$emit('change', this.dataItem); + }, + handleDelTrigger() { + this.$emit('delete', this.dataItem) + }, + handleAddItme() { + this.$emit('add') + }, + }, + + render() { + const { dataItem, inputWidth, modelList, firmwareList, options, addDisabled } = this; + + return ( + + + { dataItem && + 选择模型: + + + + 选择固件: + + + + + + { + !dataItem[options.ota_pk] && + * 未选择固件版本... + } + + + 刪除 + + { !addDisabled && 新增 } + + + } + + ) + } +} \ No newline at end of file diff --git a/src/views/profile/BatchFirmwareUpgrade/src/index.css b/src/views/profile/BatchFirmwareUpgrade/src/index.css new file mode 100644 index 00000000..bf15173a --- /dev/null +++ b/src/views/profile/BatchFirmwareUpgrade/src/index.css @@ -0,0 +1,47 @@ + +.e-batch-firmware-upgrade .e-trigger-block { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + flex-wrap: nowrap; + & > span { + margin-right: 10px; + } +} + +.ato-div { + display: flex; + flex-direction: column; +} +.ato-div-error { + margin-top: 18px; +} + +.e-form-item__error { + color: #ff4949; + font-size: 12px; +} +.e-button-del { + color: #ff4949; + font-size: 12px; + margin-left: 20px; + padding: 5px; +} +.e-button-del:hover { + background: #ff4949; + padding: 5px; + color: #fff; +} +.e-button-pro { + color: #46a6ff; + font-size: 12px; + margin-left: 20px; + padding: 5px; +} +.e-button-pro:hover { + background: #2196F3; + padding: 5px; + color: #fff; + +} diff --git a/src/views/profile/DeviceDetailsView/index.vue b/src/views/profile/DeviceDetailsView/index.vue index cb8e832f..ca063ddb 100644 --- a/src/views/profile/DeviceDetailsView/index.vue +++ b/src/views/profile/DeviceDetailsView/index.vue @@ -8,10 +8,11 @@ :wsDeviceInfo="infoData" @changeEvent="viewDeviceChange($event)" > - - + 返回列表 + 批量升级 @@ -107,6 +108,31 @@ + + + + + + + + + + @@ -340,6 +408,7 @@ export default { } } } + .link-to-list { display: flex; color: #656363; @@ -349,10 +418,13 @@ export default { display: flex; position: relative; top: 10px; - width: 100px; z-index: 100; - left: calc(100% - 110px); + width: 120px; + left: calc(100% - 120px); cursor: default; + justify-content: flex-start; + flex-wrap: nowrap; + flex-direction: row-reverse; .el-button--medium.is-circle { width: 25px; height: 20px; @@ -371,6 +443,11 @@ export default { font-size: 30px; } + .is-widening { + width: 220px; + left: calc(100% - 220px); + } + .info-tabs-circuit { position: relative; box-sizing: border-box; diff --git a/src/views/profile/attribute/attributeView.vue b/src/views/profile/attribute/attributeView.vue index 0afb9223..9ce5d50a 100644 --- a/src/views/profile/attribute/attributeView.vue +++ b/src/views/profile/attribute/attributeView.vue @@ -342,7 +342,19 @@ export default { this.loading = true this.functionList = [] setTimeout(() => { - this.functionList = this.$store.getters.attributeList + this.$store.dispatch("GetAttributeList").then((res) => { + console.log('666', res) + this.functionList = res + this.$forceUpdate() + this.loading = false + }); + }, 50) + }, + setList(list) { + this.loading = true + this.functionList = [] + setTimeout(() => { + this.functionList = list this.$forceUpdate() this.loading = false }, 50) diff --git a/src/views/profile/attribute/groupView.vue b/src/views/profile/attribute/groupView.vue index 737f634b..93ef7bc3 100644 --- a/src/views/profile/attribute/groupView.vue +++ b/src/views/profile/attribute/groupView.vue @@ -210,7 +210,20 @@ export default { this.loading = true this.cmdList = [] setTimeout(() => { - this.cmdList = this.$store.getters.groupList + this.$store.dispatch("GetGroupList").then((res) => { + this.cmdList = res + this.$forceUpdate() + this.loading = false + }); + }, 50) + + }, + /** 查询分组集列表 */ + setList(list) { + this.loading = true + this.cmdList = [] + setTimeout(() => { + this.cmdList = list this.$forceUpdate() this.loading = false }, 50) diff --git a/src/views/profile/attribute/index.vue b/src/views/profile/attribute/index.vue index b2283596..eea657c0 100644 --- a/src/views/profile/attribute/index.vue +++ b/src/views/profile/attribute/index.vue @@ -119,20 +119,49 @@ export default { }, forceUpdate(component) { if (component === "groupForm") { - this.$refs.groupref.getList(); + this.$refs.groupref && this.$refs.groupref.getList(); } else if (component === "attributeForm") { - this.$refs.attributeref.getList(); + this.$refs.attributeref && this.$refs.attributeref.getList(); + } + }, + forceUpdateList(component) { + let arttributeList = [], + groupList = []; + + try { + arttributeList = JSON.parse(this.arttributeList); + groupList = JSON.parse(this.groupList); + } catch (error) { + arttributeList = [], + groupList = []; + console.log(error); + } + + if (component === "groupForm") { + this.$refs.groupref && this.$refs.groupref.setList(groupList); + } else if (component === "attributeForm") { + this.$refs.attributeref && this.$refs.attributeref.setList(arttributeList); } }, handleInitData() { + let arttributeList = [], + groupList = []; + try { - this.$store.dispatch("InitAttributeAndGroup", { - attrList: JSON.parse(this.arttributeList), - groupList: JSON.parse(this.groupList), - }); + arttributeList = JSON.parse(this.arttributeList); + groupList = JSON.parse(this.groupList); } catch (error) { + arttributeList = [], + groupList = []; console.log(error); } + + console.log(arttributeList, groupList) + + this.$store.dispatch("InitAttributeAndGroup", { + attrList: arttributeList, + groupList: groupList, + }); }, }, };