Эх сурвалжийг харах

Merge branch 'master' of http://218.108.80.158:8081/haojs/alipay-auth-platform-admin into develop

元子 1 жил өмнө
parent
commit
9169535f62

+ 2 - 2
.env.development

@@ -3,5 +3,5 @@ ENV = 'development'
 
 # base api
 # VUE_APP_BASE_API = '/dev-api'
-VUE_APP_BASE_API = 'http://192.168.11.3:8081/hanghui-server-platform'
-# VUE_APP_BASE_API = 'https://tx.hz-hanghui.com:8088/hanghui-server-platform'
+# VUE_APP_BASE_API = 'http://192.168.11.9:8081/hanghui-server-platform'
+VUE_APP_BASE_API = 'https://tx.hz-hanghui.com:8088/hanghui-server-platform'

BIN
dist.rar


+ 71 - 0
src/api/install_task.js

@@ -0,0 +1,71 @@
+import request from "@/utils/request";
+//apk添加-编辑
+export function apkAdd(data) {
+  return request({
+    url: "/api/v1/app/apk/add",
+    method: "post",
+    data,
+  });
+}
+//apk删除
+export function apkDeleted(id) {
+  return request({
+    url: `/api/v1/app/apk/deleted/${id}`,
+    method: "post",
+  });
+}
+//查询apk列表(分页)
+export function apkpage(data) {
+  return request({
+    url: "/api/v1/app/apk/page",
+    method: "post",
+    data,
+  });
+}
+//apk打包上传file
+export function apkUpload(data) {
+  return request({
+    url: "/api/v1/app/apk/upload",
+    method: "post",
+    data,
+  });
+}
+//添加任务
+export function taskAdd(data) {
+  return request({
+    url: "/api/v1/app/task/add",
+    method: "post",
+    data,
+  });
+}
+//取消任务
+export function taskCancel(id) {
+  return request({
+    url: `/api/v1/app/task/cancel/${id}`,
+    method: "post",
+  });
+}
+//查询安装任务列表(分页)
+export function taskPage(data) {
+  return request({
+    url: `/api/v1/app/task/page`,
+    method: "post",
+    data,
+  });
+}
+//获取安装状态列表
+export function taskStatus(data) {
+  return request({
+    url: `/api/v1/app/task/status/query`,
+    method: "post",
+    data,
+  });
+}
+//查询apk列表
+export function apkList(data) {
+  return request({
+    url: `/api/v1/app/apk/list`,
+    method: "post",
+    data,
+  });
+}

BIN
src/assets/default-img-home1.png


+ 1 - 1
src/components/Pagination/index.vue

@@ -53,7 +53,7 @@ export default {
     hidden: {
       type: Boolean,
       default: false
-    }
+    },
   },
   computed: {
     currentPage: {

+ 30 - 106
src/router/index.js

@@ -148,112 +148,36 @@ export const constantRoutes = [
       }
     ]
   },
-
-  // {
-  //   path: '/example',
-  //   component: Layout,
-  //   redirect: '/example/table',
-  //   name: 'Example',
-  //   meta: { title: 'Example', icon: 'el-icon-s-help' },
-  //   children: [
-  //     {
-  //       path: 'table',
-  //       name: 'Table',
-  //       component: () => import('@/views/table/index'),
-  //       meta: { title: 'Table', icon: 'table' }
-  //     },
-  //     {
-  //       path: 'tree',
-  //       name: 'Tree',
-  //       component: () => import('@/views/tree/index'),
-  //       meta: { title: 'Tree', icon: 'tree' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/form',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       name: 'Form',
-  //       component: () => import('@/views/form/index'),
-  //       meta: { title: 'Form', icon: 'form' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/nested',
-  //   component: Layout,
-  //   redirect: '/nested/menu1',
-  //   name: 'Nested',
-  //   meta: {
-  //     title: 'Nested',
-  //     icon: 'nested'
-  //   },
-  //   children: [
-  //     {
-  //       path: 'menu1',
-  //       component: () => import('@/views/nested/menu1/index'), // Parent router-view
-  //       name: 'Menu1',
-  //       meta: { title: 'Menu1' },
-  //       children: [
-  //         {
-  //           path: 'menu1-1',
-  //           component: () => import('@/views/nested/menu1/menu1-1'),
-  //           name: 'Menu1-1',
-  //           meta: { title: 'Menu1-1' }
-  //         },
-  //         {
-  //           path: 'menu1-2',
-  //           component: () => import('@/views/nested/menu1/menu1-2'),
-  //           name: 'Menu1-2',
-  //           meta: { title: 'Menu1-2' },
-  //           children: [
-  //             {
-  //               path: 'menu1-2-1',
-  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
-  //               name: 'Menu1-2-1',
-  //               meta: { title: 'Menu1-2-1' }
-  //             },
-  //             {
-  //               path: 'menu1-2-2',
-  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
-  //               name: 'Menu1-2-2',
-  //               meta: { title: 'Menu1-2-2' }
-  //             }
-  //           ]
-  //         },
-  //         {
-  //           path: 'menu1-3',
-  //           component: () => import('@/views/nested/menu1/menu1-3'),
-  //           name: 'Menu1-3',
-  //           meta: { title: 'Menu1-3' }
-  //         }
-  //       ]
-  //     },
-  //     {
-  //       path: 'menu2',
-  //       component: () => import('@/views/nested/menu2/index'),
-  //       name: 'Menu2',
-  //       meta: { title: 'menu2' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: 'external-link',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
-  //       meta: { title: 'External Link', icon: 'link' }
-  //     }
-  //   ]
-  // },
-
+  {
+    path: '/installationPackage',
+    component: Layout,
+    redirect: '/installationPackage/index',
+    name: 'installationPackage',
+    meta: { title: '安装包列表', icon: 'el-icon-folder-opened' },
+    children: [
+      {
+        path: 'index',
+        name: 'index',
+        component: () => import('@/views/installationPackage/index'),
+        meta: { title: '安装包列表' }
+      }
+    ]
+  },
+  {
+    path: '/installationTask',
+    component: Layout,
+    redirect: '/installationTask/index',
+    name: 'installationTask',
+    meta: { title: '安装任务列表', icon: 'el-icon-document' },
+    children: [
+      {
+        path: 'index',
+        name: 'index',
+        component: () => import('@/views/installationTask/index'),
+        meta: { title: '安装任务列表' }
+      }
+    ]
+  },
   // 404 page must be placed at the end !!!
   { path: '*', redirect: '/404', hidden: true }
 ]

+ 49 - 40
src/utils/request.js

