浏览代码

数据质检模块
数据服务 - 数据服务接口,地图服务接口
首页跳转

wan.dequan 3 年之前
父节点
当前提交
5bff6debc7
共有 23 个文件被更改,包括 1980 次插入80 次删除
  1. 二进制
      public/static/images/tileservice/raster.png
  2. 二进制
      public/static/images/tileservice/raster_zj.png
  3. 二进制
      public/static/images/tileservice/topography.png
  4. 二进制
      public/static/images/tileservice/topography_zj.png
  5. 二进制
      public/static/images/tileservice/vecter.png
  6. 二进制
      public/static/images/tileservice/vecter_zj.png
  7. 二进制
      public/static/package/quality/excel.xlsx
  8. 39 0
      public/static/package/quality/geojson.json
  9. 二进制
      public/static/package/quality/shapefile.zip
  10. 0 1
      src/api/content.js
  11. 13 0
      src/api/qualityinspection.js
  12. 9 2
      src/components/DataQualityInspection/Process/AccessoryDiagram.vue
  13. 345 4
      src/components/DataQualityInspection/Process/ExcelQualityInspection.vue
  14. 345 4
      src/components/DataQualityInspection/Process/GeojsonQualityInspection.vue
  15. 8 1
      src/components/DataQualityInspection/Process/InterfaceAccessDiagram.vue
  16. 345 4
      src/components/DataQualityInspection/Process/ShapefileQualityInspection.vue
  17. 22 1
      src/components/DataQualityInspection/Rules/ImportExcelQualityInspectionRules.vue
  18. 33 10
      src/components/DataQualityInspection/Rules/ImportGeojsonQualityInspectionRules.vue
  19. 33 10
      src/components/DataQualityInspection/Rules/ImportShapefileQualityInspectionRules.vue
  20. 410 3
      src/components/DataServices/DataService.vue
  21. 235 3
      src/components/DataServices/TileService.vue
  22. 140 34
      src/views/ComprehensiveDisplay.vue
  23. 3 3
      src/views/DataQualityInspection.vue

二进制
public/static/images/tileservice/raster.png


二进制
public/static/images/tileservice/raster_zj.png


二进制
public/static/images/tileservice/topography.png


二进制
public/static/images/tileservice/topography_zj.png


二进制
public/static/images/tileservice/vecter.png


二进制
public/static/images/tileservice/vecter_zj.png


二进制
public/static/package/quality/excel.xlsx


+ 39 - 0
public/static/package/quality/geojson.json

