dedsudiyu преди 4 месеца
родител
ревизия
ba1f07e4e1

+ 144 - 0
package-lock.json

@@ -2540,6 +2540,11 @@
         "@xtuc/long": "4.2.2"
       }
     },
+    "@xmldom/xmldom": {
+      "version": "0.8.10",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+      "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="
+    },
     "@xtuc/ieee754": {
       "version": "1.2.0",
       "resolved": "https://registry.nlark.com/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz",
@@ -2723,6 +2728,26 @@
         "picomatch": "^2.0.4"
       }
     },
+    "app-info-parser": {
+      "version": "1.1.6",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/app-info-parser/-/app-info-parser-1.1.6.tgz",
+      "integrity": "sha512-ZAFCM0bN88cbpsMoRhL/JfdX3b+nb5iBEXcu30xABvbaqtw6tXfHujDnuKSpNmA3P0uwpkIxTV/Wun5HfEch8A==",
+      "requires": {
+        "bplist-parser": "^0.2.0",
+        "bytebuffer": "^5.0.1",
+        "cgbi-to-png": "^1.0.7",
+        "commander": "^7.2.0",
+        "isomorphic-unzip": "^1.1.5",
+        "plist": "^3.0.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "7.2.0",
+          "resolved": "https://mirrors.huaweicloud.com/repository/npm/commander/-/commander-7.2.0.tgz",
+          "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
+        }
+      }
+    },
     "aproba": {
       "version": "2.0.0",
       "resolved": "https://registry.nlark.com/aproba/download/aproba-2.0.0.tgz",
@@ -3173,6 +3198,11 @@
         "tryer": "^1.0.1"
       }
     },
+    "big-integer": {
+      "version": "1.6.52",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/big-integer/-/big-integer-1.6.52.tgz",
+      "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="
+    },
     "big.js": {
       "version": "5.2.2",
       "resolved": "https://registry.npmmirror.com/big.js/download/big.js-5.2.2.tgz",
@@ -3287,6 +3317,14 @@
       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
       "dev": true
     },
+    "bplist-parser": {
+      "version": "0.2.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/bplist-parser/-/bplist-parser-0.2.0.tgz",
+      "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==",
+      "requires": {
+        "big-integer": "^1.6.44"
+      }
+    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.nlark.com/brace-expansion/download/brace-expansion-1.1.11.tgz",
@@ -3426,6 +3464,11 @@
         "ieee754": "^1.1.13"
       }
     },
+    "buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="
+    },
     "buffer-from": {
       "version": "1.1.2",
       "resolved": "https://registry.nlark.com/buffer-from/download/buffer-from-1.1.2.tgz?cache=0&sync_timestamp=1627578361955&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbuffer-from%2Fdownload%2Fbuffer-from-1.1.2.tgz",
@@ -3449,6 +3492,11 @@
       "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
       "dev": true
     },
+    "bufferpack": {
+      "version": "0.0.6",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/bufferpack/-/bufferpack-0.0.6.tgz",
+      "integrity": "sha512-MTWvLHElqczrIVhge9qHtqgNigJFyh0+tCDId5yCbFAfuekHWIG+uAgvoHVflwrDPuY/e47JE1ki5qcM7w4uLg=="
+    },
     "builtin-status-codes": {
       "version": "3.0.0",
       "resolved": "https://registry.nlark.com/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz",
@@ -3460,6 +3508,14 @@
       "resolved": "https://registry.nlark.com/builtins/download/builtins-1.0.3.tgz",
       "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og="
     },
+    "bytebuffer": {
+      "version": "5.0.1",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/bytebuffer/-/bytebuffer-5.0.1.tgz",
+      "integrity": "sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ==",
+      "requires": {
+        "long": "~3"
+      }
+    },
     "bytes": {
       "version": "3.1.0",
       "resolved": "https://registry.npmmirror.com/bytes/download/bytes-3.1.0.tgz?cache=0&sync_timestamp=1637015083874&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fbytes%2Fdownload%2Fbytes-3.1.0.tgz",
@@ -3677,6 +3733,17 @@
       "resolved": "https://registry.nlark.com/caseless/download/caseless-0.12.0.tgz",
       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
     },
+    "cgbi-to-png": {
+      "version": "1.0.7",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/cgbi-to-png/-/cgbi-to-png-1.0.7.tgz",
+      "integrity": "sha512-YR80kxTPuq9oRpZUdQmNEQWrmTKLINk1cfLVfyrV7Rfr9KLtLJdcockPKbreIr4JYAq+DhHBR7w+WA/tF5VDaQ==",
+      "requires": {
+        "bufferpack": "0.0.6",
+        "crc": "^3.3.0",
+        "stream-to-buffer": "^0.1.0",
+        "streamifier": "^0.1.1"
+      }
+    },
     "chalk": {
       "version": "4.1.0",
       "resolved": "https://registry.npmmirror.com/chalk/download/chalk-4.1.0.tgz",
@@ -4708,6 +4775,14 @@
         }
       }
     },
+    "crc": {
+      "version": "3.8.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/crc/-/crc-3.8.0.tgz",
+      "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
+      "requires": {
+        "buffer": "^5.1.0"
+      }
+    },
     "create-ecdh": {
       "version": "4.0.4",
       "resolved": "https://registry.nlark.com/create-ecdh/download/create-ecdh-4.0.4.tgz",
@@ -6548,6 +6623,14 @@
         "websocket-driver": ">=0.5.1"
       }
     },
+    "fd-slicer": {
+      "version": "1.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/fd-slicer/-/fd-slicer-1.1.0.tgz",
+      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+      "requires": {
+        "pend": "~1.2.0"
+      }
+    },
     "figgy-pudding": {
       "version": "3.5.2",
       "resolved": "https://registry.nlark.com/figgy-pudding/download/figgy-pudding-3.5.2.tgz",
@@ -8300,6 +8383,15 @@
       "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
       "dev": true
     },
+    "isomorphic-unzip": {
+      "version": "1.1.5",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/isomorphic-unzip/-/isomorphic-unzip-1.1.5.tgz",
+      "integrity": "sha512-2McA51lWhmO3Kk438jxVcYeh6L+AOqVnl9XdX1yI7GlLA9RwEyTBgGem1rNuRIU2abAmOiv+IagThdUxASY4IA==",
+      "requires": {
+        "buffer": "^5.0.7",
+        "yauzl": "^2.8.0"
+      }
+    },
     "isstream": {
       "version": "0.1.2",
       "resolved": "https://registry.nlark.com/isstream/download/isstream-0.1.2.tgz",
@@ -9555,6 +9647,11 @@
       "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==",
       "dev": true
     },
+    "long": {
+      "version": "3.2.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/long/-/long-3.2.0.tgz",
+      "integrity": "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="
+    },
     "lower-case": {
       "version": "1.1.4",
       "resolved": "https://registry.nlark.com/lower-case/download/lower-case-1.1.4.tgz?cache=0&sync_timestamp=1624607698082&other_urls=https%3A%2F%2Fregistry.nlark.com%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz",
@@ -11579,6 +11676,11 @@
       "resolved": "https://registry.npmmirror.com/pdfjs-dist/download/pdfjs-dist-2.6.347.tgz",
       "integrity": "sha1-8lftZug76QDND9KFJKIYf7niXNU="
     },
+    "pend": {
+      "version": "1.2.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
+    },
     "performance-now": {
       "version": "2.1.0",
       "resolved": "https://registry.nlark.com/performance-now/download/performance-now-2.1.0.tgz",
@@ -11640,6 +11742,16 @@
         "semver-compare": "^1.0.0"
       }
     },
+    "plist": {
+      "version": "3.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/plist/-/plist-3.1.0.tgz",
+      "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
+      "requires": {
+        "@xmldom/xmldom": "^0.8.8",
+        "base64-js": "^1.5.1",
+        "xmlbuilder": "^15.1.1"
+      }
+    },
     "pnp-webpack-plugin": {
       "version": "1.7.0",
       "resolved": "https://registry.nlark.com/pnp-webpack-plugin/download/pnp-webpack-plugin-1.7.0.tgz",
@@ -14147,6 +14259,24 @@
       "resolved": "https://registry.nlark.com/stream-shift/download/stream-shift-1.0.1.tgz",
       "integrity": "sha1-1wiCgVWasneEJCebCHfaPDktWj0="
     },
+    "stream-to": {
+      "version": "0.2.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/stream-to/-/stream-to-0.2.2.tgz",
+      "integrity": "sha512-Kg1BSDTwgGiVMtTCJNlo7kk/xzL33ZuZveEBRt6rXw+f1WLK/8kmz2NVCT/Qnv0JkV85JOHcLhD82mnXsR3kPw=="
+    },
+    "stream-to-buffer": {
+      "version": "0.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz",
+      "integrity": "sha512-Da4WoKaZyu3nf+bIdIifh7IPkFjARBnBK+pYqn0EUJqksjV9afojjaCCHUemH30Jmu7T2qcKvlZm2ykN38uzaw==",
+      "requires": {
+        "stream-to": "~0.2.0"
+      }
+    },
+    "streamifier": {
+      "version": "0.1.1",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/streamifier/-/streamifier-0.1.1.tgz",
+      "integrity": "sha512-zDgl+muIlWzXNsXeyUfOk9dChMjlpkq0DRsxujtYPgyJ676yQ8jEm6zzaaWHFDg5BNcLuif0eD2MTyJdZqXpdg=="
+    },
     "strict-uri-encode": {
       "version": "1.1.0",
       "resolved": "https://registry.nlark.com/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz",
@@ -16728,6 +16858,11 @@
         "xtend": "^4.0.0"
       }
     },
+    "xmlbuilder": {
+      "version": "15.1.1",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
+      "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="
+    },
     "xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.nlark.com/xtend/download/xtend-4.0.2.tgz",
@@ -16790,6 +16925,15 @@
       "integrity": "sha1-LrfcOwKJcY/ClfNidThFxBoMlO4=",
       "dev": true
     },
+    "yauzl": {
+      "version": "2.10.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+      "requires": {
+        "buffer-crc32": "~0.2.3",
+        "fd-slicer": "~1.1.0"
+      }
+    },
     "yorkie": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/yorkie/download/yorkie-2.0.0.tgz",