@@ -1,85 +1,94 @@
-import axios from 'axios'
-import { MessageBox, Message } from 'element-ui'
-import store from '@/store'
-import { getToken } from '@/utils/auth'
+import axios from "axios";
+import { MessageBox, Message } from "element-ui";
+import store from "@/store";
+import { getToken } from "@/utils/auth";
 
 // create an axios instance
 const service = axios.create({
   baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
   // withCredentials: true, // send cookies when cross-domain requests
-  timeout: 6000 // request timeout
-})
+  timeout: 5 * 60 * 6000, // request timeout
+});
 
 // request interceptor
 service.interceptors.request.use(
-  config => {
+  (config) => {
     // do something before request is sent
 
     if (store.getters.token) {
       // let each request carry token
       // ['X-Token'] is a custom headers key
       // please modify it according to the actual situation
-      config.headers['Authorization'] = getToken()
+      config.headers["Authorization"] = getToken();
     }
-    return config
+    return config;
   },
-  error => {
+  (error) => {
     // do something with request error
-    console.log(error) // for debug
-    return Promise.reject(error)
+    console.log(error); // for debug
+    return Promise.reject(error);
   }
-)
+);
 
 // response interceptor
 service.interceptors.response.use(
   /**
    * If you want to get http information such as headers or status
    * Please return  response => response
-  */
+   */
 
   /**
    * Determine the request status by custom code
    * Here is just an example
    * You can also judge the status by HTTP Status Code
    */
-  response => {
-    const res = response.data
+  (response) => {
+    const res = response.data;
 
     // if the custom code is not 20000, it is judged as an error.
     if (res.code !== 200) {
       Message({
-        message: res.msg || 'Error',
-        type: 'error',
-        duration: 3 * 1000
-      })
+        message: res.msg || "Error",
+        type: "error",
+        duration: 3 * 1000,
+      });
 
       // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
-      if (res.code === 10001 || res.code === 50008 || res.code === 50012 || res.code === 50014) {
+      if (
+        res.code === 10001 ||
+        res.code === 50008 ||
+        res.code === 50012 ||
+        res.code === 50014
+      ) {
         // to re-login
-        MessageBox.confirm('您的账号登录已过期,您可以取消以留在此页面,或重新登录', '重新登录', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(() => {
-          store.dispatch('user/resetToken').then(() => {
-            location.reload()
-          })
-        })
+        MessageBox.confirm(
+          "您的账号登录已过期,您可以取消以留在此页面,或重新登录",
+          "重新登录",
+          {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+          }
+        ).then(() => {
+          store.dispatch("user/resetToken").then(() => {
+            location.reload();
+          });
+        });
       }
-      return Promise.reject(new Error(res.msg || 'Error'))
+      return Promise.reject(new Error(res.msg || "Error"));
     } else {
-      return res
+      return res;
     }
   },
-  error => {
-    console.log('err' + error) // for debug
+  (error) => {
+    console.log("err" + error); // for debug
     Message({
       message: error.msg,
-      type: 'error',
-      duration: 5 * 1000
-    })
-    return Promise.reject(error)
+      type: "error",
+      duration: 5 * 1000,
+    });
+    return Promise.reject(error);
   }
-)
+);
 
-export default service
+export default service;

+ 1 - 1
src/views/device/add.vue

@@ -21,7 +21,7 @@ export default {
   },
   methods: {
     back() {
-      this.$router.go(-1)
+      this.$router.back()
     }
   }
 }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 539 - 157
src/views/device/components/edit.vue


+ 397 - 235
src/views/device/index.vue

@@ -1,157 +1,284 @@
 <template>
   <div class="app-container">
-    <!-- <addModal ref="addModel" @success="modalSuccess" /> -->
-    <uploadModal ref="uploadModal" @finish="modalSuccess(false)" />
-    <div class="search-layout" style="margin-bottom: 0px;margin-top: -10px;">
-      <el-input v-model="form.sn" placeholder="设备sn" style="width: 256px;" class="filter-item" />
-      <el-input v-model="form.company" placeholder="公司名" style="width: 256px;" class="filter-item" />
-      <el-select v-model="form.tenantId" class="filter-item" placeholder="请选择服务商平台名称" clearable filterable>
-        <el-option v-for="(item, index) in merchantLists" :key="index" :label="item.name" :value="item.id" />
-      </el-select>
-      <el-select v-model="form.sceneId" class="filter-item" placeholder="请选择场景" clearable>
-        <el-option v-for="(item, index) in sceneLists" :key="index" :label="item.sceneName" :value="item.id" />
-      </el-select>
-      <el-select v-model="form.mode" class="filter-item" placeholder="请选择模式" clearable>
-        <el-option v-for="(item, index) in modeLists" :key="index" :label="item.value" :value="item.key" />
-      </el-select>
-      <el-select v-model="form.userLibId" class="filter-item" placeholder="请选择⽤户库" clearable>
-        <el-option v-for="(item, index) in userlibLists" :key="index" :label="item.userLibName" :value="item.id" />
-      </el-select>
-      <el-select v-model="form.status" class="filter-item" placeholder="请选择状态" clearable>
-        <el-option v-for="(item, index) in statusLists" :key="index" :label="item.value" :value="item.key" />
-      </el-select>
+    <div v-if="isShowUpdate">
+      <div class="head">
+        编辑设备
+        <el-button
+          type="primary"
+          size="mini"
+          style="margin-left: 20px"
+          @click="back"
+          >返回</el-button
+        >
+      </div>
+      <edit-device
+        :obj="updateData"
+        style="margin-left: 40px"
+        @finish="back"
+        @back="back"
+      />
     </div>