@@ -0,0 +1,39 @@
+{
+  "type": "FeatureCollection",
+  "features": [
+    {
+      "type": "Feature",
+      "properties": {
+        "PROJECT_AD": "士大夫撒地方",
+        "PLAN_REFOR": "第三方时发发",
+        "SCHOOL_ACREAGE": "131022",
+        "SCHOOL_LONGITUDE": "116.281312",
+        "SCHOOL_LATITUDE": "39.328326"
+      },
+      "geometry": {
+        "type": "Point",
+        "coordinates": [
+          114.45968627929688,
+          36.61552763134925
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+              "PROJECT_AD": "士大夫撒地方",
+        "PLAN_REFOR": "第三方时发发",
+        "SCHOOL_ACREAGE": "131022",
+        "SCHOOL_LONGITUDE": "116.281312",
+        "SCHOOL_LATITUDE": "39.328326"
+      },
+      "geometry": {
+        "type": "Point",
+        "coordinates": [
+          114.54345703125,
+          36.595684037179055
+        ]
+      }
+    }
+  ]
+}

二进制
public/static/package/quality/shapefile.zip


+ 0 - 1
src/api/content.js

@@ -54,7 +54,6 @@ const uploadShapeFile = (params) => {
   return postFile(systemConfig.dataUrl + '/content/addDataForShapeZip', params);
 }
 
-
 // 根据标题筛选获取模型
 const getContentForTitle = (params) => {
   let str = splicingParam(params)

+ 13 - 0
src/api/qualityinspection.js

@@ -0,0 +1,13 @@
+import {
+    postFile
+  } from '../utils/request'
+
+  //上传shape文件
+  const uploadInspectionFile = (params) => {
+    return postFile(systemConfig.dataUrl + '/qc/qualityTestingDate', params);
+  } 
+  
+  export default {
+    uploadInspectionFile
+  }
+  

+ 9 - 2
src/components/DataQualityInspection/Process/AccessoryDiagram.vue

@@ -1,6 +1,6 @@
 <template>
   <el-container>
-    <el-image :src="showImg" :preview-src-list="srcList"></el-image>
+    <el-image title="点击可查看大图" :src="showImg" :preview-src-list="srcList"></el-image>
   </el-container>
 </template>
 
@@ -28,9 +28,16 @@ export default {
   background: #ffffff;
   overflow: hidden;
   overflow-y: auto;
-  .el-image { 
+  .el-image {
     margin: 0 auto;
     display: block;
+    width: 100%;
+    height: 100%;
+    /deep/ img {
+      width: unset;
+      margin: 0 auto;
+      display: block;
+    }
   }
 }
 </style>

+ 345 - 4
src/components/DataQualityInspection/Process/ExcelQualityInspection.vue

@@ -1,23 +1,364 @@
 <template>
   <el-container>
-    <el-main> </el-main>
+    <el-row class="header">
+      <el-button type="primary" @click="addRules">添加规则</el-button>
+    </el-row>
+
+    <div class="ruleContent" ref="ruleContent">
+      <el-table
+        ref="multipleTable"
+        :data="checkDetail"
+        border
+        :max-height="tableMaxHeight"
+        style="width: 100%"
+      >
+        <el-table-column prop="index" label="序号" width="50" align="center">
+        </el-table-column>
+        <el-table-column
+          prop="name"
+          label="是否检查"
+          width="160"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <el-radio v-model="scope.row.isCheck" :label="1">是</el-radio>
+            <el-radio v-model="scope.row.isCheck" :label="0">否</el-radio>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="checkContent"
+          label="检查项"
+          width="180"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <!-- <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <span> {{ item.checkContent }} </span>
+              </el-row>
+            </div>
+            <span v-else> {{ scope.row.checkContent }} </span> -->
+            <span> {{ scope.row.checkContent }} </span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="checkDescribe" label="描述" align="center">
+          <template slot-scope="scope">
+            <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <span> {{ item.checkDescribe }} </span>
+              </el-row>
+            </div>
+            <span v-else> {{ scope.row.checkDescribe }} </span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="fieldName"
+          label="字段名称"
+          width="200"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <el-input v-model="item.fieldName"></el-input>
+              </el-row>
+            </div>
+            <el-input v-else v-model="scope.row.fieldName"></el-input>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <el-row>
+      <!-- <el-button class="uploadbtn" type="primary" @click="uploadFile">
+        上传文件
+      </el-button> -->
+      <el-upload
+        class="uploadbtn"
+        ref="upload"
+        accept="csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+        :action="''"
+        :auto-upload="true"
+        :show-file-list="false"
+        :limit="1"
+        :before-upload="uploadFile"
+      >
+        <el-button type="primary" class="add-item">上传文件</el-button>
+      </el-upload>
+    </el-row>
   </el-container>
 </template>
 
 <script>
+import qualityApi from "@/api/qualityinspection";
+
 export default {
   data() {
     return {
+      tableMaxHeight: 450,
+      defaultField: {
+        index: 1,
+        isCheck: 1,
+        checkContent: "数据完整性",
+        checkDescribe:
+          "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
+        fieldName: "",
+        delBtn: true,
+        type: "dataIntegrality",
+      },
+      checkDefaultDetail: [
+        {
+          index: 1,
+          isCheck: 1,
+          checkContent: "数据完整性",
+          checkDescribe:
+            "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
+          fieldName: "",
+          delBtn: true,
+          type: "dataIntegrality",
+        },
+        {
+          index: 2,
+          isCheck: 1,
+          checkContent: "省级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字的行政区划编码',
+          fieldName: "",
+          delBtn: false,
+          type: "provinceCode",
+        },
+        {
+          index: 3,
+          isCheck: 1,
+          checkContent: "市级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字且至少4位的行政区划编码',
+          fieldName: "",
+          type: "cityCode",
+          delBtn: false,
+        },
+        {
+          index: 4,
+          isCheck: 1,
+          checkContent: "县级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字且至少6位的行政区划编码',
+          fieldName: "",
+          type: "countryCode",
+          delBtn: false,
+        },
+        {
+          index: 5,
+          isCheck: 1,
+          checkContent: "经纬度验证",
+          checkDescribe: "经纬度是否在河北省境内",
+          fieldName: "",
+          type: "latlon",
+          delBtn: false,
+          children: [
+            {
+              checkDescribe: "验证所需经度字段名",
+              fieldName: "",
+              type: "lon",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需纬度字段名",
+              fieldName: "",
+              type: "lat",
+              delBtn: false,
+            },
+          ],
+        },
+        {
+          index: 6,
+          isCheck: 1,
+          checkContent: "行政区划+经纬度验证",
+          checkDescribe:
+            "检查经纬度点位是否在行政区划范围内部,例:经纬度为116.4,39.9的位置是否在石家庄范围内",
+          fieldName: "",
+          type: "areaLocation",
+          delBtn: false,
+          children: [
+            {
+              checkDescribe: "验证所需行政区划编码字段名",
+              fieldName: "",
+              type: "areaCode",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需经度字段名",
+              fieldName: "",
+              type: "lon",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需纬度字段名",
+              fieldName: "",
+              type: "lat",
+              delBtn: false,
+            },
+          ],
+        },
+      ],
+      checkDetail: [],
     };
   },
-  components: {
+  components: {},
+  mounted() {
+    let that = this;
+    this.checkDetail = JSON.parse(JSON.stringify(this.checkDefaultDetail));
+    setTimeout(() => {
+      that.resizeWindowEvent();
+    }, 100);
   },
   methods: {
-
+    // 重置表格高度
+    resizeWindowEvent() {
+      let that = this;
+      this.tableInterval = setInterval(() => {
+        if (that.$refs["ruleContent"]) {
+          that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
+          clearInterval(that.tableInterval);
+        }
+      }, 100);
+      window.onresize = () => {
+        return (() => {
+          if (that.$refs["ruleContent"])
+            that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
+        })();
+      };
+    },
+    addRules() {
+      let obj = JSON.parse(JSON.stringify(this.defaultField));
+      this.checkDetail.unshift(obj);
+      this.checkDetail = this.checkDetail.map(function (item, index) {
+        item.index = index + 1;
+        return item;
+      });
+    },
+    uploadFile(file) {
+      let that = this;
+      // let ceshiObj = {};
+      let obj = new FormData();
+      let completeArr = [];
+      for (let i = 0; i < this.checkDetail.length; i++) {
+        let param = this.checkDetail[i];
+        if (param.isCheck) {
+          if (!param.children) {
+            switch (param.type) {
+              case "dataIntegrality":
+                if (that.webMessage(param.fieldName, param.checkContent))
+                  return;
+                completeArr.push(param.fieldName);
+                break;
+              default:
+                if (that.webMessage(param.fieldName, param.checkContent))
+                  return;
+                obj.append(param.type, param.fieldName);
+                // ceshiObj[param.type] = param.fieldName;
+                break;
+            }
+          } else {
+            let arr = [];
+            for (let k = 0; k < param.children.length; k++) {
+              const item = param.children[k];
+              if (that.webMessage(item.fieldName, item.checkContent)) return;
+              arr.push(item.fieldName);
+            }
+            obj.append(param.type, arr);
+            // ceshiObj[param.type] = arr;
+          }
+        }
+      }
+      if (completeArr.length > 0) {
+        obj.append("dataIntegrality", completeArr);
+        // ceshiObj["dataIntegrality"] = completeArr;
+      }
+      obj.append("file", file);
+      qualityApi
+        .uploadInspectionFile(obj)
+        .then((result) => {
+          if (result.code == 200) {
+            that.$message({
+              type: "success",
+              message: result.content,
+            });
+          } else {
+            that.$message({
+              type: "error",
+              message: result.content,
+            });
+          }
+        })
+        .catch((err) => {
+          that.$message({
+            type: "error",
+            message: err,
+          });
+        });
+      return false;
+    },
+    webMessage(fieldName, str) {
+      if (fieldName == "") {
+        this.$message({
+          message: "请完善" + str,
+          type: "warning",
+        });
+        return true;
+      }
+      return false;
+    },
   },
 };
 </script>
 
 <style lang="less" scoped>
-
+.el-container {
+  display: block;
+  width: 100%;
+  padding: 10px 20px;
+  box-sizing: border-box;
+  background: #ffffff;
+  overflow: hidden;
+  overflow-y: auto;
+  .el-row {
+    line-height: 40px;
+    &::before {
+      display: unset;
+    }
+  }
+  .header {
+    margin-bottom: 10px;
+  }
+  .ruleContent {
+    height: calc(100% - 110px);
+  }
+  .el-table {
+    /deep/ .el-table--border .el-table__cell:first-child .cell {
+      padding-left: unset;
+    }
+    /deep/ .cell {
+      padding-left: unset;
+      padding-right: unset;
+    }
+    .el-input {
+      margin: 0 10px;
+      width: calc(100% - 20px);
+    }
+    .morerow {
+      .el-row {
+        padding-bottom: 10px;
+        border-bottom: 1px solid #eeeeee;
+        &:last-child {
+          padding-top: 10px;
+          padding-bottom: 0px;
+          border-bottom: 0px;
+        }
+      }
+    }
+  }
+  .uploadbtn {
+    float: right;
+    margin-top: 10px;
+    margin-right: 20px;
+  }
+}
 </style>

+ 345 - 4
src/components/DataQualityInspection/Process/GeojsonQualityInspection.vue

@@ -1,23 +1,364 @@
 <template>
   <el-container>
-    <el-main> </el-main>
+    <el-row class="header">
+      <el-button type="primary" @click="addRules">添加规则</el-button>
+    </el-row>
+
+    <div class="ruleContent" ref="ruleContent">
+      <el-table
+        ref="multipleTable"
+        :data="checkDetail"
+        border
+        :max-height="tableMaxHeight"
+        style="width: 100%"
+      >
+        <el-table-column prop="index" label="序号" width="50" align="center">
+        </el-table-column>
+        <el-table-column
+          prop="name"
+          label="是否检查"
+          width="160"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <el-radio v-model="scope.row.isCheck" :label="1">是</el-radio>
+            <el-radio v-model="scope.row.isCheck" :label="0">否</el-radio>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="checkContent"
+          label="检查项"
+          width="180"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <!-- <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <span> {{ item.checkContent }} </span>
+              </el-row>
+            </div>
+            <span v-else> {{ scope.row.checkContent }} </span> -->
+            <span> {{ scope.row.checkContent }} </span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="checkDescribe" label="描述" align="center">
+          <template slot-scope="scope">
+            <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <span> {{ item.checkDescribe }} </span>
+              </el-row>
+            </div>
+            <span v-else> {{ scope.row.checkDescribe }} </span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="fieldName"
+          label="字段名称"
+          width="200"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <el-input v-model="item.fieldName"></el-input>
+              </el-row>
+            </div>
+            <el-input v-else v-model="scope.row.fieldName"></el-input>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <el-row>
+      <!-- <el-button class="uploadbtn" type="primary" @click="uploadFile">
+        上传文件
+      </el-button> -->
+      <el-upload
+        class="uploadbtn"
+        ref="upload"
+        accept=".json"
+        :action="''"
+        :auto-upload="true"
+        :show-file-list="false"
+        :limit="1"
+        :before-upload="uploadFile"
+      >
+        <el-button type="primary" class="add-item">上传文件</el-button>
+      </el-upload>
+    </el-row>
   </el-container>
 </template>
 
 <script>
+import qualityApi from "@/api/qualityinspection";
+
 export default {
   data() {
     return {
+      tableMaxHeight: 450,
+      defaultField: {
+        index: 1,
+        isCheck: 1,
+        checkContent: "数据完整性",
+        checkDescribe:
+          "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
+        fieldName: "",
+        delBtn: true,
+        type: "dataIntegrality",
+      },
+      checkDefaultDetail: [
+        {
+          index: 1,
+          isCheck: 1,
+          checkContent: "数据完整性",
+          checkDescribe:
+            "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
+          fieldName: "",
+          delBtn: true,
+          type: "dataIntegrality",
+        },
+        {
+          index: 2,
+          isCheck: 1,
+          checkContent: "省级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字的行政区划编码',
+          fieldName: "",
+          delBtn: false,
+          type: "provinceCode",
+        },
+        {
+          index: 3,
+          isCheck: 1,
+          checkContent: "市级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字且至少4位的行政区划编码',
+          fieldName: "",
+          type: "cityCode",
+          delBtn: false,
+        },
+        {
+          index: 4,
+          isCheck: 1,
+          checkContent: "县级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字且至少6位的行政区划编码',
+          fieldName: "",
+          type: "countryCode",
+          delBtn: false,
+        },
+        {
+          index: 5,
+          isCheck: 1,
+          checkContent: "经纬度验证",
+          checkDescribe: "经纬度是否在河北省境内",
+          fieldName: "",
+          type: "latlon",
+          delBtn: false,
+          children: [
+            {
+              checkDescribe: "验证所需经度字段名",
+              fieldName: "",
+              type: "lon",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需纬度字段名",
+              fieldName: "",
+              type: "lat",
+              delBtn: false,
+            },
+          ],
+        },
+        {
+          index: 6,
+          isCheck: 1,
+          checkContent: "行政区划+经纬度验证",
+          checkDescribe:
+            "检查经纬度点位是否在行政区划范围内部,例:经纬度为116.4,39.9的位置是否在石家庄范围内",
+          fieldName: "",
+          type: "areaLocation",
+          delBtn: false,
+          children: [
+            {
+              checkDescribe: "验证所需行政区划编码字段名",
+              fieldName: "",
+              type: "areaCode",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需经度字段名",
+              fieldName: "",
+              type: "lon",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需纬度字段名",
+              fieldName: "",
+              type: "lat",
+              delBtn: false,
+            },
+          ],
+        },
+      ],
+      checkDetail: [],
     };
   },
-  components: {
+  components: {},
+  mounted() {
+    let that = this;
+    this.checkDetail = JSON.parse(JSON.stringify(this.checkDefaultDetail));
+    setTimeout(() => {
+      that.resizeWindowEvent();
+    }, 100);
   },
   methods: {
-
+    // 重置表格高度
+    resizeWindowEvent() {
+      let that = this;
+      this.tableInterval = setInterval(() => {
+        if (that.$refs["ruleContent"]) {
+          that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
+          clearInterval(that.tableInterval);
+        }
+      }, 100);
+      window.onresize = () => {
+        return (() => {
+          if (that.$refs["ruleContent"])
+            that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
+        })();
+      };
+    },
+    addRules() {
+      let obj = JSON.parse(JSON.stringify(this.defaultField));
+      this.checkDetail.unshift(obj);
+      this.checkDetail = this.checkDetail.map(function (item, index) {
+        item.index = index + 1;
+        return item;
+      });
+    },
+    uploadFile(file) {
+      let that = this;
+      // let ceshiObj = {};
+      let obj = new FormData();
+      let completeArr = [];
+      for (let i = 0; i < this.checkDetail.length; i++) {
+        let param = this.checkDetail[i];
+        if (param.isCheck) {
+          if (!param.children) {
+            switch (param.type) {
+              case "dataIntegrality":
+                if (that.webMessage(param.fieldName, param.checkContent))
+                  return;
+                completeArr.push(param.fieldName);
+                break;
+              default:
+                if (that.webMessage(param.fieldName, param.checkContent))
+                  return;
+                obj.append(param.type, param.fieldName);
+                // ceshiObj[param.type] = param.fieldName;
+                break;
+            }
+          } else {
+            let arr = [];
+            for (let k = 0; k < param.children.length; k++) {
+              const item = param.children[k];
+              if (that.webMessage(item.fieldName, item.checkContent)) return;
+              arr.push(item.fieldName);
+            }
+            obj.append(param.type, arr);
+            // ceshiObj[param.type] = arr;
+          }
+        }
+      }
+      if (completeArr.length > 0) {
+        obj.append("dataIntegrality", completeArr);
+        // ceshiObj["dataIntegrality"] = completeArr;
+      }
+      obj.append("file", file);
+      qualityApi
+        .uploadInspectionFile(obj)
+        .then((result) => {
+          if (result.code == 200) {
+            that.$message({
+              type: "success",
+              message: result.content,
+            });
+          } else {
+            that.$message({
+              type: "error",
+              message: result.content,
+            });
+          }
+        })
+        .catch((err) => {
+          that.$message({
+            type: "error",
+            message: err,
+          });
+        });
+      return false;
+    },
+    webMessage(fieldName, str) {
+      if (fieldName == "") {
+        this.$message({
+          message: "请完善" + str,
+          type: "warning",
+        });
+        return true;
+      }
+      return false;
+    },
   },
 };
 </script>
 
 <style lang="less" scoped>
-
+.el-container {
+  display: block;
+  width: 100%;
+  padding: 10px 20px;
+  box-sizing: border-box;
+  background: #ffffff;
+  overflow: hidden;
+  overflow-y: auto;
+  .el-row {
+    line-height: 40px;
+    &::before {
+      display: unset;
+    }
+  }
+  .header {
+    margin-bottom: 10px;
+  }
+  .ruleContent {
+    height: calc(100% - 110px);
+  }
+  .el-table {
+    /deep/ .el-table--border .el-table__cell:first-child .cell {
+      padding-left: unset;
+    }
+    /deep/ .cell {
+      padding-left: unset;
+      padding-right: unset;
+    }
+    .el-input {
+      margin: 0 10px;
+      width: calc(100% - 20px);
+    }
+    .morerow {
+      .el-row {
+        padding-bottom: 10px;
+        border-bottom: 1px solid #eeeeee;
+        &:last-child {
+          padding-top: 10px;
+          padding-bottom: 0px;
+          border-bottom: 0px;
+        }
+      }
+    }
+  }
+  .uploadbtn {
+    float: right;
+    margin-top: 10px;
+    margin-right: 20px;
+  }
+}
 </style>

+ 8 - 1
src/components/DataQualityInspection/Process/InterfaceAccessDiagram.vue

@@ -1,6 +1,6 @@
 <template>
   <el-container>
-    <el-image :src="showImg" :preview-src-list="srcList"></el-image>
+    <el-image title="点击可查看大图" :src="showImg" :preview-src-list="srcList"></el-image>
   </el-container>
 </template>
 
@@ -31,6 +31,13 @@ export default {
   .el-image {
     margin: 0 auto;
     display: block;
+    width: 100%;
+    height: 100%;
+    /deep/ img {
+      width: unset;
+      margin: 0 auto;
+      display: block;
+    }
   }
 }
 </style>

+ 345 - 4
src/components/DataQualityInspection/Process/ShapefileQualityInspection.vue

@@ -1,23 +1,364 @@
 <template>
   <el-container>
-    <el-main> </el-main>
+    <el-row class="header">
+      <el-button type="primary" @click="addRules">添加规则</el-button>
+    </el-row>
+
+    <div class="ruleContent" ref="ruleContent">
+      <el-table
+        ref="multipleTable"
+        :data="checkDetail"
+        border
+        :max-height="tableMaxHeight"
+        style="width: 100%"
+      >
+        <el-table-column prop="index" label="序号" width="50" align="center">
+        </el-table-column>
+        <el-table-column
+          prop="name"
+          label="是否检查"
+          width="160"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <el-radio v-model="scope.row.isCheck" :label="1">是</el-radio>
+            <el-radio v-model="scope.row.isCheck" :label="0">否</el-radio>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="checkContent"
+          label="检查项"
+          width="180"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <!-- <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <span> {{ item.checkContent }} </span>
+              </el-row>
+            </div>
+            <span v-else> {{ scope.row.checkContent }} </span> -->
+            <span> {{ scope.row.checkContent }} </span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="checkDescribe" label="描述" align="center">
+          <template slot-scope="scope">
+            <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <span> {{ item.checkDescribe }} </span>
+              </el-row>
+            </div>
+            <span v-else> {{ scope.row.checkDescribe }} </span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="fieldName"
+          label="字段名称"
+          width="200"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div class="morerow" v-if="scope.row.children != undefined">
+              <el-row v-for="(item, index) in scope.row.children" :key="index">
+                <el-input v-model="item.fieldName"></el-input>
+              </el-row>
+            </div>
+            <el-input v-else v-model="scope.row.fieldName"></el-input>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <el-row>
+      <!-- <el-button class="uploadbtn" type="primary" @click="uploadFile">
+        上传文件
+      </el-button> -->
+      <el-upload
+        class="uploadbtn"
+        ref="upload"
+        accept=".zip"
+        :action="''"
+        :auto-upload="true"
+        :show-file-list="false"
+        :limit="1"
+        :before-upload="uploadFile"
+      >
+        <el-button type="primary" class="add-item">上传文件</el-button>
+      </el-upload>
+    </el-row>
   </el-container>
 </template>
 
 <script>
+import qualityApi from "@/api/qualityinspection";
+
 export default {
   data() {
     return {
+      tableMaxHeight: 450,
+      defaultField: {
+        index: 1,
+        isCheck: 1,
+        checkContent: "数据完整性",
+        checkDescribe:
+          "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
+        fieldName: "",
+        delBtn: true,
+        type: "dataIntegrality",
+      },
+      checkDefaultDetail: [
+        {
+          index: 1,
+         isCheck: 1,
+          checkContent: "数据完整性",
+          checkDescribe:
+            "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
+          fieldName: "",
+          delBtn: true,
+          type: "dataIntegrality",
+        },
+        {
+          index: 2,
+          isCheck: 1,
+          checkContent: "省级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字的行政区划编码',
+          fieldName: "",
+          delBtn: false,
+          type: "provinceCode",
+        },
+        {
+          index: 3,
+          isCheck: 1,
+          checkContent: "市级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字且至少4位的行政区划编码',
+          fieldName: "",
+          type: "cityCode",
+          delBtn: false,
+        },
+        {
+          index: 4,
+          isCheck: 1,
+          checkContent: "县级行政区划编码检查",
+          checkDescribe: '验证是否是以"13"开头的纯数字且至少6位的行政区划编码',
+          fieldName: "",
+          type: "countryCode",
+          delBtn: false,
+        },
+        {
+          index: 5,
+          isCheck: 1,
+          checkContent: "经纬度验证",
+          checkDescribe: "经纬度是否在河北省境内",
+          fieldName: "",
+          type: "latlon",
+          delBtn: false,
+          children: [
+            {
+              checkDescribe: "验证所需经度字段名",
+              fieldName: "",
+              type: "lon",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需纬度字段名",
+              fieldName: "",
+              type: "lat",
+              delBtn: false,
+            },
+          ],
+        },
+        {
+          index: 6,
+          isCheck: 1,
+          checkContent: "行政区划+经纬度验证",
+          checkDescribe:
+            "检查经纬度点位是否在行政区划范围内部,例:经纬度为116.4,39.9的位置是否在石家庄范围内",
+          fieldName: "",
+          type: "areaLocation",
+          delBtn: false,
+          children: [
+            {
+              checkDescribe: "验证所需行政区划编码字段名",
+              fieldName: "",
+              type: "areaCode",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需经度字段名",
+              fieldName: "",
+              type: "lon",
+              delBtn: false,
+            },
+            {
+              checkDescribe: "验证所需纬度字段名",
+              fieldName: "",
+              type: "lat",
+              delBtn: false,
+            },
+          ],
+        },
+      ],
+      checkDetail: [],
     };
   },
-  components: {
+  components: {},
+  mounted() {
+    let that = this;
+    this.checkDetail = JSON.parse(JSON.stringify(this.checkDefaultDetail));
+    setTimeout(() => {
+      that.resizeWindowEvent();
+    }, 100);
   },
   methods: {
-
+    // 重置表格高度
+    resizeWindowEvent() {
+      let that = this;
+      this.tableInterval = setInterval(() => {
+        if (that.$refs["ruleContent"]) {
+          that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
+          clearInterval(that.tableInterval);
+        }
+      }, 100);
+      window.onresize = () => {
+        return (() => {
+          if (that.$refs["ruleContent"])
+            that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
+        })();
+      };
+    },
+    addRules() {
+      let obj = JSON.parse(JSON.stringify(this.defaultField));
+      this.checkDetail.unshift(obj);
+      this.checkDetail = this.checkDetail.map(function (item, index) {
+        item.index = index + 1;
+        return item;
+      });
+    },
+    uploadFile(file) {
+      let that = this;
+      // let ceshiObj = {};
+      let obj = new FormData();
+      let completeArr = [];
+      for (let i = 0; i < this.checkDetail.length; i++) {
+        let param = this.checkDetail[i];
+        if (param.isCheck) {
+          if (!param.children) {
+            switch (param.type) {
+              case "dataIntegrality":
+                if (that.webMessage(param.fieldName, param.checkContent))
+                  return;
+                completeArr.push(param.fieldName);
+                break;
+              default:
+                if (that.webMessage(param.fieldName, param.checkContent))
+                  return;
+                obj.append(param.type, param.fieldName);
+                // ceshiObj[param.type] = param.fieldName;
+                break;
+            }
+          } else {
+            let arr = [];
+            for (let k = 0; k < param.children.length; k++) {
+              const item = param.children[k];
+              if (that.webMessage(item.fieldName, item.checkContent)) return;
+              arr.push(item.fieldName);
+            }
+            obj.append(param.type, arr);
+            // ceshiObj[param.type] = arr;
+          }
+        }
+      }
+      if (completeArr.length > 0) {
+        obj.append("dataIntegrality", completeArr);
+        // ceshiObj["dataIntegrality"] = completeArr;
+      }
+      obj.append("file", file);
+      qualityApi
+        .uploadInspectionFile(obj)
+        .then((result) => {
+          if (result.code == 200) {
+            that.$message({
+              type: "success",
+              message: result.content,
+            });
+          } else {
+            that.$message({
+              type: "error",
+              message: result.content,
+            });
+          }
+        })
+        .catch((err) => {
+          that.$message({
+            type: "error",
+            message: err,
+          });
+        });
+      return false;
+    },
+    webMessage(fieldName, str) {
+      if (fieldName == "") {
+        this.$message({
+          message: "请完善" + str,
+          type: "warning",
+        });
+        return true;
+      }
+      return false;
+    },
   },
 };
 </script>
 
 <style lang="less" scoped>
-
+.el-container {
+  display: block;
+  width: 100%;
+  padding: 10px 20px;
+  box-sizing: border-box;
+  background: #ffffff;
+  overflow: hidden;
+  overflow-y: auto;
+  .el-row {
+    line-height: 40px;
+    &::before {
+      display: unset;
+    }
+  }
+  .header {
+    margin-bottom: 10px;
+  }
+  .ruleContent {
+    height: calc(100% - 110px);
+  }
+  .el-table {
+    /deep/ .el-table--border .el-table__cell:first-child .cell {
+      padding-left: unset;
+    }
+    /deep/ .cell {
+      padding-left: unset;
+      padding-right: unset;
+    }
+    .el-input {
+      margin: 0 10px;
+      width: calc(100% - 20px);
+    }
+    .morerow {
+      .el-row {
+        padding-bottom: 10px;
+        border-bottom: 1px solid #eeeeee;
+        &:last-child {
+          padding-top: 10px;
+          padding-bottom: 0px;
+          border-bottom: 0px;
+        }
+      }
+    }
+  }
+  .uploadbtn {
+    float: right;
+    margin-top: 10px;
+    margin-right: 20px;
+  }
+}
 </style>

+ 22 - 1
src/components/DataQualityInspection/Rules/ImportExcelQualityInspectionRules.vue

@@ -4,6 +4,10 @@
     <el-row class="main_body" v-for="(str, index) in textArr" :key="index">
       {{ index + 1 }}. {{ str }}
     </el-row>
+    <el-row class="first_level_title">示例数据下载</el-row>
+    <el-row>
+      <el-button @click="download">示例数据下载</el-button>
+    </el-row>
     <!-- <el-row class="first_level_title">示例截图</el-row> -->
     <el-image :src="showImg" :preview-src-list="srcList"></el-image>
   </el-container>
@@ -23,10 +27,27 @@ export default {
         "描述字段不能为空,且导入附件中包含该字段,字段内容不为空。",
         "内容描述字段可以为空,导入附件中包含内容描述对应字段,字段内容不为空。",
       ],
+      downloadExampleFileType: "Excel",
+      downloadExampleFileUrl: "./static/package/quality/excel.xlsx",
     };
   },
   components: {},
-  methods: {},
+  methods: {
+    download() {
+      const elink = document.createElement("a");
+      elink.href = this.textObj.downloadExampleFileUrl;
+      elink.setAttribute(
+        "download",
+        this.textObj.downloadExampleFileType + "示例文件.xlsx"
+      );
+      elink.style.display = "none";
+      document.body.appendChild(elink);
+      setTimeout(() => {
+        elink.click();
+        document.body.removeChild(elink);
+      }, 66);
+    },
+  },
 };
 </script>
 

+ 33 - 10
src/components/DataQualityInspection/Rules/ImportGeojsonQualityInspectionRules.vue

@@ -1,21 +1,24 @@
 <template>
   <el-container>
-    <el-row class="first_level_title">文件构成</el-row>
+    <el-row class="first_level_title">字段限制</el-row>
     <el-row
       class="main_body"
       v-for="(str, index) in textObj.textArr"
       :key="index"
     >
-      {{ str }}
+      {{ index + 1 }}. {{ str }}
     </el-row>
-    <el-row class="must_tips">{{ textObj.attention }}</el-row>
-    <el-row class="first_level_title">示例数据</el-row>
-    <json-viewer
+    <!-- <el-row class="must_tips">{{ textObj.attention }}</el-row> -->
+    <el-row class="first_level_title">示例数据下载</el-row>
+    <el-row>
+      <el-button @click="download">示例数据下载</el-button>
+    </el-row>
+    <!-- <json-viewer
       :value="textObj.exampleData"
       :expand-depth="5"
       :copyable="{ copyText: '复制', copiedText: '复制成功', timeout: 1000 }"
       theme="my-awesome-json-theme"
-    ></json-viewer>
+    ></json-viewer> -->
     <el-image :src="showImg" :preview-src-list="srcList"></el-image>
   </el-container>
 </template>
@@ -29,12 +32,17 @@ export default {
       srcList: [showImg],
       textObj: {
         textArr: [
-          "json文件中内容有两部分组成,分别为model与content,其中:",
-          "model为图层描述,用来定位excel中数据应当在哪个图层进行数据新增或更新使用;",
-          "content为excel的字段描述,用来指向哪些数据作为什么类型、什么功能进行描述。",
+          // "json文件中内容有两部分组成,分别为model与content,其中:",
+          // "model为图层描述,用来定位excel中数据应当在哪个图层进行数据新增或更新使用;",
+          // "content为excel的字段描述,用来指向哪些数据作为什么类型、什么功能进行描述。",
+          "名称标题字段不能为空,且导入附件中包含该字段,字段内容不为空。",
+          "描述字段不能为空,且导入附件中包含该字段,字段内容不为空。",
+          "内容描述字段可以为空,导入附件中包含内容描述对应字段,字段内容不为空。",
         ],
         attention:
           "注:model中如果填写id字段,其他字段可以不填写,如无id字段,则其他字段必须都填写。id字段与其他字段作为互斥关系,必须有一组要填写!!!",
+        downloadExampleFileType: "GeoJSON",
+        downloadExampleFileUrl: "./static/package/quality/geojson.json",
         exampleData: {
           model: {
             threeId: "CXJSGL",
@@ -89,7 +97,22 @@ export default {
     };
   },
   components: {},
-  methods: {},
+  methods: {
+    download() {
+      const elink = document.createElement("a");
+      elink.href = this.textObj.downloadExampleFileUrl;
+      elink.setAttribute(
+        "download",
+        this.textObj.downloadExampleFileType + "示例文件.json"
+      );
+      elink.style.display = "none";
+      document.body.appendChild(elink);
+      setTimeout(() => {
+        elink.click();
+        document.body.removeChild(elink);
+      }, 66);
+    },
+  },
 };
 </script>
 

+ 33 - 10
src/components/DataQualityInspection/Rules/ImportShapefileQualityInspectionRules.vue

@@ -1,21 +1,24 @@
 <template>
   <el-container>
-    <el-row class="first_level_title">文件构成</el-row>
+    <el-row class="first_level_title">字段限制</el-row>
     <el-row
       class="main_body"
       v-for="(str, index) in textObj.textArr"
       :key="index"
     >
-      {{ str }}
+      {{ index + 1 }}. {{ str }}
     </el-row>
-    <el-row class="must_tips">{{ textObj.attention }}</el-row>
-    <el-row class="first_level_title">示例数据</el-row>
-    <json-viewer
+    <!-- <el-row class="must_tips">{{ textObj.attention }}</el-row> -->
+    <el-row class="first_level_title">示例数据下载</el-row>
+    <el-row>
+      <el-button @click="download">示例数据下载</el-button>
+    </el-row>
+    <!-- <json-viewer
       :value="textObj.exampleData"
       :expand-depth="5"
       :copyable="{ copyText: '复制', copiedText: '复制成功', timeout: 1000 }"
       theme="my-awesome-json-theme"
-    ></json-viewer>
+    ></json-viewer> -->
     <el-image :src="showImg" :preview-src-list="srcList"></el-image>
   </el-container>
 </template>
@@ -29,12 +32,17 @@ export default {
       srcList: [showImg],
       textObj: {
         textArr: [
-          "Shapefile文件中内容有两部分组成,分别为model与content,其中:",
-          "model为图层描述,用来定位excel中数据应当在哪个图层进行数据新增或更新使用;",
-          "content为excel的字段描述,用来指向哪些数据作为什么类型、什么功能进行描述。",
+          // "Shapefile文件中内容有两部分组成,分别为model与content,其中:",
+          // "model为图层描述,用来定位excel中数据应当在哪个图层进行数据新增或更新使用;",
+          // "content为excel的字段描述,用来指向哪些数据作为什么类型、什么功能进行描述。",
+          "名称标题字段不能为空,且导入附件中包含该字段,字段内容不为空。",
+          "描述字段不能为空,且导入附件中包含该字段,字段内容不为空。",
+          "内容描述字段可以为空,导入附件中包含内容描述对应字段,字段内容不为空。",
         ],
         attention:
           "注:model中如果填写id字段,其他字段可以不填写,如无id字段,则其他字段必须都填写。id字段与其他字段作为互斥关系,必须有一组要填写!!!",
+        downloadExampleFileType: "Shapefile",
+        downloadExampleFileUrl: "./static/package/quality/shapefile.zip",
         exampleData: {
           model: {
             threeId: "CXJSGL",
@@ -89,7 +97,22 @@ export default {
     };
   },
   components: {},
-  methods: {},
+  methods: {
+    download() {
+      const elink = document.createElement("a");
+      elink.href = this.textObj.downloadExampleFileUrl;
+      elink.setAttribute(
+        "download",
+        this.textObj.downloadExampleFileType + "示例文件.zip"
+      );
+      elink.style.display = "none";
+      document.body.appendChild(elink);
+      setTimeout(() => {
+        elink.click();
+        document.body.removeChild(elink);
+      }, 66);
+    },
+  },
 };
 </script>
 

+ 410 - 3
src/components/DataServices/DataService.vue

@@ -1,13 +1,420 @@
 <template>
-  
+  <el-container>
+    <div v-for="(item, index) in content" :key="index">
+      <el-row class="first_level_title">{{ item.title }}</el-row>
+      <div>
+        <el-row v-for="(item_, index_) in item.children" :key="index_">
+          <el-col class="interface_name">
+            {{ item_.name }}
+            <el-button type="text" @click="lookDetail(item_)">详情</el-button>
+          </el-col>
+        </el-row>
+      </div>
+    </div>
+    <el-row class="first_level_title">附录</el-row>
+    <el-row>
+      <el-col class="interface_name">
+        响应状态码
+        <el-button type="text" @click="lookResponseDetail">详情</el-button>
+      </el-col>
+    </el-row>
+
+    <el-dialog
+      :class="'responseCodeDialog'"
+      :visible.sync="isResponseCodeShow"
+      width="500px"
+      top="7%"
+      :close-on-click-modal="false"
+      :before-close="dialogBeforeClose"
+    >
+      <span slot="title" class="dialog-title">
+        <div class="title">
+          <span>
+            {{ "响应状态码详情" }}
+          </span>
+        </div>
+      </span>
+      <div class="responseCodeContent">
+        <el-row v-for="(item, index) in responseCode" :key="index">
+          <el-col :span="3">{{ item.name }}:</el-col>
+          <el-col :span="21">{{ item.value }}</el-col>
+        </el-row>
+      </div>
+    </el-dialog>
+
+    <el-dialog
+      :class="'interfaceDetailDialog'"
+      :visible.sync="isInterfaceDetailShow"
+      width="800px"
+      top="7%"
+      :close-on-click-modal="false"
+      :before-close="dialogBeforeClose"
+    >
+      <span slot="title" class="dialog-title">
+        <div class="title">
+          <span v-if="interfaceDetailItem != null">
+            {{ interfaceDetailItemName }}
+          </span>
+        </div>
+      </span>
+      <div class="interfaceDetail" v-if="interfaceDetailItem != null">
+        <el-row>
+          <el-col :span="3">接口地址:</el-col>
+          <el-col :span="21">{{ interfaceDetailItem.url }}</el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="3">接口描述:</el-col>
+          <el-col :span="21">{{ interfaceDetailItem.describe }}</el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="3">请求方式:</el-col>
+          <el-col :span="21">{{ interfaceDetailItem.requestMehod }}</el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="3">请求头参数:</el-col>
+          <el-col :span="21">
+            <span v-if="interfaceDetailItem.requestHeader.length == 0">无</span>
+            <el-table
+              :data="interfaceDetailItem.requestHeader"
+              border
+              style="width: 100%"
+              v-else
+            >
+              <el-table-column prop="name" label="字段名称"> </el-table-column>
+              <el-table-column prop="explain" label="说明"> </el-table-column>
+              <el-table-column prop="type" label="字段类型"> </el-table-column>
+              <el-table-column prop="must" label="是否必传"> </el-table-column>
+            </el-table>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="3">输入参数:</el-col>
+          <el-col :span="21">
+            <span v-if="interfaceDetailItem.inputParam.length == 0">无</span>
+            <el-table
+              :data="interfaceDetailItem.inputParam"
+              border
+              style="width: 100%"
+              v-else
+            >
+              <el-table-column prop="name" label="字段名称"> </el-table-column>
+              <el-table-column prop="explain" label="说明"> </el-table-column>
+              <el-table-column prop="type" label="字段类型"> </el-table-column>
+              <el-table-column prop="must" label="是否必传"> </el-table-column>
+            </el-table>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="3">输入示例:</el-col>
+          <el-col :span="21">
+            <span
+              v-if="
+                Object.getOwnPropertyNames(
+                  JSON.parse(
+                    JSON.stringify(this.interfaceDetailItem.inputParamExample)
+                  )
+                )
+              "
+              >无</span
+            >
+            <json-viewer
+              :value="interfaceDetailItem.inputParamExample"
+              :expand-depth="10"
+              theme="my-awesome-json-theme"
+              v-else
+            >
+            </json-viewer>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="3">输出参数:</el-col>
+          <el-col :span="21">
+            <el-row>
+              <el-table
+                :data="interfaceDetailItem.outputParam.response"
+                border
+                style="width: 100%"
+              >
+                <el-table-column prop="name" label="字段名称">
+                </el-table-column>
+                <el-table-column prop="explain" label="说明"> </el-table-column>
+                <el-table-column prop="type" label="字段类型">
+                </el-table-column>
+              </el-table>
+            </el-row>
+            <el-row>其中,content响应数据返回字段详情如下:</el-row>
+            <el-row>
+              <el-table
+                :data="interfaceDetailItem.outputParam.content"
+                border
+                style="width: 100%"
+              >
+                <el-table-column prop="name" label="字段名称">
+                </el-table-column>
+                <el-table-column prop="explain" label="说明"> </el-table-column>
+                <el-table-column prop="type" label="字段类型">
+                </el-table-column>
+              </el-table>
+            </el-row>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="3">输出示例:</el-col>
+          <el-col :span="21">
+            <json-viewer
+              :value="interfaceDetailItem.outputParamExample"
+              :expand-depth="10"
+              theme="my-awesome-json-theme"
+            >
+            </json-viewer>
+          </el-col>
+        </el-row>
+      </div>
+    </el-dialog>
+  </el-container>
 </template>
 
 <script>
 export default {
-
-}
+  data() {
+    return {
+      responseCode: [],
+      isResponseCodeShow: false,
+      isInterfaceDetailShow: false,
+      interfaceDetailItem: null,
+      content: [
+        {
+          title: "通用接口",
+          children: [
+            {
+              name: "获取图层列表",
+              detail: {
+                url: "/metadata/general/getMenuData",
+                describe: "获取所有一级、二级图层数据",
+                requestMehod: "POST",
+                requestHeader: [],
+                inputParam: [],
+                inputParamExample: {},
+                outputParam: [],
+                outputParamExample: {},
+              },
+            },
+          ],
+        },
+        {
+          title: "图层数据接口",
+          children: [
+            {
+              name: "根据图层ID查询图层数据",
+              detail: {
+                url: "/metadata/model/selectById",
+                describe: "根据图层ID查询图层详细数据",
+                requestMehod: "POST",
+                requestHeader: [
+                  {
+                    name: "token",
+                    explain: "用户验证所需token",
+                    type: "string",
+                    must: "是",
+                  },
+                ],
+                inputParam: [
+                  {
+                    name: "id",
+                    explain: "图层ID",
+                    type: "string",
+                    must: "是",
+                  },
+                ],
+                inputParamExample: {
+                  id: 1,
+                },
+                outputParam: {
+                  response: [
+                    {
+                      name: "code",
+                      explain: "响应状态码",
+                      type: "number",
+                    },
+                    {
+                      name: "content",
+                      explain: "响应内容",
+                      type: "number",
+                    },
+                    {
+                      name: "message",
+                      explain: "响应状态描述",
+                      type: "number",
+                    },
+                    {
+                      name: "total",
+                      explain: "响应返回数据条数",
+                      type: "number",
+                    },
+                  ],
+                  content: [
+                    {
+                      name: "total",
+                      explain: "请求",
+                      type: "number",
+                    },
+                  ],
+                },
+                outputParamExample: {
+                  id: 2,
+                  name: "ddd",
+                },
+              },
+            },
+            {
+              name: "根据表名查询图层",
+            },
+            {
+              name: "根据标题查询图层",
+            },
+            {
+              name: "根据类型查询图层",
+            },
+          ],
+        },
+        {
+          title: "内容数据接口",
+          children: [
+            {
+              name: "根据id查询内容数据",
+            },
+            {
+              name: "根据modelID查询内容数据",
+            },
+            {
+              name: "上传geojson到指定图层下的内容数据",
+            },
+            {
+              name: "上传excel文件到指定图层下的内容数据",
+            },
+            {
+              name: "上传shape文件zip格式压缩包到指定图层下的内容数据",
+            },
+          ],
+        },
+      ],
+    };
+  },
+  mounted() {
+    let key = Object.keys(systemConfig.requestCode);
+    this.responseCode = key.map(function (str) {
+      return {
+        name: str,
+        value: systemConfig.requestCode[str],
+      };
+    });
+  },
+  methods: {
+    lookResponseDetail() {
+      this.isResponseCodeShow = true;
+    },
+    lookDetail(item) {
+      console.log(item);
+      this.interfaceDetailItemName = item.name;
+      this.interfaceDetailItem = item.detail;
+      this.isInterfaceDetailShow = true;
+    },
+    dialogBeforeClose() {
+      this.isResponseCodeShow = false;
+      this.isInterfaceDetailShow = false;
+      this.interfaceDetailItem = null;
+    },
+  },
+};
 </script>
 
 <style lang="less" scoped>
+.el-container {
+  display: block;
+  width: 100%;
+  padding: 10px 20px;
+  box-sizing: border-box;
+  background: #ffffff;
+  overflow: hidden;
+  overflow-y: auto;
+  .el-row {
+    line-height: 40px;
+    &::before {
+      display: unset;
+    }
+  }
+
+  .first_level_title {
+    font-size: 18px;
+    font-weight: bold;
+  }
+  .interface_name {
+    cursor: pointer;
+    font-size: 16px;
+  }
+
+  .responseCodeDialog {
+    /deep/ .el-dialog__header {
+      border-bottom: 1px solid #e8e8e8;
+      padding: 15px;
+    }
+    .el-row {
+      margin-bottom: 10px;
+    }
+    .title {
+      height: 30px;
+      line-height: 30px;
+      font-size: 20px;
+      font-weight: bold;
+    }
 
+    /deep/ .el-dialog__body {
+      padding-top: 20px;
+      padding-bottom: 20px;
+    }
+
+    .responseCodeContent {
+      height: 500px;
+      overflow: hidden;
+      overflow-y: auto;
+      padding-right: 15px;
+    }
+  }
+
+  .interfaceDetailDialog {
+    /deep/ .el-dialog__header {
+      border-bottom: 1px solid #e8e8e8;
+      padding: 15px;
+    }
+    .el-row {
+      margin-bottom: 10px;
+    }
+    .title {
+      height: 30px;
+      line-height: 30px;
+      font-size: 20px;
+      font-weight: bold;
+    }
+
+    /deep/ .el-dialog__body {
+      padding-top: 20px;
+      padding-bottom: 20px;
+    }
+
+    .interfaceDetail {
+      height: 500px;
+      overflow: hidden;
+      overflow-y: auto;
+      padding-right: 15px;
+    }
+    .jv-container {
+      /deep/ .jv-code {
+        padding: 0 0;
+      }
+    }
+    .el-table {
+      line-height: 23px;
+    }
+  }
+}
 </style>

+ 235 - 3
src/components/DataServices/TileService.vue

@@ -1,13 +1,245 @@
 <template>
-  
+  <el-container>
+    <div v-for="(item, index) in content" :key="index">
+      <el-row class="first_level_title">{{ item.title }}</el-row>
+      <div>
+        <el-row v-for="(item_, index_) in item.children" :key="index_">
+          <el-col class="label" :span="2"> {{ item_.label }}: </el-col>
+          <el-col class="text" :span="22">
+            {{ item_.text }}
+          </el-col>
+        </el-row>
+      </div>
+      <el-row class="image">
+        <img :src="imagePath + item.image" alt="" />
+      </el-row>
+    </div>
+  </el-container>
 </template>
 
 <script>
 export default {
-
-}
+  data() {
+    return {
+      imagePath: "./static/images/tileservice/",
+      content: [
+        {
+          title: "影像底图服务",
+          children: [
+            {
+              label: "服务类型",
+              text: "瓦片服务",
+            },
+            {
+              label: "瓦片类型",
+              text: "栅格",
+            },
+            {
+              label: "瓦片描述",
+              text: "影像底图瓦片",
+            },
+            {
+              label: "瓦片规范",
+              text: "OGC WMTS标准",
+            },
+            {
+              label: "URL地址",
+              text: "http://122.228.13.28:1100/sky0/img_w/wmts?tk=密钥",
+            },
+            {
+              label: "示例",
+              text: "http://122.228.13.28:1100/sky0/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=密钥",
+            },
+          ],
+          image: "raster.png",
+        },
+        {
+          title: "影像注记服务",
+          children: [
+            {
+              label: "服务类型",
+              text: "瓦片服务",
+            },
+            {
+              label: "瓦片类型",
+              text: "栅格",
+            },
+            {
+              label: "瓦片描述",
+              text: "影像注记瓦片",
+            },
+            {
+              label: "瓦片规范",
+              text: "OGC WMTS标准",
+            },
+            {
+              label: "URL地址",
+              text: "http://122.228.13.28:1100/sky0/cia_w/wmts?tk=密钥",
+            },
+            {
+              label: "示例",
+              text: "http://122.228.13.28:1100/sky0/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=密钥",
+            },
+          ],
+          image: "raster_zj.png",
+        },
+        {
+          title: "矢量底图服务",
+          children: [
+            {
+              label: "服务类型",
+              text: "瓦片服务",
+            },
+            {
+              label: "瓦片类型",
+              text: "栅格",
+            },
+            {
+              label: "瓦片描述",
+              text: "矢量底图瓦片",
+            },
+            {
+              label: "瓦片规范",
+              text: "OGC WMTS标准",
+            },
+            {
+              label: "URL地址",
+              text: "http://122.228.13.28:1100/sky0/vec_w/wmts?tk=密钥",
+            },
+            {
+              label: "示例",
+              text: "http://122.228.13.28:1100/sky0/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=密钥",
+            },
+          ],
+          image: "vecter.png",
+        },
+        {
+          title: "矢量注记服务",
+          children: [
+            {
+              label: "服务类型",
+              text: "瓦片服务",
+            },
+            {
+              label: "瓦片类型",
+              text: "栅格",
+            },
+            {
+              label: "瓦片描述",
+              text: "矢量注记瓦片",
+            },
+            {
+              label: "瓦片规范",
+              text: "OGC WMTS标准",
+            },
+            {
+              label: "URL地址",
+              text: "http://122.228.13.28:1100/sky0/cva_w/wmts?tk=密钥",
+            },
+            {
+              label: "示例",
+              text: "http://122.228.13.28:1100/sky0/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=密钥",
+            },
+          ],
+          image: "vecter_zj.png",
+        },
+        {
+          title: "地形晕渲服务",
+          children: [
+            {
+              label: "服务类型",
+              text: "瓦片服务",
+            },
+            {
+              label: "瓦片类型",
+              text: "栅格",
+            },
+            {
+              label: "瓦片描述",
+              text: "地形晕渲底图瓦片",
+            },
+            {
+              label: "瓦片规范",
+              text: "OGC WMTS标准",
+            },
+            {
+              label: "URL地址",
+              text: "http://122.228.13.28:1100/sky0/ter_w/wmts?tk=密钥",
+            },
+            {
+              label: "示例",
+              text: "http://122.228.13.28:1100/sky0/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=密钥",
+            },
+          ],
+          image: "topography.png",
+        },
+        {
+          title: "地形注记服务",
+          children: [
+            {
+              label: "服务类型",
+              text: "瓦片服务",
+            },
+            {
+              label: "瓦片类型",
+              text: "栅格",
+            },
+            {
+              label: "瓦片描述",
+              text: "地形注记瓦片",
+            },
+            {
+              label: "瓦片规范",
+              text: "OGC WMTS标准",
+            },
+            {
+              label: "URL地址",
+              text: "http://122.228.13.28:1100/sky0/cta_w/wmts?tk=密钥",
+            },
+            {
+              label: "示例",
+              text: "http://122.228.13.28:1100/sky0/cta_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cta&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=密钥",
+            },
+          ],
+          image: "topography_zj.png",
+        },
+      ],
+    };
+  },
+};
 </script>
 
 <style lang="less" scoped>
+.el-container {
+  display: block;
+  width: 100%;
+  padding: 10px 20px;
+  box-sizing: border-box;
+  background: #ffffff;
+  overflow: hidden;
+  overflow-y: auto;
+  .el-row {
+    // margin-bottom: 10px;
+    line-height: 40px;
+    &:last-child {
+      // margin-bottom: 10px;
+    }
+    &::before {
+      display: unset;
+    }
+  }
 
+  .first_level_title {
+    font-size: 18px;
+    font-weight: bold;
+  }
+  .label {
+    font-size: 16px;
+    // font-weight: bold;
+  }
+  .text {
+    font-size: 16px;
+    // font-weight: bold;
+  }
+}
 </style>

+ 140 - 34
src/views/ComprehensiveDisplay.vue

@@ -1,23 +1,39 @@
 <template>
   <!-- 综合展示 -->
-  <div class="ComprehensiveDisplayMain">
+  <div class="ComprehensiveDisplayMain" v-if="content != null">
     <!-- 第一层:新闻中心、平台介绍 -->
     <div class="ComprehensiveDisplayMain_IntroductionOfNewsCenterAndPlatform">
       <!-- 新闻中心 -->
       <el-card class="Newscenter">
         <!-- 新闻中心标题 -->
         <div slot="header" class="clearfix userSelect_None">
-          <span class="clearfix_title"><i class="elIcon el-icon-message-solid"></i>新闻中心</span>
+          <span class="clearfix_title"
+            ><i class="elIcon el-icon-message-solid"></i>新闻中心</span
+          >
           <span class="clearfix_titleEn" type="text">News Center</span>
         </div>
         <!-- 新闻中心主题 -->
         <div class="Newscenter_main">
           <!-- 图片轮播区域 -->
           <el-carousel class="Newscenter_main_byArea" height="200px">
-            <el-carousel-item v-for="(item, index) in data.NewscenterAreas" :key="index">
-              <el-image style="cursor: pointer" :src="item.imageUrl" @click="Jump(item.jumpUrl)" :alt="item.alt"> </el-image>
+            <el-carousel-item
+              v-for="(item, index) in content.NewscenterAreas"
+              :key="index"
+            >
+              <el-image
+                style="cursor: pointer"
+                :src="item.imageUrl"
+                @click="Jump(item.jumpUrl)"
+                :alt="item.alt"
+              >
+              </el-image>
               <div class="Newscenter_main_byArea_alt userSelect_None">
-                <el-tooltip class="item" effect="dark" :content="item.alt" :open-delay="1000">
+                <el-tooltip
+                  class="item"
+                  effect="dark"
+                  :content="item.alt"
+                  :open-delay="1000"
+                >
                   <span>{{ item.alt }}</span>
                 </el-tooltip>
               </div>
@@ -26,38 +42,91 @@
           <!-- 新闻中心内容 -->
           <div class="Newscenter_main_content">
             <!-- 标题 -->
-            <el-tooltip class="item" effect="dark" :content="data.NewscenterData.NewscenterTitle" :open-delay="1000">
-              <div class="title" @click="Jump(data.NewscenterData.NewscenterUrl)">{{ data.NewscenterData.NewscenterTitle }}</div>
+            <el-tooltip
+              class="item"
+              effect="dark"
+              :content="content.NewscenterData.NewscenterTitle"
+              :open-delay="1000"
+            >
+              <div
+                class="title"
+                @click="Jump(content.NewscenterData.NewscenterUrl)"
+              >
+                {{ content.NewscenterData.NewscenterTitle }}
+              </div>
             </el-tooltip>
             <!-- 内容 -->
-            <el-tooltip class="item" effect="dark" :content="data.NewscenterData.NewscenterContent" :open-delay="1000">
+            <el-tooltip
+              class="item"
+              effect="dark"
+              :content="content.NewscenterData.NewscenterContent"
+              :open-delay="1000"
+            >
               <div class="content userSelect_None">
-                {{ data.NewscenterData.NewscenterContent }}
+                {{ content.NewscenterData.NewscenterContent }}
               </div>
             </el-tooltip>
             <!-- 小标题 -->
-            <div v-if="data.NewscenterData.NewscenterTitles.length > 0">
+            <div v-if="content.NewscenterData.NewscenterTitles.length > 0">
               <el-carousel height="70px" direction="vertical">
-                <el-carousel-item v-for="index in Math.ceil(data.NewscenterData.NewscenterTitles.length / 2)" :key="index">
+                <el-carousel-item
+                  v-for="index in Math.ceil(
+                    content.NewscenterData.NewscenterTitles.length / 2
+                  )"
+                  :key="index"
+                >
                   <el-tooltip
                     class="item"
                     effect="dark"
-                    :content="data.NewscenterData.NewscenterTitles[2 * index - 2].title"
+                    :content="
+                      content.NewscenterData.NewscenterTitles[2 * index - 2]
+                        .title
+                    "
                     :open-delay="1000"
                   >
-                    <div class="titles" @click="Jump(data.NewscenterData.NewscenterTitles[2 * index - 2].url)">
-                      {{ data.NewscenterData.NewscenterTitles[2 * index - 2].title }}
+                    <div
+                      class="titles"
+                      @click="
+                        Jump(
+                          content.NewscenterData.NewscenterTitles[2 * index - 2]
+                            .url
+                        )
+                      "
+                    >
+                      {{
+                        content.NewscenterData.NewscenterTitles[2 * index - 2]
+                          .title
+                      }}
                     </div>
                   </el-tooltip>
-                  <div v-if="data.NewscenterData.NewscenterTitles[2 * index - 1]">
+                  <div
+                    v-if="
+                      content.NewscenterData.NewscenterTitles[2 * index - 1]
+                    "
+                  >
                     <el-tooltip
                       class="item"
                       effect="dark"
-                      :content="data.NewscenterData.NewscenterTitles[2 * index - 1].title"
+                      :content="
+                        content.NewscenterData.NewscenterTitles[2 * index - 1]
+                          .title
+                      "
                       :open-delay="1000"
                     >
-                      <div class="titles" @click="Jump(data.NewscenterData.NewscenterTitles[2 * index - 1].url)">
-                        {{ data.NewscenterData.NewscenterTitles[2 * index - 1].title }}
+                      <div
+                        class="titles"
+                        @click="
+                          Jump(
+                            content.NewscenterData.NewscenterTitles[
+                              2 * index - 1
+                            ].url
+                          )
+                        "
+                      >
+                        {{
+                          content.NewscenterData.NewscenterTitles[2 * index - 1]
+                            .title
+                        }}
                       </div>
                     </el-tooltip>
                   </div>
@@ -72,30 +141,49 @@
       <el-card class="PlatformIsIntroduced">
         <!-- 平台介绍标题 -->
         <div slot="header" class="clearfix userSelect_None">
-          <span class="clearfix_title"><i class="elIcon el-icon-s-flag"></i>平台介绍</span>
-          <span class="clearfix_titleEn" type="text">Platform Introduction</span>
+          <span class="clearfix_title"
+            ><i class="elIcon el-icon-s-flag"></i>平台介绍</span
+          >
+          <span class="clearfix_titleEn" type="text"
+            >Platform Introduction</span
+          >
         </div>
         <!-- 平台介绍主题 -->
-        <div class="PlatformIsIntroduced_main" v-html="data.PlatformIsIntroducedContent"></div>
+        <div
+          class="PlatformIsIntroduced_main"
+          v-html="content.PlatformIsIntroducedContent"
+        ></div>
       </el-card>
     </div>
     <!-- 第二层:中国地理信息平台 -->
     <el-card class="ComprehensiveDisplayMain_ChinaGeographicInformationCenter">
       <!-- 平台介绍内容 -->
-      <span class="ChinaGeographicInformationCenterTitle userSelect_None" @click="undefinedFunction()">中国地理信息平台</span>
+      <span
+        class="ChinaGeographicInformationCenterTitle userSelect_None"
+        @click="undefinedFunction()"
+        >中国地理信息平台</span
+      >
     </el-card>
     <!-- 第三层:服务中心 -->
     <el-card class="ComprehensiveDisplayMain_ServiceCenter">
       <!-- 服务中心标题 -->
       <div slot="header" class="clearfix userSelect_None">
-        <span class="clearfix_title"><i class="elIcon el-icon-s-cooperation"></i>服务中心</span>
+        <span class="clearfix_title"
+          ><i class="elIcon el-icon-s-cooperation"></i>服务中心</span
+        >
         <span class="clearfix_titleEn" type="text">Service Center</span>
       </div>
       <!-- 服务中心主题 -->
       <div class="ServiceCenter_main userSelect_None">
-        <div @click="undefinedFunction()"><i class="el-icon-s-operation" style="margin-right: 47px"></i>数据管理</div>
-        <div @click="undefinedFunction()"><i class="el-icon-s-promotion" style="margin-right: 47px"></i>专题发布</div>
-        <div @click="undefinedFunction()"><i class="el-icon-data-line" style="margin-right: 47px"></i>数据可视化</div>
+        <div @click="undefinedFunction(1)">
+          <i class="el-icon-s-operation" style="margin-right: 47px"></i>数据管理
+        </div>
+        <div @click="undefinedFunction(2)">
+          <i class="el-icon-s-promotion" style="margin-right: 47px"></i>专题发布
+        </div>
+        <div @click="undefinedFunction(3)">
+          <i class="el-icon-data-line" style="margin-right: 47px"></i>数据可视化
+        </div>
       </div>
     </el-card>
   </div>
@@ -108,25 +196,43 @@ export default {
   data() {
     //   后续可调用后端接口动态显示
     return {
-      data: {}
+      content: null,
     };
   },
   computed: {},
   created() {
     let that = this;
-    $.getJSON("./static/config/ComprehensiveDisplayData.json", function (result) {
-      that.data = result;
-    });
+    $.getJSON(
+      "./static/config/ComprehensiveDisplayData.json",
+      function (result) {
+        that.content = result;
+      }
+    );
   },
   mounted() {},
   methods: {
     Jump(jumpUrl) {
       window.open(jumpUrl);
     },
-    undefinedFunction() {
-      this.$message.info("敬请期待!");
-    }
-  }
+    undefinedFunction(key) {
+      switch (key) {
+        case 1:
+          jumpModule("2", 22); // 跳转图层管理(数据管理)
+          break;
+
+        case 2:
+          jumpModule("6", 61); // 跳转数据发布(专题发布)
+          break;
+
+        case 3:
+          jumpModule("5", 52); // 跳转GIS图层管理(数据可视化)
+          break;
+
+        default:
+          break;
+      }
+    },
+  },
 };
 </script>
 

+ 3 - 3
src/views/DataQualityInspection.vue

@@ -31,13 +31,13 @@
         ></InterfaceAccessDiagram>
         <AccessoryDiagram v-show="showIndex == '2-1-2'"></AccessoryDiagram>
         <ExcelQualityInspection
-          v-show="showIndex == '2-2-1'"
+          v-if="showIndex == '2-2-1'"
         ></ExcelQualityInspection>
         <ShapefileQualityInspection
-          v-show="showIndex == '2-2-2'"
+          v-if="showIndex == '2-2-2'"
         ></ShapefileQualityInspection>
         <GeojsonQualityInspection
-          v-show="showIndex == '2-2-3'"
+          v-if="showIndex == '2-2-3'"
         ></GeojsonQualityInspection>
       </el-main>
     </el-container>