+ 1 - 0
package.json

@@ -42,6 +42,7 @@
     "@vue-office/excel": "^1.7.6",
     "@vue-office/pdf": "^1.6.5",
     "@vue/composition-api": "^1.7.2",
+    "app-info-parser": "^1.1.6",
     "axios": "0.21.0",
     "canvas": "^2.8.0",
     "clipboard": "2.0.6",

+ 82 - 35
src/api/iotDevice/index.js

@@ -887,87 +887,134 @@ export function iotMonitorLogList(data) {
   })
 }
 /******************** 应用管理 ********************/
-//应用列表-列表
-export function iotAppInfoList(data) {
+//APP-列表
+export function terminalAppList(data) {
   return request({
-    url: '/iot/app/info/list',
+    url: '/terminal/app/list',
     method: 'post',
     data: data
   })
 }
-//应用列表-新增
-export function iotAppInfoAdd(data) {
+//APP-新增
+export function terminalAppAdd(data) {
   return request({
-    url: '/iot/app/info/add',
+    url: '/terminal/app/add',
     method: 'post',
     data: data
   })
 }
-//应用列表-编辑
-export function iotAppInfoUpdate(data) {
+//APP-新增
+export function terminalAppUpdate(data) {
   return request({
-    url: '/iot/app/info/update',
+    url: '/terminal/app/update',
     method: 'post',
     data: data
   })
 }
-//应用列表-删除
-export function iotAppInfoDelete(data) {
+//APP-删除
+export function terminalAppDelete(query) {
   return request({
-    url: '/iot/app/info/delete',
+    url: '/terminal/app/delete',
+    method: 'get',
+    params: query
+  })
+}
+//APP-版本-列表
+export function terminalVersionList(data) {
+  return request({
+    url: '/terminal/version/list',
     method: 'post',
     data: data
   })
 }
-//应用列表-获取应用版本号
-export function iotAppInfoGetLastVersion(query) {
+//APP-版本-新增
+export function terminalVersionAdd(data) {
   return request({
-    url: '/iot/app/info/getLastVersion',
-    method: 'get',
-    params: query
+    url: '/terminal/version/add',
+    method: 'post',
+    data: data
+  })
+}
+//APP-版本-编辑
+export function terminalVersionUpdate(data) {
+  return request({
+    url: '/terminal/version/update',
+    method: 'post',
+    data: data
   })
 }
-//应用列表-code列表
-export function iotAppInfoGetCodeList(query) {
+//APP-版本-删除
+export function terminalVersionDelete(query) {
   return request({
-    url: '/iot/app/info/getCodeList',
+    url: '/terminal/version/delete',
     method: 'get',
     params: query
   })
 }
-//应用列表-获取可升级设备列表
-export function iotAppInfoUpgradeDevices(data) {
+//APP-升级计划列表
+export function terminalUpgradeWebPlanList(data) {
   return request({
-    url: '/iot/app/info/upgradeDevices',
+    url: '/terminal/upgrade/web/plan/list',
     method: 'post',
     data: data
   })
 }
-//应用列表-批量升级
-export function iotAppInfoBatchUpgrade(data) {
+//APP-创建升级计划
+export function terminalUpgradeWebPlanCreate(data) {
   return request({
-    url: '/iot/app/info/batchUpgrade',
+    url: '/terminal/upgrade/web/plan/create',
     method: 'post',
     data: data
   })
 }
-//应用升级-列表
-export function iotAppUpgradeList(data) {
+//APP-升级-任务列表
+export function terminalUpgradeWebTaskList(data) {
   return request({
-    url: '/iot/app/upgrade/list',
+    url: '/terminal/upgrade/web/task/list',
     method: 'post',
     data: data
   })
 }
-//应用升级-撤销升级
-export function iotAppUpgradeDelete(data) {
+//APP-升级-计划状态列表
+export function terminalUpgradeWebPlanStatus(query) {
   return request({
-    url: '/iot/app/upgrade/delete',
-    method: 'post',
-    data: data
+    url: '/terminal/upgrade/web/plan/status',
+    method: 'get',
+    params: query
+  })
+}
+//APP-升级-任务状态列表
+export function terminalUpgradeWebTaskStatus(query) {
+  return request({
+    url: '/terminal/upgrade/web/task/status',
+    method: 'get',
+    params: query
+  })
+}
+//APP-计划终止接口
+export function terminalUpgradeWebPlanTermination(query) {
+  return request({
+    url: '/terminal/upgrade/web/plan/termination',
+    method: 'get',
+    params: query
+  })
+}
+//APP-APP选择器
+export function terminalAppSelect(query) {
+  return request({
+    url: '/terminal/app/select',
+    method: 'get',
+    params: query
+  })
+}
+//APP-版本选择器
+export function terminalVersionSelect(query) {
+  return request({
+    url: '/terminal/version/select',
+    method: 'get',
+    params: query
   })
 }
-
 /********************* 物联管理首页 *********************/
 //统计-设备在线离线
 export function iotStatisticsDeviceOnline(query) {

+ 0 - 247
src/views/iotDevice/appManage/applyList/batchUpDialog.vue

@@ -1,247 +0,0 @@
-<template>
-  <div class="applyList-batchUpDialog">
-    <el-dialog class="batchUpDialog" :title="batchUpDialogTitle"
-               :visible.sync="batchUpDialogType" v-if="batchUpDialogType" width="1240px" height="700"
-               append-to-body :close-on-click-modal="false" @close="dialogOff()">
-      <div class="page-form-title-box" style="border:none;padding:0;height:60px;">
-        <el-form :model="queryParams" class="form-box" ref="queryForm"
-                 :inline="true" style="width:100%;">
-          <el-form-item label="" prop="schoolId">
-            <el-select v-model="queryParams.schoolId" @change="changeSchool"
-                       placeholder="请选择校区" style="width: 150px">
-              <el-option v-for="(item,index) in schoolOption"
-                         :key="item.id"
-                         :label="item.name"
-                         :value="item.id"/>
-            </el-select>
-          </el-form-item>
-          <el-form-item label="" prop="buildId">
-            <el-select v-model="queryParams.buildId" @change="buildSchool"
-                       placeholder="请选择楼栋" style="width: 150px">
-              <el-option v-for="(item,index) in buildOption"
-                         :key="item.id"
-                         :label="item.name"
-                         :value="item.id"/>
-            </el-select>
-          </el-form-item>
-          <el-form-item label="" prop="subjectId">
-            <el-select v-model="queryParams.subjectId"
-                       placeholder="请选择实验室" style="width: 150px">
-              <el-option v-for="(item,index) in subjectOption"
-                         :key="item.subId"
-                         :label="item.subName"
-                         :value="item.subId"/>
-            </el-select>
-          </el-form-item>
-          <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
-          <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
-        </el-form>
-      </div>
-      <div class="page-content-box" style="padding:0;height:500px;">
-        <el-table class="table-box" border :data="tableList" ref="multipleTable" :row-key="getRowKeys"
-                  tooltip-effect="dark" @selection-change="handleSelectionChange">
-          <el-table-column type="selection" width="50" align="center" :reserve-selection="true"/>
-          <el-table-column label="名称" align="center" prop="deviceName" show-overflow-tooltip/>
-          <el-table-column label="编号" align="center" prop="deviceNo" show-overflow-tooltip width="300"/>
-          <el-table-column label="类型" align="center" prop="name" show-overflow-tooltip width="200"/>
-          <el-table-column label="位置" align="center" prop="subjectName" show-overflow-tooltip width="200">
-            <template slot-scope="scope">
-              <span>{{scope.row.subjectName?scope.row.subjectName:'--'}}</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="当前版本" align="center" prop="appName" show-overflow-tooltip width="200">
-            <template slot-scope="scope">
-              <span>{{scope.row.appName}} {{scope.row.version?' ('+scope.row.version+')':''}}</span>
-            </template>
-          </el-table-column>
-        </el-table>
-        <div class="selected-num-box" v-show="total>0">
-          <p class="selected-num-p">
-            <i class="el-icon-warning"></i>
-            已选择 {{selectedNum}} 项
-          </p>
-          <pagination :page-sizes="[20, 30, 40, 50]"
-                      :total="total"
-                      :page.sync="queryParams.page"
-                      :limit.sync="queryParams.pageSize"
-                      @pagination="getList"
-          />
-        </div>
-      </div>
-      <div slot="footer" class="dialog-footer dialog-footer-box">
-        <p class="dialog-footer-button-null"></p>
-        <p class="dialog-footer-button-info" @click="dialogOff">取消</p>
-        <p class="dialog-footer-button-primary" @click="dialogSubmit">提交</p>
-        <p class="dialog-footer-button-null"></p>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-  import { iotAppInfoUpgradeDevices,iotAppInfoBatchUpgrade, } from "@/api/iotDevice/index";
-  import { systemBuildingGetTreeList,laboratorySubRelInfoGetListByFloor } from "@/api/commonality/permission";
-  export default {
-    name: 'batchUpDialog',
-    data(){
-      return{
-        typeId:null,
-        batchUpDialogTitle:'',
-        batchUpDialogType:false,
-        //校区楼栋原始数据
-        addressList:[],
-        //校区下拉列表
-        schoolOption:[],
-        //楼栋下拉列表
-        buildOption:[],
-        //实验室下拉列表
-        subjectOption:[],
-        //列表相关
-        optionList:[],
-        queryParams:{
-          page:1,
-          pageSize:20,
-          schoolId:null,
-          buildId:null,
-          subjectId :null,
-        },
-        tableList:[],
-        total:0,
-        //勾选相关
-        selectedNum:0,
-        ids:[],
-      }
-    },
-    created(){
-
-    },
-    mounted(){
-      this.systemBuildingGetTreeList();
-    },
-    methods:{
-      //提交
-      dialogSubmit(){
-        if(!this.ids[0]){
-          this.msgError('请勾选设备')
-        }else{
-          let obj = {
-            id:this.typeId,
-            isAll:false, // true.全部升级 false.勾选升级
-            ids:this.ids
-          }
-          iotAppInfoBatchUpgrade(obj).then(response => {
-            this.msgSuccess(response.message)
-            this.dialogOff();
-          });
-        }
-      },
-      //开启
-      dialogOpen(row){
-        this.$set(this,'batchUpDialogTitle',row.name+' ('+row.info+') '+'- 批量升级');
-        this.$set(this,'typeId',row.id);
-        this.$set(this,'batchUpDialogType',true);
-        this.$nextTick(()=>{
-          this.resetQuery();
-        })
-      },
-      //关闭
-      dialogOff(){
-        this.$set(this,'batchUpDialogType',false);
-        this.$set(this,'batchUpDialogTitle','');
-      },
-      //查询
-      handleQuery(){
-        this.$refs.multipleTable.clearSelection();
-        this.$set(this.queryParams,'page',1);
-        this.$set(this,'selectedNum',0);
-        this.$set(this,'ids',[]);
-        this.getList();
-      },
-      //重置
-      resetQuery(){
-        //清除选中
-        this.$refs.multipleTable.clearSelection();
-        this.$set(this,'queryParams',{
-          page:1,
-          pageSize:20,
-          schoolId:null,
-          buildId:null,
-          subjectId :null,
-        });
-        this.$set(this,'selectedNum',0);
-        this.$set(this,'ids',[]);
-        this.getList();
-      },
-      getList(){
-        let obj = JSON.parse(JSON.stringify(this.queryParams))
-        obj.id = this.typeId;
-        iotAppInfoUpgradeDevices(obj).then(response => {
-          this.$set(this,'tableList',response.data.records);
-          this.$set(this,'total',response.data.total);
-        });
-      },
-      //获取校区
-      systemBuildingGetTreeList(){
-        systemBuildingGetTreeList({}).then(response => {
-          let list = [];
-          for(let i=0;i<response.data.length;i++){
-            list.push({
-              id:response.data[i].id,
-              name:response.data[i].name,
-            })
-          }
-          this.$set(this,'schoolOption',list);
-          this.$set(this,'addressList',response.data);
-        })
-      },
-      //校区选中
-      changeSchool(val){
-        let self = this;
-        let list = [];
-        for(let i=0;i<self.addressList.length;i++){
-          if(val == self.addressList[i].id && self.addressList[i].buildFloorVoList[0]){
-            for(let o=0;o<self.addressList[i].buildFloorVoList.length;o++){
-              list.push({
-                id:self.addressList[i].buildFloorVoList[o].id,
-                name:self.addressList[i].buildFloorVoList[o].name,
-              })
-            }
-          }
-        }
-        this.$set(this.queryParams,'buildId',null);
-        this.$set(this.queryParams,'subjectId',null);
-        this.$set(this,'buildOption',list);
-        this.$set(this,'subjectOption',[]);
-      },
-      //楼栋选中
-      buildSchool(val){
-        laboratorySubRelInfoGetListByFloor({buildId:val}).then(response => {
-          this.$set(this.queryParams,'subjectId',null);
-          this.$set(this,'subjectOption',response.data);
-        })
-      },
-      /*===记录勾选数据===
-        需要再el-table 添加  :row-key="getRowKeys"
-        需要在selection 添加 :reserve-selection="true"
-      */
-      getRowKeys(row) {
-        return row.deviceId
-      },
-      //多选框选中数据
-      handleSelectionChange(selection) {
-        this.selectedNum = selection.length;
-        this.ids = selection.map(item => item.deviceId)
-      },
-    },
-  }
-</script>
-
-<style scoped lang="scss">
-  .applyList-batchUpDialog{
-    .content-box{
-      flex:1;
-      display: flex;
-      padding:20px;
-    }
-  }
-</style>

+ 91 - 435
src/views/iotDevice/appManage/applyList/index.vue

@@ -5,79 +5,52 @@
       <div class="page-form-title-box">
         <el-form :model="queryParams" class="form-box" ref="queryForm"
                  :inline="true" style="width:100%;">
-          <el-form-item label="" prop="name" label-width="90px">
+          <el-form-item label="" prop="appName" label-width="90px">
             <el-input
               maxLength="30"
-              v-model="queryParams.searchValue"
+              v-model="queryParams.appName"
               placeholder="请输入应用名"
               style="width: 200px"
             />
           </el-form-item>
-          <el-form-item label="" prop="code">
-            <el-select v-model="queryParams.code" placeholder="请选择设备类型" style="width: 200px">
-              <el-option
-                v-for="item in optionList"
-                :key="item.code"
-                :label="item.name"
-                :value="item.code">
-              </el-option>
-            </el-select>
-          </el-form-item>
-          <el-form-item label="" prop="state">
-            <el-select v-model="queryParams.state" placeholder="请选择状态" style="width: 200px">
-              <el-option label="启用" :value="true"></el-option>
-              <el-option label="禁用" :value="false"></el-option>
+          <el-form-item label="" prop="terminalType">
+            <el-select v-model="queryParams.terminalType" placeholder="请选择类型" style="width: 200px">
+              <el-option label="化学品终端" value="aio_chemical"></el-option>
+              <el-option label="电子信息牌" value="aio_infobord"></el-option>
+              <el-option label="学习考试一体" value="aio_exam"></el-option>
             </el-select>
           </el-form-item>
           <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
           <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
           <p class="page-submit-common-style-button"
              style="float: right;"
-             @click="handleClick()"
-             v-hasPermiRouter="['iot:appInfo:add']"
-          >添加应用</p>
+             @click="tableButton(1)"
+          >新增</p>
         </el-form>
       </div>
       <div class="page-content-box">
         <el-table class="table-box" v-loading="loading" border :data="tableList" ref="multipleTable">
-          <el-table-column label="应用名" align="center" prop="name" show-overflow-tooltip/>
-          <el-table-column label="版本号" align="center" prop="version" show-overflow-tooltip width="100"/>
-          <el-table-column label="文件尺寸(MB)" align="center" prop="size" show-overflow-tooltip width="120"/>
-          <el-table-column label="版本描述" align="center" prop="info" show-overflow-tooltip width="300"/>
-          <el-table-column label="设备类型" align="center" prop="code" show-overflow-tooltip width="140">
-            <template slot-scope="scope">
-              <p v-for="item in optionList" v-if="item.code == scope.row.code">{{item.name}}</p>
-            </template>
-          </el-table-column>
-          <el-table-column label="状态" align="center" prop="state" show-overflow-tooltip width="100">
+          <el-table-column label="应用名" align="center" prop="appName" show-overflow-tooltip/>
+          <el-table-column label="类型" align="center" prop="terminalType" show-overflow-tooltip width="200">
             <template slot-scope="scope">
-              {{scope.row.state?'启用':'禁用'}}
+              {{scope.row.terminalType=='aio_chemical'?'化学品终端':(scope.row.terminalType=='aio_infobord'?'电子信息牌':(scope.row.terminalType=='aio_exam'?'学习考试一体':scope.row.terminalType))}}
             </template>
           </el-table-column>
+          <el-table-column label="描述" align="center" prop="description" show-overflow-tooltip width="600"/>
           <el-table-column label="创建时间" align="center" prop="createTime" show-overflow-tooltip width="180">
             <template slot-scope="scope">
               {{parseTime(scope.row.createTime,"{y}-{m}-{d} {h}:{i}")}}
             </template>
           </el-table-column>
-          <el-table-column label="操作" align="center" prop="deptName" width="260" v-if="tableButtonType">
+          <el-table-column label="操作" align="center" prop="deptName" width="140">
             <template slot-scope="scope">
               <div class="table-button-box">
                 <p class="table-button-null"></p>
-                <p class="table-button-p"
-                   @click="tableButton(4,scope.row)"
-                   v-hasPermiRouter="['iot:appInfo:batch']"
-                >升级</p>
-                <p class="table-button-p"
-                   @click="tableButton(1,scope.row)"
-                   v-hasPermiRouter="['iot:appInfo:download']"
-                >下载</p>
                 <p class="table-button-p"
                    @click="tableButton(2,scope.row)"
-                   v-hasPermiRouter="['iot:appInfo:edit']"
                 >编辑</p>
                 <p class="table-button-p"
                    @click="tableButton(3,scope.row)"
-                   v-hasPermiRouter="['iot:appInfo:del']"
                 >删除</p>
                 <p class="table-button-null"></p>
               </div>
@@ -93,78 +66,44 @@
         />
       </div>
     </div>
-    <el-dialog :title="dialogTitle" class="applyList-dialog-box" :visible.sync="dialogType" v-if="dialogType"
-               width="700px" append-to-body :close-on-click-modal="false">
+    <el-dialog :title="dialogForm.appId?'编辑':'新增'" class="applyList-dialog-box" :visible.sync="dialogType" v-if="dialogType"
+               width="560px" append-to-body :close-on-click-modal="false">
       <div class="applyList-dialog-min-box scrollbar-box">
         <el-form  v-loading="loading" :rules="dialogRules" :model="dialogForm" ref="dialogForm">
-          <el-form-item label="应用名称" prop="name" label-width="90px">
+          <el-form-item label="应用名称" prop="appName" label-width="90px">
             <el-input
-              :disabled="!!dialogForm.id"
-              v-model="dialogForm.name"
+              v-model="dialogForm.appName"
               maxLength="20"
               placeholder="请输入应用名称"
-              style="width: 500px"
+              style="width: 360px"
             />
           </el-form-item>
-          <el-form-item label="版本号" prop="version" label-width="90px">
-            <el-input-number
-              :disabled="!!dialogForm.id"
-              v-model="dialogForm.version"
-              :precision="2"
-              :step="0.01"
-              maxLength="20"
-              placeholder="请输入版本号"
-              style="width: 500px"
-              controls-position="right"
-              :min="minVersion" :max="100">
-            </el-input-number>
+          <el-form-item label="app包名" prop="startLaunchPackage" label-width="90px">
+            <el-input
+              v-model="dialogForm.startLaunchPackage"
+              maxLength="30"
+              placeholder="请输入包名"
+              style="width: 360px"
+            />
           </el-form-item>
-          <el-form-item label="版本描述" prop="info" label-width="90px">
+          <el-form-item label="类型" prop="terminalType" style="display: block" label-width="90px">
+            <el-select v-model="dialogForm.terminalType" placeholder="请选择类型" style="width: 360px">
+              <el-option label="化学品终端" value="aio_chemical"></el-option>
+              <el-option label="电子信息牌" value="aio_infobord"></el-option>
+              <el-option label="学习考试一体" value="aio_exam"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="描述" prop="description" label-width="90px">
             <el-input
               resize="none"
               type="textarea"
-              v-model="dialogForm.info"
-              maxLength="200"
-              placeholder="请输入版本描述"
-              style="width: 500px"
+              v-model="dialogForm.description"
+              maxLength="100"
+              placeholder="请输入描述"
+              style="width: 360px"
+              show-word-limit
             />
           </el-form-item>
-          <el-form-item label="设备类型" prop="code" style="display: block" label-width="90px">
-            <el-radio-group :disabled="!!dialogForm.id" v-model="dialogForm.code" @change="typeChange">
-              <el-radio v-for="item in optionList" :label="item.code">{{item.name}}</el-radio>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item label="状态" prop="state" style="display: block" label-width="90px">
-            <el-radio v-model="dialogForm.state" :label="true">启用</el-radio>
-            <el-radio v-model="dialogForm.state" :label="false">禁用</el-radio>
-          </el-form-item>
-          <el-form-item label="安装包" prop="state" style="display: block" label-width="90px" v-if="upDataType">
-            <p class="up-data-p" @click="upDataButton">重新上传</p>
-          </el-form-item>
-          <el-form-item label="安装包" prop="url" label-width="90px" v-if="!upDataType">
-            <uploader
-              :autoStart="false"
-              :options="options"
-              ref="uploader"
-              :file-list="fileList"
-              :file-status-text="statusText"
-              class="uploader-example"
-              @file-complete="fileComplete"
-              @complete="complete"
-              @file-success="fileSuccess"
-              @files-added="filesAdded">
-              <uploader-unsupport></uploader-unsupport>
-              <uploader-drop>
-                <i class="el-icon-upload"></i>
-                <div class="el-upload__text">将文件拖到此处,或 <uploader-btn :single="true" :attrs="attrs">点击上传</uploader-btn></div>
-              </uploader-drop>
-              <div class="text-box" v-if="fileData.name">
-                <p>{{fileData.name}}</p>
-                <p>{{fileData.size}}MB</p>
-                <p>{{fileData.text}}</p>
-              </div>
-            </uploader>
-          </el-form-item>
         </el-form>
       </div>
       <div slot="footer" class="dialog-footer dialog-footer-box">
@@ -174,115 +113,45 @@
         <p class="dialog-footer-button-null"></p>
       </div>
     </el-dialog>
-    <batch-up-dialog ref="batchUpDialog"></batch-up-dialog>
   </div>
 </template>
 
 <script>
-
-  import batchUpDialog from './batchUpDialog.vue'
-  import { iotAppInfoList,iotAppInfoGetCodeList,iotAppInfoAdd,iotAppInfoUpdate,
-    iotAppInfoDelete,iotAppInfoGetLastVersion,iotAppInfoBatchUpgrade, } from "@/api/iotDevice/index";
-  import { getToken } from "@/utils/auth";
-  import axios from 'axios'
-  import SparkMD5 from 'spark-md5'
-  let httpHeader=window.location.href.split('://')[0]+'://'
+  import {
+    terminalAppList,
+    terminalAppDelete,
+    terminalAppAdd,
+    terminalAppUpdate,
+  } from "@/api/iotDevice/index";
   export default {
     name: 'applyList',
-    components: {
-      batchUpDialog
-    },
     data(){
       return{
-        tableButtonType:this.hasPermiDom(['iot:appInfo:batch','iot:appInfo:download','iot:appInfo:edit','iot:appInfo:del']),
         loading:false,
-        optionList:[],
         queryParams:{
           page:1,
           pageSize:20,
-          searchValue:"",
-          code:null,
-          state:null,
+          appName:"",
+          terminalType:"",
         },
         tableList:[],
         total:0,
-        dialogTitle:"",
         dialogType:false,
-        upDataType:false,
         dialogForm:{
-          name:"",
-          version:"",
-          info:"",
-          code:1,
-          state:true,
-          url:'',
-        },
-        //版本号最小值
-        minVersion:null,
-        //文件列表
-        fileList:[],
-        options: {
-          target: httpHeader+this.judgmentNetworkReturnAddress()+"/system/file/upload/apk/chunk",
-          // 开启服务端分片校验功能
-          testChunks: true,
-          single: true,
-          fileParameterName: 'file',
-          headers: {
-            Authorization: getToken(),
-          },
-          parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) {
-            return parsedTimeRemaining
-              .replace(/\syears?/, "年")
-              .replace(/\days?/, "天")
-              .replace(/\shours?/, "小时")
-              .replace(/\sminutes?/, "分钟")
-              .replace(/\sseconds?/, "秒");
-          },
-          // // 服务器分片校验函数
-          checkChunkUploadedByResponse: (chunk, message) => {
-            const result = JSON.parse(message);
-            if (result.data.skipUpload) {
-              this.skip = true;
-              return true;
-            }
-            return (result.data.uploaded || []).indexOf(chunk.offset + 1) >= 0;
-          },
-        },
-        attrs: {
-          accept: [".apk"]
-        },
-        statusText: {
-          success: "上传成功",
-          error: "上传出错了",
-          uploading: "上传中...",
-          paused: "暂停中...",
-          waiting: "等待中...",
-          cmd5: "计算文件MD5中...",
-        },
-        fileData:{
-          name:"",
-          size:"",
-          text:"",
+          appName:"",
+          startLaunchPackage:"",
+          terminalType:"",
+          description:"",
         },
         dialogRules:{
-          name: [
+          appName: [
             { required: true, message: "请输入应用名称", trigger: "blur" }
           ],
-          version: [
-            { required: true, message: "请输入版本编号", trigger: "blur" },
-            // { required: true, message: "只能输入数字", validator: this.isNum, trigger: "blur" },
-          ],
-          info: [
-            { required: true, message: "请输入版本描述", trigger: "blur" }
-          ],
-          code: [
-            { required: true, message: "请选择设备类型", trigger: "blur" }
+          startLaunchPackage: [
+            { required: true, message: "请输入包名", trigger: "blur" }
           ],
-          state: [
-            { required: true, message: "请选择状态", trigger: "blur" }
-          ],
-          url: [
-            { required: true, message: "请上传安装包", trigger: "blur" }
+          terminalType: [
+            { required: true, message: "请选择类型", trigger: "blur" },
           ],
         },
       }
@@ -292,177 +161,32 @@
     },
     mounted(){
       this.getList();
-      this.iotAppInfoGetCodeList();
     },
     methods:{
-      fileSuccess(rootFile, file, response, chunk) {
-        const result = JSON.parse(response);
-        if (result.code == 200 && !this.skip) {
-          axios.post(httpHeader+this.judgmentNetworkReturnAddress()+"/system/file/upload/merge", {
-            identifier: file.uniqueIdentifier,
-            filename: file.name,
-            totalChunks: chunk.offset,
-          },{
-            headers: {
-              Authorization: getToken(),
-            }
-          }).then((res) => {
-            if (res.data.code==200) {
-              this.dialogForm.url=res.data.data;
-            } else {
-            }
-          }).catch(function (error) {
-          });
-        } else if(result.code == 200){
-        }else{
-          this.msgError(result.code+result.message)
-        }
-        if (this.skip) {
-          this.skip = false;
-        }
-      },
-      fileComplete(rootFile) {
-        // 一个根文件(文件夹)成功上传完成。
-        this.fileName=rootFile.name;
-        this.fileSize=rootFile.size;
-        this.fileData = {
-          name:rootFile.name,
-          size:(parseInt(rootFile._prevUploadedSize/1024)/1024).toFixed(2),
-          text:"上传完成"
-        }
-      },
-      complete(file) {
-        // 上传完毕。
-      },
-      filesAdded(file, fileList, event) {
-        if(file[0].fileType !== "application/vnd.android.package-archive"){
-          this.msgError('请上传APK文件')
-          return
-        }
-        this.fileData = {
-          name:file[0].name,
-          size:"",
-          text:"上传中..."
-        }
-        this.fileList=[];
-        file.forEach((e) => {
-          this.fileList.push(e);
-          this.computeMD5(e);
-        });
-      },
-      computeMD5(file) {
-        let fileReader = new FileReader();
-        let time = new Date().getTime();
-        let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
-        let currentChunk = 0;
-        const chunkSize = 1024 * 1024;
-        let chunks = Math.ceil(file.size / chunkSize);
-        let spark = new SparkMD5.ArrayBuffer();
-        // 文件状态设为"计算MD5"
-        file.cmd5 = true; //文件状态为“计算md5...”
-        file.pause();
-        loadNext();
-        fileReader.onload = (e) => {
-          spark.append(e.target.result);
-          if (currentChunk < chunks) {
-            currentChunk++;
-            loadNext();
-            // 实时展示MD5的计算进度
-          } else {
-            let md5 = spark.end();
-            spark.destroy(); //释放缓存
-            file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
-            file.cmd5 = false; //取消计算md5状态
-            file.resume(); //开始上传
-          }
-        };
-        fileReader.onerror = function () {
-          this.error(`文件${file.name}读取出错,请检查该文件`);
-          file.cancel();
-        };
-        function loadNext() {
-          let start = currentChunk * chunkSize;
-          let end = start + chunkSize >= file.size ? file.size : start + chunkSize;
-          fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
-        }
-      },
+      //提交按钮
       dialogSubmit(){
-        if(this.loading){
-          return
-        }
-        if(this.dialogForm.id){//编辑
-          this.$refs["dialogForm"].validate(valid => {
-            if (valid) {
-              let obj = {
-                id:this.dialogForm.id,
-                name:this.dialogForm.name,
-                version:this.dialogForm.version,
-                info:this.dialogForm.info,
-                code:this.dialogForm.code,
-                url:this.dialogForm.url,
-                state:this.dialogForm.state,
-                // fileData:JSON.stringify(this.fileData),
-              };
-              iotAppInfoUpdate(obj).then( response => {
-                this.msgSuccess("编辑成功");
-                this.getList()
-                this.dialogType = false;
-                this.dialogForm = {};
-                this.fileList=[];
-                this.fileData = {};
+        this.$refs["dialogForm"].validate(valid => {
+          if (valid) {
+            if(this.dialogForm.appId){
+              terminalAppUpdate(this.dialogForm).then( response => {
+                this.msgSuccess(response.message);
+                this.$set(this,'dialogType',false);
+                this.resetQuery();
               });
-            }
-          });
-
-        }else{//添加
-          this.$refs["dialogForm"].validate(valid => {
-            if (valid) {
-              let obj = {
-                name:this.dialogForm.name,
-                version:this.dialogForm.version,
-                info:this.dialogForm.info,
-                code:this.dialogForm.code,
-                state:this.dialogForm.state,
-                url:this.dialogForm.url,
-                size:this.fileData.size,
-                // fileData:JSON.stringify(this.fileData),
-              };
-              iotAppInfoAdd(obj).then( response => {
-                this.msgSuccess("新增成功");
-                this.getList()
-                this.dialogType = false;
-                this.dialogForm = {};
-                this.fileList=[];
-                this.fileData = {};
+            }else{
+              terminalAppAdd(this.dialogForm).then( response => {
+                this.msgSuccess(response.message);
+                this.$set(this,'dialogType',false);
+                this.resetQuery();
               });
             }
-          });
-        }
+          }
+        })
       },
+      //关闭按钮
       dialogCancel(){
         this.$set(this,'dialogType',false);
       },
-      //新增
-      handleClick(){
-        this.$set(this,'dialogForm',{
-          name:"",
-          version:"",
-          info:"",
-          code:1,
-          state:true,
-          url:"",
-        });
-        this.$set(this,'fileList',[]);
-        this.$set(this,'fileData',{
-          name:"",
-          size:"",
-          text:"",
-        });
-        this.iotAppInfoGetLastVersion();
-        this.$set(this,'dialogTitle','上传APK');
-        this.$set(this,'upDataType',false);
-        this.$set(this,'dialogType',true);
-      },
       //查询
       handleQuery(){
         this.$set(this.queryParams,'page',1);
@@ -473,9 +197,8 @@
         this.$set(this,'queryParams',{
           page:1,
           pageSize:20,
-          searchValue:"",
-          code:null,
-          state:null,
+          appName:"",
+          terminalType:"",
         });
         this.getList();
       },
@@ -483,116 +206,49 @@
       getList(){
         this.$set(this,'loading',true);
         let obj = JSON.parse(JSON.stringify(this.queryParams))
-        iotAppInfoList(obj).then(response => {
+        terminalAppList(obj).then(response => {
           this.$set(this,'loading',false);
           this.$set(this,'tableList',response.data.records);
           this.$set(this,'total',response.data.total);
         });
       },
-      //获取设备类型
-      iotAppInfoGetCodeList(){
-        iotAppInfoGetCodeList().then(response => {
-          this.$set(this,'optionList',response.data);
-        });
-      },
-      //重新上传开关
-      upDataButton(){
-        this.$set(this.dialogForm,'url','');
-        this.$set(this,'upDataType',!this.upDataType);
-      },
       //操作按钮
       tableButton(type,row){
         let self = this;
         if(type == 1){
-          let format = row.url.split('.');
-          let name = row.name+'.'+format[format.length-1];
-          this.downloadGet(row.url,name);
-        }else if(type == 2){
-          let obj = JSON.parse(JSON.stringify(row));
+          //新增
           this.$set(this,'dialogForm',{
-            id:obj.id,
-            name:obj.name,
-            version:obj.version,
-            info:obj.info,
-            code:obj.code,
-            url:obj.url,
-            state:obj.state,
+            appName:"",
+            startLaunchPackage:"",
+            terminalType:"",
+            description:"",
           });
-          this.$set(this,'minVersion',obj.version);
-          this.$set(this,'fileList',[]);
-          this.$set(this,'fileData',{
-            name:"",
-            size:"",
-            text:"",
+          this.$set(this,'dialogType',true);
+        }else if(type == 2){
+          let obj = JSON.parse(JSON.stringify(row))
+          this.$set(this,'dialogForm',{
+            appId:obj.id,
+            appName:obj.appName,
+            startLaunchPackage:obj.startLaunchPackage,
+            terminalType:obj.terminalType,
+            description:obj.description,
           });
-          this.$set(this,'dialogTitle','上传APK');
-          this.$set(this,'upDataType',true);
           this.$set(this,'dialogType',true);
         }else if(type == 3){
+          //删除
           this.$confirm('是否确认删除?', "警告", {
             confirmButtonText: "确定",
             cancelButtonText: "取消",
             type: "warning"
           }).then(function() {
           }).then(() => {
-            iotAppInfoDelete({id:row.id}).then(response => {
+            terminalAppDelete({appId:row.id}).then(response => {
               self.msgSuccess(response.message)
               self.getList();
             });
           }).catch(() => {});
-        }else  if (type == 4){
-          this.$confirm('请选择升级方式?', "提示", {
-            confirmButtonText: "批量升级",
-            cancelButtonText: "全部升级",
-            confirmButtonClass:'confirmBatchButton',
-            cancelButtonClass:'confirmBatchButton',
-            type: "warning"
-          }).then(function() {
-          }).then(() => {
-            this.$refs.batchUpDialog.dialogOpen(row);
-          }).catch(() => {
-            self.$confirm('是否确认批量升级?', "警告", {
-              confirmButtonText: "确定",
-              cancelButtonText: "取消",
-              type: "warning"
-            }).then(function() {
-            }).then(() => {
-              let obj = {
-                id:row.id,
-                isAll:true, // true.全部升级 false.勾选升级
-              }
-              iotAppInfoBatchUpgrade(obj).then(response => {
-                this.msgSuccess(response.message)
-              });
-            }).catch(() => {});
-
-          });
-
         }
       },
-      //选中设备类型
-      typeChange(val){
-        this.iotAppInfoGetLastVersion();
-      },
-      //通过类型获取当前APK版本号
-      iotAppInfoGetLastVersion(){
-        iotAppInfoGetLastVersion({code:this.dialogForm.code?this.dialogForm.code:1}).then(response => {
-          let minVersion = Number(this.accAdd(response.data,0.01));
-          this.$set(this,'minVersion',minVersion);
-          this.$set(this.dialogForm,'version',minVersion);
-          // this.$set(this,'minVersion',Number(this.accAdd(response.data,0.01)));
-          // this.$set(this.dialogForm,'version',response.data);
-          // this.$set(this.dialogForm,'version',response.data);
-        });
-      },
-      //加法
-      accAdd(arg1,arg2){
-        var r1,r2,m;
-        try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
-        try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
-        m=Math.pow(10,Math.max(r1,r2))
-        return ((arg1*m+arg2*m)/m).toFixed(2);
-      },
     },
   }
 </script>

+ 395 - 0
src/views/iotDevice/appManage/applyListVersions/index.vue

@@ -0,0 +1,395 @@
+<!-- 应用版本列表 -->
+<template>
+  <div class="app-container applyListVersions">
+    <div class="page-container applyListVersionsPage" v-if="pageType === 1">
+      <div class="page-form-title-box">
+        <el-form :model="queryParams" class="form-box" ref="queryForm"
+                 :inline="true" style="width:100%;">
+          <el-form-item label="" prop="appName" label-width="90px">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.appName"
+              placeholder="请输入应用名"
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="versionName" label-width="90px">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.versionName"
+              placeholder="请输入版本号"
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="terminalType">
+            <el-select v-model="queryParams.terminalType" placeholder="请选择类型" style="width: 200px">
+              <el-option label="化学品终端" value="aio_chemical"></el-option>
+              <el-option label="电子信息牌" value="aio_infobord"></el-option>
+              <el-option label="学习考试一体" value="aio_exam"></el-option>
+            </el-select>
+          </el-form-item>
+          <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
+          <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
+          <p class="page-submit-common-style-button"
+             style="float: right;"
+             @click="tableButton(1)"
+             v-hasPermiRouter="['demo:demo:add']"
+          >新增</p>
+        </el-form>
+      </div>
+      <div class="page-content-box">
+        <el-table class="table-box" v-loading="loading" border :data="dataList">
+          <el-table-column label="应用名" prop="appName"  show-overflow-tooltip/>
+          <el-table-column label="版本号" prop="versionCode" width="100" show-overflow-tooltip/>
+          <el-table-column label="版本名称" prop="versionName" width="140" show-overflow-tooltip/>
+          <el-table-column label="类型" align="center" prop="terminalType" show-overflow-tooltip width="200">
+            <template slot-scope="scope">
+              {{scope.row.terminalType=='aio_chemical'?'化学品终端':(scope.row.terminalType=='aio_infobord'?'电子信息牌':(scope.row.terminalType=='aio_exam'?'学习考试一体':scope.row.terminalType))}}
+            </template>
+          </el-table-column>
+          <el-table-column label="大小" prop="fileSize" width="100" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ scope.row.fileSize?scope.row.fileSize+'MB':''}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="升级说明" prop="releaseNotes" width="260" show-overflow-tooltip/>
+          <el-table-column label="创建时间" prop="createTime" width="160" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.createTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" width="140" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <div class="table-button-box">
+                <p class="table-button-null"></p>
+                <p class="table-button-p"
+                   @click="tableButton(2,scope.row)"
+                >编辑</p>
+                <p class="table-button-p"
+                   @click="tableButton(3,scope.row)"
+                >删除</p>
+                <p class="table-button-null"></p>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination :page-sizes="[20, 30, 40, 50]"
+                    v-show="total>0"
+                    :total="total"
+                    :page.sync="queryParams.page"
+                    :limit.sync="queryParams.pageSize"
+                    @pagination="getList"
+        />
+      </div>
+    </div>
+    <el-dialog :title="dialogForm.versionId?'编辑':'新增'" class="applyList-dialog-box" :visible.sync="dialogType" v-if="dialogType"
+               width="560px" append-to-body :close-on-click-modal="false">
+      <div class="applyList-dialog-min-box scrollbar-box">
+        <el-form  :rules="dialogRules" v-loading="loading" :model="dialogForm" ref="dialogForm">
+          <el-form-item label="app" prop="appId" label-width="90px">
+            <el-select v-model="dialogForm.appId" :disabled="dialogForm.versionId?true:false" placeholder="请选择app" style="width: 360px">
+              <el-option v-for="(item,index) in optionList"
+                         :key="item.appId"
+                         :label="item.appName"
+                         :value="item.appId"/>
+            </el-select>
+          </el-form-item>
+          <!--<el-form-item label="app包名" prop="package" label-width="90px">-->
+            <!--<el-input-->
+              <!--disabled-->
+              <!--v-model="dialogForm.package"-->
+              <!--maxLength="20"-->
+              <!--placeholder="请上传APK"-->
+              <!--style="width: 360px"-->
+            <!--/>-->
+          <!--</el-form-item>-->
+          <el-form-item label="版本号" prop="versionCode" label-width="90px">
+            <el-input
+              disabled
+              v-model="dialogForm.versionCode"
+              maxLength="20"
+              placeholder="请上传APK"
+              style="width: 360px"
+            />
+          </el-form-item>
+          <el-form-item label="版本名称" prop="versionName" label-width="90px">
+            <el-input
+              disabled
+              v-model="dialogForm.versionName"
+              maxLength="20"
+              placeholder="请上传APK"
+              style="width: 360px"
+            />
+          </el-form-item>
+          <el-form-item label="大小" prop="fileSize" label-width="90px">
+            <el-input
+              disabled
+              v-model="dialogForm.fileSize"
+              maxLength="20"
+              placeholder="请上传APK"
+              style="width: 360px"
+            />
+          </el-form-item>
+          <el-form-item label="描述" prop="releaseNotes" label-width="90px">
+            <el-input
+              resize="none"
+              type="textarea"
+              v-model="dialogForm.releaseNotes"
+              maxlength="100"
+              placeholder="请输入描述"
+              style="width: 360px"
+              show-word-limit
+              :rows="4"
+            />
+          </el-form-item>
+          <el-upload
+            style="margin:0 90px;"
+            class="upload-demo"
+            :action="uploadImgUrl"
+            :show-file-list="false"
+            drag
+            multiple
+            :on-success="(res)=>handleAvatarSuccess(res)"
+            :headers="headers"
+            :before-upload="beforeAvatarUpload">
+            <i class="el-icon-upload" style="color:#CCE6FE;margin-top:40px;"></i>
+            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+          </el-upload>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer dialog-footer-box">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogCancel">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">提交</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+  const ApkParser = require('app-info-parser/src/apk');
+  import {
+    terminalVersionList,
+    terminalVersionAdd,
+    terminalVersionUpdate,
+    terminalVersionDelete,
+    terminalAppSelect,
+  } from "@/api/iotDevice/index";
+  import { getToken } from '@/utils/auth'
+  export default {
+    name: 'index',
+    //components: {
+    //  addPage
+    //},
+    data () {
+      return {
+        uploadImgUrl: this.uploadUrl(), // 上传的图片服务器地址
+        headers: {
+          Authorization: getToken(),
+        },
+        //页面状态
+        pageType:1,
+        //页面遮罩
+        loading:false,
+        //下拉列表数据
+        optionList:[],
+        //查询条件
+        queryParams:{
+          page:1,
+          pageSize:20,
+          appName:"",
+          versionName :null,
+          terminalType :null,
+        },
+        //时间数据
+        dateRange:[],
+        //列表数据
+        dataList:[],
+        //数据数量
+        total:0,
+        dialogType:false,
+        dialogForm:{
+          appName:"",
+          terminalType:"",
+          description:"",
+        },
+        dialogRules:{
+          appId: [
+            { required: true, message: "app", trigger: "blur" }
+          ],
+          // package: [
+          //   { required: true, message: "请上传APK", trigger: "blur" }
+          // ],
+          versionCode: [
+            { required: true, message: "请上传APK", trigger: "blur" },
+          ],
+          versionName: [
+            { required: true, message: "请上传APK", trigger: "blur" },
+          ],
+          size: [
+            { required: true, message: "请上传APK", trigger: "blur" },
+          ],
+        },
+        apkData:{},
+      }
+    },
+    created () {
+
+    },
+    mounted () {
+      this.terminalAppSelect();
+      this.getList();
+    },
+    methods: {
+      //提交按钮
+      dialogSubmit(){
+        if(this.loading){
+          return
+        }
+        this.$refs["dialogForm"].validate(valid => {
+          if (valid) {
+            if(this.dialogForm.versionId){
+              terminalVersionUpdate(this.dialogForm).then( response => {
+                this.msgSuccess(response.message);
+                this.$set(this,'dialogType',false);
+                this.resetQuery();
+              });
+            }else{
+              terminalVersionAdd(this.dialogForm).then( response => {
+                this.msgSuccess(response.message);
+                this.$set(this,'dialogType',false);
+                this.resetQuery();
+              });
+            }
+          }
+        })
+      },
+      //关闭按钮
+      dialogCancel(){
+        this.$set(this,'dialogType',false);
+      },
+      //查询按钮
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      //重置按钮
+      resetQuery(){
+        this.$set(this,'dateRange',[])
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          appName:"",
+          versionName :null,
+          terminalType :null,
+        });
+        this.getList();
+      },
+      //获取数据列表
+      getList(){
+        this.$set(this,'loading',true);
+        terminalVersionList(this.queryParams).then(response => {
+          this.$set(this,'loading',false);
+          this.$set(this,'dataList',response.data.records);
+          this.$set(this,'total',response.data.total);
+        });
+      },
+      terminalAppSelect(){
+        terminalAppSelect({}).then(response => {
+          this.$set(this,'optionList',response.data);
+        });
+      },
+      //操作按钮
+      tableButton(type,row){
+        let self = this;
+        if(type == 1){
+          //新增
+          this.$set(this,'dialogForm',{
+            appId:"",
+            // package:"",
+            versionCode:"",
+            versionName:"",
+            apkUrl:"",
+            fileSize:"",
+            releaseNotes:"",
+          });
+          this.$set(this,'dialogType',true);
+        }else if(type == 2){
+          //编辑
+          let obj = JSON.parse(JSON.stringify(row))
+          this.$set(this,'dialogForm',{
+            versionId:obj.versionId,
+            appId:obj.appId,
+            // package:obj.package,
+            versionCode:obj.versionCode,
+            versionName:obj.versionName,
+            apkUrl:obj.apkUrl,
+            fileSize:obj.fileSize,
+            releaseNotes:obj.releaseNotes,
+          });
+          this.$set(this,'dialogType',true);
+        }else if(type == 3){
+          //删除
+          this.$confirm('是否确认删除?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            terminalVersionDelete({versionId:row.versionId}).then(response => {
+              self.msgSuccess(response.message)
+              self.getList();
+            });
+          }).catch(() => {});
+        }
+      },
+      //上传相关
+      handleAvatarSuccess(res) {
+        // this.$set(this.dialogForm,'package',this.apkData.package);
+        this.$set(this.dialogForm,'versionCode',this.apkData.versionCode);
+        this.$set(this.dialogForm,'versionName',this.apkData.versionName);
+        this.$set(this.dialogForm,'fileSize',res.data.size);
+        this.$set(this.dialogForm,'apkUrl',res.data.url);
+        this.$set(this,'loading',false);
+        this.$forceUpdate()
+      },
+      beforeAvatarUpload(file) {
+        this.$set(this,'loading',true);
+        let type = false;
+        if (file.type == 'application/vnd.android.package-archive' ) {
+          if(file.size> 210000000){
+            this.msgError('上传图片大小不能超过200M')
+            this.$set(this,'loading',true);
+            return false
+          }
+          const parser = new ApkParser(file);
+          parser
+            .parse()
+            .then((result) => {
+              this.$set(this,'apkData',{
+                // package:result.package,
+                versionCode:result.versionCode,
+                versionName:result.versionName,
+              });
+            })
+            .catch((err) => {
+
+            });
+          type = true;
+        }else{
+          this.msgError('请上传APK文件')
+          type = false;
+          this.$set(this,'loading',false);
+        }
+        return type;
+      },
+    },
+  }
+</script>
+<style scoped lang="scss">
+  .applyListVersions{
+    .applyListVersionsPage{
+
+    }
+  }
+</style>

+ 290 - 68
src/views/iotDevice/appManage/applyUpgrades/index.vue

@@ -1,59 +1,55 @@
-<!--应用升级-->
+<!--应用升级计划列表-->
 <template>
   <div class="app-container applyUpgrades">
     <div class="page-container applyUpgradesPage">
       <div class="page-form-title-box">
         <el-form :model="queryParams" class="form-box" ref="queryForm"
                  :inline="true" style="width:100%;">
-          <el-form-item label="" prop="searchValue" label-width="90px">
+          <el-form-item label="" prop="appName" label-width="90px">
             <el-input
               maxLength="30"
-              v-model="queryParams.searchValue"
-              placeholder="请输入设备名称"
+              v-model="queryParams.appName"
+              placeholder="app名称"
               clearable
               style="width: 200px"
             />
           </el-form-item>
-          <el-form-item label="" prop="code">
-            <el-select v-model="queryParams.code" clearable placeholder="请选择设备类型" style="width: 200px">
-              <el-option
-                v-for="item in optionList"
-                :key="item.code"
-                :label="item.name"
-                :value="item.code">
-              </el-option>
-            </el-select>
+          <el-form-item label="" prop="appVersion" label-width="90px">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.appVersion"
+              placeholder="app版本号"
+              clearable
+              style="width: 200px"
+            />
           </el-form-item>
-          <el-form-item label="" prop="state">
-            <el-select v-model="queryParams.state" clearable placeholder="请选择状态" style="width: 200px">
-              <el-option label="待升级" :value="0"></el-option>
-              <el-option label="成功" :value="1"></el-option>
-              <el-option label="失败" :value="2"></el-option>
+          <el-form-item label="" prop="status">
+            <el-select v-model="queryParams.status" placeholder="状态" clearable style="width:200px;">
+              <el-option
+                v-for="dict in optionList"
+                :key="dict.code"
+                :label="dict.description"
+                :value="dict.code"
+              ></el-option>
             </el-select>
           </el-form-item>
           <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
           <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
-          <!--<p class="page-submit-common-style-button"-->
-             <!--style="float: right;"-->
-             <!--@click="handleClick()"-->
-          <!--&gt;批量升级</p>-->
+          <p class="page-submit-common-style-button"
+             style="float: right;"
+             @click="addButton"
+          >新增</p>
         </el-form>
       </div>
       <div class="page-content-box">
         <el-table class="table-box" v-loading="loading" border :data="tableList" ref="multipleTable">
-          <el-table-column label="设备名称" align="center" prop="deviceName" show-overflow-tooltip/>
-          <el-table-column label="设备编号" align="center" prop="deviceNo" show-overflow-tooltip width="240"/>
-          <el-table-column label="设备类型" align="center" prop="type" show-overflow-tooltip width="180">
-            <template slot-scope="scope">
-              <p v-for="item in optionList" v-if="item.code == scope.row.code">{{item.name}}</p>
-            </template>
-          </el-table-column>
-          <el-table-column label="应用名" align="center" prop="appName" show-overflow-tooltip width="180"/>
-          <!--<el-table-column label="原始版本" align="center" prop="info" show-overflow-tooltip width="100"/>-->
-          <el-table-column label="升级版本" align="center" prop="upgradedVersion" show-overflow-tooltip width="120"/>
-          <el-table-column label="状态" align="center" prop="state" show-overflow-tooltip width="100">
+          <el-table-column label="app名称" align="center" prop="appName" show-overflow-tooltip/>
+          <el-table-column label="app版本" align="center" prop="appVersion" show-overflow-tooltip width="240"/>
+          <el-table-column label="总设备数" align="center" prop="totalDevices" show-overflow-tooltip width="240"/>
+          <el-table-column label="分批升级数量" align="center" prop="batchSize" show-overflow-tooltip width="240"/>
+          <el-table-column label="状态" align="center" prop="status" show-overflow-tooltip width="180">
             <template slot-scope="scope">
-              {{scope.row.state == 0?'待升级':(scope.row.state == 1?'成功':(scope.row.state == 2?'失败':''))}}
+              {{scope.row.status=='pending'?'待执行':(scope.row.status=='in_progress'?'进行中':(scope.row.status=='completed'?'已完成':(scope.row.status=='termination'?'终止':'')))}}
             </template>
           </el-table-column>
           <el-table-column label="时间" align="center" prop="createTime" show-overflow-tooltip width="180">
@@ -61,14 +57,13 @@
               {{parseTime(scope.row.createTime,"{y}-{m}-{d} {h}:{i}")}}
             </template>
           </el-table-column>
-          <el-table-column label="操作" align="center" prop="deptName" width="100" v-if="tableButtonType">
+          <el-table-column label="操作" align="center" prop="deptName" width="100">
             <template slot-scope="scope">
               <div class="table-button-box">
                 <p class="table-button-null"></p>
                 <p class="table-button-p"
-                   v-hasPermiRouter="['iot:appUpgrade:del']"
-                   v-if="scope.row.state == 0"
-                   @click="tableButton(1,scope.row)">撤销</p>
+                   @click="terminalUpgradeWebPlanTermination(scope.row)"
+                >终止计划</p>
                 <p class="table-button-null"></p>
               </div>
             </template>
@@ -83,27 +78,160 @@
         />
       </div>
     </div>
+    <el-dialog :title="dialogForm.appId?'编辑':'新增'" class="applyList-dialog-box" :visible.sync="dialogType" v-if="dialogType"
+               width="700px" append-to-body :close-on-click-modal="false">
+      <div class="applyList-dialog-min-box scrollbar-box">
+        <el-form  v-loading="loading" :rules="dialogRules" :model="dialogForm" ref="dialogForm">
+          <el-form-item label="APP" prop="appId" label-width="120px">
+            <el-select v-model="dialogForm.appId" @change="terminalVersionSelect" placeholder="请选择APP" style="width: 360px">
+              <el-option v-for="(item,index) in optionListOne"
+                         :key="item.appId"
+                         :label="item.appName"
+                         :value="item.appId"/>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="版本" prop="versionId" label-width="120px">
+            <el-select v-model="dialogForm.versionId" placeholder="请选择版本" style="width: 360px">
+              <el-option v-for="(item,index) in optionListTwo"
+                         :key="item.versionId"
+                         :label="item.versionName"
+                         :value="item.versionId"/>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="类型" prop="deviceCode" style="display: block" label-width="120px">
+            <el-select v-model="dialogForm.deviceCode" placeholder="请选择类型" style="width: 360px">
+              <el-option label="化学品终端" value="aio_chemical"></el-option>
+              <el-option label="电子信息牌" value="aio_infobord"></el-option>
+              <el-option label="学习考试一体" value="aio_exam"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="分批升级数量" prop="batchSize" label-width="120px">
+            <el-input-number v-model="dialogForm.batchSize" :step="1" :min="1" :max="200" step-strictly style="width: 360px"></el-input-number>
+          </el-form-item>
+          <el-form-item label="强制更新" prop="isForceUpdate" style="display: block" label-width="120px">
+            <el-radio-group v-model="dialogForm.isForceUpdate" style="width:320px;">
+              <el-radio :label="true">是</el-radio>
+              <el-radio :label="false">否</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="升级范围" prop="upRadius" style="display: block" label-width="120px">
+            <el-radio-group v-model="dialogForm.upRadius" style="width:320px;">
+              <el-radio :label="1">校区</el-radio>
+              <el-radio :label="2">楼栋</el-radio>
+              <el-radio :label="3">实验室</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="校区" prop="schoolId" style="display: block" label-width="120px" v-if="dialogForm.upRadius == 1 || dialogForm.upRadius == 2 || dialogForm.upRadius == 3">
+            <el-select v-model="dialogForm.schoolId" @change="changeSchool" filterable
+                       placeholder="请选择校区" style="width: 360px">
+              <el-option v-for="(item,index) in schoolOption"
+                         :key="item.id"
+                         :label="item.name"
+                         :value="item.id"/>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="楼栋" prop="buildId" style="display: block" label-width="120px" v-if="dialogForm.upRadius == 2 || dialogForm.upRadius == 3">
+            <el-select v-model="dialogForm.buildId" @change="buildSchool" filterable
+                       placeholder="请选择楼栋" style="width: 360px">
+              <el-option v-for="(item,index) in buildOption"
+                         :key="item.id"
+                         :label="item.name"
+                         :value="item.id"/>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="实验室" prop="subjectId" style="display: block" label-width="120px" v-if="dialogForm.upRadius == 3">
+            <el-select v-model="dialogForm.subjectId" filterable
+                       placeholder="请选择实验室" style="width: 360px">
+              <el-option v-for="(item,index) in subjectOption"
+                         :key="item.subId"
+                         :label="item.subName"
+                         :value="item.subId"/>
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer dialog-footer-box">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-info" @click="dialogCancel">取消</p>
+        <p class="dialog-footer-button-primary" @click="dialogSubmit">提交</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-  // import { iotAppUpgradeList,appInfoAdd,iotAppInfoGetCodeList } from "@/api/serviceCenter/index";
-  import { iotAppUpgradeList,iotAppInfoGetCodeList,iotAppUpgradeDelete, } from "@/api/iotDevice/index";
+  import { systemBuildingGetTreeList,laboratorySubRelInfoGetListByFloor } from "@/api/commonality/permission";
+  import {
+    terminalUpgradeWebPlanList,
+    terminalUpgradeWebPlanCreate,
+    terminalUpgradeWebPlanStatus,
+    terminalUpgradeWebPlanTermination,
+    terminalAppSelect,
+    terminalVersionSelect,
+  } from "@/api/iotDevice/index";
   export default {
     name: 'applyUpgrades',
     data(){
       return{
-        tableButtonType:this.hasPermiDom(['iot:appUpgrade:del']),
         loading:false,
         optionList:[],
+        optionListOne:[],
+        optionListTwo:[],
         queryParams:{
           page:1,
           pageSize:20,
-          searchValue:"",
-          code:"",
+          appName:"",
+          appVersion:"",
+          status:"",
         },
         tableList:[],
         total:0,
+        dialogType:false,
+        dialogForm:{
+          appId:null,
+          versionId:null,
+          deviceCode:null,
+          batchSize:null,
+          isForceUpdate:null,
+          upRadius:null,
+          schoolId:null,
+          buildId:null,
+          subjectId:null,
+        },
+        dialogRules:{
+          appId: [
+            { required: true, message: "请选择APP", trigger: "blur" }
+          ],
+          versionId: [
+            { required: true, message: "请选择版本", trigger: "blur" },
+          ],
+          deviceCode: [
+            { required: true, message: "请选择类型", trigger: "blur" },
+          ],
+          batchSize: [
+            { required: true, message: "请选择分批升级数量", trigger: "blur" },
+          ],
+          isForceUpdate: [
+            { required: true, message: "请选择是否强制更新", trigger: "blur" }
+          ],
+          upRadius: [
+            { required: true, message: "请选择升级范围", trigger: "blur" },
+          ],
+          schoolId: [
+            { required: true, message: "请选择校区", trigger: "blur" }
+          ],
+          buildId: [
+            { required: true, message: "请选择楼栋", trigger: "blur" },
+          ],
+          subjectId: [
+            { required: true, message: "请选择实验室", trigger: "blur" }
+          ],
+        },
+        schoolOption:[],
+        buildOption:[],
+        addressList:[],
+        subjectOption:[],
       }
     },
     created(){
@@ -111,18 +239,70 @@
     },
     mounted(){
       this.getList();
-      this.iotAppInfoGetCodeList();
+      this.terminalUpgradeWebPlanStatus();
+      this.systemBuildingGetTreeList();
+      this.terminalAppSelect();
     },
     methods:{
-      //获取设备类型
-      iotAppInfoGetCodeList(){
-        iotAppInfoGetCodeList().then(response => {
-          this.$set(this,'optionList',response.data);
+      //新增
+      addButton(){
+        this.$set(this,'dialogForm',{
+          appId:null,
+          versionId:null,
+          deviceCode:null,
+          batchSize:null,
+          isForceUpdate:null,
+          upRadius:null,
+          schoolId:null,
+          buildId:null,
+          subjectId:null,
         });
+        this.$set(this,'dialogType',true);
       },
-      //新增
-      handleClick(){
-
+      //提交按钮
+      dialogSubmit(){
+        this.$refs["dialogForm"].validate(valid => {
+          if (valid) {
+            let obj = {
+              appId:this.dialogForm.appId,
+              versionId:this.dialogForm.versionId,
+              deviceCode:this.dialogForm.deviceCode,
+              batchSize:this.dialogForm.batchSize,
+              isForceUpdate:this.dialogForm.isForceUpdate,
+              scope:{},
+            }
+            if(this.dialogForm.upRadius == 1){
+              obj.scope.campusId = this.dialogForm.schoolId;
+            }else if(this.dialogForm.upRadius == 2){
+              obj.scope.buildingId = this.dialogForm.buildId;
+            }else if(this.dialogForm.upRadius == 3){
+              obj.scope.subId = this.dialogForm.subjectId;
+            }
+            terminalUpgradeWebPlanCreate(obj).then(response => {
+              this.msgSuccess(response.message)
+              this.resetQuery();
+            });
+          }
+        })
+      },
+      //关闭按钮
+      dialogCancel(){
+        this.$set(this,'dialogType',false);
+      },
+      //终止计划
+      terminalUpgradeWebPlanTermination(row){
+        let self = this;
+        this.$confirm('是否确认终止计划?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+        }).then(() => {
+          terminalUpgradeWebPlanTermination({planId:row.planId}).then(response => {
+            self.msgSuccess(response.message)
+            self.getList();
+          });
+        }).catch(() => {});
       },
       //查询
       handleQuery(){
@@ -134,8 +314,9 @@
         this.$set(this,'queryParams',{
           page:1,
           pageSize:20,
-          searchValue:"",
-          code:"",
+          appName:"",
+          appVersion:"",
+          status:"",
         });
         this.getList();
       },
@@ -143,28 +324,69 @@
       getList(){
         this.$set(this,'loading',true);
         let obj = JSON.parse(JSON.stringify(this.queryParams))
-        iotAppUpgradeList(obj).then(response => {
+        terminalUpgradeWebPlanList(obj).then(response => {
           this.$set(this,'loading',false);
           this.$set(this,'tableList',response.data.records);
           this.$set(this,'total',response.data.total);
         });
       },
-      //操作按钮
-      tableButton(type,row){
+      //计划状态列表
+      terminalUpgradeWebPlanStatus(){
+        terminalUpgradeWebPlanStatus({}).then(response => {
+          this.$set(this,'optionList',response.data);
+        });
+      },//获取校区
+      systemBuildingGetTreeList(){
+        systemBuildingGetTreeList({}).then(response => {
+          let list = [];
+          for(let i=0;i<response.data.length;i++){
+            list.push({
+              id:response.data[i].id,
+              name:response.data[i].name,
+            })
+          }
+          this.$set(this,'schoolOption',list);
+          this.$set(this,'addressList',response.data);
+        })
+      },
+      //校区选中
+      changeSchool(val){
         let self = this;
-        if(type == 1){
-          this.$confirm('是否确认撤销?', "警告", {
-            confirmButtonText: "确定",
-            cancelButtonText: "取消",
-            type: "warning"
-          }).then(function() {
-          }).then(() => {
-            iotAppUpgradeDelete({id:row.id}).then(response => {
-              self.msgSuccess(response.message)
-              self.getList();
-            });
-          }).catch(() => {});
+        let list = [];
+        for(let i=0;i<self.addressList.length;i++){
+          if(val == self.addressList[i].id && self.addressList[i].buildFloorVoList[0]){
+            for(let o=0;o<self.addressList[i].buildFloorVoList.length;o++){
+              list.push({
+                id:self.addressList[i].buildFloorVoList[o].id,
+                name:self.addressList[i].buildFloorVoList[o].name,
+              })
+            }
+          }
         }
+        this.$set(this.dialogForm,'buildId',null);
+        this.$set(this.dialogForm,'subjectId',null);
+        this.$set(this,'buildOption',list);
+        this.$set(this,'subjectOption',[]);
+      },
+      //楼栋选中
+      buildSchool(val){
+        laboratorySubRelInfoGetListByFloor({buildId:val}).then(response => {
+          this.$set(this.dialogForm,'subjectId',null);
+          this.$set(this,'subjectOption',response.data);
+        })
+      },
+      //APP选择器
+      terminalAppSelect(){
+        terminalAppSelect({}).then(response => {
+          this.$set(this,'optionListOne',response.data);
+        });
+      },
+      //版本选择器
+      terminalVersionSelect(){
+        terminalVersionSelect({appId:this.dialogForm.appId}).then(response => {
+          this.$set(this,'optionListTwo',response.data);
+          this.$set(this.dialogForm,'versionId',"");
+        });
       },
     },
   }

+ 185 - 0
src/views/iotDevice/appManage/applyUpgradesQuest/index.vue

@@ -0,0 +1,185 @@
+<!-- 应用升级任务列表 -->
+<template>
+  <div class="app-container applyUpgradesQuest">
+    <div class="page-container applyUpgradesQuestPage">
+      <div class="page-form-title-box">
+        <el-form :model="queryParams" class="form-box" ref="queryForm"
+                 :inline="true" style="width:100%;">
+          <el-form-item label="" prop="appName">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.appName"
+              placeholder="app名称"
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="batchNumber">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.batchNumber"
+              placeholder="批次号"
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="appVersion">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.appVersion"
+              placeholder="app版本"
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="deviceName">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.deviceName"
+              placeholder="设备名称"
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="status">
+            <el-select v-model="queryParams.status" placeholder="任务状态" clearable style="width:200px;">
+              <el-option
+                v-for="dict in optionList"
+                :key="dict.code"
+                :label="dict.description"
+                :value="dict.code"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="" prop="terminalType">
+            <el-select v-model="queryParams.terminalType" placeholder="app类型" style="width: 200px">
+              <el-option label="化学品终端" value="aio_chemical"></el-option>
+              <el-option label="电子信息牌" value="aio_infobord"></el-option>
+              <el-option label="学习考试一体" value="aio_exam"></el-option>
+            </el-select>
+          </el-form-item>
+          <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
+          <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
+        </el-form>
+      </div>
+      <div class="page-content-box">
+        <el-table class="table-box" v-loading="loading" border :data="dataList">
+          <el-table-column label="app名称" prop="appName"  show-overflow-tooltip/>
+          <el-table-column label="app版本" prop="appVersion" width="80" show-overflow-tooltip/>
+          <el-table-column label="设备码" prop="deviceCode" width="170" show-overflow-tooltip/>
+          <el-table-column label="设备名称" prop="deviceName" width="170" show-overflow-tooltip/>
+          <el-table-column label="批次号" prop="batchNumber" width="100" show-overflow-tooltip/>
+          <el-table-column label="优先级" prop="priority" width="60" show-overflow-tooltip/>
+          <el-table-column label="包名" prop="startLaunchPackage" width="120" show-overflow-tooltip/>
+          <el-table-column label="app版本" prop="appVersion" width="60" show-overflow-tooltip/>
+          <el-table-column label="app版本" prop="appVersion" width="60" show-overflow-tooltip/>
+          <el-table-column label="状态" prop="status" width="90" show-overflow-tooltip>
+            <template slot-scope="scope">
+              {{scope.row.status=='failed'?'失败':(scope.row.status=='downloaded'?'下载成功':(scope.row.status=='success'?'升级成功':''))}}
+            </template>
+          </el-table-column>
+          <el-table-column label="开始时间" prop="startTime" width="150" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.startTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="结束时间" prop="endTime" width="150" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.endTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="创建时间" prop="createTime" width="150" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.createTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination :page-sizes="[20, 30, 40, 50]"
+                    v-show="total>0"
+                    :total="total"
+                    :page.sync="queryParams.page"
+                    :limit.sync="queryParams.pageSize"
+                    @pagination="getList"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  import {
+    terminalUpgradeWebTaskList,
+    terminalUpgradeWebTaskStatus,
+  } from "@/api/iotDevice/index";
+  export default {
+    name: 'index',
+    data () {
+      return {
+        //页面遮罩
+        loading:false,
+        //下拉列表数据
+        optionList:[],
+        //查询条件
+        queryParams:{
+          page:1,
+          pageSize:20,
+          status:"",
+          appName :"",
+          batchNumber :"",
+          appVersion :"",
+          terminalType :"",
+          deviceName :"",
+        },
+        //列表数据
+        dataList:[],
+        //数据数量
+        total:0,
+      }
+    },
+    created () {
+
+    },
+    mounted () {
+      this.terminalUpgradeWebTaskStatus();
+      this.getList();
+    },
+    methods: {
+      //查询按钮
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      //重置按钮
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          status:"",
+          appName :"",
+          batchNumber :"",
+          appVersion :"",
+          terminalType :"",
+          deviceName :"",
+        });
+        this.getList();
+      },
+      //获取数据列表
+      getList(){
+        this.$set(this,'loading',true);
+        let obj = JSON.parse(JSON.stringify(this.queryParams))
+        terminalUpgradeWebTaskList(obj).then(response => {
+          this.$set(this,'loading',false);
+          this.$set(this,'dataList',response.data.records);
+          this.$set(this,'total',response.data.total);
+        });
+      },
+      terminalUpgradeWebTaskStatus(){
+        terminalUpgradeWebTaskStatus({}).then(response => {
+          this.$set(this,'optionList',response.data);
+        });
+      },
+    },
+  }
+</script>
+<style scoped lang="scss">
+  .applyUpgradesQuest{
+    .applyUpgradesQuestPage{
+
+    }
+  }
+</style>