Browse Source

系统管理权限

tianyabing 2 năm trước cách đây
mục cha
commit
34351943c2
45 tập tin đã thay đổi với 2093 bổ sung694 xóa
  1. 3 1
      package.json
  2. 4 0
      public/config.js
  3. 11 9
      public/index.html
  4. 1 1
      src/App.vue
  5. 21 0
      src/api/data/AuthInfo.js
  6. 13 0
      src/api/data/ImportData.js
  7. 31 0
      src/api/data/IotData.js
  8. 11 0
      src/api/data/SystemInfo.js
  9. 6 0
      src/api/login.js
  10. BIN
      src/assets/fonts/AlibabaPuHuiTi-Regular.ttf
  11. BIN
      src/assets/fonts/AlibabaSans-Regular.ttf
  12. BIN
      src/assets/img/bg.jpg
  13. BIN
      src/assets/img/header.png
  14. BIN
      src/assets/img/icons/dataDetail.png
  15. BIN
      src/assets/img/icons/introduce.png
  16. BIN
      src/assets/img/icons/platform.png
  17. BIN
      src/assets/img/icons/systemInfo.png
  18. BIN
      src/assets/img/title.png
  19. 189 5
      src/components/dataManage/ImportData.vue
  20. 13 21
      src/components/dataManage/dataDetail/BusinessDataDetail.vue
  21. 241 0
      src/components/dataManage/dataDetail/IotDataDetail.vue
  22. 12 20
      src/components/dataManage/dataDetail/MetaDataDetail.vue
  23. 13 28
      src/components/dataManage/dataDetail/ModelDataDetail.vue
  24. 122 64
      src/components/dataManage/dataDetail/ThreeDimensionalDataDetail.vue
  25. 43 23
      src/components/dataManage/dataDetail/TwoDimensionalDataDetail.vue
  26. 10 4
      src/components/dataManage/dataShow/BusinessData.vue
  27. 257 72
      src/components/dataManage/dataShow/IotData.vue
  28. 16 5
      src/components/dataManage/dataShow/MetaData.vue
  29. 16 5
      src/components/dataManage/dataShow/ModelData.vue
  30. 17 6
      src/components/dataManage/dataShow/ThreeDimensionalData.vue
  31. 10 4
      src/components/dataManage/dataShow/TwoDimensionalData.vue
  32. 122 108
      src/components/home/DataManage.vue
  33. 61 49
      src/components/home/DataPublish.vue
  34. 228 68
      src/components/home/HomeIndex.vue
  35. 61 47
      src/components/home/PluginManage.vue
  36. 101 2
      src/components/home/SystemManage.vue
  37. 27 0
      src/components/map/CesiumMap.vue
  38. 19 3
      src/components/map/OlMap.vue
  39. 140 0
      src/components/systemManage/AuthManage.vue
  40. 114 0
      src/components/systemManage/SystemLogs.vue
  41. 5 0
      src/main.js
  42. 1 1
      src/static/datas/PluginData.json
  43. 11 0
      src/style/element-variables.scss
  44. 2 0
      src/utils/constant.js
  45. 141 148
      src/views/HomeView.vue

+ 3 - 1
package.json

@@ -16,9 +16,11 @@
     "copy-webpack-plugin": "^11.0.0",
     "core-js": "^3.8.3",
     "dayjs": "^1.11.5",
+    "echarts": "^5.4.0",
     "element-plus": "^2.2.18",
     "element-resize-detector": "^1.2.4",
     "node-polyfill-webpack-plugin": "^2.0.1",
+    "node-sass": "^7.0.3",
     "ol": "^7.1.0",
     "path": "^0.12.7",
     "qs": "^6.11.0",
@@ -41,6 +43,6 @@
     "eslint": "^7.32.0",
     "eslint-plugin-vue": "^8.0.3",
     "sass": "^1.32.7",
-    "sass-loader": "^12.0.0"
+    "sass-loader": "^12.6.0"
   }
 }

+ 4 - 0
public/config.js

@@ -0,0 +1,4 @@
+var systemConfig = {
+    // 天地图tk
+    tdt_tk: 'b57488e37657af2abde80438a911a635',
+}

+ 11 - 9
public/index.html

@@ -1,17 +1,19 @@
 <!DOCTYPE html>
 <html lang="">
-  <head>
+<head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= htmlWebpackPlugin.options.title %></title>
-  </head>
-  <body>
-    <noscript>
-      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
-    </noscript>
-    <div id="app"></div>
-    <!-- built files will be auto injected -->
-  </body>
+    <script src="config.js" type="text/javascript"></script>
+</head>
+<body>
+<noscript>
+    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
+        Please enable it to continue.</strong>
+</noscript>
+<div id="app"></div>
+<!-- built files will be auto injected -->
+</body>
 </html>

+ 1 - 1
src/App.vue

@@ -26,7 +26,7 @@ html,body {
   margin: auto;
 }
 #app {
-  font-family: Avenir, Helvetica, Arial, sans-serif;
+  font-family: AlibabaPuHuiTi-Regular, Avenir, Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
   color: #2c3e50;

+ 21 - 0
src/api/data/AuthInfo.js

@@ -0,0 +1,21 @@
+import request from "@/utils/request";
+import constant from "@/utils/constant";
+
+// 查询当前系统普通角色
+const getRoleList = (params) => {
+    return request.postForm(constant.oauthProxy + '/role/getRoleByServiceId', params);
+}
+// 查询当前系统所有权限
+const getAuthList = (params) => {
+    return request.postForm(constant.oauthProxy + '/permission/getPermissionTreeByServiceId', params);
+}
+// 更新当前角色权限
+const updateRoleAuth = (params) =>{
+    return request.postForm(constant.oauthProxy + '/role/updateRolePermission', params);
+}
+
+export default {
+    getRoleList,
+    getAuthList,
+    updateRoleAuth,
+}

+ 13 - 0
src/api/data/ImportData.js

@@ -0,0 +1,13 @@
+import request from "@/utils/request";
+import constant from "@/utils/constant";
+
+// 导入二维数据-Shape
+const importTwoDData = (params, type) => {
+    if (type==='Shape') {
+        return request.postForm(constant.dtbserverProxy + '/latlon/addDataForShapeZip', params)
+    }
+}
+
+export default {
+    importTwoDData,
+}

+ 31 - 0
src/api/data/IotData.js

@@ -0,0 +1,31 @@
+import request from "@/utils/request";
+import constant from "@/utils/constant";
+
+// 分页查询物联感知数据
+const getData = (params) => {
+    return request.postForm(constant.dtbserverProxy + '/iotData/selectIOTDataData', params);
+}
+// 通过ID查询物联感知数据
+const getDataById = (params) => {
+    return request.postForm(constant.dtbserverProxy + '/iotData/getIOTById', params)
+}
+// 新增物联感知数据
+const addData = (params) => {
+    return request.postForm(constant.dtbserverProxy + '/iotData/addIotData', params);
+}
+// 修改物联感知数据
+const updateData = (params) => {
+    return request.postForm(constant.dtbserverProxy + '/iotData/addIotData', params);
+}
+// 删除物联感知数据
+const deleteData = (params) => {
+    return request.postForm(constant.dtbserverProxy + '/iotData/deleteIOTData', params)
+}
+
+export default {
+    getData,
+    getDataById,
+    addData,
+    updateData,
+    deleteData,
+}

+ 11 - 0
src/api/data/SystemInfo.js

@@ -0,0 +1,11 @@
+import request from "@/utils/request";
+import constant from "@/utils/constant";
+
+// 分页查询系统日志
+const getLogData = (params) => {
+    return request.postForm(constant.oauthProxy + '/record/getRecord', params);
+}
+
+export default {
+    getLogData,
+}

+ 6 - 0
src/api/login.js

@@ -5,6 +5,12 @@ const userLogin = (params) => {
     return request.postForm(constant.oauthProxy + '/api/user/login', params);
 }
 
+// 查询用户的权限
+const getUserPermissions = (params) => {
+    return request.postForm(constant.oauthProxy + '/api/user/getUserAuthsByToken', params);
+}
+
 export default {
     userLogin,
+    getUserPermissions,
 }

BIN
src/assets/fonts/AlibabaPuHuiTi-Regular.ttf


BIN
src/assets/fonts/AlibabaSans-Regular.ttf


BIN
src/assets/img/bg.jpg


BIN
src/assets/img/header.png


BIN
src/assets/img/icons/dataDetail.png


BIN
src/assets/img/icons/introduce.png


BIN
src/assets/img/icons/platform.png


BIN
src/assets/img/icons/systemInfo.png


BIN
src/assets/img/title.png


+ 189 - 5
src/components/dataManage/ImportData.vue

@@ -2,28 +2,212 @@
   <div id="ImportData">
     <h2>数据导入</h2>
     <el-divider></el-divider>
-    <el-form>
-      <el-form-item>
-        <el-upload></el-upload>
+    <el-form v-if="auth" :model="importForm" ref="importForm" :rules="importFormRules" :label-width="120">
+      <el-form-item label="数据类型:" prop="dataType">
+        <el-select v-model="importForm.dataType" placeholder="请选择要导入的数据类型">
+          <el-option v-for="item in dataTypes" :key="item.value" :label="item.label" :value="item.value"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="导入类型:" prop="importType">
+        <el-select v-model="importForm.importType" placeholder="请选择导入的文件类型">
+          <el-option v-for="item in currImportTypes" :key="item.value" :value="item.value" :label="item.label"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="文件选择:" prop="file">
+        <el-upload ref="upload"
+                   v-model:file-list="importForm['fileList']"
+                   :limit="1"
+                   :auto-upload="false"
+                   :on-exceed="handleUploadExceed"
+                   :on-change="handleUploadChange"
+                   :before-remove="handleUploadRemove"
+                   style="min-width: 50%"
+        >
+          <el-input v-model="importForm.file" :disabled="true" type="hidden"/>
+          <el-button type="default" size="small">选择文件</el-button>
+        </el-upload>
+      </el-form-item>
+
+      <el-form-item label="字段映射:" v-if="importForm.dataType">
+        <el-table :data="importForm.tableData" border stripe max-height="220">
+          <el-table-column prop="fieldName" label="字段名称"/>
+          <el-table-column prop="newFieldName" label="文件中字段名称">
+            <template #default="scope">
+              <el-form-item :prop="scope.row.fieldName==='数据类型'?'menuId':scope.row.fieldName">
+                <el-select v-model="importForm['menuId']" @change="handleMenuIdSelect"
+                           v-if="scope.row.fieldName==='数据类型'">
+                  <el-option v-for="item in category" :key="item.id" :label="item.title" :value="item.id"/>
+                </el-select>
+                <el-input v-model="importForm[scope.row.fieldName]" placeholder="请输入文件中对应字段的名字" v-else/>
+              </el-form-item>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+
+      <el-form-item label-width="70%">
+        <el-button type="primary" @click="submit">确认导入</el-button>
       </el-form-item>
     </el-form>
+    <el-empty v-if="!auth" description="无权限" ></el-empty>
   </div>
 </template>
 
 <script>
+import {genFileId} from "element-plus";
+import menuApi from "@/api/data/MenuData";
+import api from "@/api/data/ImportData"
+
 export default {
   data() {
+    return {
+      auth: false,
+      importForm: {},
+      importFormRules: {
+        dataType: [
+          {required: true, message: '请选择数据类型', trigger: 'blur'},
+          {required: true, message: '请选择数据类型', trigger: 'change'}
+        ],
+        importType: [
+          {required: true, message: '请选择导入类型', trigger: 'blur'},
+          {required: true, message: '请选择导入类型', trigger: 'change'}
+        ],
+        file: [
+          {required: true, message: '请选择文件', trigger: 'blur'},
+          {required: true, message: '请选择文件', trigger: 'change'},
+        ],
+        title: [
+          {required: true, message: '字段不能为空', trigger: 'blur'},
+          {required: true, message: '字段不能为空', trigger: 'change'},
+        ],
+        content: [
+          {required: true, message: '字段不能为空', trigger: 'blur'},
+          {required: true, message: '字段不能为空', trigger: 'change'},
+        ],
+        thirdId: [
+          {required: true, message: '字段不能为空', trigger: 'blur'},
+          {required: true, message: '字段不能为空', trigger: 'change'},
+        ],
+        address: [
+          {required: true, message: '字段不能为空', trigger: 'blur'},
+          {required: true, message: '字段不能为空', trigger: 'change'},
+        ],
+        menuId: [
+          {required: true, message: '字段不能为空', trigger: 'blur'},
+          {required: true, message: '字段不能为空', trigger: 'change'},
+        ],
 
-  },
-  props: {
 
+      },
+      dataTypes: [
+        {label: '二维数据', value: 1},
+        // {label: '三维数据', value: 2},
+        // {label: '业务数据', value: 3},
+        // {label: '模型数据', value: 4},
+        // {label: '元数据', value: 5},
+        // {label: '物联感知数据', value: 6},
+      ],
+      currImportTypes: [],
+      importTypes: {
+        1: [
+          {label: 'Shape', value: 'Shape'}
+        ],
+        2: [],
+        3: [],
+        4: [],
+        5: [],
+        6: [],
+      },
+      fieldTableData: {
+        1: [
+          {fieldName: 'title', newFieldName: ''},
+          {fieldName: 'content', newFieldName: ''},
+          {fieldName: 'thirdId', newFieldName: ''},
+          // {fieldName: 'addId', newFieldName: ''},
+          {fieldName: 'address', newFieldName: ''},
+          {fieldName: '数据类型', newFieldName: ''},
+        ],
+      },
+      category: []
+    }
+  },
+  props: {},
+  watch: {
+    "importForm.dataType": function (newVal, oldVal) {
+      if (newVal) {
+        this.currImportTypes = this.importTypes[newVal];
+        this.importForm.tableData = this.fieldTableData[newVal];
+        this.getMenuData(newVal)
+      }
+    }
   },
   created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
   },
   mounted() {
   },
   methods: {
+    handleUploadChange(file) {
+      let fileObj = file.raw;
+      // if (this.uploadType[this.importForm.fileType].indexOf(fileObj.type)<0) {
+      //   this.$message({message: '不支持的文件类型', type: 'warning'})
+      //   this.$refs.upload.clearFiles();
+      //   this.importForm.file=null;
+      //   return;
+      // }
+      this.importForm.file = file.raw;
 
+    },
+    getMenuData(type) {
+      let app = this;
+      let params = {
+        type: type,
+        parentId: "1",
+      }
+      menuApi.getMenuData(params).then(res => {
+        if (res.code === 200) {
+          app.category = res.content
+        }
+      })
+    },
+    handleMenuIdSelect(val) {
+      for (let i = 0; i < this.category.length; i++) {
+        let item = this.category[i];
+        if (item.id == val) {
+          this.importForm['menuNameTwo'] = item.title
+          break;
+        }
+      }
+    },
+    handleUploadExceed(file) {
+      this.$refs.upload.clearFiles();
+      file = file[0];
+      file.uid = genFileId()
+      this.$refs.upload.handleStart(file);
+    },
+    handleUploadRemove(val) {
+      this.importForm.file = null;
+    },
+    submit() {
+      let app = this;
+      this.$refs.importForm.validate(valid => {
+        if (valid) {
+          let params = JSON.parse(JSON.stringify(app.importForm));
+          delete params.tableData;
+          delete params.fileList;
+          delete params.dataType;
+          delete params.importType;
+          params['userName'] = app.$store.state.userInfo.username;
+          api.importTwoDData(params, app.importForm.importType)
+        } else {
+          app.$message({message: '请先检查并完善信息', type: 'warning'})
+        }
+      })
+    },
   }
 }
 </script>