-    <div class="search-layout">
-      <el-button class="filter-item" style="margin-right: 0;" type="primary" icon="el-icon-search" @click="query">
-        搜索
-      </el-button>
-      <el-button class="filter-item" style="margin-right: 0;" type="primary" icon="el-icon-plus" @click="handleCreate">
-        添加
-      </el-button>
-      <el-button type="primary" icon="el-icon-download" @click="download">下载模板</el-button>
-      <el-button type="primary" plain @click="addOrUpdate">批量导入</el-button>
-    </div>
-    <el-table
-      v-loading="tableLoading"
-      :data="tableData"
-      element-loading-text="加载中..."
-      border
-      fit
-      highlight-current-row
-    >
-      <el-table-column align="center" label="序号" width="95">
-        <template slot-scope="scope">
-          {{ ((pagination.current - 1) * pagination.pageSize) + (scope.$index + 1) }}
-        </template>
-      </el-table-column>
-      <el-table-column label="设备sn">
-        <template slot-scope="scope">
-          {{ scope.row.sn }}
-        </template>
-      </el-table-column>
-      <el-table-column label="公司名称">
-        <template slot-scope="scope">
-          {{ scope.row.company }}
-        </template>
-      </el-table-column>
-      <el-table-column label="服务商平台名称">
-        <template slot-scope="scope">
-          {{ scope.row.tenantName }}
-        </template>
-      </el-table-column>
-      <!-- <el-table-column label="设备appId">
+    <div v-show="!isShowUpdate">
+      <!-- <addModal ref="addModel" @success="modalSuccess" /> -->
+      <uploadModal ref="uploadModal" @finish="modalSuccess(false)" />
+      <div class="search-layout" style="margin-bottom: 0px; margin-top: -10px">
+        <el-input
+          v-model="form.sn"
+          placeholder="设备sn"
+          style="width: 256px"
+          class="filter-item"
+        />
+        <el-input
+          v-model="form.company"
+          placeholder="公司名"
+          style="width: 256px"
+          class="filter-item"
+        />
+        <el-select
+          v-model="form.tenantId"
+          class="filter-item"
+          placeholder="请选择服务商平台名称"
+          clearable
+          filterable
+        >
+          <el-option
+            v-for="(item, index) in merchantLists"
+            :key="index"
+            :label="item.name"
+            :value="item.id"
+          />
+        </el-select>
+        <el-select
+          v-model="form.sceneId"
+          class="filter-item"
+          placeholder="请选择场景"
+          clearable
+        >
+          <el-option
+            v-for="(item, index) in sceneLists"
+            :key="index"
+            :label="item.sceneName"
+            :value="item.id"
+          />
+        </el-select>
+        <el-select
+          v-model="form.mode"
+          class="filter-item"
+          placeholder="请选择模式"
+          clearable
+        >
+          <el-option
+            v-for="(item, index) in modeLists"
+            :key="index"
+            :label="item.value"
+            :value="item.key"
+          />
+        </el-select>
+        <el-select
+          v-model="form.userLibId"
+          class="filter-item"
+          placeholder="请选择⽤户库"
+          clearable
+        >
+          <el-option
+            v-for="(item, index) in userlibLists"
+            :key="index"
+            :label="item.userLibName"
+            :value="item.id"
+          />
+        </el-select>
+        <el-select
+          v-model="form.status"
+          class="filter-item"
+          placeholder="请选择状态"
+          clearable
+        >
+          <el-option
+            v-for="(item, index) in statusLists"
+            :key="index"
+            :label="item.value"
+            :value="item.key"
+          />
+        </el-select>
+      </div>
+      <div class="search-layout">
+        <el-button
+          class="filter-item"
+          style="margin-right: 0"
+          type="primary"
+          icon="el-icon-search"
+          @click="query(1)"
+        >
+          搜索
+        </el-button>
+        <el-button
+          class="filter-item"
+          style="margin-right: 0"
+          type="primary"
+          icon="el-icon-plus"
+          @click="handleCreate"
+        >
+          添加
+        </el-button>
+        <el-button type="primary" icon="el-icon-download" @click="download"
+          >下载模板</el-button
+        >
+        <el-button type="primary" plain @click="addOrUpdate"
+          >批量导入</el-button
+        >
+      </div>
+      <el-table
+        v-loading="tableLoading"
+        :data="tableData"
+        element-loading-text="加载中..."
+        border
+        fit
+        highlight-current-row
+      >
+        <el-table-column align="center" label="序号" width="95">
+          <template slot-scope="scope">
+            {{
+              (pagination.page - 1) * pagination.pageSize +
+              (scope.$index + 1)
+            }}
+          </template>
+        </el-table-column>
+        <el-table-column label="设备sn">
+          <template slot-scope="scope">
+            {{ scope.row.sn }}
+          </template>
+        </el-table-column>
+        <el-table-column label="公司名称">
+          <template slot-scope="scope">
+            {{ scope.row.company }}
+          </template>
+        </el-table-column>
+        <el-table-column label="服务商平台名称">
+          <template slot-scope="scope">
+            {{ scope.row.tenantName }}
+          </template>
+        </el-table-column>
+        <!-- <el-table-column label="设备appId">
         <template slot-scope="scope">
           {{ scope.row.tenantMachineAppId }}
         </template>
       </el-table-column> -->
-      <!-- <el-table-column label="商户appId">
+        <!-- <el-table-column label="商户appId">
         <template slot-scope="scope">
           {{ scope.row.tenantServiceAppId }}
         </template>
       </el-table-column> -->
-      <!-- <el-table-column label="商户平台地址">
+        <!-- <el-table-column label="商户平台地址">
         <template slot-scope="scope">
           {{ scope.row.tenantServiceAddress }}
         </template>
       </el-table-column> -->
-      <el-table-column label="场景名称">
-        <template slot-scope="scope">
-          {{ scope.row.sceneName }}
-        </template>
-      </el-table-column>
-      <el-table-column label="模式">
-        <template slot-scope="scope">
-          {{ scope.row.mode | modeFilter }}
-        </template>
-      </el-table-column>
-      <el-table-column label="⽤⼾库名称">
-        <template slot-scope="scope">
-          {{ scope.row.userLibName }}
-        </template>
-      </el-table-column>
-      <el-table-column label="状态" align="center" class-name="status-col" width="120">
-        <template slot-scope="{row}">
-          <el-tag :type="row.status | statusFilter">
-            {{ row.status | statusFilterStr }}
-          </el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center" width="250" class-name="small-padding fixed-width">
-        <template slot-scope="{row,$index}">
-          <el-button type="primary" size="mini" @click="handleUpdate(row)">
-            编辑
-          </el-button>
-          <el-button size="mini" type="danger" @click="handleDelete(row, $index)">
-            删除
-          </el-button>
-          <template>
-            <el-button v-if="row.status" size="mini" type="danger" @click="handleAuth(row, false)">取消授权</el-button>
-            <el-button v-else size="mini" type="danger" @click="handleAuth(row, true)">获取授权</el-button>
+        <el-table-column label="场景名称">
+          <template slot-scope="scope">
+            {{ scope.row.sceneName }}
           </template>
