From 3bb3488abec439ea977329505633b50ff56bce43 Mon Sep 17 00:00:00 2001
From: 唐耀东 <18861537@qq.com>
Date: 星期五, 13 五月 2022 17:20:16 +0800
Subject: [PATCH] 提交代码

---
 src/views/components/school/index.vue             |    1 
 vue.config.js                                     |    2 
 src/api/oa/exchange.js                            |   44 +
 src/views/components/server/list.vue              |  157 ++++
 src/views/construction/server/index.vue           |  504 +++++++++++++++
 src/api/oa/system.js                              |   44 +
 src/views/construction/system/index.vue           |  449 +++++++++++++
 src/api/oa/server.js                              |   44 +
 src/views/construction/exchange/index.vue         |  538 ++++++++++++++++
 src/views/construction/ipc/index.vue              |   38 
 src/views/construction/iot/index.vue              |    1 
 src/views/construction/constructionList/index.vue |   24 
 src/views/components/server/index.vue             |   87 ++
 src/views/construction/ai/index.vue               |    6 
 src/views/construction/nvr/index.vue              |    5 
 src/components/FileUpload/index.vue               |    2 
 16 files changed, 1,925 insertions(+), 21 deletions(-)

diff --git a/src/api/oa/exchange.js b/src/api/oa/exchange.js
new file mode 100644
index 0000000..4f2c27c
--- /dev/null
+++ b/src/api/oa/exchange.js
@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 鏌ヨ浜ゆ崲璁惧鍒楄〃
+export function listExchange(query) {
+  return request({
+    url: '/oa/exchange/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏌ヨ浜ゆ崲璁惧璇︾粏
+export function getExchange(id) {
+  return request({
+    url: '/oa/exchange/' + id,
+    method: 'get'
+  })
+}
+
+// 鏂板浜ゆ崲璁惧
+export function addExchange(data) {
+  return request({
+    url: '/oa/exchange',
+    method: 'post',
+    data: data
+  })
+}
+
+// 淇敼浜ゆ崲璁惧
+export function updateExchange(data) {
+  return request({
+    url: '/oa/exchange',
+    method: 'put',
+    data: data
+  })
+}
+
+// 鍒犻櫎浜ゆ崲璁惧
+export function delExchange(id) {
+  return request({
+    url: '/oa/exchange/' + id,
+    method: 'delete'
+  })
+}
diff --git a/src/api/oa/server.js b/src/api/oa/server.js
new file mode 100644
index 0000000..940335d
--- /dev/null
+++ b/src/api/oa/server.js
@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鏈嶅姟鍣ㄥ垪琛�
+export function listServer(query) {
+  return request({
+    url: '/oa/server/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏌ヨ鏈嶅姟鍣ㄨ缁�
+export function getServer(id) {
+  return request({
+    url: '/oa/server/' + id,
+    method: 'get'
+  })
+}
+
+// 鏂板鏈嶅姟鍣�
+export function addServer(data) {
+  return request({
+    url: '/oa/server',
+    method: 'post',
+    data: data
+  })
+}
+
+// 淇敼鏈嶅姟鍣�
+export function updateServer(data) {
+  return request({
+    url: '/oa/server',
+    method: 'put',
+    data: data
+  })
+}
+
+// 鍒犻櫎鏈嶅姟鍣�
+export function delServer(id) {
+  return request({
+    url: '/oa/server/' + id,
+    method: 'delete'
+  })
+}
diff --git a/src/api/oa/system.js b/src/api/oa/system.js
new file mode 100644
index 0000000..151d154
--- /dev/null
+++ b/src/api/oa/system.js
@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 鏌ヨ杞欢绯荤粺鍒楄〃
+export function listSystem(query) {
+  return request({
+    url: '/oa/system/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏌ヨ杞欢绯荤粺璇︾粏
+export function getSystem(id) {
+  return request({
+    url: '/oa/system/' + id,
+    method: 'get'
+  })
+}
+
+// 鏂板杞欢绯荤粺
+export function addSystem(data) {
+  return request({
+    url: '/oa/system',
+    method: 'post',
+    data: data
+  })
+}
+
+// 淇敼杞欢绯荤粺
+export function updateSystem(data) {
+  return request({
+    url: '/oa/system',
+    method: 'put',
+    data: data
+  })
+}
+
+// 鍒犻櫎杞欢绯荤粺
+export function delSystem(id) {
+  return request({
+    url: '/oa/system/' + id,
+    method: 'delete'
+  })
+}
diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue
index 49a77bb..5c02bb0 100644
--- a/src/components/FileUpload/index.vue
+++ b/src/components/FileUpload/index.vue
@@ -60,7 +60,7 @@
     // 鏂囦欢绫诲瀷, 渚嬪['png', 'jpg', 'jpeg']
     fileType: {
       type: Array,
-      default: () => ["doc", "xls", "ppt", "txt", "pdf"],
+      default: () => ["doc", "xls", "ppt", "txt", "pdf", "zip"],
     },
     // 鏄惁鏄剧ず鎻愮ず
     isShowTip: {
diff --git a/src/views/components/school/index.vue b/src/views/components/school/index.vue
index 1679ecd..d8fe39d 100644
--- a/src/views/components/school/index.vue
+++ b/src/views/components/school/index.vue
@@ -41,7 +41,6 @@
   },
   methods: {
     getList() {
-      this.loading = true;
       listSchool(this.queryParams).then(r => {
         this.list = r.data;
         if (this.list.length > 0) {
diff --git a/src/views/components/server/index.vue b/src/views/components/server/index.vue
new file mode 100644
index 0000000..d51ccf1
--- /dev/null
+++ b/src/views/components/server/index.vue
@@ -0,0 +1,87 @@
+<template>
+  <div>
+    <el-input placeholder="璇烽�夋嫨" :value="name" disabled>
+      <el-button slot="append" icon="el-icon-thumb" @click="handleClick"></el-button>
+    </el-input>
+    <el-dialog title="鏈嶅姟鍣�" :visible.sync="open" width="1000px" :append-to-body="true" :destroy-on-close="true">
+      <server-list v-if="open" ref="serverRef" :schoolId="schoolId"></server-list>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="open = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import serverList from "./list";
+import {getServer} from "@/api/oa/server";
+
+/**
+ * 楂樻牎NVR
+ */
+export default {
+  name: "ServerInput",
+  components: {
+    serverList
+  },
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  props: {
+    value: {
+      type: [Number],
+      default: undefined
+    },
+    schoolId: {
+      type: Number,
+      default: undefined
+    }
+  },
+  data() {
+    return {
+      open: false,
+      name: ''
+    }
+  },
+  watch: {
+    'value': function (v) {
+      if (v) {
+        getServer(v).then(response => {
+          this.name = response.data.deploymentName;
+        });
+      }else {
+        this.name = '';
+      }
+    }
+  },
+  created() {
+    if (this.value) {
+      getServer(this.value).then(response => {
+        this.name = response.data.deploymentName;
+      });
+    }
+  },
+  methods: {
+    handleClick() {
+      this.open = true;
+    },
+    submitForm() {
+      const row = this.$refs.serverRef.currentRow;
+      if (!row) {
+        this.$message.warning("璇烽�夋嫨涓�鏉℃暟鎹�")
+        this.buttonLoading = false;
+        return;
+      }
+      this.name = row.deploymentName;
+      this.open = false;
+      this.$emit("change", row.id);
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/views/components/server/list.vue b/src/views/components/server/list.vue
new file mode 100644
index 0000000..8ccb372
--- /dev/null
+++ b/src/views/components/server/list.vue
@@ -0,0 +1,157 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="閮ㄧ讲浣嶇疆" prop="buildingId">
+        <building v-model="queryParams.buildingId" :schoolId="schoolId"></building>
+      </el-form-item>
+      <el-form-item label="閮ㄧ讲鍚嶇О" prop="name">
+        <el-input v-model="queryParams.deploymentName" placeholder="璇疯緭鍏ラ儴缃插悕绉�" />
+      </el-form-item>
+<!--      <el-form-item label="鎵�灞炲崟浣�" prop="organizationId">-->
+<!--        <organization v-model="queryParams.organizationId" :schoolId="schoolId"></organization>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="鏂藉伐鎵规" prop="constructionBatchId">-->
+<!--        <construction-batch v-model="queryParams.constructionBatchId" :schoolId="schoolId"></construction-batch>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="鍨嬪彿" prop="model">-->
+<!--        <el-input-->
+<!--            v-model="queryParams.model"-->
+<!--            placeholder="璇疯緭鍏ュ瀷鍙�"-->
+<!--            clearable-->
+<!--            size="small"-->
+<!--            @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="鐢熶骇鍘傚晢" prop="manufacturerId">-->
+<!--        <manufacturer v-model="queryParams.manufacturerId"></manufacturer>-->
+<!--      </el-form-item>-->
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-table v-loading="loading" :data="serverList" highlight-current-row
+              @current-change="handleCurrentChange">
+      <el-table-column label="搴忓彿" type="index" align="center">
+        <template slot-scope="scope">
+          <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="閮ㄧ讲鍚嶇О" align="center" prop="deploymentName"/>
+      <el-table-column label="LAN" align="center" prop="lan"/>
+      <el-table-column label="IP" align="center" prop="ip"/>
+      <el-table-column label="鎿嶄綔绯荤粺" align="center" prop="operatingSystem">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.DICT115" :value="scope.row.operatingSystem"/>
+        </template>
+      </el-table-column>
+      <!--      <el-table-column label="璐︽埛" align="center" prop="account" />-->
+      <el-table-column label="閮ㄧ讲浣嶇疆" align="center" prop="buildingId_dictText"/>
+      <el-table-column label="鏈烘煖鍙�" align="center" prop="cabinetNumber"/>
+      <el-table-column label="鏈烘灦鍙�" align="center" prop="rackNumber"/>
+      <el-table-column label="鎵�灞炲崟浣�" align="center" prop="organizationId_dictText"/>
+      <el-table-column label="鏂藉伐鎵规" align="center" prop="constructionBatchId_dictText"/>
+      <!--      <el-table-column label="搴忓垪鍙�" align="center" prop="serialNumber" />-->
+      <el-table-column label="鍨嬪彿" align="center" prop="model"/>
+      <el-table-column label="鐢熶骇鍘傚晢" align="center" prop="manufacturerId_dictText"/>
+      <!--      <el-table-column label="鎬ц兘鎸囨爣" align="center" prop="performanceIndex" />-->
+      <!--      <el-table-column label="澶囨敞" align="center" prop="remarks" />-->
+      <!--      <el-table-column label="闄勪欢" align="center" prop="filePath" />-->
+    </el-table>
+
+    <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+import {listServer, getServer, delServer, addServer, updateServer} from "@/api/oa/server";
+import building from "../../components/building";
+import organization from "../../components/organization";
+import constructionBatch from "../../components/constructionBatch";
+import manufacturer from "../../components/manufacturer";
+import nvr from "../../components/nvr";
+
+export default {
+  name: "Server",
+  dicts: ['DICT115'],
+  components: {
+    building,
+    organization,
+    constructionBatch,
+    manufacturer,
+    nvr
+  },
+  props: {
+    schoolId: {
+      type: Number,
+      default: undefined
+    }
+  },
+  data() {
+    return {
+      // 鎸夐挳loading
+      buttonLoading: false,
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鏈嶅姟鍣ㄨ〃鏍兼暟鎹�
+      serverList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        buildingId: undefined,
+        organizationId: undefined,
+        constructionBatchId: undefined,
+        model: undefined,
+        manufacturerId: undefined,
+        deploymentName: undefined
+      },
+      currentRow: undefined
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 鏌ヨ鏈嶅姟鍣ㄥ垪琛� */
+    getList() {
+      this.loading = true;
+      listServer(Object.assign({}, this.queryParams, {schoolId: this.schoolId})).then(response => {
+        this.serverList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    handleCurrentChange(v) {
+      this.currentRow = v;
+    }
+  }
+};
+</script>
diff --git a/src/views/construction/ai/index.vue b/src/views/construction/ai/index.vue
index ec0e800..033ecb4 100644
--- a/src/views/construction/ai/index.vue
+++ b/src/views/construction/ai/index.vue
@@ -68,7 +68,11 @@
 
     <el-table v-loading="loading" :data="aiList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center"/>
-      <el-table-column label="" align="center" prop="id" v-if="true"/>
+      <el-table-column label="搴忓彿" type="index" align="center">
+        <template slot-scope="scope">
+          <span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
+        </template>
+      </el-table-column>
       <el-table-column label="閮ㄧ讲鍚嶇О" align="center" prop="deploymentName"/>
       <el-table-column label="鏀寔閫氶亾" align="center" prop="passageway">
         <template slot-scope="scope">
diff --git a/src/views/construction/constructionList/index.vue b/src/views/construction/constructionList/index.vue
index a9374a4..10a2808 100644
--- a/src/views/construction/constructionList/index.vue
+++ b/src/views/construction/constructionList/index.vue
@@ -4,7 +4,7 @@
       <div class="tree-list">
         <school ref="schoolRef" @schoolChange="schoolChange"></school>
       </div>
-      <div class="right-view">
+      <div class="right-view" v-loading="loading">
         <el-tabs v-model="activeName" @tab-click="handleClick">
           <el-tab-pane label="鏂藉伐姒傚喌" name="first">鏂藉伐姒傚喌</el-tab-pane>
           <el-tab-pane label="IPC璁惧" name="second">
@@ -19,9 +19,15 @@
           <el-tab-pane label="AI璁惧" name="five">
             <ai v-if="activeName === 'five'" :schoolId="schoolId"></ai>
           </el-tab-pane>
-          <el-tab-pane label="浜ゆ崲璁惧" name="six">浜ゆ崲璁惧</el-tab-pane>
-          <el-tab-pane label="鏈嶅姟鍣�" name="seven">鏈嶅姟鍣�</el-tab-pane>
-          <el-tab-pane label="杞欢绯荤粺" name="eight">杞欢绯荤粺</el-tab-pane>
+          <el-tab-pane label="浜ゆ崲璁惧" name="six">
+            <exchange v-if="activeName === 'six'" :schoolId="schoolId"></exchange>
+          </el-tab-pane>
+          <el-tab-pane label="鏈嶅姟鍣�" name="seven">
+            <server v-if="activeName === 'seven'" :schoolId="schoolId"></server>
+          </el-tab-pane>
+          <el-tab-pane label="杞欢绯荤粺" name="eight">
+            <system v-if="activeName === 'eight'" :schoolId="schoolId"></system>
+          </el-tab-pane>
         </el-tabs>
         <div class="right-view-title-icon">
           <i class="el-icon-search" @click="batchOpen = true"></i>
@@ -47,6 +53,9 @@
 import ipc from '../ipc'
 import iot from '../iot'
 import ai from '../ai'
+import exchange from '../exchange'
+import server from '../server'
+import system from '../system'
 
 export default {
   name: "constructionList",
@@ -57,10 +66,14 @@
     nvr,
     ipc,
     iot,
-    ai
+    ai,
+    exchange,
+    server,
+    system
   },
   data() {
     return {
+      loading: true,
       activeName: 'first',
       batchOpen: false,
       ipOpen: false,
@@ -72,6 +85,7 @@
     schoolChange(v) {
       this.schoolId = v;
       this.activeName = 'first';
+      this.loading = false;
     },
     handleClick(tab, event) {
       console.log(tab, event);
diff --git a/src/views/construction/exchange/index.vue b/src/views/construction/exchange/index.vue
new file mode 100644
index 0000000..2849e98
--- /dev/null
+++ b/src/views/construction/exchange/index.vue
@@ -0,0 +1,538 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="瀹夎浣嶇疆" prop="buildingId">
+        <building v-model="queryParams.buildingId" :schoolId="schoolId"></building>
+      </el-form-item>
+      <el-form-item label="鎵�灞炲崟浣�" prop="organizationId">
+        <organization v-model="queryParams.organizationId" :schoolId="schoolId"></organization>
+      </el-form-item>
+      <el-form-item label="鏂藉伐鎵规" prop="constructionBatchId">
+        <construction-batch v-model="queryParams.constructionBatchId" :schoolId="schoolId"></construction-batch>
+      </el-form-item>
+      <el-form-item label="鍨嬪彿" prop="model">
+        <el-input
+            v-model="queryParams.model"
+            placeholder="璇疯緭鍏ュ瀷鍙�"
+            clearable
+            size="small"
+            @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="鐢熶骇鍘傚晢" prop="manufacturerId">
+        <manufacturer v-model="queryParams.manufacturerId"></manufacturer>
+      </el-form-item>
+      <el-form-item label="缃戠粶绔彛" prop="networkPort">
+        <el-select v-model="queryParams.networkPort" placeholder="璇烽�夋嫨缃戠粶绔彛" clearable size="small">
+          <el-option
+              v-for="dict in dict.type.DICT113"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鎸囨爣A" prop="idnexA">
+        <el-select v-model="queryParams.idnexA" placeholder="璇烽�夋嫨鎸囨爣A" clearable size="small">
+          <el-option
+              v-for="dict in dict.type.DICT114"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="绾ц仈绔彛" prop="cascadePort">
+        <el-select v-model="queryParams.cascadePort" placeholder="璇烽�夋嫨绾ц仈绔彛" clearable size="small">
+          <el-option
+              v-for="dict in dict.type.DICT113"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鎸囨爣B" prop="indexB">
+        <el-select v-model="queryParams.indexB" placeholder="璇烽�夋嫨鎸囨爣B" clearable size="small">
+          <el-option
+              v-for="dict in dict.type.DICT114"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+            type="primary"
+            plain
+            icon="el-icon-plus"
+            size="mini"
+            @click="handleAdd"
+            v-hasPermi="['oa:exchange:add']"
+        >鏂板
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="success"
+            plain
+            icon="el-icon-edit"
+            size="mini"
+            :disabled="single"
+            @click="handleUpdate"
+            v-hasPermi="['oa:exchange:edit']"
+        >淇敼
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="danger"
+            plain
+            icon="el-icon-delete"
+            size="mini"
+            :disabled="multiple"
+            @click="handleDelete"
+            v-hasPermi="['oa:exchange:remove']"
+        >鍒犻櫎
+        </el-button>
+      </el-col>
+    </el-row>
+
+    <el-table v-loading="loading" :data="exchangeList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="搴忓彿" type="index" align="center">
+        <template slot-scope="scope">
+          <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="缃戠粶绔彛" align="center" prop="networkPort">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.DICT113" :value="scope.row.networkPort"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎸囨爣A" align="center" prop="idnexA">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.DICT114" :value="scope.row.idnexA"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="绾ц仈绔彛" align="center" prop="cascadePort">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.DICT113" :value="scope.row.cascadePort"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎸囨爣B" align="center" prop="indexB">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.DICT114" :value="scope.row.indexB"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="瀹夎浣嶇疆" align="center" prop="buildingId_dictText"/>
+      <el-table-column label="鍏蜂綋浣嶇疆" align="center" prop="address"/>
+      <el-table-column label="鎵�灞炲崟浣�" align="center" prop="organizationId_dictText"/>
+      <el-table-column label="鏂藉伐鎵规" align="center" prop="constructionBatchId_dictText"/>
+      <el-table-column label="鍨嬪彿" align="center" prop="model"/>
+      <el-table-column label="鐢熶骇鍘傚晢" align="center" prop="manufacturerId_dictText"/>
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleInfo(scope.row)"
+          >鏌ョ湅
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              v-hasPermi="['oa:exchange:edit']"
+          >淇敼
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-folder"
+              @click="handleUpload(scope.row)"
+          >闄勪欢
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              class="del-btn"
+              icon="el-icon-delete"
+              @click="handleDelete(scope.row)"
+              v-hasPermi="['oa:exchange:remove']"
+          >鍒犻櫎
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <!-- 娣诲姞鎴栦慨鏀逛氦鎹㈣澶囧璇濇 -->
+    <el-dialog :title="title" :visible.sync="open" width="700px" :append-to-body="true" :close-on-click-modal="false">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px" :disabled="disabled">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="缃戠粶绔彛" prop="networkPort">
+              <el-select v-model="form.networkPort" placeholder="璇烽�夋嫨缃戠粶绔彛">
+                <el-option
+                    v-for="dict in dict.type.DICT113"
+                    :key="dict.value"
+                    :label="dict.label"
+                    :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣A" prop="idnexA">
+              <el-select v-model="form.idnexA" placeholder="璇烽�夋嫨鎸囨爣A">
+                <el-option
+                    v-for="dict in dict.type.DICT114"
+                    :key="dict.value"
+                    :label="dict.label"
+                    :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="绾ц仈绔彛" prop="cascadePort">
+              <el-select v-model="form.cascadePort" placeholder="璇烽�夋嫨绾ц仈绔彛">
+                <el-option
+                    v-for="dict in dict.type.DICT113"
+                    :key="dict.value"
+                    :label="dict.label"
+                    :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣B" prop="indexB">
+              <el-select v-model="form.indexB" placeholder="璇烽�夋嫨鎸囨爣B">
+                <el-option
+                    v-for="dict in dict.type.DICT114"
+                    :key="dict.value"
+                    :label="dict.label"
+                    :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="瀹夎浣嶇疆" prop="buildingId">
+          <building v-if="open" v-model="form.buildingId" :schoolId="schoolId"></building>
+        </el-form-item>
+        <el-form-item label="鍏蜂綋浣嶇疆" prop="address">
+          <el-input v-model="form.address" maxlength="512" show-word-limit type="textarea" :rows="8" placeholder="璇疯緭鍏ュ叿浣撲綅缃�""/>
+        </el-form-item>
+        <el-form-item label="鎵�灞炲崟浣�" prop="organizationId">
+          <organization v-if="open" v-model="form.organizationId" :schoolId="schoolId"></organization>
+        </el-form-item>
+        <el-form-item label="鏂藉伐鎵规" prop="constructionBatchId">
+          <constructionBatch v-if="open" v-model="form.constructionBatchId" :schoolId="schoolId"></constructionBatch>
+        </el-form-item>
+        <el-form-item label="搴忓垪鍙�" prop="serialNumber">
+          <el-input v-model="form.serialNumber" maxlength="64" show-word-limit placeholder="璇疯緭鍏ュ簭鍒楀彿"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鍨嬪彿" prop="model">
+              <el-input v-model="form.model" maxlength="64" show-word-limit placeholder="璇疯緭鍏ュ瀷鍙�"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐢熶骇鍘傚晢" prop="manufacturerId">
+              <manufacturer v-model="form.manufacturerId"></manufacturer>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="buttonLoading" :disabled="disabled" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 闄勪欢 -->
+    <Dialog title="闄勪欢" :visible.sync="fileOpen" width="500px" :append-to-body="true" :destroy-on-close="true">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="闄勪欢" prop="filePath">
+          <fileUpload v-model="form.filePath" :limit="1"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </Dialog>
+  </div>
+</template>
+
+<script>
+import {listExchange, getExchange, delExchange, addExchange, updateExchange} from "@/api/oa/exchange";
+import building from "../../components/building";
+import organization from "../../components/organization";
+import constructionBatch from "../../components/constructionBatch";
+import manufacturer from "../../components/manufacturer";
+import nvr from "../../components/nvr";
+
+export default {
+  name: "Exchange",
+  dicts: ['DICT113', 'DICT114', 'DICT113', 'DICT114'],
+  components: {
+    building,
+    organization,
+    constructionBatch,
+    manufacturer,
+    nvr
+  },
+  props: {
+    schoolId: {
+      type: Number,
+      default: undefined
+    }
+  },
+  data() {
+    return {
+      // 鎸夐挳loading
+      buttonLoading: false,
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 浜ゆ崲璁惧琛ㄦ牸鏁版嵁
+      exchangeList: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        schoolId: undefined,
+        networkPort: undefined,
+        idnexA: undefined,
+        cascadePort: undefined,
+        indexB: undefined,
+        buildingId: undefined,
+        organizationId: undefined,
+        constructionBatchId: undefined,
+        manufacturerId: undefined,
+        model: undefined
+      },
+      // 琛ㄥ崟鍙傛暟
+      form: {},
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+        id: [
+          {required: true, message: "涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        schoolId: [
+          {required: true, message: "楂樻牎涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        networkPort: [
+          {required: true, message: "缃戠粶绔彛涓嶈兘涓虹┖", trigger: "change"}
+        ],
+        idnexA: [
+          {required: true, message: "鎸囨爣A涓嶈兘涓虹┖", trigger: "change"}
+        ],
+        cascadePort: [
+          {required: true, message: "绾ц仈绔彛涓嶈兘涓虹┖", trigger: "change"}
+        ],
+        indexB: [
+          {required: true, message: "鎸囨爣B涓嶈兘涓虹┖", trigger: "change"}
+        ],
+        buildingId: [
+          {required: true, message: "瀹夎浣嶇疆涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        organizationId: [
+          {required: true, message: "鎵�灞炲崟浣嶄笉鑳戒负绌�", trigger: "blur"}
+        ],
+        constructionBatchId: [
+          {required: true, message: "鏂藉伐鎵规涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+      },
+      disabled: false,
+      fileOpen: false
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 鏌ヨ浜ゆ崲璁惧鍒楄〃 */
+    getList() {
+      this.loading = true;
+      listExchange(Object.assign({}, this.queryParams, {schoolId: this.schoolId})).then(response => {
+        this.exchangeList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 鍙栨秷鎸夐挳
+    cancel() {
+      this.open = false;
+      this.fileOpen = false;
+      this.reset();
+    },
+    // 琛ㄥ崟閲嶇疆
+    reset() {
+      this.form = {
+        id: undefined,
+        schoolId: undefined,
+        networkPort: undefined,
+        idnexA: undefined,
+        cascadePort: undefined,
+        indexB: undefined,
+        buildingId: undefined,
+        address: undefined,
+        organizationId: undefined,
+        constructionBatchId: undefined,
+        serialNumber: undefined,
+        model: undefined,
+        manufacturerId: undefined,
+        createTime: undefined,
+        createBy: undefined,
+        updateBy: undefined,
+        updateTime: undefined,
+        delFlag: undefined
+      };
+      this.resetForm("form");
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd() {
+      this.reset();
+      this.disabled = false;
+      this.open = true;
+      this.title = "娣诲姞浜ゆ崲璁惧";
+    },
+    handleInfo(row) {
+      this.loading = true;
+      this.reset();
+      this.disabled = true;
+      getExchange(row.id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "浜ゆ崲璁惧璇︽儏";
+      });
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+      this.loading = true;
+      this.disabled = false
+      this.reset();
+      const id = row.id || this.ids
+      getExchange(id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "淇敼浜ゆ崲璁惧";
+      });
+    },
+    handleUpload(row) {
+      this.loading = true;
+      this.disabled = false
+      this.reset();
+      getExchange(row.id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.fileOpen = true;
+      });
+    },
+    /** 鎻愪氦鎸夐挳 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.buttonLoading = true;
+          this.form.schoolId = this.schoolId;
+          if (this.form.id != null) {
+            updateExchange(this.form).then(response => {
+              this.$modal.msgSuccess("淇敼鎴愬姛");
+              this.open = false;
+              this.fileOpen = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          } else {
+            addExchange(this.form).then(response => {
+              this.$modal.msgSuccess("鏂板鎴愬姛");
+              this.open = false;
+              this.fileOpen = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          }
+        }
+      });
+    },
+    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('鏄惁纭鍒犻櫎浜ゆ崲璁惧缂栧彿涓�"' + ids + '"鐨勬暟鎹」锛�').then(() => {
+        this.loading = true;
+        return delExchange(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
+    handleExport() {
+      this.download('oa/exchange/export', {
+        ...this.queryParams
+      }, `exchange_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>
diff --git a/src/views/construction/iot/index.vue b/src/views/construction/iot/index.vue
index 7485690..7d63c1e 100644
--- a/src/views/construction/iot/index.vue
+++ b/src/views/construction/iot/index.vue
@@ -131,7 +131,6 @@
               type="text"
               icon="el-icon-view"
               @click="handleInfo(scope.row)"
-              v-hasPermi="['oa:iot:edit']"
           >鏌ョ湅
           </el-button>
           <el-button
diff --git a/src/views/construction/ipc/index.vue b/src/views/construction/ipc/index.vue
index 0b9ad00..fe7c503 100644
--- a/src/views/construction/ipc/index.vue
+++ b/src/views/construction/ipc/index.vue
@@ -88,6 +88,13 @@
           <el-button
               size="mini"
               type="text"
+              icon="el-icon-view"
+              @click="handleInfo(scope.row)"
+          >鏌ョ湅
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
               icon="el-icon-edit"
               @click="handleUpdate(scope.row)"
               v-hasPermi="['oa:ipc:edit']"
@@ -117,7 +124,7 @@
     <!-- 娣诲姞鎴栦慨鏀筰pc璁惧瀵硅瘽妗� -->
     <el-dialog :title="title" :visible.sync="open" width="700px" :append-to-body="true" :close-on-click-modal="false"
                :destroy-on-close="true">
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px" :disabled="disabled">
         <el-row>
           <el-col :span="9">
             <el-form-item label="MAC" prop="mac">
@@ -183,8 +190,8 @@
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button :loading="buttonLoading" type="primary" @click="copy">澶嶅埗涓婁竴鏉′俊鎭�</el-button>
-        <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button :loading="buttonLoading" :disabled="disabled" type="primary" @click="copy">澶嶅埗涓婁竴鏉′俊鎭�</el-button>
+        <el-button :loading="buttonLoading" :disabled="disabled" type="primary" @click="submitForm">纭� 瀹�</el-button>
         <el-button @click="cancel">鍙� 娑�</el-button>
       </div>
     </el-dialog>
@@ -286,7 +293,8 @@
           {required: true, message: "鏂藉伐鎵规涓嶈兘涓虹┖", trigger: "blur"}
         ],
         passageway: []
-      }
+      },
+      disabled: false
     };
   },
   computed: {
@@ -367,19 +375,33 @@
     /** 鏂板鎸夐挳鎿嶄綔 */
     handleAdd() {
       this.reset();
+      this.disabled = false;
       this.open = true;
-      this.title = "娣诲姞ipc璁惧";
+      this.title = "娣诲姞IPC璁惧";
     },
-    /** 淇敼鎸夐挳鎿嶄綔 */
-    handleUpdate(row) {
+    handleInfo(row) {
       this.loading = true;
+      this.disabled = true;
       this.reset();
       const id = row.id || this.ids
       getIpc(id).then(response => {
         this.loading = false;
         this.form = response.data;
         this.open = true;
-        this.title = "淇敼ipc璁惧";
+        this.title = "IPC璁惧璇︽儏";
+      });
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+      this.loading = true;
+      this.disabled = false;
+      this.reset();
+      const id = row.id || this.ids
+      getIpc(id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "淇敼IPC璁惧";
       });
     },
     /** 鎻愪氦鎸夐挳 */
diff --git a/src/views/construction/nvr/index.vue b/src/views/construction/nvr/index.vue
index 31db4eb..e010a33 100644
--- a/src/views/construction/nvr/index.vue
+++ b/src/views/construction/nvr/index.vue
@@ -446,7 +446,7 @@
         this.loading = false;
         this.form = response.data;
         this.open = true;
-        this.title = "淇敼NVR璁惧";
+        this.title = "NVR璁惧璇︽儏";
       });
     },
     /** 淇敼鎸夐挳鎿嶄綔 */
@@ -515,8 +515,7 @@
       this.loading = true;
       this.disabled = false;
       this.reset();
-      const id = row.id || this.ids
-      getNvr(id).then(response => {
+      getNvr(row.id).then(response => {
         this.loading = false;
         this.form = response.data;
         this.fileOpen = true;
diff --git a/src/views/construction/server/index.vue b/src/views/construction/server/index.vue
new file mode 100644
index 0000000..28dccd1
--- /dev/null
+++ b/src/views/construction/server/index.vue
@@ -0,0 +1,504 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="閮ㄧ讲浣嶇疆" prop="buildingId">
+        <building v-model="queryParams.buildingId" :schoolId="schoolId"></building>
+      </el-form-item>
+      <el-form-item label="鎵�灞炲崟浣�" prop="organizationId">
+        <organization v-model="queryParams.organizationId" :schoolId="schoolId"></organization>
+      </el-form-item>
+      <el-form-item label="鏂藉伐鎵规" prop="constructionBatchId">
+        <construction-batch v-model="queryParams.constructionBatchId" :schoolId="schoolId"></construction-batch>
+      </el-form-item>
+      <el-form-item label="鍨嬪彿" prop="model">
+        <el-input
+            v-model="queryParams.model"
+            placeholder="璇疯緭鍏ュ瀷鍙�"
+            clearable
+            size="small"
+            @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="鐢熶骇鍘傚晢" prop="manufacturerId">
+        <manufacturer v-model="queryParams.manufacturerId"></manufacturer>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+            type="primary"
+            plain
+            icon="el-icon-plus"
+            size="mini"
+            @click="handleAdd"
+            v-hasPermi="['oa:server:add']"
+        >鏂板
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="success"
+            plain
+            icon="el-icon-edit"
+            size="mini"
+            :disabled="single"
+            @click="handleUpdate"
+            v-hasPermi="['oa:server:edit']"
+        >淇敼
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="danger"
+            plain
+            icon="el-icon-delete"
+            size="mini"
+            :disabled="multiple"
+            @click="handleDelete"
+            v-hasPermi="['oa:server:remove']"
+        >鍒犻櫎
+        </el-button>
+      </el-col>
+    </el-row>
+
+    <el-table v-loading="loading" :data="serverList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="搴忓彿" type="index" align="center">
+        <template slot-scope="scope">
+          <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="閮ㄧ讲鍚嶇О" align="center" prop="deploymentName"/>
+      <el-table-column label="LAN" align="center" prop="lan"/>
+      <el-table-column label="IP" align="center" prop="ip"/>
+      <el-table-column label="鎿嶄綔绯荤粺" align="center" prop="operatingSystem">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.DICT115" :value="scope.row.operatingSystem"/>
+        </template>
+      </el-table-column>
+      <!--      <el-table-column label="璐︽埛" align="center" prop="account" />-->
+      <el-table-column label="閮ㄧ讲浣嶇疆" align="center" prop="buildingId_dictText"/>
+      <el-table-column label="鏈烘煖鍙�" align="center" prop="cabinetNumber"/>
+      <el-table-column label="鏈烘灦鍙�" align="center" prop="rackNumber"/>
+      <el-table-column label="鎵�灞炲崟浣�" align="center" prop="organizationId_dictText"/>
+      <el-table-column label="鏂藉伐鎵规" align="center" prop="constructionBatchId_dictText"/>
+      <!--      <el-table-column label="搴忓垪鍙�" align="center" prop="serialNumber" />-->
+      <el-table-column label="鍨嬪彿" align="center" prop="model"/>
+      <el-table-column label="鐢熶骇鍘傚晢" align="center" prop="manufacturerId_dictText"/>
+      <!--      <el-table-column label="鎬ц兘鎸囨爣" align="center" prop="performanceIndex" />-->
+      <!--      <el-table-column label="澶囨敞" align="center" prop="remarks" />-->
+      <!--      <el-table-column label="闄勪欢" align="center" prop="filePath" />-->
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleInfo(scope.row)"
+          >鏌ョ湅
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              v-hasPermi="['oa:server:edit']"
+          >淇敼
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-folder"
+              @click="handleUpload(scope.row)"
+          >闄勪欢
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              class="del-btn"
+              icon="el-icon-delete"
+              @click="handleDelete(scope.row)"
+              v-hasPermi="['oa:server:remove']"
+          >鍒犻櫎
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <!-- 娣诲姞鎴栦慨鏀规湇鍔″櫒瀵硅瘽妗� -->
+    <el-dialog :title="title" :visible.sync="open" width="700px" :append-to-body="true" :close-on-click-modal="false">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px" :disabled="disabled">
+        <el-form-item label="閮ㄧ讲鍚嶇О" prop="deploymentName">
+          <el-input v-model="form.deploymentName" maxlength="64" show-word-limit placeholder="璇疯緭鍏ラ儴缃插悕绉�"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="LAN" prop="lan">
+              <el-input v-model="form.lan" placeholder="璇疯緭鍏AN"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="IP" prop="ip">
+              <el-input v-model="form.ip" placeholder="璇疯緭鍏P"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鎿嶄綔绯荤粺" prop="operatingSystem">
+              <el-select v-model="form.operatingSystem" placeholder="璇烽�夋嫨鎿嶄綔绯荤粺">
+                <el-option
+                    v-for="dict in dict.type.DICT115"
+                    :key="dict.value"
+                    :label="dict.label"
+                    :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璐︽埛" prop="account">
+              <el-input v-model="form.account" maxlength="64" show-word-limit placeholder="璇疯緭鍏ヨ处鎴�"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="閮ㄧ讲浣嶇疆" prop="buildingId">
+          <building v-if="open" v-model="form.buildingId" :schoolId="schoolId"></building>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鏈烘煖鍙�" prop="cabinetNumber">
+              <el-input v-model="form.cabinetNumber" maxlength="64" show-word-limit placeholder="璇疯緭鍏ユ満鏌滃彿"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏈烘灦鍙�" maxlength="64" show-word-limit prop="rackNumber">
+              <el-input v-model="form.rackNumber" maxlength="64" show-word-limit placeholder="璇疯緭鍏ユ満鏋跺彿"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鎵�灞炲崟浣�" prop="organizationId">
+          <organization v-if="open" v-model="form.organizationId" :schoolId="schoolId"></organization>
+        </el-form-item>
+        <el-form-item label="鏂藉伐鎵规" prop="constructionBatchId">
+          <constructionBatch v-if="open" v-model="form.constructionBatchId" :schoolId="schoolId"></constructionBatch>
+        </el-form-item>
+        <el-form-item label="搴忓垪鍙�" prop="serialNumber">
+          <el-input v-model="form.serialNumber" maxlength="64" show-word-limit placeholder="璇疯緭鍏ュ簭鍒楀彿"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鍨嬪彿" prop="model">
+              <el-input v-model="form.model" maxlength="64" show-word-limit placeholder="璇疯緭鍏ュ瀷鍙�"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐢熶骇鍘傚晢" prop="manufacturerId">
+              <manufacturer v-model="form.manufacturerId"></manufacturer>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鎬ц兘鎸囨爣" prop="performanceIndex">
+          <el-input v-model="form.performanceIndex" type="textarea" :rows="8" maxlength="64" show-word-limit
+                    placeholder="璇疯緭鍏ュ唴瀹�"/>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remarks">
+          <el-input v-model="form.remarks" type="textarea" :rows="8" maxlength="64" show-word-limit
+                    placeholder="璇疯緭鍏ュ唴瀹�"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="buttonLoading" :disabled="disabled" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 闄勪欢 -->
+    <Dialog title="闄勪欢" :visible.sync="fileOpen" width="500px" :append-to-body="true" :destroy-on-close="true">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="闄勪欢" prop="filePath">
+          <fileUpload v-model="form.filePath" :limit="1"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </Dialog>
+  </div>
+</template>
+
+<script>
+import {listServer, getServer, delServer, addServer, updateServer} from "@/api/oa/server";
+import building from "../../components/building";
+import organization from "../../components/organization";
+import constructionBatch from "../../components/constructionBatch";
+import manufacturer from "../../components/manufacturer";
+import nvr from "../../components/nvr";
+
+export default {
+  name: "Server",
+  dicts: ['DICT115'],
+  components: {
+    building,
+    organization,
+    constructionBatch,
+    manufacturer,
+    nvr
+  },
+  props: {
+    schoolId: {
+      type: Number,
+      default: undefined
+    }
+  },
+  data() {
+    return {
+      // 鎸夐挳loading
+      buttonLoading: false,
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鏈嶅姟鍣ㄨ〃鏍兼暟鎹�
+      serverList: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        buildingId: undefined,
+        organizationId: undefined,
+        constructionBatchId: undefined,
+        model: undefined,
+        manufacturerId: undefined,
+      },
+      // 琛ㄥ崟鍙傛暟
+      form: {},
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+        id: [
+          {required: true, message: "涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        schoolId: [
+          {required: true, message: "楂樻牎涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        deploymentName: [
+          {required: true, message: "閮ㄧ讲鍚嶇О涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        lan: [
+          {required: true, message: "LAN涓嶈兘涓虹┖", trigger: "blur"},
+          {
+            pattern: /^[A-F0-9]{2}(-[A-F0-9]{2}){5}$|^[A-F0-9]{2}(:[A-F0-9]{2}){5}$|^[A-F0-9]{12}$|^[A-F0-9]{4}(\.[A-F0-9]{4}){2}$/,
+            message: "璇疯緭鍏ユ纭殑LAN",
+            trigger: "blur"
+          }
+        ],
+        ip: [
+          {required: true, message: "IP涓嶈兘涓虹┖", trigger: "blur"},
+          {
+            pattern: /^(\d|[1-9]\d|1\d{2}|2[0-5][0-5])\.(\d|[1-9]\d|1\d{2}|2[0-5][0-5])\.(\d|[1-9]\d|1\d{2}|2[0-5][0-5])\.(\d|[1-9]\d|1\d{2}|2[0-5][0-5])$/,
+            message: "璇疯緭鍏ユ纭殑ip鍦板潃",
+            trigger: "blur"
+          }
+        ],
+        operatingSystem: [
+          {required: true, message: "鎿嶄綔绯荤粺涓嶈兘涓虹┖", trigger: "change"}
+        ],
+        account: [
+          {required: true, message: "璐︽埛涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        buildingId: [
+          {required: true, message: "閮ㄧ讲浣嶇疆涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        organizationId: [
+          {required: true, message: "鎵�灞炲崟浣嶄笉鑳戒负绌�", trigger: "blur"}
+        ],
+        constructionBatchId: [
+          {required: true, message: "鏂藉伐鎵规涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+      },
+      disabled: false,
+      fileOpen: false
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 鏌ヨ鏈嶅姟鍣ㄥ垪琛� */
+    getList() {
+      this.loading = true;
+      listServer(Object.assign({}, this.queryParams, {schoolId: this.schoolId})).then(response => {
+        this.serverList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 鍙栨秷鎸夐挳
+    cancel() {
+      this.open = false;
+      this.fileOpen = false;
+      this.reset();
+    },
+    // 琛ㄥ崟閲嶇疆
+    reset() {
+      this.form = {
+        id: undefined,
+        schoolId: undefined,
+        deploymentName: undefined,
+        lan: undefined,
+        ip: undefined,
+        operatingSystem: undefined,
+        account: undefined,
+        buildingId: undefined,
+        cabinetNumber: undefined,
+        rackNumber: undefined,
+        organizationId: undefined,
+        constructionBatchId: undefined,
+        serialNumber: undefined,
+        model: undefined,
+        manufacturerId: undefined,
+        performanceIndex: undefined,
+        remarks: undefined,
+        filePath: undefined,
+        createBy: undefined,
+        createTime: undefined,
+        updateBy: undefined,
+        updateTime: undefined,
+        delFlag: undefined
+      };
+      this.resetForm("form");
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd() {
+      this.reset();
+      this.disabled = false;
+      this.open = true;
+      this.title = "娣诲姞鏈嶅姟鍣�";
+    },
+    handleInfo(row) {
+      this.loading = true;
+      this.disabled = true;
+      this.reset();
+      getServer(row.id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "鏈嶅姟鍣ㄨ鎯�";
+      });
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+      this.loading = true;
+      this.disabled = false;
+      this.reset();
+      const id = row.id || this.ids
+      getServer(id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "淇敼鏈嶅姟鍣�";
+      });
+    },
+    handleUpload(row) {
+      this.loading = true;
+      this.disabled = false;
+      this.reset();
+      getServer(row.id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.fileOpen = true;
+      });
+    },
+    /** 鎻愪氦鎸夐挳 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.buttonLoading = true;
+          this.form.schoolId = this.schoolId;
+          if (this.form.id != null) {
+            updateServer(this.form).then(response => {
+              this.$modal.msgSuccess("淇敼鎴愬姛");
+              this.open = false;
+              this.fileOpen = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          } else {
+            addServer(this.form).then(response => {
+              this.$modal.msgSuccess("鏂板鎴愬姛");
+              this.open = false;
+              this.fileOpen = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          }
+        }
+      });
+    },
+    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('鏄惁纭鍒犻櫎鏈嶅姟鍣ㄧ紪鍙蜂负"' + ids + '"鐨勬暟鎹」锛�').then(() => {
+        this.loading = true;
+        return delServer(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
+    handleExport() {
+      this.download('oa/server/export', {
+        ...this.queryParams
+      }, `server_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>
diff --git a/src/views/construction/system/index.vue b/src/views/construction/system/index.vue
new file mode 100644
index 0000000..f0ee5d2
--- /dev/null
+++ b/src/views/construction/system/index.vue
@@ -0,0 +1,449 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="杞欢鍚嶇О" prop="name">
+        <el-input
+            v-model="queryParams.name"
+            placeholder="璇疯緭鍏ヨ蒋浠跺悕绉�"
+            clearable
+            size="small"
+            @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="杞戒綋鏈嶅姟鍣�" prop="serverId">
+        <server v-model="queryParams.serverId" :schoolId="schoolId"></server>
+      </el-form-item>
+      <el-form-item label="鏂藉伐鎵规" prop="constructionBatchId">
+        <construction-batch v-model="queryParams.constructionBatchId" :schoolId="schoolId"></construction-batch>
+      </el-form-item>
+      <el-form-item label="鐢熶骇鍘傚晢" prop="manufacturerId">
+        <manufacturer v-model="queryParams.manufacturerId"></manufacturer>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+            type="primary"
+            plain
+            icon="el-icon-plus"
+            size="mini"
+            @click="handleAdd"
+            v-hasPermi="['oa:system:add']"
+        >鏂板
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="success"
+            plain
+            icon="el-icon-edit"
+            size="mini"
+            :disabled="single"
+            @click="handleUpdate"
+            v-hasPermi="['oa:system:edit']"
+        >淇敼
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="danger"
+            plain
+            icon="el-icon-delete"
+            size="mini"
+            :disabled="multiple"
+            @click="handleDelete"
+            v-hasPermi="['oa:system:remove']"
+        >鍒犻櫎
+        </el-button>
+      </el-col>
+    </el-row>
+
+    <el-table v-loading="loading" :data="systemList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="搴忓彿" type="index" align="center">
+        <template slot-scope="scope">
+          <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="杞欢鍚嶇О" align="center" prop="name"/>
+      <el-table-column label="鐗堟湰" align="center" prop="edition"/>
+      <el-table-column label="鍔熻兘鎻忚堪" align="center" prop="functionDescription"/>
+      <el-table-column label="鎺堟潈鏂瑰紡" align="center" prop="authorizationMethod_dictText"/>
+      <el-table-column label="鎺堟潈鏁伴噺" align="center" prop="authorizedQuantity"/>
+      <el-table-column label="杞戒綋鏈嶅姟鍣�" align="center" prop="serverId_dictText"/>
+      <el-table-column label="鏂藉伐鎵规" align="center" prop="constructionBatchId_dictText"/>
+      <el-table-column label="鐢熶骇鍘傚晢" align="center" prop="manufacturerId_dictText"/>
+      <el-table-column label="澶囨敞" align="center" prop="remarks"/>
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleInfo(scope.row)"
+          >鏌ョ湅
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              v-hasPermi="['oa:system:edit']"
+          >淇敼
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-folder"
+              @click="handleUpload(scope.row)"
+          >闄勪欢
+          </el-button>
+          <el-button
+              size="mini"
+              type="text"
+              class="del-btn"
+              icon="el-icon-delete"
+              @click="handleDelete(scope.row)"
+              v-hasPermi="['oa:system:remove']"
+          >鍒犻櫎
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <!-- 娣诲姞鎴栦慨鏀硅蒋浠剁郴缁熷璇濇 -->
+    <el-dialog :title="title" :visible.sync="open" width="700px" :append-to-body="true" :close-on-click-modal="false">
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px" :disabled="disabled">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="杞欢鍚嶇О" prop="name">
+              <el-input v-model="form.name" maxlength="64" show-word-limit placeholder="璇疯緭鍏ヨ蒋浠跺悕绉�"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐗堟湰" prop="edition">
+              <el-input v-model="form.edition" maxlength="64" show-word-limit placeholder="璇疯緭鍏ョ増鏈�"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍔熻兘鎻忚堪" prop="functionDescription">
+          <el-input v-model="form.functionDescription" :rows="8" maxlength="64" show-word-limit type="textarea"
+                    placeholder="璇疯緭鍏ュ唴瀹�"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鎺堟潈鏂瑰紡" prop="authorizationMethod">
+              <el-select v-model="form.authorizationMethod" placeholder="璇烽�夋嫨鎺堟潈鏂瑰紡">
+                <el-option
+                    v-for="dict in dict.type.DICT116"
+                    :key="dict.value"
+                    :label="dict.label"
+                    :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎺堟潈鏁伴噺" prop="authorizedQuantity">
+              <el-input v-model="form.authorizedQuantity" maxlength="64" show-word-limit placeholder="璇疯緭鍏ユ巿鏉冩暟閲�"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="杞戒綋鏈嶅姟鍣�" prop="serverId">
+          <server v-if="open" v-model="form.serverId" :schoolId="schoolId"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鏂藉伐鎵规" prop="constructionBatchId">
+              <constructionBatch v-if="open" v-model="form.constructionBatchId"
+                                 :schoolId="schoolId"></constructionBatch>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐢熶骇鍘傚晢" prop="manufacturerId">
+              <manufacturer v-model="form.manufacturerId"></manufacturer>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="澶囨敞" prop="remarks">
+          <el-input v-model="form.remarks" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="buttonLoading" :disabled="disabled" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 闄勪欢 -->
+    <Dialog title="闄勪欢" :visible.sync="fileOpen" width="500px" :append-to-body="true" :destroy-on-close="true">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="闄勪欢" prop="filePath">
+          <fileUpload v-model="form.filePath" :limit="1"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </Dialog>
+  </div>
+</template>
+
+<script>
+import {listSystem, getSystem, delSystem, addSystem, updateSystem} from "@/api/oa/system";
+import building from "../../components/building";
+import organization from "../../components/organization";
+import constructionBatch from "../../components/constructionBatch";
+import manufacturer from "../../components/manufacturer";
+import nvr from "../../components/nvr";
+import server from '../../components/server'
+
+export default {
+  name: "System",
+  dicts: ['DICT116'],
+  components: {
+    building,
+    organization,
+    constructionBatch,
+    manufacturer,
+    nvr,
+    server
+  },
+  props: {
+    schoolId: {
+      type: Number,
+      default: undefined
+    }
+  },
+  data() {
+    return {
+      // 鎸夐挳loading
+      buttonLoading: false,
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 杞欢绯荤粺琛ㄦ牸鏁版嵁
+      systemList: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        schoolId: undefined,
+        name: undefined,
+        serverId: undefined,
+        constructionBatchId: undefined,
+        manufacturerId: undefined,
+      },
+      // 琛ㄥ崟鍙傛暟
+      form: {},
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+        id: [
+          {required: true, message: "涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        schoolId: [
+          {required: true, message: "楂樻牎涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        name: [
+          {required: true, message: "杞欢鍚嶇О涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        edition: [
+          {required: true, message: "鐗堟湰涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        functionDescription: [
+          {required: true, message: "鍔熻兘鎻忚堪涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        authorizationMethod: [
+          {required: true, message: "鎺堟潈鏂瑰紡涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        authorizedQuantity: [
+          {required: true, message: "鎺堟潈鏁伴噺涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+        serverId: [
+          {required: true, message: "杞戒綋鏈嶅姟鍣ㄤ笉鑳戒负绌�", trigger: "blur"}
+        ],
+        constructionBatchId: [
+          {required: true, message: "鏂藉伐鎵规涓嶈兘涓虹┖", trigger: "blur"}
+        ],
+      },
+      disabled: false,
+      fileOpen: false
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 鏌ヨ杞欢绯荤粺鍒楄〃 */
+    getList() {
+      this.loading = true;
+      listSystem(Object.assign({}, this.queryParams, {schoolId: this.schoolId})).then(response => {
+        this.systemList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 鍙栨秷鎸夐挳
+    cancel() {
+      this.open = false;
+      this.fileOpen = false;
+      this.reset();
+    },
+    // 琛ㄥ崟閲嶇疆
+    reset() {
+      this.form = {
+        id: undefined,
+        schoolId: undefined,
+        name: undefined,
+        edition: undefined,
+        functionDescription: undefined,
+        authorizationMethod: undefined,
+        authorizedQuantity: undefined,
+        serverId: undefined,
+        constructionBatchId: undefined,
+        manufacturerId: undefined,
+        remarks: undefined,
+        filePath: undefined,
+        createBy: undefined,
+        createTime: undefined,
+        updateBy: undefined,
+        updateTime: undefined,
+        delFlag: undefined
+      };
+      this.resetForm("form");
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd() {
+      this.reset();
+      this.disabled = false;
+      this.open = true;
+      this.title = "娣诲姞杞欢绯荤粺";
+    },
+    handleInfo(row) {
+      this.loading = true;
+      this.disabled = true;
+      this.reset();
+      getSystem(row.id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "杞欢绯荤粺璇︽儏";
+      });
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+      this.loading = true;
+      this.disabled = false;
+      this.reset();
+      const id = row.id || this.ids
+      getSystem(id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "淇敼杞欢绯荤粺";
+      });
+    },
+    handleUpload(row) {
+      this.loading = true;
+      this.disabled = false;
+      this.reset();
+      getSystem(row.id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.fileOpen = true;
+      });
+    },
+    /** 鎻愪氦鎸夐挳 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.buttonLoading = true;
+          this.form.schoolId = this.schoolId;
+          if (this.form.id != null) {
+            updateSystem(this.form).then(response => {
+              this.$modal.msgSuccess("淇敼鎴愬姛");
+              this.open = false;
+              this.fileOpen = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          } else {
+            addSystem(this.form).then(response => {
+              this.$modal.msgSuccess("鏂板鎴愬姛");
+              this.open = false;
+              this.fileOpen = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          }
+        }
+      });
+    },
+    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('鏄惁纭鍒犻櫎杞欢绯荤粺缂栧彿涓�"' + ids + '"鐨勬暟鎹」锛�').then(() => {
+        this.loading = true;
+        return delSystem(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
+    handleExport() {
+      this.download('oa/system/export', {
+        ...this.queryParams
+      }, `system_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>
diff --git a/vue.config.js b/vue.config.js
index 4358146..b3ac9e8 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -34,7 +34,7 @@
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
         // target: `http://101.35.174.42:8082`,
-        target: `http://localhost:8080`,
+        target: `http://localhost:8081`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''

--
Gitblit v1.9.1