+ 13 - 21
src/components/dataManage/dataDetail/BusinessDataDetail.vue

@@ -18,7 +18,7 @@
           <el-input v-model="formData.content" placeholder="请输入描述" :disabled="formData.isDataView" />
         </el-form-item>
         <el-form-item label="类别:" prop="menuId">
-          <el-select v-model="formData.menuId" placeholder="请选择类别" :disabled="formData.isDataView" >
+          <el-select v-model="formData.menuId" placeholder="请选择类别" @change="handleMenuIdSelect" :disabled="formData.isDataView" >
             <el-option
                 v-for="item in category"
                 :key="item.value"
@@ -111,26 +111,7 @@ export default {
     close: Function
   },
   watch: {
-    "formData.menuId": function (newVal, oldVal) {
-      let app = this;
-      if (app.formData.isEdit) {
-        if (newVal!==app.oriFormData.menuId) {
-          app.$msgbox.confirm('修改类型需重新设置地理信息,确定要修改吗?','Warning', {
-            confirmButtonText: '确认修改',
-            cancelButtonText: '恢复原始类别及地理信息',
-            type: 'warning',
-          }).then(()=>{
-            app.formData.geometryStr = ''
-          }).catch(()=>{
-            app.formData.menuId = app.oriFormData.menuId;
-            app.formData.geometryStr = app.oriFormData.geometryStr;
-          })
-        } else {
-          app.formData.geometryStr = app.oriFormData.geometryStr;
-        }
 
-      }
-    }
   },
   mounted() {
     this.getMenuData()
@@ -189,6 +170,7 @@ export default {
     addData() {
       let app = this;
       let params = JSON.parse(JSON.stringify(app.formData));
+      params['userName'] = app.$store.state.userInfo.username;
       params['menuNameOne'] = '二维数据'
       api.addData(params).then(res=>{
         if (res.code===200) {
@@ -201,6 +183,7 @@ export default {
     updateData() {
       let app = this;
       let params = JSON.parse(JSON.stringify(app.formData));
+      params['userName'] = app.$store.state.userInfo.username;
       delete params.createDate;
       delete params.updateDate;
       api.updateData(params).then(res=>{
@@ -212,7 +195,16 @@ export default {
     },
     handleJsonDataView(flag) {
       this.isJsonDataView = flag;
-    }
+    },
+    handleMenuIdSelect(val) {
+      for (let i = 0; i < this.category.length; i++) {
+        let item = this.category[i];
+        if (item.id == val) {
+          this.formData['menuNameTwo'] = item.title
+          break;
+        }
+      }
+    },
   }
 }
 </script>

+ 241 - 0
src/components/dataManage/dataDetail/IotDataDetail.vue

@@ -0,0 +1,241 @@
+<template>
+  <el-dialog v-if="isShow"
+             :model-value="isShow"
+             title="编辑数据"
+             :width="700"
+             :close-on-click-modal="false"
+             :before-close="handleClose"
+  >
+    <div id="addData">
+      <el-form ref="form" :inline="true" :model="formData" :rules="formDataRules" style="margin: 0 15px"
+               :label-width="110">
+        <el-form-item label="ID:" v-show="false">
+          <el-input v-model="formData.id"/>
+        </el-form-item>
+        <el-form-item label="标题:" prop="title" style="width: 100%">
+          <el-input v-model="formData.title" placeholder="请输入标题" :disabled="formData.isDataView"/>
+        </el-form-item>
+        <el-form-item label="描述:" prop="content" style="width: 100%">
+          <el-input v-model="formData.content" placeholder="请输入描述" :disabled="formData.isDataView"/>
+        </el-form-item>
+        <el-form-item label="媒体类型:" prop="modelType" style="width: 100%">
+          <el-input v-model="formData.modelType" placeholder="请输入类型" :disabled="formData.isDataView"/>
+        </el-form-item>
+        <el-form-item label="媒体地址:" prop="url" style="width: 100%">
+          <el-input v-model="formData.url" placeholder="请输入媒体地址" :disabled="formData.isDataView"/>
+        </el-form-item>
+        <el-form-item label="类别:" prop="menuId">
+          <el-select v-model="formData.menuId" placeholder="请选择类别" @change="handleMenuIdSelect" :disabled="formData.isDataView">
+            <el-option
+                v-for="item in category"
+                :key="item.id"
+                :label="item.title"
+                :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <br/>
+        <el-form-item label="经度:" style="width: 40%" prop="lon">
+          <el-input :model-value="formData.lon" placeholder="经度" :disabled="formData.isDataView">
+          </el-input>
+        </el-form-item>
+        <el-form-item label="纬度:" style="width: 35%" :label-width="70" prop="lat">
+          <el-input :model-value="formData.lat" placeholder="纬度" :disabled="formData.isDataView">
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button style="font-size: 18px" @click="handleLonlatSelect" >
+            <el-icon><ElIconLocation/></el-icon>
+          </el-button>
+        </el-form-item>
+        <br/>
+        <el-form-item label="地名地址库:" prop="address" style="width: 100%">
+          <el-input v-model="formData.address" placeholder="请输入地名地址库名称" :disabled="formData.isDataView"/>
+        </el-form-item>
+      </el-form>
+    </div>
+    <template #footer>
+      <el-button type="primary" @click="submit" v-show="!formData.isDataView">保存</el-button>
+    </template>
+  </el-dialog>
+
+  <OlMap v-if="isLonLatShow"
+         :is-show="isLonLatShow"
+         :is-view="formData.isDataView"
+         :geometry-str="formData.geometryStr"
+         :menuId="1"
+         :callback="setLonLatData"
+         :close="handleLonlatSelect">
+  </OlMap>
+</template>
+
+<script>
+import OlMap from "@/components/map/OlMap";
+import api from "@/api/data/ModelData";
+import menuApi from "@/api/data/MenuData";
+
+export default {
+  data() {
+    return {
+      formData: {},
+      oriFormData: {},
+      formDataRules: {
+        title: [
+          {required: true, message: '请输入标题', trigger: 'blur'},
+          {required: true, message: '请输入标题', trigger: 'change'},
+        ],
+        content: [
+          {required: true, message: '请输入描述', trigger: 'blur'},
+          {required: true, message: '请输入描述', trigger: 'change'},
+        ],
+        modelType: [
+          {required: true, message: '请输入类型', trigger: 'blur'},
+          {required: true, message: '请输入类型', trigger: 'change'},
+        ],
+        menuId: [
+          {required: true, message: '请选择类别', trigger: 'blur'},
+          {required: true, message: '请选择类别', trigger: 'change'},
+        ],
+        geometryStr: [
+          {required: true, message: '请输入Geojson数据', trigger: 'blur'},
+        ],
+        url: [
+          {required: true, message: '该字段不能为空', trigger: 'blur'},
+          {required: true, message: '该字段不能为空', trigger: 'change'},
+        ],
+        lon: [
+          {required: true, message: '该字段不能为空', trigger: 'blur'},
+          {required: true, message: '该字段不能为空', trigger: 'change'},
+        ],
+        lat: [
+          {required: true, message: '该字段不能为空', trigger: 'blur'},
+          {required: true, message: '该字段不能为空', trigger: 'change'},
+        ]
+        // address: [
+        //   { required: true, message: '请输入地名地址库名称', trigger: 'change' },
+        // ]
+      },
+      category: [],
+      isLonLatShow: false,
+
+    }
+  },
+  props: {
+    isShow: Boolean,
+    item: Object,
+    close: Function
+  },
+  watch: {
+
+  },
+  mounted() {
+    this.getMenuData();
+    this.formData = this.item;
+    this.oriFormData = JSON.parse(JSON.stringify(this.formData))
+  },
+  components: {
+    OlMap,
+  },
+  methods: {
+    handleLonlatSelect(flag) {
+      if (flag) {
+        this.formData.geometryStr = JSON.stringify(this.covertToGeometry())
+        this.isLonLatShow = true
+      } else {
+        this.isLonLatShow = false
+      }
+    },
+    covertToGeometry() {
+      let geometry = {
+        type: 'Point',
+        coordinates: []
+      }
+      if (this.formData.lon && this.formData.lon!=='' && this.formData.lat && this.formData.lat !=='') {
+        geometry.coordinates.push(this.formData.lon)
+        geometry.coordinates.push(this.formData.lat)
+        return geometry;
+      } else {
+        return '';
+      }
+    },
+    setLonLatData(obj) {
+      if (obj.coordinates && obj.coordinates.length>1) {
+        this.formData.lon = obj.coordinates[0];
+        this.formData.lat = obj.coordinates[1];
+      }
+    },
+    getMenuData() {
+      let app = this;
+      let params = {
+        type: "1",
+        parentId: "4",
+      }
+      menuApi.getMenuData(params).then(res => {
+        if (res.code === 200) {
+          app.category = res.content
+        }
+      })
+    },
+    handleClose() {
+      this.close();
+    },
+    submit() {
+      let app = this;
+      app.$refs.form.validate(valid => {
+        if (valid) {
+          if (app.formData.isEdit) {
+            app.updateData();
+          } else {
+            app.addData();
+          }
+        } else {
+          app.$message({message: '请完善数据', type: 'warning'})
+        }
+      })
+    },
+    // 数据录入
+    addData() {
+      let app = this;
+      let params = JSON.parse(JSON.stringify(app.formData));
+      params['menuNameOne'] = '模型数据'
+      params['userName'] = app.$store.state.userInfo.username;
+      api.addData(params).then(res => {
+        if (res.code === 200) {
+          app.$message({message: '录入成功', type: 'success'})
+          app.close(true);
+        }
+      })
+    },
+    // 编辑数据
+    updateData() {
+      let app = this;
+      let params = JSON.parse(JSON.stringify(app.formData));
+      delete params.createDate;
+      delete params.updateDate;
+      params['userName'] = app.$store.state.userInfo.username;
+      api.updateData(params).then(res => {
+        if (res.code === 200) {
+          app.$message({message: '修改成功', type: 'success'})
+          app.close(true);
+        }
+      })
+    },
+    handleMenuIdSelect(val) {
+      for (let i = 0; i < this.category.length; i++) {
+        let item = this.category[i];
+        if (item.id == val) {
+          this.formData['menuNameTwo'] = item.title
+          break;
+        }
+      }
+    },
+  }
+}
+</script>
+
+<style>
+#addData {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 12 - 20
src/components/dataManage/dataDetail/MetaDataDetail.vue

@@ -18,7 +18,7 @@
           <el-input v-model="formData.content" placeholder="请输入描述" :disabled="formData.isDataView" />
         </el-form-item>
         <el-form-item label="类别:" prop="menuId">
-          <el-select v-model="formData.menuId" placeholder="请选择类别" :disabled="formData.isDataView" >
+          <el-select v-model="formData.menuId" placeholder="请选择类别" @change="handleMenuIdSelect" :disabled="formData.isDataView" >
             <el-option
                 v-for="item in category"
                 :key="item.value"
@@ -126,26 +126,7 @@ export default {
     close: Function
   },
   watch: {
-    "formData.menuId": function (newVal, oldVal) {
-      let app = this;
-      if (app.formData.isEdit) {
-        if (newVal!==app.oriFormData.menuId) {
-          app.$msgbox.confirm('修改类型需重新设置地理信息,确定要修改吗?','Warning', {
-            confirmButtonText: '确认修改',
-            cancelButtonText: '恢复原始类别及地理信息',
-            type: 'warning',
-          }).then(()=>{
-            app.formData.geometryStr = ''
-          }).catch(()=>{
-            app.formData.menuId = app.oriFormData.menuId;
-            app.formData.geometryStr = app.oriFormData.geometryStr;
-          })
-        } else {
-          app.formData.geometryStr = app.oriFormData.geometryStr;
-        }
 
-      }
-    }
   },
   mounted() {
     this.getMenuData()
@@ -199,6 +180,7 @@ export default {
       let app = this;
       let params = JSON.parse(JSON.stringify(app.formData));
       params['menuNameOne'] = '二维数据'
+      params['userName'] = app.$store.state.userInfo.username;
       api.addData(params).then(res=>{
         if (res.code===200) {
           app.$message({message: '录入成功', type: 'success'})
@@ -212,6 +194,7 @@ export default {
       let params = JSON.parse(JSON.stringify(app.formData));
       delete params.createDate;
       delete params.updateDate;
+      params['userName'] = app.$store.state.userInfo.username;
       api.updateData(params).then(res=>{
         if (res.code===200) {
           app.$message({message: '修改成功', type: 'success'})
@@ -219,6 +202,15 @@ export default {
         }
       })
     },
+    handleMenuIdSelect(val) {
+      for (let i = 0; i < this.category.length; i++) {
+        let item = this.category[i];
+        if (item.id == val) {
+          this.formData['menuNameTwo'] = item.title
+          break;
+        }
+      }
+    },
   }
 }
 </script>

+ 13 - 28
src/components/dataManage/dataDetail/ModelDataDetail.vue

@@ -22,7 +22,7 @@
           <el-input v-model="formData.modelType" placeholder="请输入类型" :disabled="formData.isDataView"/>
         </el-form-item>
         <el-form-item label="类别:" prop="menuId">
-          <el-select v-model="formData.menuId" placeholder="请选择类别" :disabled="formData.isDataView">
+          <el-select v-model="formData.menuId" placeholder="请选择类别" @change="handleMenuIdSelect" :disabled="formData.isDataView">
             <el-option
                 v-for="item in category"
                 :key="item.id"
@@ -150,26 +150,7 @@ export default {
     close: Function
   },
   watch: {
-    "formData.menuId": function (newVal, oldVal) {
-      let app = this;
-      if (app.formData.isEdit) {
-        if (oldVal && newVal !== app.oriFormData.menuId) {
-          app.$msgbox.confirm('修改类型需重新设置地理信息,确定要修改吗?', 'Warning', {
-            confirmButtonText: '确认修改',
-            cancelButtonText: '恢复原始类别及地理信息',
-            type: 'warning',
-          }).then(() => {
-            app.formData.geometryStr = ''
-          }).catch(() => {
-            app.formData.menuId = app.oriFormData.menuId;
-            app.formData.geometryStr = app.oriFormData.geometryStr;
-          })
-        } else {
-          app.formData.geometryStr = app.oriFormData.geometryStr;
-        }
 
-      }
-    }
   },
   mounted() {
     this.getMenuData();
@@ -257,13 +238,7 @@ export default {
       let app = this;
       let params = JSON.parse(JSON.stringify(app.formData));
       params['menuNameOne'] = '模型数据'
-      for (let i = 0; i < this.category.length; i++) {
-        let obj = this.category[i];
-        if (obj.id === params.menuId) {
-          params['menuNameTwo'] = obj.title;
-          break;
-        }
-      }
+      params['userName'] = app.$store.state.userInfo.username;
       api.addData(params).then(res => {
         if (res.code === 200) {
           app.$message({message: '录入成功', type: 'success'})
@@ -277,6 +252,7 @@ export default {
       let params = JSON.parse(JSON.stringify(app.formData));
       delete params.createDate;
       delete params.updateDate;
+      params['userName'] = app.$store.state.userInfo.username;
       api.updateData(params).then(res => {
         if (res.code === 200) {
           app.$message({message: '修改成功', type: 'success'})
@@ -286,7 +262,16 @@ export default {
     },
     handleJsonDataView(flag) {
       this.isJsonDataView = flag;
-    }
+    },
+    handleMenuIdSelect(val) {
+      for (let i = 0; i < this.category.length; i++) {
+        let item = this.category[i];
+        if (item.id == val) {
+          this.formData['menuNameTwo'] = item.title
+          break;
+        }
+      }
+    },
   }
 }
 </script>

+ 122 - 64
src/components/dataManage/dataDetail/ThreeDimensionalDataDetail.vue

@@ -7,18 +7,22 @@
              :before-close="handleClose"
   >
     <div id="addData">
-      <el-form ref="form" :model="formData" :rules="formDataRules" style="margin: 0 15px" :label-width="110">
+      <el-form ref="form" :inline="true" :model="formData" :rules="formDataRules" style="margin: 0 15px"
+               :label-width="110">
         <el-form-item label="ID:" v-show="false">
-          <el-input v-model="formData.id" />
+          <el-input v-model="formData.id"/>
         </el-form-item>
-        <el-form-item label="标题:" prop="title" >
-          <el-input v-model="formData.title" placeholder="请输入标题" :disabled="formData.isDataView" />
+        <el-form-item label="标题:" prop="title" style="width: 100%">
+          <el-input v-model="formData.title" placeholder="请输入标题" :disabled="formData.isDataView"/>
         </el-form-item>
-        <el-form-item label="描述:" prop="content">
-          <el-input v-model="formData.content" placeholder="请输入描述" :disabled="formData.isDataView" />
+        <el-form-item label="描述:" prop="content" style="width: 100%">
+          <el-input v-model="formData.content" placeholder="请输入描述" :disabled="formData.isDataView"/>
+        </el-form-item>
+        <el-form-item label="类型:" prop="modelType" style="width: 100%">
+          <el-input v-model="formData.modelType" placeholder="请输入类型" :disabled="formData.isDataView"/>
         </el-form-item>
         <el-form-item label="类别:" prop="menuId">
-          <el-select v-model="formData.menuId" placeholder="请选择类别" :disabled="formData.isDataView" >
+          <el-select v-model="formData.menuId" placeholder="请选择类别" @change="handleMenuIdSelect" :disabled="formData.isDataView">
             <el-option
                 v-for="item in category"
                 :key="item.id"
@@ -27,24 +31,32 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="地理信息:" prop="geometryStr" >
-          <el-input v-model="formData.geometryStr" placeholder="请设置地理信息" :disabled="true" >
-            <template #prepend>
-              <el-button @click="handleMapShow(true)">
-                <span v-if="formData.isDataView">查看</span>
-                <span v-else>设置</span>
-                地理信息
-              </el-button>
-            </template>
+        <br/>
+        <el-form-item label="经度:" style="width: 40%" prop="lon">
+          <el-input :model-value="formData.lon" placeholder="经度" :disabled="formData.isDataView">
+          </el-input>
+        </el-form-item>
+        <el-form-item label="纬度:" style="width: 35%" :label-width="70" prop="lat">
+          <el-input :model-value="formData.lat" placeholder="纬度" :disabled="formData.isDataView">
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button style="font-size: 18px" @click="handleLonlatSelect" >
+            <el-icon><ElIconLocation/></el-icon>
+          </el-button>
+        </el-form-item>
+        <br/>
+        <el-form-item label="模型数据:" prop="url" style="width: 100%">
+          <el-input v-model="formData.url" placeholder="请设置模型地址" :disabled="formData.isDataView">
             <template #append>
-              <el-button @click="handleJsonDataView(true)">
-                查看GeoJson
+              <el-button @click="handleMapShow(true)">
+                查看模型
               </el-button>
             </template>
           </el-input>
         </el-form-item>
-        <el-form-item label="地名地址库:" prop="address" >
-          <el-input v-model="formData.address" placeholder="请输入地名地址库名称" :disabled="formData.isDataView" />
+        <el-form-item label="地名地址库:" prop="address" style="width: 100%">
+          <el-input v-model="formData.address" placeholder="请输入地名地址库名称" :disabled="formData.isDataView"/>
         </el-form-item>
       </el-form>
     </div>
@@ -52,14 +64,20 @@
       <el-button type="primary" @click="submit" v-show="!formData.isDataView">保存</el-button>
     </template>
   </el-dialog>
-    <OlMap v-if="isMapShow"
-           :is-show="isMapShow"
-           :is-view="formData.isDataView"
-           :menuId="formData.menuId"
-           :geometryStr="formData.geometryStr"
-           :callback="setMapData"
-           :close="handleMapShow">
-    </OlMap>
+  <CesiumMap v-if="isMapShow"
+             :is-show="isMapShow"
+             :item="formData"
+             :close="handleMapShow">
+  </CesiumMap>
+
+  <OlMap v-if="isLonLatShow"
+         :is-show="isLonLatShow"
+         :is-view="formData.isDataView"
+         :geometry-str="formData.geometryStr"
+         :menuId="1"
+         :callback="setLonLatData"
+         :close="handleLonlatSelect">
+  </OlMap>
 
   <JsonDataView v-if="isJsonDataView"
                 :is-show="isJsonDataView"
@@ -71,9 +89,10 @@
 </template>
 
 <script>
+import CesiumMap from "@/components/map/CesiumMap";
 import OlMap from "@/components/map/OlMap";
 import JsonDataView from "@/components/json/JsonDataView";
-import api from "@/api/data/TwoDimensionalData";
+import api from "@/api/data/ThreeDimensionalData";
 import menuApi from "@/api/data/MenuData";
 
 export default {
@@ -83,23 +102,43 @@ export default {
       oriFormData: {},
       formDataRules: {
         title: [
-          { required: true, message: '请输入标题', trigger: 'change' },
+          {required: true, message: '请输入标题', trigger: 'blur'},
+          {required: true, message: '请输入标题', trigger: 'change'},
         ],
         content: [
-          { required: true, message: '请输入描述', trigger: 'change' },
+          {required: true, message: '请输入描述', trigger: 'blur'},
+          {required: true, message: '请输入描述', trigger: 'change'},
+        ],
+        modelType: [
+          {required: true, message: '请输入类型', trigger: 'blur'},
+          {required: true, message: '请输入类型', trigger: 'change'},
         ],
         menuId: [
-          { required: true, message: '请选择类别', trigger: 'change' },
+          {required: true, message: '请选择类别', trigger: 'blur'},
+          {required: true, message: '请选择类别', trigger: 'change'},
         ],
         geometryStr: [
-          { required: true, message: '请输入Geojson数据', trigger: 'blur' },
+          {required: true, message: '请输入Geojson数据', trigger: 'blur'},
+        ],
+        url: [
+          {required: true, message: '该字段不能为空', trigger: 'blur'},
+          {required: true, message: '该字段不能为空', trigger: 'change'},
+        ],
+        lon: [
+          {required: true, message: '该字段不能为空', trigger: 'blur'},
+          {required: true, message: '该字段不能为空', trigger: 'change'},
         ],
+        lat: [
+          {required: true, message: '该字段不能为空', trigger: 'blur'},
+          {required: true, message: '该字段不能为空', trigger: 'change'},
+        ]
         // address: [
         //   { required: true, message: '请输入地名地址库名称', trigger: 'change' },
         // ]
       },
       category: [],
       isMapShow: false,
+      isLonLatShow: false,
 
       isJsonDataView: false,
 
@@ -111,56 +150,64 @@ export default {
     close: Function
   },
   watch: {
-    "formData.menuId": function (newVal, oldVal) {
-      let app = this;
-      if (app.formData.isEdit) {
-        if (newVal!==app.oriFormData.menuId) {
-          app.$msgbox.confirm('修改类型需重新设置地理信息,确定要修改吗?','Warning', {
-            confirmButtonText: '确认修改',
-            cancelButtonText: '恢复原始类别及地理信息',
-            type: 'warning',
-          }).then(()=>{
-            app.formData.geometryStr = ''
-          }).catch(()=>{
-            app.formData.menuId = app.oriFormData.menuId;
-            app.formData.geometryStr = app.oriFormData.geometryStr;
-          })
-        } else {
-          app.formData.geometryStr = app.oriFormData.geometryStr;
-        }
-
-      }
-    }
   },
   mounted() {
-    this.getMenuData()
+    this.getMenuData();
     this.formData = this.item;
     this.oriFormData = JSON.parse(JSON.stringify(this.formData))
   },
   components: {
+    CesiumMap,
     OlMap,
     JsonDataView,
   },
   methods: {
     handleMapShow(flag) {
       if (flag) {
-        if (this.formData.menuId) {
+        if (this.formData.url && this.formData.url !== '') {
           this.isMapShow = true
         } else {
-          this.$message({message: '请先选择类别', type: 'warning'})
+          this.$message({message: '请输入模型地址', type: 'warning'})
         }
       } else {
         this.isMapShow = false
       }
     },
+    handleLonlatSelect(flag) {
+      if (flag) {
+        this.formData.geometryStr = JSON.stringify(this.covertToGeometry())
+        this.isLonLatShow = true
+      } else {
+        this.isLonLatShow = false
+      }
+    },
+    covertToGeometry() {
+      let geometry = {
+        type: 'Point',
+        coordinates: []
+      }
+      if (this.formData.lon && this.formData.lon!=='' && this.formData.lat && this.formData.lat !=='') {
+        geometry.coordinates.push(this.formData.lon)
+        geometry.coordinates.push(this.formData.lat)
+        return geometry;
+      } else {
+        return '';
+      }
+    },
+    setLonLatData(obj) {
+      if (obj.coordinates && obj.coordinates.length>1) {
+        this.formData.lon = obj.coordinates[0];
+        this.formData.lat = obj.coordinates[1];
+      }
+    },
     getMenuData() {
       let app = this;
       let params = {
         type: "1",
         parentId: "2",
       }
-      menuApi.getMenuData(params).then(res=>{
-        if (res.code===200) {
+      menuApi.getMenuData(params).then(res => {
+        if (res.code === 200) {
           app.category = res.content
         }
       })
@@ -189,9 +236,10 @@ export default {
     addData() {
       let app = this;
       let params = JSON.parse(JSON.stringify(app.formData));
-      params['menuNameOne'] = '二维数据'
-      api.addData(params).then(res=>{
-        if (res.code===200) {
+      params['menuNameOne'] = '模型数据'
+      params['userName'] = app.$store.state.userInfo.username;
+      api.addData(params).then(res => {
+        if (res.code === 200) {
           app.$message({message: '录入成功', type: 'success'})
           app.close(true);
         }
@@ -203,8 +251,9 @@ export default {
       let params = JSON.parse(JSON.stringify(app.formData));
       delete params.createDate;
       delete params.updateDate;
-      api.updateData(params).then(res=>{
-        if (res.code===200) {
+      params['userName'] = app.$store.state.userInfo.username;
+      api.updateData(params).then(res => {
+        if (res.code === 200) {
           app.$message({message: '修改成功', type: 'success'})
           app.close(true);
         }
@@ -212,7 +261,16 @@ export default {
     },
     handleJsonDataView(flag) {
       this.isJsonDataView = flag;
-    }
+    },
+    handleMenuIdSelect(val) {
+      for (let i = 0; i < this.category.length; i++) {
+        let item = this.category[i];
+        if (item.id == val) {
+          this.formData['menuNameTwo'] = item.title
+          break;
+        }
+      }
+    },
   }
 }
 </script>

+ 43 - 23
src/components/dataManage/dataDetail/TwoDimensionalDataDetail.vue

@@ -18,7 +18,7 @@
           <el-input v-model="formData.content" placeholder="请输入描述" :disabled="formData.isDataView" />
         </el-form-item>
         <el-form-item label="类别:" prop="menuId">
-          <el-select v-model="formData.menuId" placeholder="请选择类别" :disabled="formData.isDataView" >
+          <el-select v-model="formData.menuId" placeholder="请选择类别" @change="handleMenuIdSelect" :disabled="formData.isDataView" >
             <el-option
                 v-for="item in category"
                 :key="item.id"
@@ -46,6 +46,30 @@
         <el-form-item label="地名地址库:" prop="address" >
           <el-input v-model="formData.address" placeholder="请输入地名地址库名称" :disabled="formData.isDataView" />
         </el-form-item>
+        <el-link style="float: right" @click="highOptionShow=!highOptionShow">高级选项
+          <span v-if="highOptionShow"><el-icon><ElIconCaretTop /></el-icon></span>
+          <span v-else><el-icon><ElIconCaretBottom /></el-icon></span>
+        </el-link>
+        <el-table :data="highOptionTableData" v-if="highOptionShow" >
+          <el-table-column prop="key" label="key" >
+            <template #default="scope" >
+              <el-input v-model="scope.row.key" placeholder="请输入字段名" />
+            </template>
+          </el-table-column>
+          <el-table-column prop="value" label="值" >
+            <template #default="scope" >
+              <el-input v-model="scope.row.value" placeholder="请输入值" />
+            </template>
+          </el-table-column>
+          <el-table-column align="center" width="100">
+            <template #header>
+              <el-button @click="highOptionTableData.push({key:'',value:''})"><el-icon><ElIconPlus /></el-icon></el-button>
+            </template>
+            <template #default="scope">
+              <el-button @click="highOptionTableData.splice(scope.$index,1)"><el-icon><ElIconMinus /></el-icon></el-button>
+            </template>
+          </el-table-column>
+        </el-table>
       </el-form>
     </div>
     <template #footer>
@@ -103,6 +127,12 @@ export default {
 
       isJsonDataView: false,
 
+      highOptionShow: false,
+      highOptionTableData: [{
+        key: '',
+        value: ''
+      }],
+
     }
   },
   props: {
@@ -111,26 +141,6 @@ export default {
     close: Function
   },
   watch: {
-    "formData.menuId": function (newVal, oldVal) {
-      let app = this;
-      if (app.formData.isEdit) {
-        if (newVal!==app.oriFormData.menuId) {
-          app.$msgbox.confirm('修改类型需重新设置地理信息,确定要修改吗?','Warning', {
-            confirmButtonText: '确认修改',
-            cancelButtonText: '恢复原始类别及地理信息',
-            type: 'warning',
-          }).then(()=>{
-            app.formData.geometryStr = ''
-          }).catch(()=>{
-            app.formData.menuId = app.oriFormData.menuId;
-            app.formData.geometryStr = app.oriFormData.geometryStr;
-          })
-        } else {
-          app.formData.geometryStr = app.oriFormData.geometryStr;
-        }
-
-      }
-    }
   },
   mounted() {
     this.getMenuData()
@@ -190,7 +200,7 @@ export default {
       let app = this;
       let params = JSON.parse(JSON.stringify(app.formData));
       params['menuNameOne'] = '二维数据'
-      params['username'] = app.$store.state.user.username;
+      params['userName'] = app.$store.state.userInfo.username;
       api.addData(params).then(res=>{
         if (res.code===200) {
           app.$message({message: '录入成功', type: 'success'})
@@ -202,6 +212,7 @@ export default {
     updateData() {
       let app = this;
       let params = JSON.parse(JSON.stringify(app.formData));
+      params['userName'] = app.$store.state.userInfo.username;
       delete params.createDate;
       delete params.updateDate;
       api.updateData(params).then(res=>{
@@ -213,7 +224,16 @@ export default {
     },
     handleJsonDataView(flag) {
       this.isJsonDataView = flag;
-    }
+    },
+    handleMenuIdSelect(val) {
+      for (let i = 0; i < this.category.length; i++) {
+        let item = this.category[i];
+        if (item.id == val) {
+          this.formData['menuNameTwo'] = item.title
+          break;
+        }
+      }
+    },
   }
 }
 </script>

+ 10 - 4
src/components/dataManage/dataShow/BusinessData.vue

@@ -1,8 +1,8 @@
 <!-- 业务数据 -->
 <template>
   <div id="data">
-    <el-button type="primary" @click="addDataClick">录入业务数据</el-button>
-    <el-button type="warning" @click="batchDelete">批量删除</el-button>
+    <el-button v-if="auth" type="primary" @click="addDataClick">录入业务数据</el-button>
+    <el-button v-if="auth" type="warning" @click="batchDelete">批量删除</el-button>
     <div class="operation">
       <el-form :model="filterForm" :inline="true">
         <el-form-item label="地名地址库名称:">
@@ -49,7 +49,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="编辑" placement="top-start">
+            <el-tooltip v-if="auth" class="box-item" effect="dark" content="编辑" placement="top-start">
               <el-button type="primary" @click="editData(scope.row)" circle>
                 <el-icon>
                   <ElIconEdit/>
@@ -57,7 +57,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="删除" placement="top-start">
+            <el-tooltip v-if="auth" class="box-item" effect="dark" content="删除" placement="top-start">
               <el-button type="danger" @click="deleteData(scope.row)" circle>
                 <el-icon>
                   <ElIconDelete/>
@@ -84,6 +84,7 @@ import BusinessDataDetail from "@/components/dataManage/dataDetail/BusinessDataD
 export default {
   data() {
     return {
+      auth: false,
       loading: false,
       filterForm: {},
       tableData: [],
@@ -102,6 +103,11 @@ export default {
     BusinessDataDetail
   },
   created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
   },
   mounted() {
     this.getData();

+ 257 - 72
src/components/dataManage/dataShow/IotData.vue

@@ -1,95 +1,280 @@
 <!-- 物联感知数据 -->
 <template>
-    <div id="data">
-        <el-button type="primary">录入物联感知数据</el-button>
-        <el-button type="warning">批量删除</el-button>
-        <div class="operation" >
-            <el-form :model="filterForm" :inline="true">
-                <el-form-item label="地名地址库名称:">
-                    <el-input v-model="filterForm.name" placeholder="请输入地名地址库名称"></el-input>
-                </el-form-item>
-                <el-form-item>
-                    <el-button type="primary">搜索</el-button>
-                </el-form-item>
-            </el-form>
-        </div>
-        <div class="list">
-            <el-table ref="dataTable" :data="tableData" :border="true" :stripe="true" :height="440" style="width: 100%;margin-bottom: 15px;" @selection-change="handleTableSelect">
-                <el-table-column type="selection" width="55" />
-                <el-table-column prop="id" label="ID" />
-                <el-table-column prop="title" label="标题" />
-                <el-table-column prop="desc" label="描述" />
-                <el-table-column prop="createTime" label="创建时间" />
-                <el-table-column prop="creator" label="创建人" />
-                <el-table-column prop="updateTime" label="修改时间" />
-                <el-table-column prop="updator" label="修改人" />
-                <el-table-column prop="operation" label="操作" width="150">
-                    <template #default="scope">
-                        <el-tooltip class="box-item" effect="dark" content="查看详情" placement="top-start">
-                            <el-button type="default" circle>
-                                <el-icon>
-                                    <ElIconView />
-                                </el-icon>
-                            </el-button>
-                        </el-tooltip>
+  <div id="data">
+    <el-button v-if="auth" type="primary" @click="addDataClick">录入物联感知数据</el-button>
+    <el-button v-if="auth" type="warning" @click="batchDelete">批量删除</el-button>
+    <div class="operation">
+      <el-form :model="filterForm" :inline="true">
+        <el-form-item label="地名地址库名称:">
+          <el-input v-model="filterForm.address" placeholder="请输入地名地址库名称"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="search">搜索</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="list">
+      <el-table ref="dataTable" v-loading="loading" element-loading-text="正在加载,请稍后..." :data="tableData"
+                :border="true" :stripe="true" :height="440" style="width: 100%;margin-bottom: 15px;"
+                @selection-change="handleTableSelect">
+        <el-table-column type="selection" width="55"/>
+        <el-table-column prop="id" label="ID" width="100" :show-overflow-tooltip="true">
+          <template #default="scope">
+            <span style="cursor: pointer" @click="$util.clipboard.copyText(scope.row.id)"> {{ scope.row.id }} </span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="title" label="标题" width="200"/>
+        <el-table-column prop="content" label="描述" width="250"/>
+        <el-table-column prop="menuNameTwo" label="类别" width="80"/>
+        <el-table-column prop="mediaType" label="媒体类型" width="120"/>
+        <el-table-column prop="url" label="媒体路径" width="120"/>
+        <el-table-column prop="lon" label="位置" width="180">
+          <template #default="scope">
+            [
+            <span v-if="scope.row.lon && scope.row.lon!=='' && scope.row.lat && scope.row.lat!==''">
+              {{ scope.row.lon }},<br/> {{ scope.row.lat }}
+            </span>
+            ]
+          </template>
+        </el-table-column>
+        <el-table-column prop="importType" label="导入类型" width="150"/>
+        <el-table-column prop="address" label="地名地址库" width="150"/>
+        <el-table-column prop="userName" label="修改人"/>
+        <el-table-column prop="updateDate" label="修改时间" width="160">
+          <template #default="scope">
+            {{ $util.datetime.format(scope.row.updateDate) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="createDate" label="创建时间" width="160">
+          <template #default="scope">
+            {{ $util.datetime.format(scope.row.createDate) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="operation" label="操作" width="150" fixed="right">
+          <template #default="scope">
+            <el-tooltip class="box-item" effect="dark" content="查看详情" placement="top-start">
+              <el-button type="default" @click="viewData(scope.row)" circle>
+                <el-icon>
+                  <ElIconView/>
+                </el-icon>
+              </el-button>
+            </el-tooltip>
 
-                        <el-tooltip class="box-item" effect="dark" content="编辑" placement="top-start">
-                            <el-button type="primary" circle>
-                                <el-icon>
-                                    <ElIconEdit />
-                                </el-icon>
-                            </el-button>
-                        </el-tooltip>
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="编辑" placement="top-start">
+              <el-button type="primary" @click="editData(scope.row)" circle>
+                <el-icon>
+                  <ElIconEdit/>
+                </el-icon>
+              </el-button>
+            </el-tooltip>
 
-                        <el-tooltip class="box-item" effect="dark" content="删除" placement="top-start">
-                            <el-button type="danger" circle>
-                                <el-icon>
-                                    <ElIconDelete />
-                                </el-icon>
-                            </el-button>
-                        </el-tooltip>
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="删除" placement="top-start">
+              <el-button type="danger" @click="deleteData(scope.row)" circle>
+                <el-icon>
+                  <ElIconDelete/>
+                </el-icon>
+              </el-button>
+            </el-tooltip>
 
-                    </template>
-                </el-table-column>
-            </el-table>
-            <el-pagination style="float:right" background layout="sizes, prev, pager, next, jumper, totle"
-                v-model:current-page="pageInfo.page" :total="1000" />
-        </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination style="float:right" background layout="sizes, prev, pager, next, jumper, total"
+                     v-model:current-page="pageInfo.page" v-model:page-size="pageInfo.pageSize"
+                     v-model:total="pageInfo.total"/>
     </div>
+  </div>
+
+  <IotDataDetail v-if="isDetailShow" :is-show="isDetailShow" :item="currRow" :close="handleDetailShow"></IotDataDetail>
 </template>
 
 <script>
-import mockData from '@/static/files/mockData'
+import api from '@/api/data/IotData'
+import IotDataDetail from "@/components/dataManage/dataDetail/IotDataDetail";
 
 export default {
-    data() {
-        return {
-            filterForm: {},
-            tableData: [],
-            pageInfo: {
-                page: 1,
-                pageSize: 10
-            }
+  data() {
+    return {
+      auth: false,
+      loading: false,
+      filterForm: {},
+      tableData: [],
+      currRow: {},
+      selectedRows: [],
+      pageInfo: {
+        page: 1,
+        pageSize: 10,
+        total: 0,
+      },
+
+      isDetailShow: false,
+    }
+  },
+  components: {
+    IotDataDetail
+  },
+  created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
+  },
+  mounted() {
+    this.getData();
+  },
+  watch: {
+    "pageInfo.page": function (val) {
+      if (val > 0) {
+        this.getData();
+      }
+    },
+    "pageInfo.pageSize": function () {
+      let app = this;
+      this.pageInfo.page = -1;
+      setTimeout(function () {
+        app.pageInfo.page = 1;
+      }, 50)
+    },
+  },
+  methods: {
+    handleLoading(flag) {
+      let app = this;
+      if (flag) {
+        app.loading = true;
+      } else {
+        setTimeout(() => {
+          app.loading = false;
+        }, 500);
+      }
+    },
+    getData() {
+      let app = this;
+      let params = {
+        address: app.filterForm.address,
+        page: app.pageInfo.page,
+        pageSize: app.pageInfo.pageSize,
+      }
+      app.handleLoading(true)
+      api.getData(params).then(res => {
+        if (res.code === 200) {
+          app.pageInfo.total = res.total;
+          app.tableData = res.content
         }
+        app.handleLoading(false)
+      }).catch(err => {
+        app.handleLoading(false)
+      })
     },
-    created() {
-        this.getData();
+    search() {
+      let app = this;
+      this.pageInfo.pageSize = -1;
+      setTimeout(function () {
+        app.pageInfo.pageSize = 10;
+      })
     },
-    mounted() {
-
+    handleTableSelect(val) {
+      this.selectedRows = val;
     },
-    methods: {
-        getData() {
-            this.tableData = mockData;
-        },
-        handleTableSelect(val) {
+    handleDetailShow(flag) {
+      if (flag) {
+        this.getData()
+      }
+      this.isDetailShow = false
+    },
+    // 录入数据
+    addDataClick() {
+      this.currRow = {};
+      this.isDetailShow = true;
+    },
+    // 批量删除数据
+    batchDelete() {
+      let app = this;
+      if (!this.selectedRows) {
+        return;
+      }
+      let ids = this.selectedRows.map(i=> {return i.id}).join(',');
+      let params = {
+        latlonDataId: ids
+      }
+      this.$msgbox.confirm('确定要删除吗?').then(()=>{
+        api.deleteData(params).then(res=>{
+          if (res.code===200) {
+            app.getData();
+            app.$message({message: '删除成功', type: 'success'})
+          }
+        })
+      })
+    },
+    // 查看详情
+    viewData(item) {
+      let app = this;
+      let params = {
+        latlonDataId: item.id
+      }
+      app.$util.loading.handleLoading(true);
+      api.getDataById(params).then(res=>{
+        if (res.code===200) {
+          if (!res.content.id || res.content.id==='') {
+            app.$message({message: '该数据不存在', type: 'error'})
+            return;
+          }
+          if (res.content.menuId) {
+            res.content.menuId = Number(res.content.menuId);
+            res.content.geometryStr = JSON.stringify(res.content.geometry);
+            delete res.content.geometry;
+          }
+          app.currRow = JSON.parse(JSON.stringify(res.content))
+          this.currRow.isDataView = true;
+          app.isDetailShow = true
         }
-    }
+        app.$util.loading.handleLoading(false);
+      })
+    },
+    // 编辑数据
+    editData(item) {
+      let app = this;
+      let params = {
+        latlonDataId: item.id
+      }
+      app.$util.loading.handleLoading(true);
+      api.getDataById(params).then(res=>{
+        if (!res.content.id || res.content.id==='') {
+          app.$message({message: '该数据不存在', type: 'error'})
+          return;
+        }
+        if (res.code===200) {
+          if (res.content.menuId) {
+            res.content.menuId = Number(res.content.menuId);
+            res.content.geometryStr = JSON.stringify(res.content.geometry);
+            delete res.content.geometry;
+          }
+          app.currRow = JSON.parse(JSON.stringify(res.content))
+          app.currRow.isEdit = true;
+          app.isDetailShow = true
+        }
+        app.$util.loading.handleLoading(false);
+      })
+
+    },
+    // 删除数据
+    deleteData(item) {
+      let app = this;
+      app.$msgbox.confirm('确认要删除此条数据吗?').then(()=>{
+        api.deleteData({latlonDataId: item.id}).then(res=>{
+          if (res.code === 200) {
+            app.getData();
+            app.$message({message: '删除成功', type: 'success'});
+          }
+        })
+      })
+    },
+  }
 }
 </script>
 
 <style>
 #data .operation {
-    float: right;
+  float: right;
 }
 </style>

+ 16 - 5
src/components/dataManage/dataShow/MetaData.vue

@@ -1,8 +1,8 @@
 <!-- 业务数据 -->
 <template>
   <div id="data">
-    <el-button type="primary" @click="addDataClick">录入元数据</el-button>
-    <el-button type="warning" @click="batchDelete">批量删除</el-button>
+    <el-button v-if="auth"  type="primary" @click="addDataClick">录入元数据</el-button>
+    <el-button v-if="auth"  type="warning" @click="batchDelete">批量删除</el-button>
     <div class="operation">
       <el-form :model="filterForm" :inline="true">
         <el-form-item label="地名地址库名称:">
@@ -49,7 +49,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="编辑" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="编辑" placement="top-start">
               <el-button type="primary" @click="editData(scope.row)" circle>
                 <el-icon>
                   <ElIconEdit/>
@@ -57,7 +57,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="删除" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="删除" placement="top-start">
               <el-button type="danger" @click="deleteData(scope.row)" circle>
                 <el-icon>
                   <ElIconDelete/>
@@ -85,6 +85,7 @@ import menuApi from "@/api/data/MenuData";
 export default {
   data() {
     return {
+      auth: false,
       loading: false,
       filterForm: {},
       tableData: [],
@@ -103,6 +104,11 @@ export default {
     MetaDataDetail
   },
   created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
   },
   mounted() {
     this.getData();
@@ -135,6 +141,7 @@ export default {
     getData() {
       let app = this;
       let params = {
+        address: app.filterForm.address,
         page: app.pageInfo.page,
         pageSize: app.pageInfo.pageSize
       }
@@ -150,7 +157,11 @@ export default {
       })
     },
     search() {
-
+      let app = this;
+      this.pageInfo.pageSize = -1;
+      setTimeout(function () {
+        app.pageInfo.pageSize = 10;
+      })
     },
     handleTableSelect(val) {
       this.selectedRows = val;

+ 16 - 5
src/components/dataManage/dataShow/ModelData.vue

@@ -1,8 +1,8 @@
 <!-- 模型数据 -->
 <template>
   <div id="data">
-    <el-button type="primary" @click="addDataClick">录入模型数据</el-button>
-    <el-button type="warning" @click="batchDelete">批量删除</el-button>
+    <el-button v-if="auth"  type="primary" @click="addDataClick">录入模型数据</el-button>
+    <el-button v-if="auth"  type="warning" @click="batchDelete">批量删除</el-button>
     <div class="operation">
       <el-form :model="filterForm" :inline="true">
         <el-form-item label="地名地址库名称:">
@@ -59,7 +59,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="编辑" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="编辑" placement="top-start">
               <el-button type="primary" @click="editData(scope.row)" circle>
                 <el-icon>
                   <ElIconEdit/>
@@ -67,7 +67,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="删除" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="删除" placement="top-start">
               <el-button type="danger" @click="deleteData(scope.row)" circle>
                 <el-icon>
                   <ElIconDelete/>
@@ -94,6 +94,7 @@ import ModelDataDetail from "@/components/dataManage/dataDetail/ModelDataDetail"
 export default {
   data() {
     return {
+      auth: false,
       loading: false,
       filterForm: {},
       tableData: [],
@@ -112,6 +113,11 @@ export default {
     ModelDataDetail
   },
   created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
   },
   mounted() {
     this.getData();
@@ -144,6 +150,7 @@ export default {
     getData() {
       let app = this;
       let params = {
+        address: app.filterForm.address,
         page: app.pageInfo.page,
         pageSize: app.pageInfo.pageSize
       }
@@ -159,7 +166,11 @@ export default {
       })
     },
     search() {
-
+      let app = this;
+      this.pageInfo.pageSize = -1;
+      setTimeout(function () {
+        app.pageInfo.pageSize = 10;
+      })
     },
     handleTableSelect(val) {
       this.selectedRows = val;

+ 17 - 6
src/components/dataManage/dataShow/ThreeDimensionalData.vue

@@ -1,8 +1,8 @@
 <!-- 三维数据 -->
 <template>
   <div id="data">
-    <el-button type="primary" @click="addDataClick">录入三维数据</el-button>
-    <el-button type="warning" @click="batchDelete">批量删除</el-button>
+    <el-button v-if="auth"  type="primary" @click="addDataClick">录入三维数据</el-button>
+    <el-button v-if="auth"  type="warning" @click="batchDelete">批量删除</el-button>
     <div class="operation">
       <el-form :model="filterForm" :inline="true">
         <el-form-item label="地名地址库名称:">
@@ -27,7 +27,7 @@
         <el-table-column prop="content" label="描述" width="250"/>
         <el-table-column prop="modelType" label="类型" width="120"/>
         <el-table-column prop="menuNameTwo" label="类别" width="120"/>
-        <el-table-column prop="lon" label="位置" width="130">
+        <el-table-column prop="lon" label="位置" width="180">
           <template #default="scope">
             [
             <span v-if="scope.row.lon && scope.row.lon!=='' && scope.row.lat && scope.row.lat!==''">
@@ -59,7 +59,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="编辑" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="编辑" placement="top-start">
               <el-button type="primary" @click="editData(scope.row)" circle>
                 <el-icon>
                   <ElIconEdit/>
@@ -67,7 +67,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="删除" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="删除" placement="top-start">
               <el-button type="danger" @click="deleteData(scope.row)" circle>
                 <el-icon>
                   <ElIconDelete/>
@@ -94,6 +94,7 @@ import ThreeDimensionalDataDetail from "@/components/dataManage/dataDetail/Three
 export default {
   data() {
     return {
+      auth: false,
       loading: false,
       filterForm: {},
       tableData: [],
@@ -112,6 +113,11 @@ export default {
     ThreeDimensionalDataDetail
   },
   created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
   },
   mounted() {
     this.getData();
@@ -144,6 +150,7 @@ export default {
     getData() {
       let app = this;
       let params = {
+        address: app.filterForm.name,
         page: app.pageInfo.page,
         pageSize: app.pageInfo.pageSize
       }
@@ -159,7 +166,11 @@ export default {
       })
     },
     search() {
-
+      let app = this;
+      this.pageInfo.pageSize = -1;
+      setTimeout(function () {
+        app.pageInfo.pageSize = 10;
+      })
     },
     handleTableSelect(val) {
       this.selectedRows = val;

+ 10 - 4
src/components/dataManage/dataShow/TwoDimensionalData.vue

@@ -1,8 +1,8 @@
 <!-- 二维数据 -->
 <template>
   <div id="data">
-    <el-button type="primary" @click="addDataClick">录入二维数据</el-button>
-    <el-button type="warning" @click="batchDelete">批量删除</el-button>
+    <el-button v-if="auth" type="primary" @click="addDataClick">录入二维数据</el-button>
+    <el-button v-if="auth" type="warning" @click="batchDelete">批量删除</el-button>
     <div class="operation">
       <el-form :model="filterForm" :inline="true">
         <el-form-item label="地名地址库名称:">
@@ -49,7 +49,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="编辑" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="编辑" placement="top-start">
               <el-button type="primary" @click="editData(scope.row)" circle>
                 <el-icon>
                   <ElIconEdit/>
@@ -57,7 +57,7 @@
               </el-button>
             </el-tooltip>
 
-            <el-tooltip class="box-item" effect="dark" content="删除" placement="top-start">
+            <el-tooltip v-if="auth"  class="box-item" effect="dark" content="删除" placement="top-start">
               <el-button type="danger" @click="deleteData(scope.row)" circle>
                 <el-icon>
                   <ElIconDelete/>
@@ -85,6 +85,7 @@ import TwoDimensionalDataDetail from "@/components/dataManage/dataDetail/TwoDime
 export default {
   data() {
     return {
+      auth: false,
       loading: false,
       filterForm: {},
       tableData: [],
@@ -103,6 +104,11 @@ export default {
     TwoDimensionalDataDetail
   },
   created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
   },
   mounted() {
     this.getData();

+ 122 - 108
src/components/home/DataManage.vue

@@ -1,131 +1,145 @@
 <template>
-    <div id="dataManage">
-        <div class="left">
-            <el-menu default-active="1-1" class="dataManage-menu" @select="handleMenuSelect">
-                <el-sub-menu index="1">
-                    <template #title>
-                        <el-icon>
-                            <IconPark-table-file />
-                        </el-icon>
-                        <span>数据管理</span>
-                    </template>
-                    <el-menu-item index="1-1">
-                        <el-icon>
-                            <IconPark-multi-triangular />
-                        </el-icon>
-                        <span>二维数据</span>
-                    </el-menu-item>
-                    <el-menu-item index="1-2">
-                        <el-icon>
-                            <IconPark-sphere />
-                        </el-icon>
-                        <span>三维数据</span>
-                    </el-menu-item>
-                    <el-menu-item index="1-3">
-                        <el-icon>
-                            <IconPark-internal-data />
-                        </el-icon>
-                        <span>业务数据</span>
-                    </el-menu-item>
-                    <el-menu-item index="1-4">
-                        <el-icon>
-                            <IconPark-graphic-stitching />
-                        </el-icon>
-                        <span>模型数据</span>
-                    </el-menu-item>
-                    <el-menu-item index="1-5">
-                        <el-icon :color="'#303133'">
-                            <IconPark-data />
-                        </el-icon>
-                        <span>元数据</span>
-                    </el-menu-item>
-                    <el-menu-item index="1-6">
-                        <el-icon>
-                            <IconPark-connection-point />
-                        </el-icon>
-                        <span>物联感知数据</span>
-                    </el-menu-item>
-                </el-sub-menu>
-                <el-menu-item index="2">
-                    <el-icon>
-                        <IconPark-external-transmission />
-                    </el-icon>
-                    <span>数据导入</span>
-                </el-menu-item>
-                <el-menu-item index="3">
-                    <el-icon>
-                        <IconPark-refresh />
-                    </el-icon>
-                    <span>接口同步</span>
-                </el-menu-item>
-            </el-menu>
-        </div>
-        <div class="content">
-            <TwoDimensionalData v-if="activeName==='1-1'" />
-            <ThreeDimensionalData v-if="activeName==='1-2'" />
-            <BusinessData v-if="activeName==='1-3'" />
-            <ModelData v-if="activeName==='1-4'" />
-            <MetaData v-if="activeName==='1-5'" />
-            <IotData v-if="activeName==='1-6'" />
+  <div id="dataManage">
+    <br/>
+    <div class="left">
+      <el-menu default-active="1-1" class="dataManage-menu" @select="handleMenuSelect">
+        <el-sub-menu index="1">
+          <template #title>
+            <el-icon>
+              <IconPark-table-file/>
+            </el-icon>
+            <span>数据管理</span>
+          </template>
+          <el-menu-item index="1-1">
+            <el-icon>
+              <IconPark-multi-triangular/>
+            </el-icon>
+            <span>二维数据</span>
+          </el-menu-item>
+          <el-menu-item index="1-2">
+            <el-icon>
+              <IconPark-sphere/>
+            </el-icon>
+            <span>三维数据</span>
+          </el-menu-item>
+          <el-menu-item index="1-3">
+            <el-icon>
+              <IconPark-internal-data/>
+            </el-icon>
+            <span>业务数据</span>
+          </el-menu-item>
+          <el-menu-item index="1-4">
+            <el-icon>
+              <IconPark-graphic-stitching/>
+            </el-icon>
+            <span>模型数据</span>
+          </el-menu-item>
+          <el-menu-item index="1-5">
+            <el-icon :color="'#303133'">
+              <IconPark-data/>
+            </el-icon>
+            <span>元数据</span>
+          </el-menu-item>
+          <el-menu-item index="1-6">
+            <el-icon>
+              <IconPark-connection-point/>
+            </el-icon>
+            <span>物联感知数据</span>
+          </el-menu-item>
+        </el-sub-menu>
+        <el-menu-item index="2">
+          <el-icon>
+            <IconPark-external-transmission/>
+          </el-icon>
+          <span>数据导入</span>
+        </el-menu-item>
+        <!--<el-menu-item index="3">-->
+        <!--  <el-icon>-->
+        <!--    <IconPark-refresh/>-->
+        <!--  </el-icon>-->
+        <!--  <span>接口同步</span>-->
+        <!--</el-menu-item>-->
+      </el-menu>
+    </div>
+    <div class="content">
+      <TwoDimensionalData v-if="activeName==='1-1'"/>
+      <ThreeDimensionalData v-if="activeName==='1-2'"/>
+      <BusinessData v-if="activeName==='1-3'"/>
+      <ModelData v-if="activeName==='1-4'"/>
+      <MetaData v-if="activeName==='1-5'"/>
+      <IotData v-if="activeName==='1-6'"/>
 
-            <ImportData v-if="activeName==='2'" />
-            <SyncInterface v-if="activeName==='3'" />
-        </div>
+      <ImportData v-if="activeName==='2'"/>
+      <SyncInterface v-if="activeName==='3'"/>
     </div>
+  </div>
 </template>
 
 <script>
-import { defineAsyncComponent } from "vue";
+import {defineAsyncComponent} from "vue";
 
 export default {
-    data() {
-        return {
-            activeName: '1-1',
-        }
-    },
-    components: {
-        TwoDimensionalData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/TwoDimensionalData.vue")),
-        ThreeDimensionalData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/ThreeDimensionalData.vue")),
-        BusinessData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/BusinessData.vue")),
-        ModelData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/ModelData.vue")),
-        MetaData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/MetaData.vue")),
-        IotData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/IotData.vue")),
+  data() {
+    return {
+      activeName: '1-1',
+    }
+  },
+  components: {
+    TwoDimensionalData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/TwoDimensionalData.vue")),
+    ThreeDimensionalData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/ThreeDimensionalData.vue")),
+    BusinessData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/BusinessData.vue")),
+    ModelData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/ModelData.vue")),
+    MetaData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/MetaData.vue")),
+    IotData: defineAsyncComponent(() => import("@/components/dataManage/dataShow/IotData.vue")),
 
-        ImportData: defineAsyncComponent(() => import("@/components/dataManage/ImportData.vue")),
-        SyncInterface: defineAsyncComponent(() => import("@/components/dataManage/SyncInterface.vue")),
-    },
-    created() {
+    ImportData: defineAsyncComponent(() => import("@/components/dataManage/ImportData.vue")),
+    SyncInterface: defineAsyncComponent(() => import("@/components/dataManage/SyncInterface.vue")),
+  },
+  created() {
 
-    },
-    mounted() {
+  },
+  mounted() {
+
+  },
+  methods: {
+    handleMenuSelect(val) {
+      this.activeName = '-1';
+      setTimeout(() => {
+        this.activeName = val;
+      }, 10);
 
-    },
-    methods: {
-        handleMenuSelect(val) {
-            this.activeName = '-1';
-            setTimeout(() => {
-                this.activeName = val;
-            }, 10);
-            
-        }
     }
+  }
 }
 </script>
 
 <style scoped>
 #dataManage {
-    width: 100%;
-    height: 100%;
+  width: 100%;
+  height: 100%;
 }
+
 #dataManage .left {
-    width: 20%;
-    display: inline-block;
+  width: 20%;
+  display: inline-block;
 }
+
 #dataManage .content {
-    width: 78%;
-    height: 100%;
-    display: inline-block;
-    vertical-align: top;
-    margin-left: 2%;
+  width: 78%;
+  height: 100%;
+  display: inline-block;
+  vertical-align: top;
+  margin-left: 2%;
+}
+</style>
+
+<style>
+#dataManage .el-menu-item,.el-sub-menu__title {
+  font-size: 17px !important;
+  font-weight: 600;
+  color: #373737;
+}
+#dataManage .dataManage-menu .is-active {
+  color: #6566f4;
 }
 </style>

+ 61 - 49
src/components/home/DataPublish.vue

@@ -1,22 +1,23 @@
 <template>
-    <div id="dataPublish">
-        <div class="left">
-            <el-scrollbar :max-height="menuHeight">
-                <el-menu default-active="0" class="dataPublish-menu" @select="handleServiceSelect">
-                    <el-menu-item v-for="(item,index) of serviceList" :key="index" :index="index+''">
-                        <el-icon>
-                            <IconPark-server />
-                        </el-icon>
-                        <span>{{ item.serviceName }}</span>
-                    </el-menu-item>
-                </el-menu>
-            </el-scrollbar>
+  <div id="dataPublish">
+    <br/>
+    <div class="left">
+      <el-scrollbar :max-height="menuHeight">
+        <el-menu default-active="0" class="dataPublish-menu" @select="handleServiceSelect">
+          <el-menu-item v-for="(item,index) of serviceList" :key="index" :index="index+''">
+            <el-icon>
+              <IconPark-server/>
+            </el-icon>
+            <span>{{ item.serviceName }}</span>
+          </el-menu-item>
+        </el-menu>
+      </el-scrollbar>
 
-        </div>
-        <div class="content">
-            <PublishDetail :data="currService" />
-        </div>
     </div>
+    <div class="content">
+      <PublishDetail :data="currService"/>
+    </div>
+  </div>
 </template>
 
 <script>
@@ -24,48 +25,59 @@ import PublishDetail from '@/components/dataPublish/PublishDetail'
 import ServiceData from "@/static/datas/ServiceData";
 
 export default {
-    data() {
-        return {
-            menuHeight: '',
-            serviceList: [],
-            currService: {}
-        }
-    },
-    props: {
-        height: Object
-    },
-    components: {
-        PublishDetail
-    },
-    created() {
-        this.menuHeight = this.height*0.7;
-        this.serviceList = JSON.parse(JSON.stringify(ServiceData))
-        if (this.serviceList.length>0) {
-            this.currService = this.serviceList[0]
-        }
-    },
-    mounted() {
-    },
-    methods: {
-        handleServiceSelect(val) {
-            this.currService = this.serviceList[Number(val)]
-        }
+  data() {
+    return {
+      menuHeight: '',
+      serviceList: [],
+      currService: {}
+    }
+  },
+  props: {
+    height: Object
+  },
+  components: {
+    PublishDetail
+  },
+  created() {
+    this.menuHeight = this.height * 0.7;
+    this.serviceList = JSON.parse(JSON.stringify(ServiceData))
+    if (this.serviceList.length > 0) {
+      this.currService = this.serviceList[0]
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    handleServiceSelect(val) {
+      this.currService = this.serviceList[Number(val)]
     }
+  }
 }
 
 </script>
 
 <style scoped>
 #dataPublish .left {
-    display: inline-block;
-    width: 20%;
-    height: 100%;
+  display: inline-block;
+  width: 20%;
+  height: 100%;
 }
 
 #dataPublish .content {
-    display: inline-block;
-    width: 79%;
-    vertical-align: top;
-    height: 100%;
+  display: inline-block;
+  width: 79%;
+  vertical-align: top;
+  height: 100%;
+}
+</style>
+
+<style>
+#dataPublish .el-menu-item,.el-sub-menu__title {
+  font-size: 17px !important;
+  font-weight: 600;
+  color: #373737;
+}
+#dataPublish .dataPublish-menu .is-active {
+  color: #6566f4;
 }
 </style>

+ 228 - 68
src/components/home/HomeIndex.vue

@@ -1,90 +1,250 @@
 <template>
-    <div id="HomeContainer">
-        <el-row :gutter="30">
-            <el-col :span="12" >
-                <el-card class="box-card">
-                    <template #header>
-                        <div class="card-header">
-                            <span class="cardTitle">平台介绍</span>
-                        </div>
-                    </template>
-                    <div >平台介绍内容</div>
-                </el-card>
-            </el-col>
-            <el-col :span="12">
-                <el-card class="box-card">
-                    <template #header>
-                        <div class="card-header">
-                            <span class="cardTitle">专项介绍</span>
-                        </div>
-                    </template>
-                    <div >专项介绍内容</div>
-                </el-card>
-            </el-col>
-            <el-col :span="24" ><br/></el-col>
-            <el-col :span="24" ><br/></el-col>
-            <el-col :span="12">
-                <el-card class="box-card">
-                    <template #header>
-                        <div class="card-header">
-                            <span class="cardTitle">系统概览</span>
-                        </div>
-                    </template>
-                    <div >系统信息</div>
-                </el-card>
-            </el-col>
-            <el-col :span="12">
-                <el-card class="box-card">
-                    <template #header>
-                        <div class="card-header">
-                            <span class="cardTitle">数据明细</span>
-                        </div>
-                    </template>
-                    <div >数据明细内容</div>
-                </el-card>
-            </el-col>
-        </el-row>
+  <div id="HomeContainer">
+    <br/>
+    <el-row v-if="auth" :gutter="30">
+      <el-col :span="12">
+        <el-card class="box-card" :style="cardStyle">
+          <template #header>
+            <div class="card-header">
+              <span class="cardTitle">
+                <el-icon><img :src="platformIcon" ></el-icon>
+                <span class="cardTitleText">平台介绍</span>
+              </span>
+              <span class="cardDesc">PlatForm Introduction</span>
+            </div>
+          </template>
+          <div>
+            <el-scrollbar :style="cardBodyStyle">
+              平台介绍内容1<br>
+              平台介绍内容2<br>
+              平台介绍内容3<br>
+              平台介绍内容4<br>
+              平台介绍内容5<br>
+              平台介绍内容6<br>
+              平台介绍内容7<br>
+              平台介绍内容8<br>
+              平台介绍内容9<br>
+              平台介绍内容10<br>
+            </el-scrollbar>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card class="box-card" :style="cardStyle">
+          <template #header>
+            <div class="card-header">
+              <span class="cardTitle">
+                <el-icon><img :src="introduceIcon" ></el-icon>
+                <span class="cardTitleText">专项介绍</span>
+              </span>
+              <span class="cardDesc">Special Introduction</span>
+            </div>
+          </template>
+          <div>
+            <el-scrollbar :style="cardBodyStyle">
+              <el-row>
+                <el-col :span="10">
+                  <el-carousel height="150px">
+                    <el-carousel-item v-for="item in 2" :key="item">
+                      <h3 class="small justify-center" text="2xl">{{ item }}</h3>
+                    </el-carousel-item>
+                  </el-carousel>
+                </el-col>
+                <el-col :span="1"></el-col>
+                <el-col :span="13">
+                  <el-link>专项介绍内容1</el-link><br/>
+                  <el-link>专项介绍内容2</el-link><br/>
+                  <el-link>专项介绍内容3</el-link><br/>
+                  <el-link>专项介绍内容4</el-link><br/>
+                  <el-link>专项介绍内容5</el-link><br/>
+                </el-col>
+              </el-row>
+            </el-scrollbar>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="24"><br/></el-col>
+      <el-col :span="24"><br/></el-col>
+      <el-col :span="12">
+        <el-card class="box-card" :style="cardStyle">
+          <template #header>
+            <div class="card-header">
+              <span class="cardTitle">
+                <el-icon><img :src="systemInfoIcon" ></el-icon>
+                <span class="cardTitleText">系统概览</span>
+              </span>
+              <span class="cardDesc">System Overview</span>
+            </div>
+          </template>
+          <div>
+            <el-scrollbar :style="cardBodyStyle">
+              <el-row>
+                <el-col :span="6" >
+                  <div>数据占比:</div>
+                  <div id="system-overview-data-percent" style="width: 100%;height: 100px"></div>
+                </el-col>
+                <el-col :span="6" >123</el-col>
+                <el-col :span="6" >123</el-col>
+                <el-col :span="6" >123</el-col>
+              </el-row>
+            </el-scrollbar>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card class="box-card" :style="cardStyle">
+          <template #header>
+            <div class="card-header">
+              <span class="cardTitle">
+                <el-icon><img :src="dataDetail" ></el-icon>
+                <span class="cardTitleText">数据明细</span>
+              </span>
+              <span class="cardDesc">Data Details</span>
+            </div>
+          </template>
+          <div>数据明细内容</div>
+        </el-card>
+      </el-col>
+    </el-row>
 
+    <el-empty v-if="!auth" description="暂无权限查看" />
 
-    </div>
+  </div>
 </template>
 
 <script>
-export default {
-    name: 'HomeIndex',
-    data() {
-        return {
-
-        }
-    },
-    created() {
+import platformIcon from "@/assets/img/icons/platform.png"
+import introduceIcon from "@/assets/img/icons/introduce.png"
+import systemInfoIcon from "@/assets/img/icons/systemInfo.png"
+import dataDetail from "@/assets/img/icons/dataDetail.png"
 
-    },
-    mounted() {
-
-    },
-    methods: {
+export default {
+  name: 'HomeIndex',
+  data() {
+    return {
+      platformIcon,introduceIcon,systemInfoIcon,dataDetail,
+      cardStyle: {
+        height: 200+'px'
+      },
+      cardBodyStyle: {
+        height: 150+'px'
+      },
+      systemOverviewOptions: {
+        dataPercent :{
+          // title: {
+          //   text: 'Referer of a Website',
+          //   subtext: 'Fake Data',
+          //   left: 'center'
+          // },
+          tooltip: {
+            trigger: 'item'
+          },
+          legend: {
+            orient: 'vertical',
+            left: 'left'
+          },
+          series: [
+            {
+              name: 'Access From',
+              type: 'pie',
+              radius: '50%',
+              data: [
+                { value: 1048, name: 'Search Engine' },
+                { value: 735, name: 'Direct' },
+                { value: 580, name: 'Email' },
+                { value: 484, name: 'Union Ads' },
+                { value: 300, name: 'Video Ads' }
+              ],
+              emphasis: {
+                itemStyle: {
+                  shadowBlur: 10,
+                  shadowOffsetX: 0,
+                  shadowColor: 'rgba(0, 0, 0, 0.5)'
+                }
+              }
+            }
+          ]
+        },
+      }
+    }
+  },
+  props: {
+    auth: Boolean,
+  },
+  created() {
 
+  },
+  mounted() {
+    let container = document.getElementById("HomeContainer")
+    if (container && container.clientHeight>=500) {
+      this.cardStyle.height = container.clientHeight*0.4+'px';
+    } else {
+      this.cardStyle.height = 200+'px';
     }
+    this.cardBodyStyle.height = this.cardStyle.height*0.7;
+    // let mycharts = this.$echarts.init(document.getElementById('system-overview-data-percent'))
+    // mycharts.setOption(this.systemOverviewOptions.dataPercent)
+  },
+  methods: {
+
+  }
 }
 </script>
 
 <style scoped>
 #HomeContainer {
-    width: 100%;
-    height: 100%;
+  width: 100%;
+  height: 100%;
 }
 
 .box-card {
-    width: 100%;
-    margin: 1%;
-    height: 100%;
-    min-height: 200px;
-    display: inline-block;
+  width: 100%;
+  margin: 1%;
+  height: 100%;
+  display: inline-block;
 }
 
 .box-card .cardTitle {
-    font-weight: bold;
-    font-size: 25px;
+  font-weight: bold;
+  font-size: 22px;
+  color: #4041fd;
+  cursor: default;
+}
+.box-card .cardTitle img {
+  width: 100%;
+  vertical-align: top;
+}
+.box-card .cardTitleText {
+  display: inline-block;
+  margin-left: 18px;
+}
+.box-card .cardDesc {
+  font-family: AlibabaSans-Regular,serif;
+  font-weight: bold;
+  float: right;
+  padding-top: 12px;
+  color: #4041fd;
+  font-size: 15px;
+  font-style: italic;
+  cursor: default;
+}
+.demonstration {
+  color: var(--el-text-color-secondary);
+}
+
+.el-carousel__item h3 {
+  color: #475669;
+  opacity: 0.75;
+  line-height: 150px;
+  margin: 0;
+  text-align: center;
+}
+
+.el-carousel__item:nth-child(2n) {
+  background-color: #99a9bf;
+}
+
+.el-carousel__item:nth-child(2n + 1) {
+  background-color: #d3dce6;
 }
 </style>

+ 61 - 47
src/components/home/PluginManage.vue

@@ -1,20 +1,23 @@
 <template>
-    <div id="pluginManage">
-        <div class="left">
-            <el-scrollbar :max-height="menuHeight">
-                <el-menu default-active="0" class="pluginManage-menu" @select="handlePluginSelect">
-                    <el-menu-item v-for="(item,index) of pluginList" :key="index" :index="index+''">
-                        <el-icon><ElIconMagicStick /></el-icon>
-                        <span>{{ item.pluginName }}</span>
-                    </el-menu-item>
-                </el-menu>
-            </el-scrollbar>
+  <div id="pluginManage">
+    <br/>
+    <div class="left">
+      <el-scrollbar :max-height="menuHeight">
+        <el-menu default-active="0" class="pluginManage-menu" @select="handlePluginSelect">
+          <el-menu-item v-for="(item,index) of pluginList" :key="index" :index="index+''">
+            <el-icon>
+              <ElIconMagicStick/>
+            </el-icon>
+            <span>{{ item.pluginName }}</span>
+          </el-menu-item>
+        </el-menu>
+      </el-scrollbar>
 
-        </div>
-        <div class="content">
-            <PluginDetail :data="currPlugin" />
-        </div>
     </div>
+    <div class="content">
+      <PluginDetail :data="currPlugin"/>
+    </div>
+  </div>
 </template>
 
 <script>
@@ -22,48 +25,59 @@ import PluginDetail from '@/components/pluginManage/PluginDetail'
 import PluginData from '@/static/datas/PluginData'
 
 export default {
-    data() {
-        return {
-            menuHeight: '',
-            pluginList: [],
-            currPlugin: {}
-        }
-    },
-    props: {
-        height: Object
-    },
-    components: {
-        PluginDetail
-    },
-    created() {
-        this.menuHeight = this.height*0.7;
-        this.pluginList = JSON.parse(JSON.stringify(PluginData))
-        if (this.pluginList.length>0) {
-            this.currPlugin = this.pluginList[0]
-        }
-    },
-    mounted() {
-    },
-    methods: {
-        handlePluginSelect(val) {
-            this.currPlugin = this.pluginList[Number(val)]
-        }
+  data() {
+    return {
+      menuHeight: '',
+      pluginList: [],
+      currPlugin: {}
+    }
+  },
+  props: {
+    height: Object
+  },
+  components: {
+    PluginDetail
+  },
+  created() {
+    this.menuHeight = this.height * 0.7;
+    this.pluginList = JSON.parse(JSON.stringify(PluginData))
+    if (this.pluginList.length > 0) {
+      this.currPlugin = this.pluginList[0]
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    handlePluginSelect(val) {
+      this.currPlugin = this.pluginList[Number(val)]
     }
+  }
 }
 
 </script>
 
 <style scoped>
 #pluginManage .left {
-    display: inline-block;
-    width: 20%;
-    height: 100%;
+  display: inline-block;
+  width: 20%;
+  height: 100%;
 }
 
 #pluginManage .content {
-    display: inline-block;
-    width: 79%;
-    vertical-align: top;
-    height: 100%;
+  display: inline-block;
+  width: 79%;
+  vertical-align: top;
+  height: 100%;
+}
+</style>
+
+<style>
+#pluginManage .el-menu-item,.el-sub-menu__title {
+  font-size: 17px !important;
+  font-weight: 600;
+  color: #373737;
+}
+#pluginManage .pluginManage-menu .is-active {
+  color: #6566f4;
 }
 </style>

+ 101 - 2
src/components/home/SystemManage.vue

@@ -1,3 +1,102 @@
 <template>
-    
-</template>
+  <div id="SystemMgrContainer">
+    <br/>
+    <div v-if="auth" class="left">
+      <el-scrollbar>
+        <el-menu default-active="2" class="SystemMgr-menu" @select="handleSelect">
+          <!--<el-menu-item index="1">-->
+          <!--  <el-icon>-->
+          <!--    <IconPark-peoples-two />-->
+          <!--  </el-icon>-->
+          <!--  <span>用户管理</span>-->
+          <!--</el-menu-item>-->
+          <el-menu-item index="2">
+            <el-icon>
+              <IconPark-permissions />
+            </el-icon>
+            <span>权限管理</span>
+          </el-menu-item>
+          <el-menu-item index="3">
+            <el-icon>
+              <IconPark-log />
+            </el-icon>
+            <span>系统日志</span>
+          </el-menu-item>
+        </el-menu>
+      </el-scrollbar>
+    </div>
+
+    <div v-if="auth" class="content">
+      <AuthManage v-if="activeIndex=='2'" />
+      <SystemLogs v-if="activeIndex=='3'" />
+    </div>
+
+    <el-empty v-if="!auth" description="您不是管理员,暂无权限查看"></el-empty>
+  </div>
+</template>
+
+<script>
+import {defineAsyncComponent} from "vue";
+
+export default {
+  data() {
+    return {
+      auth: false,
+      activeIndex: '2'
+    }
+  },
+  components: {
+    SystemLogs: defineAsyncComponent(() => import("@/components/systemManage/SystemLogs")),
+    AuthManage: defineAsyncComponent(() => import("@/components/systemManage/AuthManage")),
+  },
+  created() {
+    let userInfo = this.$store.state.userInfo;
+    if (userInfo.userLevel<2
+        || (userInfo.userLevel===2) && userInfo.serviceId.split(',').indexOf(this.$constant.serviceId)>-1 ) {
+      this.auth = true;
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    handleSelect(val) {
+      let app = this;
+      this.activeIndex = '0';
+      setTimeout(function () {
+        app.activeIndex = val
+      })
+
+    }
+  }
+}
+</script>
+
+<style scoped>
+#SystemMgrContainer {
+  width: 100%;
+  height: 100%;
+}
+#SystemMgrContainer .left {
+  display: inline-block;
+  width: 20%;
+  height: 100%;
+}
+
+#SystemMgrContainer .content {
+  display: inline-block;
+  width: 79%;
+  vertical-align: top;
+  height: 100%;
+}
+</style>
+
+<style>
+#SystemMgrContainer .el-menu-item,.el-sub-menu__title {
+  font-size: 17px !important;
+  font-weight: 600;
+  color: #373737;
+}
+#SystemMgrContainer .SystemMgr-menu .is-active {
+  color: #6566f4;
+}
+</style>

+ 27 - 0
src/components/map/CesiumMap.vue

@@ -93,6 +93,33 @@ export default {
         app.viewer.scene.postRender.addEventListener(function () {
           app.loading = false;
         })
+        // 加载底图
+        app.viewer.imageryLayers.addImageryProvider(
+            new Cesium.WebMapTileServiceImageryProvider({
+              url:  'http://t{s}.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk='+systemConfig.tdt_tk,
+              layer: "img",
+              style: "default",
+              // tileMatrixSetID: "w",
+              format: "image/jpeg",
+              subdomains: ["0", "1", "2", "3", "4", "5", "6", "7"],
+              tileMatrixSetID: "GoogleMapsCompatible",
+              show: true,
+              minimumLevel: 1,
+              maximumLevel: 18,
+            })
+        );
+        // 加载注记
+        app.viewer.imageryLayers.addImageryProvider(
+            new Cesium.WebMapTileServiceImageryProvider({
+              url: 'http://t{s}.tianditu.gov.cn/cia_w/wmts?tk='+systemConfig.tdt_tk,
+              layer: "cia",
+              style: "default",
+              tileMatrixSetID: "w",
+              format: "tiles",
+              subdomains: ["0", "1", "2", "3", "4", "5", "6", "7"],
+              maximumLevel: 20,
+            })
+        );
         // 加载模型
         if (app.item.url && app.item.url!=='') {
           app.add3DTiles(app.viewer, app.item.url)

+ 19 - 3
src/components/map/OlMap.vue

@@ -33,6 +33,7 @@ import TileLayer from 'ol/layer/Tile'
 import OSM from 'ol/source/OSM'
 import {GeoJSON} from "ol/format";
 import {Draw} from "ol/interaction";
+import {XYZ} from "ol/source";
 
 export default {
   data() {
@@ -101,13 +102,28 @@ export default {
   methods: {
     initMap() {
       let app = this;
+      // 天地图底图
+      let tileLayer = new TileLayer({
+        title: '天地图',
+        source: new XYZ({
+          url: 'http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk='+systemConfig.tdt_tk,
+        })
+      })
+      // 标注图层
+      let tileMark = new TileLayer({
+        title: '标注图层',
+        source: new XYZ({
+          url: 'http://t4.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk='+systemConfig.tdt_tk,
+        })
+      })
       app.map = new Map({
         target: app.$refs.map,
         logo: false,
         layers: [
-          new TileLayer({
-            source: new OSM()
-          })
+          // new TileLayer({
+          //   source: new OSM()
+          // })
+          tileLayer, tileMark
         ],
         view: new View({
           projection: 'EPSG:4326', // 使用这个坐标系

+ 140 - 0
src/components/systemManage/AuthManage.vue

@@ -0,0 +1,140 @@
+<template>
+  <div id="AuthManageContainer">
+    <h3>角色权限管理</h3>
+    <el-divider />
+    <el-card class="box-card" style="width: 35%; display: inline-block;vertical-align: top">
+      <template #header>
+        <div class="card-header">
+          <span style="font-weight: bold">角色列表</span>
+        </div>
+      </template>
+      <div v-for="role in roleList" :key="role.id" class="roleItem" :style="currRole.id===role.id?checkRoleStyle:''" @click="handleRoleSelect(role)">{{ role.noteStr }}</div>
+    </el-card>
+
+    <div class="authDetails" v-show="currRole.id">
+      <h4 style="display: inline-block;padding-top: 3px">权限管理</h4>
+      <el-button type="default" title="保存" @click="submit" style="display: inline-block;font-size: 15px;float: right">
+        <el-icon><IconPark-save /></el-icon>
+      </el-button>
+      <el-divider />
+      <el-tree v-loading="authLoading" ref="authTree" :data="authData" :props="authDataProps" node-key="id" show-checkbox />
+    </div>
+  </div>
+</template>
+
+<script>
+import api from "@/api/data/AuthInfo";
+
+export default {
+  data() {
+    return {
+      roleList: [],
+      authData: [],
+      authDataProps: {
+        children: 'children',
+        label: 'name',
+      },
+      currRole: {},
+      checkRoleStyle: {
+        background: 'rgba(101,102,244,0.7)',
+        color: 'white',
+      },
+      currCheckedAuth: [],
+      authLoading: false
+    }
+  },
+  created() {
+    this.getRoleList();
+    this.getAuthList();
+  },
+  mounted() {
+  },
+  methods: {
+    getRoleList() {
+      let app = this;
+      let params = {
+        serviceId: this.$constant.serviceId,
+      }
+      api.getRoleList(params).then(res=>{
+        if (res.code===200) {
+          app.roleList = []
+          res.content.list.forEach(item => {
+            if (item.id>1) {
+              app.roleList.push(item)
+            }
+          })
+        }
+      })
+    },
+    handleRoleSelect(role) {
+      let app = this;
+      this.authLoading = true;
+      this.currRole = role;
+      this.$refs.authTree.setCheckedKeys([]);
+      if (role.permissionId) {
+        this.$refs.authTree.setCheckedKeys(role.permissionId.split(','))
+      }
+      setTimeout(function () {
+        app.authLoading = false
+      },300)
+    },
+    getAuthList() {
+      let app = this;
+      let params = {
+        serviceId: this.$constant.serviceId,
+        type: app.$constant.authType,
+      }
+      api.getAuthList(params).then(res=>{
+        if (res.code===200) {
+          app.authData = res.content
+        }
+      })
+    },
+    submit() {
+      let app = this;
+      let params = {
+        serviceId: this.$constant.serviceId,
+        type: app.$constant.authType,
+        roleId: this.currRole.id,
+        permissionId: this.$refs.authTree.getCheckedKeys().join(','),
+      }
+      app.$util.loading.handleLoading(true);
+      api.updateRoleAuth(params).then(res=>{
+        if (res.code===200) {
+          app.$message({ message: '保存成功', type: 'success' });
+          app.getRoleList()
+          app.$util.loading.handleLoading(false);
+        }
+      })
+    },
+  }
+}
+</script>
+
+<style scoped>
+#AuthManageContainer {
+  width: 100%;
+  height: 100%;
+  padding-left: 2%;
+}
+.roleItem {
+  padding: 5px 15px;
+  cursor: pointer;
+  border-radius: 12px;
+  margin-bottom: 5px;
+}
+.roleItem:hover {
+  background-color: rgba(100,90,200,0.1);
+}
+.authDetails {
+  width: 45%;
+  margin-left: 2%;
+  padding: 1%;
+  padding-left: 3%;
+  border: 1px solid #e4e7ed;
+  box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
+  border-radius: 3px;
+  height: 60%;
+  display: inline-block;
+}
+</style>

+ 114 - 0
src/components/systemManage/SystemLogs.vue

@@ -0,0 +1,114 @@
+<template>
+  <div id="SystemLogs">
+    <h3 style="display: inline-block">系统日志</h3>
+    <div style="display: inline-block; cursor: pointer; margin-left: 20px" @click="refresh">
+      <el-tooltip
+          class="box-item"
+          effect="dark"
+          content="刷新日志"
+          placement="right"
+      >
+        <el-icon ><IconPark-refresh/></el-icon>
+      </el-tooltip>
+    </div>
+    <el-divider/>
+    <el-table :data="tableData" v-loading="loading" element-loading-text="正在加载,请稍后..."
+              :border="true" :stripe="true" :height="440" style="width: 100%;margin-bottom: 15px;">
+      <el-table-column prop="userName" label="用户名"/>
+      <el-table-column prop="loginIp" label="访问ip"/>
+      <el-table-column prop="createTime" label="访问时间">
+        <template #default="scope">
+          {{ $util.datetime.format(scope.row.createTime) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="requestUrl" label="访问接口"/>
+    </el-table>
+    <el-pagination style="float:right" background layout="sizes, prev, pager, next, jumper, total"
+                   v-model:current-page="pageInfo.page" v-model:page-size="pageInfo.pageSize"
+                   v-model:total="pageInfo.total"/>
+  </div>
+</template>
+
+<script>
+import api from "@/api/data/SystemInfo"
+
+export default {
+  data() {
+    return {
+      loading: false,
+      tableData: [],
+      pageInfo: {
+        page: 1,
+        pageSize: 10,
+        total: 0
+      }
+    }
+  },
+  created() {
+  },
+  mounted() {
+    this.getData();
+  },
+  watch: {
+    "pageInfo.page": function (val) {
+      if (val > 0) {
+        this.getData();
+      }
+    },
+    "pageInfo.pageSize": function () {
+      let app = this;
+      this.pageInfo.page = -1;
+      setTimeout(function () {
+        app.pageInfo.page = 1;
+      }, 50)
+    },
+  },
+  methods: {
+    handleLoading(flag) {
+      let app = this;
+      if (flag) {
+        app.loading = true;
+      } else {
+        setTimeout(() => {
+          app.loading = false;
+        }, 500);
+      }
+    },
+    getData() {
+      let app = this;
+      let end = app.$util.datetime.nowTimestamp();
+      let start = app.$util.datetime.now().subtract(7, 'day').valueOf();
+      let params = {
+        page: app.pageInfo.page-1,
+        pageSize: app.pageInfo.pageSize,
+        startDate: start,
+        endDate: end,
+        serviceId: this.$constant.serviceId
+      };
+      app.handleLoading(true)
+      api.getLogData(params).then(res=>{
+        if (res.code===200) {
+          app.tableData=res.content;
+          app.pageInfo.total = res.total;
+        }
+        app.handleLoading(false)
+      }).catch(()=>{
+        app.handleLoading(false)
+      })
+    },
+    refresh() {
+      let app = this;
+      app.pageInfo.pageSize=-1;
+      setTimeout(function () {
+        app.pageInfo.pageSize=10;
+      })
+    }
+  }
+}
+</script>
+
+<style>
+#SystemLogs {
+  padding-left: 2%;
+}
+</style>

+ 5 - 0
src/main.js

@@ -7,6 +7,7 @@ import store from './store'
 import ElementPlus from 'element-plus'
 import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
 import 'element-plus/dist/index.css'
+import '@/style/element-variables.scss'
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 //iconpark
 import {install} from '@icon-park/vue-next/es/all';
@@ -27,6 +28,10 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
 // iconpark, 以IconPark开头, 例如IconPark-people
 install(app, 'IconPark')
 
+//echarts
+import * as echarts from 'echarts'
+app.config.globalProperties.$echarts = echarts;
+
 // 全局方法
 import util from '@/utils/index'
 app.config.globalProperties.$util = util

+ 1 - 1
src/static/datas/PluginData.json

@@ -1,7 +1,7 @@
 [
     {
         "pluginName": "水面模拟插件",
-        "methods": "测试\n1.测试\n2.测试",
+        "methods": "测试\n1. 测试\n2. 测试",
         "params": "测试",
         "example": "测试",
         "response": "测试",

+ 11 - 0
src/style/element-variables.scss

@@ -0,0 +1,11 @@
+:root {
+  --el-color-primary: #6566f4;
+}
+@font-face{
+  font-family:"AlibabaPuHuiTi-Regular";
+  src:url("@/assets/fonts/AlibabaPuHuiTi-Regular.ttf")
+}
+@font-face{
+  font-family:"AlibabaSans-Regular";
+  src:url("@/assets/fonts/AlibabaSans-Regular.ttf")
+}

+ 2 - 0
src/utils/constant.js

@@ -1,6 +1,8 @@
 // 常量
 
 export default {
+    serviceId: 9, // 对接oauth服务id
+    authType: 90, // 菜单权限在oauth中类型id
     oauthProxy: '/proxy_oauth', // oauth 代理地址前缀
     dtbserverProxy: '/proxy_dtbserver' // dtbserver 代理地址前缀
 }

+ 141 - 148
src/views/HomeView.vue

@@ -2,74 +2,60 @@
   <div id="home">
     <div id="Header">
       <div class="loginForm" v-if="isLogin">
-        用户名:
-        <span style="display: inline-block; padding: 0 20px 0 0">{{ $store.getters.getUserName || '未登录' }}</span>
-        <el-link type="warning" :underline="false" class="logout" @click="logout"> 退出登录 </el-link>
+        <span style="color: white">用户名:</span>
+        <span style="color: white">{{ $store.getters.getUserName || '未登录' }}</span>
+        <el-link type="warning" :underline="false" class="logout" @click="logout"> 退出登录</el-link>
       </div>
       <div class="loginForm" v-else>
-        <el-form :inline="true" :model="loginForm" :rules="loginFormRules" ref="loginForm">
-          <el-form-item prop="userName">
-            <template #label>
-              <span class="formLabel">用户名:</span>
-            </template>
-            <el-input v-model="loginForm.userName" placeholder="请输入用户名"></el-input>
-          </el-form-item>
-          <el-form-item prop="password">
-            <template #label>
-              <span class="formLabel">密码:</span>
-            </template>
-            <el-input type="password" v-model="loginForm.password" placeholder="请输入密码"></el-input>
-          </el-form-item>
-          <el-form-item>
-            <el-button type="default" @click="login">登录</el-button>
-          </el-form-item>
-        </el-form>
+        <span class="formLabel">用户名:</span>
+        <input class="formInput" type="text" v-model="loginForm.userName" placeholder="请输入用户名"/>
+        &nbsp;&nbsp;
+        <span class="formLabel">密&nbsp;&nbsp;码:</span>
+        <input class="formInput" type="password" v-model="loginForm.password" placeholder="请输入密码"/>
+        &nbsp;&nbsp;
+        <el-button type="warning" @click="login" size="small">登录</el-button>
+      </div>
+      <div class="title">
+        <img :src="titleImg"/>
       </div>
-      <div class="title">可视化数据管理平台</div>
     </div>
     <div id="Menu" :style="{height: contentHeight+'px'}">
       <div id="Tags">
-        <el-tabs v-model="activeName" type="card" @tab-click="handleMenuClick" style="margin: auto;" stretch>
-          <div class="content">
-            <el-tab-pane label="综合展示" name="homeIndex">
-                <div class="tabPanel">
-                  <HomeIndex v-if="activeName==='homeIndex'" />
-                </div>
-              </el-tab-pane>
-              <span v-if="isLogin">
-                <el-tab-pane label="数据管理" name="dataManage">
-                  <div class="tabPanel">
-                    <DataManage :height="contentHeight" v-if="activeName==='dataManage'" />
-                  </div>
-                </el-tab-pane>
-                <el-tab-pane label="数据发布" name="datePublish">
-                  <div class="tabPanel">
-                    <DataPublish :height="contentHeight" v-if="activeName==='datePublish'" />
-                  </div>
-                </el-tab-pane>
-                <el-tab-pane label="插件管理" name="pluginManage">
-                  <div class="tabPanel">
-                    <PluginManage v-if="activeName==='pluginManage'" />
-                  </div>
-                </el-tab-pane>
-                <el-tab-pane label="系统管理" name="systemManage">
-                  <div class="tabPanel">
-                    <SystemManage v-if="activeName==='systemManage'" />
-                  </div>
-                </el-tab-pane>
-              </span>
-          </div>
-        </el-tabs>
+        <el-menu
+            :default-active="activeIndex"
+            class="el-menu-demo"
+            mode="horizontal"
+            background-color="#6162f2"
+            text-color="white"
+            active-text-color="#ffc01c"
+            @select="handleMenuClick"
+        >
+          <el-menu-item index="1" >综合展示</el-menu-item>
+          <el-menu-item index="2" v-if="isLogin && pageShow['DTB-DATAMANAGE']">数据管理</el-menu-item>
+          <el-menu-item index="3" v-if="isLogin && pageShow['DTB-DATAPUBLISH']">数据发布</el-menu-item>
+          <el-menu-item index="4" v-if="isLogin && pageShow['DTB-PLUGINMANAGE']">插件管理</el-menu-item>
+          <el-menu-item index="5" v-if="isLogin && pageShow['DTB-SYSTEMMANAGE']">系统管理</el-menu-item>
+        </el-menu>
+      </div>
+      <div class="content">
+        <!--<HomeIndex :auth="pageShow['DTB-HOMEINDEX']" v-if="activeIndex==1"/>-->
+        <HomeIndex :auth="true" v-if="activeIndex==1"/>
+        <DataManage v-if="activeIndex==2"/>
+        <DataPublish v-if="activeIndex==3"/>
+        <PluginManage v-if="activeIndex==4"/>
+        <SystemManage v-if="activeIndex==5"/>
       </div>
     </div>
   </div>
 </template>
 
 <script>
-import { defineAsyncComponent } from "vue";
+import {defineAsyncComponent} from "vue";
 import loginApi from "@/api/login";
 import elementResizeDetectorMaker from "element-resize-detector";
 
+import titleImg from "@/assets/img/title.png"
+
 
 export default {
   name: 'homeIndex',
@@ -82,24 +68,22 @@ export default {
   },
   data() {
     return {
-      activeName: 'homeIndex',
+      titleImg,
+      activeIndex: '1',
       fullscreenLoading: null,
       contentHeight: '',
       isLogin: false,
       loginForm: {
         userName: 'user001',
         password: '1234567890',
-        clientId: '0',
+        clientId: this.$constant.serviceId,
       },
-      loginFormRules: {
-        userName: [
-          { required: true, message: '请输入用户名', trigger: 'blur' },
-          { required: true, message: '请输入用户名', trigger: 'change' }
-        ],
-        password: [
-          { required: true, message: '请输入用户名', trigger: 'blur' },
-          { required: true, message: '请输入用户名', trigger: 'change' }
-        ]
+      pageShow: {
+        "DTB-HOMEINDEX": false, // 综合展示
+        "DTB-DATAMANAGE": false, // 数据管理
+        "DTB-DATAPUBLISH": false, // 数据发布
+        "DTB-PLUGINMANAGE": false, // 插件管理
+        "DTB-SYSTEMMANAGE": false, // 系统管理
       }
     }
   },
@@ -108,44 +92,56 @@ export default {
   },
   mounted() {
     this.judgeLogin();
-    // 监听高度变化
-    let app = this;
-    let erd = elementResizeDetectorMaker();
-    let minHeight = document.getElementById('home').scrollHeight * 0.779;
-    erd.listenTo(document.getElementsByClassName('content'), e => {
-      if (e.scrollHeight && e.scrollHeight >= minHeight - 70) {
-        app.contentHeight = e.scrollHeight + 70
-      } else {
-        app.contentHeight = minHeight;
-      }
-    })
   },
   methods: {
     judgeLogin() {
       let token = this.$store.getters.getToken;
       this.isLogin = token && token !== '';
-      this.activeName = 'homeIndex'
-    },
-    handleMenuClick(panel, event) {
-      this.activeName = panel.paneName;
+      this.activeIndex = 1;
+      if (this.isLogin) {
+        this.updateAuth();
+      }
     },
-    login() {
+    updateAuth() {
       let app = this;
-      this.$refs.loginForm.validate((valid) => {
-        if (valid) {
-          app.$util.loading.handleLoading(true)
-          loginApi.userLogin(app.loginForm).then(res => {
-            app.$store.state.token = res.message
-            app.$store.commit('setUserInfo', res.content);
-            app.$store.commit('setToken', res.message);
-            app.$util.loading.handleLoading(false);
-            app.judgeLogin()
-          }).catch(err => {
-            app.$util.loading.handleLoading(false);
-            app.judgeLogin();
+      let params = {
+        serviceId: this.$constant.serviceId,
+        type: app.$constant.authType
+      }
+      let keys = Object.keys(app.pageShow);
+      loginApi.getUserPermissions(params).then(res=>{
+        if (res.code === 200) {
+          res.content.forEach(item => {
+            if (keys.indexOf(item.permissionName)>-1) {
+              app.pageShow[item.permissionName] = true;
+            }
           })
         }
       })
+    },
+    handleMenuClick(val) {
+      this.activeIndex = val;
+    },
+    login() {
+      let app = this;
+      if (!app.loginForm.userName || app.loginForm.userName==='') {
+        app.$message({message: '请输入用户名', type: 'warning'});
+        return;
+      } else if (!app.loginForm.password || app.loginForm.password==='') {
+        app.$message({message: '请输入密码', type: 'warning'});
+        return;
+      }
+      app.$util.loading.handleLoading(true)
+      loginApi.userLogin(app.loginForm).then(res => {
+        app.$store.state.token = res.message
+        app.$store.commit('setUserInfo', res.content);
+        app.$store.commit('setToken', res.message);
+        app.$util.loading.handleLoading(false);
+        app.judgeLogin()
+      }).catch(err => {
+        app.$util.loading.handleLoading(false);
+        app.judgeLogin();
+      })
 
     },
     logout() {
@@ -183,41 +179,52 @@ export default {
 
 #Header {
   /* background-image: linear-gradient(#90e2fc, white); */
-  background-image: url('@/assets/img/bg.jpg');
-  background-size: 100% 180%;
-  height: 22%;
+  background-image: url('@/assets/img/header.png');
+  background-size: 100% 100%;
+  height: 18%;
 }
 
-#Menu {
-  height: 76%;
-  overflow: visible;
-  background-image: linear-gradient(white 93%, #2970d8);
-}
-
-#Tags {
-  /* background-color: #02a7f0; */
-  margin-top: 10px;
-  width: 100%;
+#Header .title {
   height: 100%;
-  /* color: white; */
-  /* height: 8%; */
+  padding: 3.5% 0 0 10%;
 }
 
-#Header .title {
-  /* color: #0d8ee9; */
-  color: white;
-  height: 100%;
-  padding: 4% 0 0 10%;
-  font-size: 40px;
-  font-weight: bold;
+#Header .title img {
+  width: 12%;
 }
 
 #Header .loginForm {
   float: right;
+  /*width: 30%;*/
+  /*float: right;*/
   margin-top: 1%;
+  margin-right: 3%;
+  /*color: white;*/
+}
+
+.loginForm .formLabel {
+  display: inline-block;
+}
+
+.loginForm .formInput {
+  margin-right: 5px;
+  border-color: transparent;
+  border-radius: 3px;
+  height: 20px;
   color: white;
+  padding-left: 6px;
+  background: rgba(255, 255, 255, 0.3);
+}
+
+.loginForm .formInput:hover {
+  background-color: rgba(255, 255, 255, 0.6);
 }
 
+.loginForm .formInput:focus {
+  outline: 1px solid rgba(255, 255, 255, 0.6);
+}
+
+
 .logout {
   color: #e1e1e1;
   padding: 0 15px 5px
@@ -231,52 +238,38 @@ export default {
   color: white;
 }
 
-.content {
-  width: 100%;
-  height: 100%;
-  padding-top: 1%;
-}
-
-.tabPanel {
-  width: 70%;
-  margin: 0 auto;
-}
-
-/* tabs 样式 start */
-:deep .el-tabs__nav-scroll {
-  width: 50%;
-  background-color: #0d8ee9;
-  margin: 0 auto
+#Menu {
+  height: 76%;
+  overflow: visible;
 }
 
-:deep .el-tabs__content {
-  overflow: visible;
+#Tags {
+  width: 100%;
 }
 
-:deep .el-tabs__item {
-  color: white;
-  font-size: 15px;
+.content {
+  width: 80%;
+  margin: 0 auto;
+  /*padding-top: 1%;*/
+  height: 95%;
+  /*overflow: visible;*/
 }
 
-:deep .el-tabs__item:hover {
-  color: white;
-  background-color: #2ba7ff;
-  font-size: 15px;
+.el-menu-demo {
+  align-items: center;
+  justify-content: center;
 }
 
-:deep .el-tabs__item.is-active {
-  color: white;
-  font-weight: bolder;
-  font-size: 18px;
-  background-color: #2ba7ff;
+.el-menu-item {
+  font-size: 20px;
+  font-weight: 600;
+  margin: 0 5% !important;
 }
 
-:deep .el-tabs__active-bar {
-  border-radius: 30px;
-  background-color: #0d8ee9;
+.el-menu-item:focus {
+  background-color: #6162f2 !important;
 }
 
-/* tabs 样式 end */
 
 </style>