-        </template>
-      </el-table-column>
-    </el-table>
-    <pagination
-      :total="pagination.total"
-      :page.sync="pagination.current"
-      :limit.sync="pagination.pageSize"
-      :page-sizes="pagination.pageSizeOptions"
-      :layout="pagination.layout"
-      @pagination="handleSizeChange"
-    />
+        </el-table-column>
+        <el-table-column label="模式">
+          <template slot-scope="scope">
+            {{ scope.row.mode | modeFilter }}
+          </template>
+        </el-table-column>
+        <el-table-column label="⽤⼾库名称">
+          <template slot-scope="scope">
+            {{ scope.row.userLibName }}
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="状态"
+          align="center"
+          class-name="status-col"
+          width="120"
+        >
+          <template slot-scope="{ row }">
+            <el-tag :type="row.status | statusFilter">
+              {{ row.status | statusFilterStr }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="操作"
+          align="center"
+          width="250"
+          class-name="small-padding fixed-width"
+        >
+          <template slot-scope="{ row, $index }">
+            <el-button type="primary" size="mini" @click="handleUpdate(row)">
+              编辑
+            </el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(row, $index)"
+            >
+              删除
+            </el-button>
+            <template>
+              <el-button
+                v-if="row.status"
+                size="mini"
+                type="danger"
+                @click="handleAuth(row, false)"
+                >取消授权</el-button
+              >
+              <el-button
+                v-else
+                size="mini"
+                type="danger"
+                @click="handleAuth(row, true)"
+                >获取授权</el-button
+              >
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        :total="pagination.total"
+        :page.sync="pagination.page"
+        :limit.sync="pagination.pageSize"
+        :page-sizes="pagination.pageSizeOptions"
+        :layout="pagination.layout"
+        @pagination="handleSizeChange"
+      />
+    </div>
   </div>
 </template>
 
 <script>
+import EditDevice from "./components/edit";
 // import AddModal from './modal/AddModal.vue'
-import UploadModal from './modal/UploadModal.vue'
-import tableMixins from '@/mixins/tableMixins'
-import { getList, deleteById, autoById, autoCancelById } from '@/api/device'
-import { getAllList as getMerchantList } from '@/api/merchant'
-import { getList as getSceneList } from '@/api/scene'
-import { getList as getUserlibList } from '@/api/userlib'
-import Pagination from '@/components/Pagination'
+import UploadModal from "./modal/UploadModal.vue";
+import tableMixins from "@/mixins/tableMixins";
+import { getList, deleteById, autoById, autoCancelById } from "@/api/device";
+import { getAllList as getMerchantList } from "@/api/merchant";
+import { getList as getSceneList } from "@/api/scene";
+import { getList as getUserlibList } from "@/api/userlib";
+import Pagination from "@/components/Pagination";
 
 export default {
-  components: { Pagination, UploadModal },
+  components: { Pagination, UploadModal, EditDevice },
   filters: {
     statusFilter(status) {
-      return status ? 'success' : 'info'
+      return status ? "success" : "info";
     },
     statusFilterStr(status) {
-      return status ? '已授权' : '未授权'
+      return status ? "已授权" : "未授权";
     },
     modeFilter(value) {
-      if (value === 'public') {
-        return '开放'
-      } else if (value === 'close') {
-        return '封闭'
-      } else if (value === 'elasticity') {
-        return '弹性'
+      if (value === "public") {
+        return "开放";
+      } else if (value === "close") {
+        return "封闭";
+      } else if (value === "elasticity") {
+        return "弹性";
       } else {
-        return ''
+        return "";
       }
-    }
+    },
   },
   mixins: [tableMixins],
   data() {
@@ -161,69 +288,80 @@ export default {
       userlibLists: [],
       modeLists: [
         {
-          key: 'public',
-          value: '开放'
+          key: "public",
+          value: "开放",
         },
         {
-          key: 'close',
-          value: '封闭'
+          key: "close",
+          value: "封闭",
         },
         {
-          key: 'elasticity',
-          value: '弹性'
-        }
+          key: "elasticity",
+          value: "弹性",
+        },
       ],
       statusLists: [
         {
           key: false,
-          value: '未授权'
+          value: "未授权",
         },
         {
           key: true,
-          value: '已授权'
-        }
+          value: "已授权",
+        },
       ],
-      form: {}
-    }
+      form: {},
+      isShowUpdate: false,
+      updateData: {},
+      pagination:{
+        page:1,
+        current:1,
+      }
+    };
   },
   methods: {
     initData() {
-      this.getTableList()
-      this.getMerchantList()
-      this.getSceneList()
-      this.getUserlibList()
+      this.getTableList();
+      this.getMerchantList();
+      this.getSceneList();
+      this.getUserlibList();
     },
     getMerchantList() {
-      getMerchantList().then(res => {
-        this.merchantLists = res.data
-      })
+      getMerchantList().then((res) => {
+        this.merchantLists = res.data;
+      });
     },
     getSceneList() {
-      getSceneList({ pageNumber: 1, pageSize: 1000 }).then(res => {
-        this.sceneLists = res.data.records
-      })
+      getSceneList({ pageNumber: 1, pageSize: 1000 }).then((res) => {
+        this.sceneLists = res.data.records;
+      });
     },
     getUserlibList() {
-      getUserlibList({ pageNumber: 1, pageSize: 1000 }).then(res => {
-        this.userlibLists = res.data.records
-      })
+      getUserlibList({ pageNumber: 1, pageSize: 1000 }).then((res) => {
+        this.userlibLists = res.data.records;
+      });
     },
     // 获取表格数据
     async getTableList() {
-      this.tableLoading = true
+      this.pagination.current=this.pagination.page
+      this.tableLoading = true;
       try {
-        const result = await getList(this.getFilterParams())
-        this.setDataList(result.data)
+        const result = await getList(this.getFilterParams());
+        this.setDataList(result.data);
       } catch (e) {
-        console.log(e)
+        console.log(e);
       } finally {
-        this.tableLoading = false
+        this.tableLoading = false;
       }
     },
     // 获取筛选信息
-    query() {
-      this.clearPageParams()
-      this.getTableList()
+    query(type) {
+      if(type){
+        this.pagination.page=1
+        this.pagination.current=1
+      }
+      this.clearPageParams();
+      this.getTableList();
     },
     // 增加筛选条件
     transformFilterForm() {
@@ -234,121 +372,145 @@ export default {
         sceneId: this.form.sceneId || null,
         mode: this.form.mode || null,
         userLibId: this.form.userLibId || null,
-        status: this.form.status === '' ? null : this.form.status
-      }
+        status: this.form.status === "" ? null : this.form.status,
+      };
     },
     // 下载模板
     download() {
-      window.location.href = process.env.VUE_APP_BASE_API + '/static/deviceListExcel.xlsx'
+      window.location.href =
+        process.env.VUE_APP_BASE_API + "/static/deviceListExcel.xlsx";
     },
     addOrUpdate() {
-      this.$refs.uploadModal.open()
+      this.$refs.uploadModal.open();
     },
     modalSuccess(isEdit) {
       if (!isEdit) {
-        this.clearPageParams()
+        this.clearPageParams();
       }
-      this.getTableList()
+      this.getTableList();
     },
     handleCreate() {
       // this.$refs.addModel.open()
-      this.$router.push({ path: '/device/add' })
+      this.$router.push({ path: "/device/add" });
     },
     handleUpdate(row) {
+      this.isShowUpdate = true;
+      this.updateData = JSON.parse(JSON.stringify(row));
       // this.$refs.addModel.open(Object.assign({}, row))
-      this.$router.push({ path: '/device/change', query: { obj: encodeURIComponent(JSON.stringify(row)) }})
+      // this.$router.push({
+      //   path: "/device/change",
+      //   query: { obj: encodeURIComponent(JSON.stringify(row)) },
+      // });
+    },
+    back() {
+      this.isShowUpdate=false
+      this.query()
     },
     handleAuth(row, needAuth) {
-      const that = this
-      this.$confirm(`确定 ${needAuth ? '获取授权' : '取消授权'} 操作吗?`, '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        showClose: false,
-        type: 'warning',
-        beforeClose: async(action, instance, done) => {
-          if (action === 'confirm') {
-            instance.confirmButtonLoading = true
-            instance.cancelButtonLoading = true
-            instance.confirmButtonText = '提交中...'
-            try {
-              if (needAuth) {
-                await autoById(row.id)
-              } else {
-                await autoCancelById(row.id)
+      const that = this;
+      this.$confirm(
+        `确定 ${needAuth ? "获取授权" : "取消授权"} 操作吗?`,
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          showClose: false,
+          type: "warning",
+          beforeClose: async (action, instance, done) => {
+            if (action === "confirm") {
+              instance.confirmButtonLoading = true;
+              instance.cancelButtonLoading = true;
+              instance.confirmButtonText = "提交中...";
+              try {
+                if (needAuth) {
+                  await autoById(row.id);
+                } else {
+                  await autoCancelById(row.id);
+                }
+                this.$message({
+                  type: "success",
+                  message: "操作成功!",
+                });
+                that.getTableList();
+              } catch (e) {
+                // this.$message({
+                //   type: 'error',
+                //   message: '删除失败!'
+                // })
+              } finally {
+                done();
+                setTimeout(() => {
+                  instance.confirmButtonLoading = false;
+                  instance.cancelButtonLoading = false;
+                }, 300);
               }
-              this.$message({
-                type: 'success',
-                message: '操作成功!'
-              })
-              that.getTableList()
-            } catch (e) {
-              // this.$message({
-              //   type: 'error',
-              //   message: '删除失败!'
-              // })
-            } finally {
-              done()
-              setTimeout(() => {
-                instance.confirmButtonLoading = false
-                instance.cancelButtonLoading = false
-              }, 300)
+            } else {
+              done();
             }
-          } else {
-            done()
-          }
+          },
         }
-      }).then(() => {}).catch(() => {})
+      )
+        .then(() => {})
+        .catch(() => {});
     },
     handleDelete(row, index) {
-      const that = this
-      this.$confirm('确定删除吗?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
+      const that = this;
+      this.$confirm("确定删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
         showClose: false,
-        type: 'warning',
-        beforeClose: async(action, instance, done) => {
-          if (action === 'confirm') {
-            instance.confirmButtonLoading = true
-            instance.cancelButtonLoading = true
-            instance.confirmButtonText = '提交中...'
+        type: "warning",
+        beforeClose: async (action, instance, done) => {
+          if (action === "confirm") {
+            instance.confirmButtonLoading = true;
+            instance.cancelButtonLoading = true;
+            instance.confirmButtonText = "提交中...";
             try {
-              await deleteById(row.id)
+              await deleteById(row.id);
               this.$message({
-                type: 'success',
-                message: '删除成功!'
-              })
-              that.getTableList()
+                type: "success",
+                message: "删除成功!",
+              });
+              that.getTableList();
             } catch (e) {
               // this.$message({
               //   type: 'error',
               //   message: '删除失败!'
               // })
             } finally {
-              done()
+              done();
               setTimeout(() => {
-                instance.confirmButtonLoading = false
-                instance.cancelButtonLoading = false
-              }, 300)
+                instance.confirmButtonLoading = false;
+                instance.cancelButtonLoading = false;
+              }, 300);
             }
           } else {
-            done()
+            done();
           }
-        }
-      }).then(() => {}).catch(() => {})
-    }
-  }
-}
+        },
+      })
+        .then(() => {})
+        .catch(() => {});
+    },
+  },
+};
 </script>
 
 <style scoped>
-  .search-layout {
-    margin-bottom: 20px;
-  }
-  .search-layout .filter-item {
-    margin-right: 20px;
-    margin-top: 10px;
-  }
-  .search-layout .filter-item:last-of-type {
-    margin-right: 0;
-  }
+.search-layout {
+  margin-bottom: 20px;
+}
+.search-layout .filter-item {
+  margin-right: 20px;
+  margin-top: 10px;
+}
+.search-layout .filter-item:last-of-type {
+  margin-right: 0;
+}
+.head {
+  margin-left: 16px;
+  font-weight: 600;
+  font-size: 18px;
+  color: #333333;
+}
 </style>

+ 1 - 0
src/views/device/modal/AddModal.vue

@@ -119,6 +119,7 @@ export default {
   },
   methods: {
     open(obj) {
+      console.log(obj);
       this.visible = true
       this.submitLoading = false
       this.$nextTick(() => {

+ 230 - 0
src/views/installationPackage/index.vue

@@ -0,0 +1,230 @@
+<template>
+  <div class="app-container">
+    <addModal ref="addModel" @success="modalSuccess" />
+    <div style="margin-bottom: 20px">
+      <el-button
+        class="filter-item"
+        type="primary"
+        icon="el-icon-plus"
+        @click="handleCreate"
+      >
+        上传安装包
+      </el-button>
+      <el-input
+        clearable
+        v-model="form.apkTitle"
+        placeholder="安装包名称"
+        class="filter-item wid"
+      />
+      <el-input
+        clearable
+        v-model="form.apkVersion"
+        placeholder="版本号"
+        class="filter-item wid"
+      />
+      <el-date-picker
+        v-model="form.startTime"
+        type="datetime"
+        placeholder="起始时间"
+        value-format="yyyy-MM-dd HH:mm:ss"
+        class="filter-item wid"
+      >
+      </el-date-picker>
+      <el-date-picker
+        v-model="form.endTime"
+        type="datetime"
+        placeholder="结束时间"
+        value-format="yyyy-MM-dd HH:mm:ss"
+        class="filter-item wid"
+      >
+      </el-date-picker>
+      <el-button
+        class="filter-item"
+        type="primary"
+        style="margin-left: 10px"
+        icon="el-icon-search"
+        @click="query"
+      >
+        搜索
+      </el-button>
+    </div>
+    <el-table
+      v-loading="tableLoading"
+      :data="tableData"
+      element-loading-text="加载中..."
+      border
+      fit
+      highlight-current-row
+    >
+      <el-table-column align="center" label="序号" width="95">
+        <template slot-scope="scope">
+          {{
+            (pagination.current - 1) * pagination.pageSize + (scope.$index + 1)
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="安装包名称">
+        <template slot-scope="scope">
+          {{ scope.row.apkTitle }}
+        </template>
+      </el-table-column>
+      <el-table-column label="版本号">
+        <template slot-scope="scope">
+          {{ scope.row.apkVersion }}
+        </template>
+      </el-table-column>
+      <el-table-column label="安装包地址">
+        <template slot-scope="scope">
+          {{ scope.row.apkPath }}
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间">
+        <template slot-scope="scope">
+          {{ scope.row.createTime }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="操作"
+        align="center"
+        width="180"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="{ row, $index }">
+          <el-button type="primary" size="mini" @click="handleUpdate(row)">
+            编辑
+          </el-button>
+          <el-button
+            size="mini"
+            type="danger"
+            @click="handleDelete(row, $index)"
+          >
+            删除
+          </el-button>
+          <!-- <el-button
+            size="mini"
+            type="warning"
+            @click="cancelHandle(row, false)"
+            >取消</el-button
+          > -->
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      :total="pagination.total"
+      :page.sync="pagination.current"
+      :limit.sync="pagination.pageSize"
+      :page-sizes="pagination.pageSizeOptions"
+      :layout="pagination.layout"
+      @pagination="handleSizeChange"
+    />
+  </div>
+</template>
+
+<script>
+import AddModal from "./modal/AddModal.vue";
+import tableMixins from "@/mixins/tableMixins";
+import { apkpage, apkDeleted } from "@/api/install_task";
+import Pagination from "@/components/Pagination";
+
+export default {
+  components: { Pagination, AddModal },
+  filters: {
+    statusFilter(status) {
+      return status ? "success" : "info";
+    },
+    statusFilterStr(status) {
+      return status ? "已启用" : "已停用";
+    },
+  },
+  mixins: [tableMixins],
+  data() {
+    return {
+      form: {},
+    };
+  },
+  methods: {
+    initData() {
+      this.getTableList();
+    },
+    // 获取表格数据
+    async getTableList() {
+      this.tableLoading = true;
+      try {
+        const result = await apkpage(this.getFilterParams());
+        this.setDataList(result.data);
+      } catch (e) {
+        console.log(e);
+      } finally {
+        this.tableLoading = false;
+      }
+    },
+    // 获取筛选信息
+    query() {
+      this.clearPageParams();
+      this.getTableList();
+    },
+    // 增加筛选条件
+    transformFilterForm() {
+      return {
+        apkTitle: this.form.apkTitle || null,
+        apkVersion: this.form.apkVersion || null,
+        startTime: this.form.startTime || null,
+        endTime: this.form.endTime || null,
+      };
+    },
+    modalSuccess(isEdit) {
+      if (!isEdit) {
+        this.clearPageParams();
+      }
+      this.getTableList();
+    },
+    handleCreate() {
+      this.$refs.addModel.open();
+    },
+    handleUpdate(row) {
+      this.$refs.addModel.open(Object.assign({}, row));
+    },
+    handleDelete(row, index) {
+      const that = this;
+      this.$confirm("确定删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        showClose: false,
+        type: "warning",
+        beforeClose: async (action, instance, done) => {
+          if (action === "confirm") {
+            instance.confirmButtonLoading = true;
+            instance.cancelButtonLoading = true;
+            instance.confirmButtonText = "提交中...";
+            try {
+              await apkDeleted(row.id);
+              this.$message({
+                type: "success",
+                message: "删除成功!",
+              });
+              that.getTableList();
+            } catch (e) {
+            } finally {
+              done();
+              setTimeout(() => {
+                instance.confirmButtonLoading = false;
+                instance.cancelButtonLoading = false;
+              }, 300);
+            }
+          } else {
+            done();
+          }
+        },
+      })
+        .then(() => {})
+        .catch(() => {});
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.wid {
+  width: 200px;
+  margin-left: 10px;
+}
+</style>

+ 202 - 0
src/views/installationPackage/modal/AddModal.vue

@@ -0,0 +1,202 @@
+// 添加/修改授权
+<template>
+  <el-dialog
+    :title="isEdit ? '编辑安装包' : '上传安装包'"
+    width="700px"
+    :visible.sync="visible"
+    :destroy-on-close="false"
+    :close-on-click-modal="false"
+    :center="true"
+  >
+    <el-form
+      ref="form"
+      :rules="rules"
+      :model="form"
+      label-position="left"
+      label-width="120px"
+    >
+      <el-form-item label="安装包名称" prop="apkTitle">
+        <el-input v-model="form.apkTitle" placeholder="请输入安装包名称" />
+      </el-form-item>
+      <el-form-item label="安装包版本号" prop="apkVersion">
+        <el-input v-model="form.apkVersion" placeholder="请输入安装包版本号" />
+      </el-form-item>
+      <el-form-item label="上传安装包" prop="apkPath">
+        <a href="javascript:;" class="file" v-loading="uploadLoading"
+          >上传<input
+            type="file"
+            name="file"
+            ref="file"
+            @change="uploadFile($event)"
+        /></a>
+        <span class="m-l" v-if="fileaName">{{ fileaName }}</span>
+        <!-- 进度条 -->
+        <el-progress v-if="percentage" :percentage="percentage"></el-progress>
+        <p></p>
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="visible = false"> 取消 </el-button>
+      <el-button
+        type="primary"
+        :loading="submitLoading"
+        @click="submit"
+        :disabled="uploadLoading"
+      >
+        确定
+      </el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { apkAdd } from "@/api/install_task";
+import { androidApk } from "@/api/ordinary_user";
+import request from "@/utils/request";
+export default {
+  data() {
+    return {
+      form: {
+        apkTitle: null,
+        apkVersion: null,
+        apkPath: "",
+      },
+      rules: {
+        apkTitle: [
+          {
+            required: true,
+            message: "不能为空!",
+            trigger: "blur",
+          },
+        ],
+        apkVersion: [
+          {
+            required: true,
+            message: "不能为空!",
+            trigger: "blur",
+          },
+        ],
+        apkPath: [
+          {
+            required: true,
+            message: "不能为空!",
+          },
+        ],
+      },
+      visible: false,
+      submitLoading: false,
+      isEdit: false,
+      fileaName: "",
+      percentage: 0, //进度条
+      uploadLoading: false,
+    };
+  },
+  created() {},
+  methods: {
+    open(obj) {
+      this.visible = true;
+      this.submitLoading = false;
+      this.percentage = 0;
+      this.fileaName = "";
+      this.$nextTick(() => {
+        this.$refs.form.resetFields();
+        if (obj && Object.keys(obj).length > 0) {
+          this.form = obj;
+          this.isEdit = true;
+        } else {
+          this.form = {};
+          this.isEdit = false;
+        }
+      });
+    },
+    submit(e) {
+      console.log(this.form);
+      e.preventDefault();
+      this.$refs.form.validate(async (valid) => {
+        if (!valid) {
+          return false;
+        }
+        if (this.submitLoading) {
+          return;
+        }
+        this.submitLoading = true;
+        try {
+          await apkAdd(this.form);
+          this.visible = false;
+          this.$emit("success", this.isEdit);
+        } catch (e) {
+          console.info("add", e);
+        } finally {
+          this.submitLoading = false;
+        }
+      });
+    },
+    async uploadFile(e) {
+      let that = this;
+      that.uploadLoading = true;
+      this.fileaName = "";
+      var files = e.currentTarget.files;
+      if (!files.length) {
+        return;
+      }
+      this.fileaName = files[0].name;
+      var formData = new FormData(); // 必需声明一个FormData对象
+      formData.append("file", files[0]);
+      const { data: res } = await request({
+        method: "post",
+        url: "api/v1/upload/android/apk",
+        headers: {
+          "Content-Type": "multipart/form-data",
+        },
+        data: formData,
+        onUploadProgress: function (progressEvent) {
+          that.percentage = Math.round(
+            (progressEvent.loaded * 100) / progressEvent.total
+          );
+        },
+      });
+      that.form.apkPath = res;
+      that.uploadLoading = false;
+      console.log(that.form.apkPath);
+    },
+  },
+};
+</script>
+
+<style scoped>
+::v-deep .el-select {
+  width: 100%;
+}
+.m-l {
+  margin-left: 20px;
+}
+/*批量导入按钮*/
+.file {
+  position: relative;
+  background: #d0eeff;
+  border: 1px solid #99d3f5;
+  border-radius: 4px;
+  padding: 10px 20px;
+  box-sizing: border-box;
+  overflow: hidden;
+  color: #1e88c7;
+  text-decoration: none;
+  text-indent: 0;
+}
+.file input {
+  position: absolute;
+  font-size: 14px;
+  width: 106px;
+  height: 40px;
+  left: 0;
+  top: 0;
+  opacity: 0;
+  cursor: pointer;
+}
+.file:hover {
+  background: #aadffd;
+  border-color: #78c3f3;
+  color: #004974;
+  text-decoration: none;
+}
+</style>

+ 316 - 0
src/views/installationTask/index.vue

@@ -0,0 +1,316 @@
+<template>
+  <div class="app-container">
+    <addModal
+      ref="addModel"
+      @success="modalSuccess"
+      :snList="snList"
+      :installationPackageList="installationPackageList"
+    />
+    <div style="margin-bottom: 20px">
+      <el-button
+        class="filter-item"
+        type="primary"
+        icon="el-icon-plus"
+        @click="handleCreate"
+      >
+        添加安装任务
+      </el-button>
+      <!-- <el-select
+        filterable
+        clearable
+        v-model="form.sn"
+        placeholder="设备sn"
+        class="filter-item wid"
+      >
+        <el-option
+          v-for="item in snList"
+          :key="item.id"
+          :label="item.name"
+          :value="item.id"
+        >
+        </el-option>
+      </el-select> -->
+      <el-input
+        v-model="form.company"
+        placeholder="公司名称"
+        class="filter-item wid"
+        clearable
+      />
+      <el-input
+        clearable
+        v-model="form.sn"
+        placeholder="设备sn"
+        class="filter-item wid"
+      />
+      <el-input
+        clearable
+        v-model="form.apkTitle"
+        placeholder="安装包名称"
+        class="filter-item wid"
+      />
+      <el-input
+        clearable
+        v-model="form.apkVersion"
+        placeholder="版本号"
+        class="filter-item wid"
+      />
+      <el-select
+        filterable
+        clearable
+        v-model="form.status"
+        placeholder="安装状态"
+        class="filter-item wid"
+      >
+        <el-option
+          v-for="item in installSearch"
+          :key="item.code"
+          :label="item.desc"
+          :value="item.code"
+        >
+        </el-option>
+      </el-select>
+      <el-date-picker
+        v-model="form.startTime"
+        type="datetime"
+        placeholder="起始时间"
+        value-format="yyyy-MM-dd HH:mm:ss"
+        class="filter-item wid"
+      >
+      </el-date-picker>
+      <el-date-picker
+        v-model="form.endTime"
+        type="datetime"
+        placeholder="结束时间"
+        value-format="yyyy-MM-dd HH:mm:ss"
+        class="filter-item wid"
+      >
+      </el-date-picker>
+      <el-button
+        class="filter-item"
+        type="primary"
+        style="margin-left: 20px"
+        icon="el-icon-search"
+        @click="query"
+      >
+        搜索
+      </el-button>
+    </div>
+    <el-table
+      v-loading="tableLoading"
+      :data="tableData"
+      element-loading-text="加载中..."
+      border
+      fit
+      highlight-current-row
+    >
+      <el-table-column align="center" label="序号" width="95">
+        <template slot-scope="scope">
+          {{
+            (pagination.current - 1) * pagination.pageSize + (scope.$index + 1)
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="设备sn">
+        <template slot-scope="scope">
+          {{ scope.row.sn }}
+        </template>
+      </el-table-column>
+      <el-table-column label="公司名称">
+        <template slot-scope="scope">
+          {{ scope.row.company }}
+        </template>
+      </el-table-column>
+      <el-table-column label="安装包名称">
+        <template slot-scope="scope">
+          {{ scope.row.apkTitle }}
+        </template>
+      </el-table-column>
+      <el-table-column label="版本号">
+        <template slot-scope="scope">
+          {{ scope.row.apkVersion }}
+        </template>
+      </el-table-column>
+      <!-- <el-table-column label="安装包地址">
+        <template slot-scope="scope">
+          {{ scope.row.apkPath }}
+        </template>
+      </el-table-column> -->
+      <el-table-column
+        label="安装状态"
+        align="center"
+        class-name="status-col"
+        width="100"
+      >
+        <template slot-scope="{ row }">
+          <el-tag :type="row.status | statusFilter">
+            {{ row.status | statusFilterStr }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="安装完成时间">
+        <template slot-scope="scope">
+          {{ scope.row.installTime }}
+        </template>
+      </el-table-column>
+      <el-table-column label="	创建时间">
+        <template slot-scope="scope">
+          {{ scope.row.createTime }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="操作"
+        align="center"
+        width="120"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="{ row, $index }">
+          <el-button
+            :disabled="row.status == 2 || row.status == 3"
+            size="mini"
+            type="warning"
+            @click="cancelHandle(row, $index)"
+          >
+            取消
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      :total="pagination.total"
+      :page.sync="pagination.current"
+      :limit.sync="pagination.pageSize"
+      :page-sizes="pagination.pageSizeOptions"
+      :layout="pagination.layout"
+      @pagination="handleSizeChange"
+    />
+  </div>
+</template>
+
+<script>
+import AddModal from "./modal/AddModal.vue";
+import tableMixins from "@/mixins/tableMixins";
+import { taskPage, taskStatus, taskCancel,apkList } from "@/api/install_task";
+import { snList } from "@/api/device";
+import Pagination from "@/components/Pagination";
+
+export default {
+  components: { Pagination, AddModal },
+  filters: {
+    statusFilter(status) {
+      return status == 0
+        ? "info"
+        : status == 1
+        ? "primary"
+        : status == 2
+        ? "success"
+        : "info";
+    },
+    statusFilterStr(status) {
+      return status == 0
+        ? "等待中"
+        : status == 1
+        ? "下载中"
+        : status == 2
+        ? "完成"
+        : "取消";
+    },
+  },
+  mixins: [tableMixins],
+  data() {
+    return {
+      form: {
+        pageNumber: 1,
+        pageSize: 10000,
+      },
+      installSearch: [],
+      snList: [],
+      installationPackageList: [],
+    };
+  },
+  methods: {
+    initData() {
+      this.getTableList();
+      this.taskStatus();
+      this.apkList();
+      this.snListFun();
+    },
+    // 获取表格数据
+    async getTableList() {
+      this.tableLoading = true;
+      try {
+        const result = await taskPage(this.getFilterParams());
+        this.setDataList(result.data);
+      } catch (e) {
+        console.log(e);
+      } finally {
+        this.tableLoading = false;
+      }
+    },
+    // 增加筛选条件
+    transformFilterForm() {
+      return {
+        sn: this.form.sn || null,
+        company: this.form.company || null,
+        apkTitle: this.form.apkTitle || null,
+        apkVersion: this.form.apkVersion || null,
+        startTime: this.form.startTime || null,
+        endTime: this.form.endTime || null,
+        status: this.form.status === "" ? null : this.form.status,
+      };
+    },
+    taskStatus() {
+      taskStatus().then((res) => {
+        this.installSearch = res.data;
+      });
+    },
+    snListFun() {
+      snList().then((res) => {
+        this.snList = res.data;
+      });
+    },
+    apkList() {
+      apkList().then((res) => {
+        this.installationPackageList = res.data;
+      });
+    },
+    // 获取筛选信息
+    query() {
+      this.clearPageParams();
+      this.getTableList();
+    },
+    modalSuccess(isEdit) {
+      if (!isEdit) {
+        this.clearPageParams();
+      }
+      this.getTableList();
+    },
+    handleCreate() {
+      this.$refs.addModel.open();
+    },
+    // 取消
+    cancelHandle(row) {
+      this.$confirm("确定要取消吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+        center: true,
+      }).then(() => {
+        console.log(row);
+        taskCancel(row.id).then((res) => {
+          this.getTableList();
+          this.$message({
+            type: "success",
+            message: "取消成功!",
+          });
+        });
+      });
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.wid {
+  width: 200px;
+  margin-left: 20px;
+}
+</style>

+ 145 - 0
src/views/installationTask/modal/AddModal.vue

@@ -0,0 +1,145 @@
+// 添加/修改授权
+<template>
+  <el-dialog
+    title="添加安装任务"
+    width="800px"
+    :visible.sync="visible"
+    :destroy-on-close="false"
+    :close-on-click-modal="false"
+    :center="true"
+  >
+    <el-form
+      ref="form"
+      :rules="rules"
+      :model="form"
+      label-position="left"
+      label-width="100px"
+    >
+      <el-form-item label="设备an" prop="sns" required>
+        <el-select
+          style="width: 100%"
+          filterable
+          clearable
+          multiple
+          v-model="form.sns"
+          placeholder="请选择设备an"
+        >
+          <el-option
+            v-for="item in snList"
+            :key="item"
+            :label="item"
+            :value="item"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="安装包" prop="appApkId" required>
+        <el-select
+          style="width: 100%"
+          clearable
+          filterable
+          v-model="form.appApkId"
+          placeholder="请选择安装包"
+        >
+          <el-option
+            v-for="item in installationPackageList"
+            :key="item.id"
+            :label="item.apkTitle"
+            :value="item.id"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="visible = false"> 取消 </el-button>
+      <el-button type="primary" :loading="submitLoading" @click="submit">
+        确定
+      </el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { taskAdd } from "@/api/install_task";
+
+export default {
+  data() {
+    return {
+      form: {
+        sns: [],
+        appApkId: null,
+      },
+      rules: {
+        sns: [
+          {
+            required: true,
+            message: "不能为空!",
+            trigger: "blur",
+          },
+        ],
+        appApkId: [
+          {
+            required: true,
+            message: "不能为空!",
+            trigger: "blur",
+          },
+        ],
+      },
+      visible: false,
+      submitLoading: false,
+    };
+  },
+  props: {
+    snList: {
+      type: Array,
+      default: function () {
+        return [];
+      },
+    },
+    installationPackageList: {
+      type: Array,
+      default: function () {
+        return [];
+      },
+    },
+  },
+  created() {},
+  methods: {
+    open(obj) {
+      this.visible = true;
+      this.submitLoading = false;
+      this.$nextTick(() => {
+        this.$refs.form.resetFields();
+      });
+    },
+    submit(e) {
+      e.preventDefault();
+      this.$refs.form.validate(async (valid) => {
+        if (!valid) {
+          return false;
+        }
+        if (this.submitLoading) {
+          return;
+        }
+        this.submitLoading = true;
+        try {
+          await taskAdd(this.form);
+          this.visible = false;
+          this.$emit("success", false);
+        } catch (e) {
+          console.info("add", e);
+        } finally {
+          this.submitLoading = false;
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style scoped>
+::v-deep .el-select {
+  width: 100%;
+}
+</style>

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно