浏览代码

Merge remote-tracking branch 'origin/dev' into dev

shaun-sheep 4 年之前
父节点
当前提交
01859930c8

+ 2 - 2
package.json

@@ -20,9 +20,9 @@
   },
   "dependencies": {
     "@saga-web/base": "2.1.27",
-    "@saga-web/cad-engine": "2.0.577",
+    "@saga-web/cad-engine": "2.0.578",
     "@saga-web/draw": "2.1.110",
-    "@saga-web/graph": "2.1.132",
+    "@saga-web/graph": "2.1.133",
     "axios": "^0.18.0",
     "echarts": "^4.1.0",
     "el-cascader-multi": "^1.1.8",

+ 5 - 0
src/api/model/file.js

@@ -345,3 +345,8 @@ export function unassignQuery(param, success) {
     let url = `${revitUrl}/task/query`;
     httputils.postJson(url, param, success)
 }
+
+// 根据条件查询统计数量
+export function countModel(params, success) {
+    return httputils.postJson(`${baseUrl}/model-file/count`, params, success)
+}

+ 1 - 1
src/api/scan/config.js

@@ -18,7 +18,7 @@ export const message = baseUrl + '/message-center'
 
 export const shaft = object + '/shaft'
 export const tenant = dataCenter + '/tenant'
-export const floor = dataCenter + '/floor'
+export const floor = object + '/floor'
 export const dict = dataCenter + '/dict'
 export const classDef = dataCenter + '/class-def'
 export const locationPoint = dataCenter + '/location-point'

+ 3 - 14
src/api/scan/request.js

@@ -1655,11 +1655,6 @@ export function floorQuery(param, success) {
 }
 
 //查询楼层信息+sign
-// export function floorQueryAndSign(param, success) {
-//   let url = `${baseUrl}${component}/floor/query`;
-//   http.postJson(url, param, success)
-// }
-//查询楼层信息+sign
 export function floorQueryAndSign(param, success) {
   let url = `${baseUrl}${component}/floor/query`;
   http.postJson(url, param, success)
@@ -1790,12 +1785,8 @@ export function manageCreateFloor(param, success) {
 }
 
 //建筑楼层管理-删除楼层
-// export function manageDeleteFloor(param, success) {
-//   let url = `${baseUrl}${floor}/delete`;
-//   http.postJson(url, param, success)
-// }
 export function manageDeleteFloor(param, success) {
-  let url = `${baseUrl}${object}/floor/delete`;
+  let url = `${baseUrl}${floor}/delete`;
   http.postJson(url, param, success)
 }
 
@@ -1829,15 +1820,13 @@ export function floorUpdate(param, success) {
 
 //楼层接口-----更新楼层轮廓
 export function floorUpdateOutline(param, success) {
-  // let url = `${baseUrl}${object}/floor/update-outline`;
-  let url = `${baseUrl}${object}/floor/outline/update`;
+  let url = `${baseUrl}${floor}/outline/update`;
   http.postJson(url, param, success)
 }
 
 //楼层接口-----查询楼层轮廓
 export function floorQueryOutline(param, success) {
-  // let url = `${baseUrl}${object}/floor/query-outline`;
-  let url = `${baseUrl}${object}/floor/outline/query`;
+  let url = `${baseUrl}${floor}/outline/query`;
   http.postJson(url, param, success)
 }
 

+ 2 - 5
src/components/business_space/business/handsontable.vue

@@ -397,9 +397,6 @@ export default {
           this.myDialog.uploadImgs = true;
         }
       }
-      console.log('=============');
-      console.log(inputData);
-      console.log('=============');
       if (!this.onlyRead && !inputData.editable) {
         this.$message("该信息点的值为自动生成,不可人工维护!");
         return false;
@@ -506,9 +503,9 @@ export default {
           }
         }
       }
-      param.objectType = this.zoneParam.ZoneType ? this.zoneParam.ZoneType : this.zoneCode;
+      param.classCode = this.zoneParam.ZoneType ? this.zoneParam.ZoneType : this.zoneCode;
       let params = {
-        Content: [param]
+        content: [param]
       };
       zoneCreate(params, res => {
         this.$message.success("添加成功!")

+ 2 - 1
src/components/business_space/newGraphy/graphy.vue

@@ -362,7 +362,8 @@
       that.clearGraphy()
       that.scene = new DivideFloorScene();
       that.canvasLoading = true;
-      if (this.FloorMap.split('.')[1].toString() == 'png' || this.FloorMap.split('.')[1].toString() == 'jpg') {
+      const temp = this.FloorMap.split('.')[1];
+      if (temp && (temp.toLowerCase() == 'png' || temp.toLowerCase() == 'jpg')) {
         that.scene.loadImg(`/image-service/common/image_get?systemId=dataPlatform&key=${this.FloorMap}`, res => {
           this.getGraphtSuc(res)
         })

+ 11 - 11
src/components/ledger/cenote/relatedSpaceList.vue

@@ -73,32 +73,32 @@ export default {
       this.loading = true;
       let params = {
         data: {
-          Filters: "not RoomID isNull",
-          Orders: "localName desc",
-          PageNumber: this.page.pageNumber,
-          PageSize: this.page.pageSize
+          filters: "not id isNull",
+          orders: "localName desc",
+          pageNumber: this.page.pageNumber,
+          pageSize: this.page.pageSize
         },
         ShaftId: this.$route.query.ShaftId
       };
       if (this.Buildfloor[0] == "noKnow") {
-        params.data.Filters += `;buildingId isNull`;
+        params.data.filters += `;buildingId isNull`;
       } else if (this.Buildfloor[0] && this.Buildfloor[0] != "all") {
-        params.data.Filters += `;buildingId='${this.Buildfloor[0]}'`;
+        params.data.filters += `;buildingId='${this.Buildfloor[0]}'`;
       }
       if (this.Buildfloor[1] == "noKnow") {
-        params.data.Filters += `;floorId isNull`;
+        params.data.filters += `;floorId isNull`;
       } else if (this.Buildfloor[1] && this.Buildfloor[1] != "all") {
-        params.data.Filters += `;floorId='${this.Buildfloor[1]}'`;
+        params.data.filters += `;floorId='${this.Buildfloor[1]}'`;
       }
       if (this.space) {
-        params.data.Filters += `;ObjectType='${this.space}'`;
+        params.data.filters += `;objectType='${this.space}'`;
       }
       if (this.keyword) {
-        params.data.Filters += `;RoomName contain '${this.keyword}' or RoomLocalName contain '${this.keyword}'`;
+        params.data.filters += `;name contain '${this.keyword}' or localName contain '${this.keyword}'`;
       }
       shaftSpaceQuery(params, res => {
         this.loading = false;
-        this.tableData = res.Content
+        this.tableData = res.content
       })
     },
     //切换楼层

+ 2 - 2
src/components/ledger/lib/bimDialog.vue

@@ -152,11 +152,11 @@ export default {
     },
     //获取楼层数据
     getFloorData() {
-      console.log(this.floorData)
       if (this.floorData && this.floorData.StructureInfo && this.floorData.StructureInfo.FloorMap) {
         this.isdata = true
         let floorMap = this.floorData.StructureInfo.FloorMap
-        if (floorMap.split('.')[1].toString() == 'png' || floorMap.split('.')[1].toString() == 'jpg') {
+        const temp = floorMap.split('.')[1];
+        if (temp && (temp.toLowerCase() == 'png' || temp.toLowerCase() == 'jpg')) {
           this.initGraphy(floorMap, 3)
         } else {
           this.initGraphy(floorMap, 2)

+ 31 - 0
src/components/ready/buildfloor/backTips.vue

@@ -0,0 +1,31 @@
+<template>
+  <el-dialog title="提示" :visible.sync="dialogVis" width="500px" id="tipsDialog" :close-on-click-modal='false'>
+    <el-row>
+      <div style="line-height:32px;">上传图片未保存,退出后上传图片将失效。是否确认退出?</div>
+    </el-row>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVis=false">取消</el-button>
+      <el-button size="small" type="primary" @click="confirm">确认</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      dialogVis: false,
+      scaleInput: '',
+      item: '', // 当前修改的item
+    }
+  },
+  methods: {
+    showDialog(v) {
+      this.dialogVis = true
+    },
+    confirm() {
+      this.dialogVis = false;
+      this.$emit('back');
+    }
+  }
+}
+</script>

+ 58 - 0
src/components/ready/buildfloor/setScaleDialog.vue

@@ -0,0 +1,58 @@
+<template>
+  <el-dialog title="设定比例尺" :visible.sync="dialogVis" width="500px" id="scaleDialog" :close-on-click-modal='false'>
+    <el-row>
+      <div style="line-height:32px;">设定比例尺长度 : </div>
+      <div style="width:70%">
+        <el-input-number v-model="scaleInput" controls-position="right" :min="0"></el-input-number> mm
+      </div>
+    </el-row>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVis=false">取消</el-button>
+      <el-button size="small" type="primary" @click="confirm">确认</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+import { createRelationInFloor } from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      dialogVis: false,
+      scaleInput: '',
+      item: '', // 当前修改的item
+    }
+  },
+  methods: {
+    showDialog(v) {
+      this.dialogVis = true
+      this.item = v;
+      this.scaleInput = v.text.substring(0, v.text.length - 3);
+    },
+    confirm() {
+      this.item.text = this.scaleInput + ' mm';
+      this.item.update()
+      this.$emit('textChange', this.scaleInput)
+      this.dialogVis = false
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+#scaleDialog {
+  .el-row{
+    height: 50px;
+    max-height: 200px;
+    overflow-y: auto;
+    overflow-x: hidden;
+  }
+  .el-row > div {
+    float: left;
+  }
+  .el-row > div + div {
+    margin-left: 10px;
+  }
+  /deep/ .el-input__inner {
+    vertical-align: baseline;
+  }
+}
+</style>

+ 6 - 6
src/views/data_admin/buildGraphy/createPointZone.vue

@@ -102,12 +102,12 @@ export default {
         Type: item.Type
       }))
       if (this.RoomLocalName && this.buildFloor.length && this.space) {
-        zObj.ObjectType = this.space;
-        zObj.RoomLocalName = this.RoomLocalName;
-        zObj.RoomLocalID = this.RoomLocalID;
-        zObj.BuildingId = this.buildFloor[0];
-        zObj.FloorId = this.buildFloor[1];
-        param.Content = [zObj];
+        zObj.classCode = this.space;
+        zObj.localName = this.RoomLocalName;
+        zObj.localId = this.RoomLocalID;
+        zObj.buildingId = this.buildFloor[0];
+        zObj.floorId = this.buildFloor[1];
+        param.content = [zObj];
         zoneCreate(param, res => {
           this.$message.success("创建成功");
           this.$refs.pointMsg.clearImg();

+ 23 - 22
src/views/ledger/cenotelist/relatedSpace.vue

@@ -3,7 +3,7 @@
     <div class="condition">
       <div class="header">
         <el-button style="float:left;" size="small" type="default" icon="el-icon-back" @click="goBack"></el-button>
-        <div class="edit-tool" v-if="!cenoteObj.onlyRead">
+        <div class="edit-tool" v-if="!(cenoteObj.onlyRead == 'true')">
           <el-button v-if="isMyTab == 2" size="small" style="float:right" @click="dialogVisible = true">添加</el-button>
           <div v-else>
             <el-button v-show="!isEdit" @click="changeEditType" size="small" style="float:right">编辑</el-button>
@@ -32,11 +32,11 @@
           <label style="line-height:32px;padding: 0 10px;">所属建筑:</label>
           <el-select v-model="building" placeholder="请选择建筑" @change="changeBuilding" v-loading="buildingLoading">
             <el-option v-for="item in buildingList" :key="item.value"
-                       :label="item.BuildLocalName?item.BuildLocalName:item.BuildName"
-                       :value="item.BuildID"></el-option>
+                       :label="item.localName || item.name"
+                       :value="item.id"></el-option>
           </el-select>
         </el-badge>
-        <el-switch v-if="!cenoteObj.onlyRead" style="margin-left:15px;" v-model="isAI" @change="handleChangeAI"
+        <el-switch v-if="!(cenoteObj.onlyRead == 'true')" style="margin-left:15px;" v-model="isAI" @change="handleChangeAI"
                    active-text="打开AI">
         </el-switch>
         <div style="height:calc(100% - 42px);margin:10px 0 0 0;width:100%;">
@@ -59,7 +59,7 @@
             </el-col>
           </el-row>
           <div class="elevation-box">
-            <elevation-map ref="elevationMap" :onlyRead="cenoteObj.onlyRead" :isEdit="isEdit" :isAI="isAI"
+            <elevation-map ref="elevationMap" :onlyRead="cenoteObj.onlyRead=='true'" :isEdit="isEdit" :isAI="isAI"
                            @elevationChecked="handleCheckedSpace"
                            @elevationUncheck="handleUncheckSpace"
                            :params="{BuildingId: building, ObjectType: ObjectType, ShaftId: $route.query.ShaftId}">
@@ -84,7 +84,6 @@ import elevationMap from "@/components/ledger/cenote/elevationMap";
 import addSpaceDialog from '@/components/ledger/cenote/dialog/addSpaceDialog';
 import {
   queryAllZoneType,
-  // buildingQuery,
   shaftSpaceTypeQuery,
   shaftSpaceBuildingQuery,
   verticalSpace
@@ -120,10 +119,10 @@ export default {
       return this.$route.query;
     },
     showSpaceDot() {
-      return this.spaceList.length > 1 && this.cenoteObj.onlyRead ? true : false;
+      return this.spaceList.length > 1 && this.cenoteObj.onlyRead == 'true' ? true : false;
     },
     showBuildDot() {
-      return this.buildingList.length > 1 && this.cenoteObj.onlyRead ? true : false;
+      return this.buildingList.length > 1 && this.cenoteObj.onlyRead == 'true' ? true : false;
     },
     ...mapGetters("layout", ["projectId"])
   },
@@ -136,13 +135,13 @@ export default {
     elevationMap
   },
   created() {
-    this.isAI = this.$route.query.onlyRead ? false : true;
+    this.isAI = this.$route.query.onlyRead == 'true' ? false : true;
     this.getSpaceData();
   },
   methods: {
     //获取空间信息
     getSpaceData() {
-      if (this.cenoteObj.onlyRead) {
+      if (this.cenoteObj.onlyRead == 'true') {
         let pa = {
           shaftId: this.$route.query.ShaftId
         }
@@ -174,7 +173,13 @@ export default {
             }
             return t;
           });
-          this.space = [val2.content[0].objectType];
+          if (val2.content.length) {
+            this.space = [val2.content[0].objectType];
+          } else {
+            this.space = this.spaceList.find((item) => {
+              return item.Code == "GeneralZone"
+            }) ? ["GeneralZone"] : [this.spaceList[0].Code];
+          }
           this.ObjectType = this.space[0];
           //加载楼层信息
           this.loadBuildingData();
@@ -183,7 +188,7 @@ export default {
     },
     //默认显示默认分区,无默认分区显示第一个分区
     showDefaultSpace() {
-      if (this.spaceList.length && this.cenoteObj.onlyRead) {
+      if (this.spaceList.length && this.cenoteObj.onlyRead == 'true') {
         this.space = this.spaceList.find((item) => {
           return item.Code == "GeneralZone"
         }) ? ["GeneralZone"] : [this.spaceList[0].Code];
@@ -200,7 +205,7 @@ export default {
     },
     //获取楼层信息
     loadBuildingData() {
-      if (this.cenoteObj.onlyRead) {
+      if (this.cenoteObj.onlyRead == 'true') {
         let param = {
           ShaftId: this.$route.query.ShaftId,
           ObjectType: this.ObjectType
@@ -245,19 +250,15 @@ export default {
         this.$refs.relatedSpacelist.setFloorData(this.buildingList);
       }
       if (this.buildingList.length) {
-        // if (this.buildingList.length > 1 && this.cenoteObj.onlyRead) {
-        //   this.showBuildDot = true;
-        // }
         this.changeBuilding(this.buildingList[0].id);
       } else {
         this.buildingList = [];
         this.building = '';
         this.floor = '';
-        // this.showBuildDot = false;
       }
       this.buildingList.map(item => {
-        if (item.id && item.BuildLocalName) {
-          this.floorType[item.id] = item.BuildLocalName;
+        if (item.id && item.localName) {
+          this.floorType[item.id] = item.localName;
           if (item.floor instanceof Array) {
             item.floor.map(f => {
               if (f.id && f.localName) {
@@ -272,9 +273,9 @@ export default {
     calculateRelation() {
       if (this.isAI && this.building && this.ObjectType && this.cenoteObj.ShaftId) {
         let params = {
-          BuildingId: this.building,
-          ObjectType: this.ObjectType,
-          ShaftId: this.cenoteObj.ShaftId,
+          buildingId: this.building,
+          objectType: this.ObjectType,
+          shaftId: this.cenoteObj.ShaftId,
         }
         verticalSpace(params, res => {
           console.log(res)

+ 2 - 2
src/views/ledger/spacelist/spaceadd/index.vue

@@ -189,7 +189,7 @@ export default {
             item.floorId = item.flowBuild.split("-")[1]
           }
         }
-        item.objectType = this.space.spaceType;
+        item.classCode = this.space.spaceType;
       })
       if (flag) {
         this.$message.info("存在业务空间的本地名称为空,请检查")
@@ -197,7 +197,7 @@ export default {
       }
       //待接口修改为关联创建即可修改
       let param = {
-        Content: newData
+        content: newData
       }
       zoneCreate(param, res => {
         this.$message.success('创建成功')

+ 5 - 5
src/views/ready/buildfloor/drawGraphy/checkGraphy.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-dialog id='checkGraphy' title='添加平面图' :visible.sync='checkGraphyVisible' width='900px' @close='handleClose'>
+  <el-dialog id='checkGraphy' title='添加平面图' :visible.sync='checkGraphyVisible' width='500px' @close='handleClose'>
     <div class='bodys'>
       <el-cascader
         :options='options'
@@ -10,17 +10,17 @@
         placeholder='请选择模型文件'
         v-model='casVal'
       ></el-cascader>
-      <span>
+      <!-- <span>
                 &nbsp;&nbsp;或&nbsp;&nbsp;
                 <el-upload class='upload-demo' action='string' :http-request='uploadAndSubmit' :show-file-list='false'>
                     <el-button type>上传图片</el-button>
                 </el-upload>
                 <span>(支持jpg,png格式)</span>
-            </span>
+            </span> -->
       <!-- 展示框 -->
-      <div class='showBox'>
+      <!-- <div class='showBox'>
         <drawFloor ref='drawFloorDialog' :showTools='false' :id='0' :dialog='true'></drawFloor>
-      </div>
+      </div> -->
     </div>
     <span slot='footer' class='dialog-footer'>
             <el-button @click='handleClose'>取 消</el-button>

+ 80 - 43
src/views/ready/buildfloor/drawGraphy/drawFloor.vue

@@ -2,7 +2,7 @@
   <div :id="`drawFloor${id}`" class="drawFloor" v-loading="canvasLoading">
     <canvas :id="`floorCanvas${id}`" :width="cadWidth" :height="cadHeight" ref="canvas" tabindex="0"></canvas>
     <div class="operate" v-if="showTools">
-      <canvasFun @fit="fit" @savePng="savePng" @saveSvg="saveSvg" @divide="divide" @clearDivide="clearDivide" @undo="undo" @redo="redo" @scale="scale"
+      <canvasFun @fit="fit" @savePng="savePng" @saveSvg="saveSvg" @divide="divide" @clearDivide="clearDivide" @scale="scale"
         @changeAbsorb="changeAbsorb" :config="config" ref="canvasFun" @saveJson="saveJson"></canvasFun>
     </div>
   </div>
@@ -12,8 +12,10 @@
 import { DivideFloorScene, FloorView, Opt } from "@saga-web/cad-engine/lib"
 import { SColor, SPoint } from "@saga-web/draw/lib";
 import canvasFun from "@/components/business_space/newGraphy/canvasFun"
-import { floorQueryOutline } from "@/api/scan/request";
+import { floorQueryOutline, floorQueryAndSign } from "@/api/scan/request";
+import { EditLineItem } from "@saga-web/cad-engine"
 import { mapGetters } from "vuex";
+import { floorQuery } from "@/api/object/floor.js"
 export default {
   components: {
     canvasFun
@@ -26,7 +28,6 @@ export default {
       cadWidth: 800,
       cadHeight: 600,
       canvasLoading: false,
-      modelId: '',
       FloorID: '',
       Outline: [],
       floorData: {},
@@ -34,7 +35,10 @@ export default {
         isEdit: false,
         divide: true
       },
-      shadeList: []
+      shadeList: [],
+      type: 1, // 当前图展示类型
+      scaleItem: null, // 比例尺item
+      urlModelId: '', // url中传入的modelid
     };
   },
   props: {
@@ -62,6 +66,7 @@ export default {
   },
   created() {
     this.FloorID = this.$route.query.FloorID;
+    this.urlModelId = this.$route.query.modelId
     Opt.sceneMarkColor = new SColor('#00000080');
     if (!this.dialog) {
       this.init();
@@ -80,8 +85,9 @@ export default {
     initGraphy(Id, type) {
       // type=1 => id:模型id
       // type=2 => id:floormap
+      // type=3 => id:图片的key
       let that = this;
-      that.modelId = Id;
+      that.type = type;
       that.clearGraphy()
       that.drawMainScene = new DivideFloorScene();
       that.canvasLoading = true;
@@ -95,11 +101,9 @@ export default {
         })
       }else if(type==3){
         that.drawMainScene.loadImg(`/image-service/common/image_get?systemId=dataPlatform&key=${Id}`, res=>{
-        // fdfd
           that.getGraphtSuc(res)
-      })
+        })
       }
-
     },
     // 获取底图成功
     getGraphtSuc(res) {
@@ -118,12 +122,24 @@ export default {
       this.view.fitSceneToView();
       this.drawMainScene.isSpaceSelectable = false;
 
+      if (this.type == 3) {
+        this.addScaleItem(this.floorData.properties)
+        this.$emit('getGraphSuc');
+        if (this.floorData.properties) {
+          const x = this.floorData.properties.X;
+          const y = this.floorData.properties.Y;
+          if (x != 0 || y != 0) {
+            this.drawMainScene.imgList[0].moveTo(x, y);
+          }
+        }
+      }
+
       if (this.$refs.canvasFun) {
         this.view.minScale = this.view.scale;
         this.$refs.canvasFun.everyScale = this.view.scale;
       }
-      if (this.floorData.Outline && this.floorData.Outline.length) {
-        let newArr = this.floorData.Outline.map(t => {
+      if (this.floorData.outline && this.floorData.outline.length) {
+        let newArr = this.floorData.outline.map(t => {
           return new SPoint(t.X, t.Y);
         })
         this.drawMainScene.addSceneMark(newArr)
@@ -132,38 +148,65 @@ export default {
     // 获取楼层数据
     getFloorData() {
       let pa = {
-        filters: `id='${this.FloorID}'`
+        filters: `id='${this.FloorID}'`,
+        cascader: [{ name: 'floorOutline' }]
+      }
+      // 先用 floorQuery 级联 floorOutline  以后与 floorQueryOutline 一块使用
+      console.log(this.urlModelId);
+      const temp = this.urlModelId && this.urlModelId.split('.')[1].toLowerCase()
+      if (temp == 'png' || temp == 'jpg') { //底图为图片且已经绑定过图片
+        floorQueryAndSign(pa, res => {
+          this.floorData = res.content[0];
+          if (this.floorData.infos && this.floorData.infos.floorMap) {
+            let floorMap = this.floorData.infos.floorMap
+            this.initGraphy(floorMap, 3)
+          }
+        })
+      } else {
+        // floorQueryOutline
+        floorQuery(pa, res => {
+          this.floorData = res.content[0];
+          if (this.floorData.infos && this.floorData.infos.FloorMap) {
+            this.getOtherFloorOutLine();
+            let floorMap = this.floorData.infos.FloorMap
+            this.initGraphy(floorMap, 2)
+          }
+        })
       }
-      floorQueryOutline(pa, res => {
-        this.floorData = res.Content[0];
-        this.getOtherFloorOutLine();
-        let floorMap = this.floorData.StructureInfo.FloorMap
-        if(floorMap.split('.')[1].toString() == 'png' || floorMap.split('.')[1].toString() == 'jpg'){
-           this.initGraphy(floorMap, 3)
-        }else{
-           this.initGraphy(floorMap, 2)
-        }
-      })
     },
     // 获取绑定该模型id的其他楼层轮廓线
     getOtherFloorOutLine() {
-      let modelid = this.floorData.ModelId;
-      let pa = {
-        Filters: `ModelId='${modelid}'`
-      }
-      this.shadeList = [];
-      floorQueryOutline(pa, res => {
-        res.Content.map(t => {
-          if (t.FloorID != this.FloorID && t.Outline && t.Outline.length) {
-            let line = t.Outline.map(item => {
-              return new SPoint(item.X, item.Y);
-            })
-            this.shadeList.push(line);
-          }
+      let modelid = this.floorData.modelId;
+      if (modelid) {
+        let pa = {
+          filters: `modelId='${modelid}'`
+        }
+        this.shadeList = [];
+        floorQueryOutline(pa, res => {
+          res.content.map(t => {
+            if (t.id != this.FloorID && t.outline && t.outline.length) {
+              let line = t.outline.map(item => {
+                return new SPoint(item.X, item.Y);
+              })
+              this.shadeList.push(line);
+            }
+          });
+          this.drawMainScene.addAllShade(this.shadeList);
+          this.$emit('changeSign', res.content.length > 1);
         });
-        this.drawMainScene.addAllShade(this.shadeList);
-        this.$emit('changeSign', res.Content.length > 1);
-      });
+      }
+    },
+    // 添加比例尺item 当楼层图为图片类型时 回显比例尺
+    addScaleItem(data) {
+      this.scaleItem = new EditLineItem(null)
+      this.scaleItem.strokeColor = SColor.Red;
+      this.drawMainScene.addItem(this.scaleItem)
+      if (data && data.Line && data.Line.length == 2) {
+        this.scaleItem.line = data.Line;
+        this.scaleItem.text = data.Text;
+        // todo
+        this.scaleItem.pointChange();
+      }
     },
     // 清空平面图
     clearGraphy() {
@@ -207,12 +250,6 @@ export default {
     changeAbsorb(isAbsorbing) {
       this.drawMainScene.isAbsorbing = isAbsorbing;
     },
-    // 撤销
-    undo() {
-
-    },
-    // 反撤销
-    redo() { },
     // 缩放
     scale(val) {
       if (!this.view) {

+ 5 - 37
src/views/ready/buildfloor/index.vue

@@ -66,9 +66,7 @@
             <el-table-column label="楼层贯通关系" prop="SubTypeName">
               <template slot-scope="scope">
                 <span
-                  style="margin-right:20px">{{
-                    scope.row.floorThroughList ? scope.row.floorThroughList.length : 0
-                  }}</span>
+                  style="margin-right:20px">{{ scope.row.floorThroughList ? scope.row.floorThroughList.length : 0 }}</span>
                 <el-button @click="changeConnection(scope.row)" icon="el-icon-edit-outline" plain size="mini"/>
               </template>
             </el-table-column>
@@ -113,10 +111,7 @@
     </el-dialog>
     <!-- 添加贯通关系弹窗 -->
     <addConnectivity @refresh="refresh" ref="addConnectivity"/>
-    <!-- 查看图片弹窗 -->
-    <checkGraphy :alreadyRelatedModel='alreadyRelatedModel' @refresh="bindRefresh" ref="checkGraphy"></checkGraphy>
   </div>
-
 </template>
 
 <script>
@@ -124,7 +119,6 @@ import addFloor from "@/views/ready/buildfloor/addFloor/index";
 import addBuild from "@/components/ready/buildfloor/addBuild";
 import { mapGetters } from "vuex";
 import addConnectivity from "@/components/ready/buildfloor/addConnectivity";
-import checkGraphy from "./drawGraphy/checkGraphy"; //查看图片
 import tools from "@/utils/buildfloor/tools";
 import {
   buildingQueryAndCount,
@@ -137,13 +131,11 @@ import {
 } from "@/api/scan/request";
 import { getDataDictionary } from "@/api/dict";
 
-
 export default {
   components: {
     addFloor,
     addBuild,
-    addConnectivity,
-    checkGraphy
+    addConnectivity
   },
   data() {
     return {
@@ -171,8 +163,6 @@ export default {
       curBuildName: "", //当前选中建筑的名称
       curFloorId: "", //当前选中的楼层id
       modelId: "",
-      alreadyRelatedModel: [],
-      // currentType: 'add'
       buildMessage: {},
       selectedBuildIndex: 0
     };
@@ -225,7 +215,6 @@ export default {
     handleSearchBuildKey() {
       let params = {
         type: 'building',
-        // orders: "sort asc,infoPointCode asc",
         pageNumber: 1,
         pageSize: 1000
       };
@@ -299,15 +288,6 @@ export default {
           this.$refs.addBuildDialog.closeDialog()
         })
       } else {
-        // if(Object.keys(newform).length > 0) {
-        //   objectCreateBuild(Param, res => {
-        //     this.$message.success('创建成功')
-        //     this.$refs.addBuildDialog.closeDialog()
-        //   })
-        // } else {
-        //   this.$refs.addBuildDialog.closeDialog()
-        //   return false
-        // }
         objectCreateBuild(Param, res => {
           this.$message.success('创建成功')
           this.$refs.addBuildDialog.closeDialog()
@@ -344,15 +324,8 @@ export default {
       floorQueryAndSign(floorParam, res => {
         this.tableData = res.content;
         this.page.total = res.total;
-        this.alreadyRelatedModel = res.content.map(t => {
-          return t.modelId
-        }).filter(t => t);
       });
     },
-    // 绑定图以后刷新
-    bindRefresh() {
-      this.init();
-    },
     // 创建楼层成功-修改关系成功
     refresh() {
       this.getFloorTableData();
@@ -389,7 +362,6 @@ export default {
     },
     // 修改楼层信息
     editFloorData(floor) {
-      console.log(floor, 'floor')
       this.floorTitle = "编辑楼层信息";
       this.curFloorId = floor.id;
       this.$refs.addFloorDialog.showDialog(floor);
@@ -402,24 +374,20 @@ export default {
     // 查看平面图
     checkDrawImg(row, index) {
       if (3 == index) {
-        this.$refs.checkGraphy.showDialog(row);
         this.modelId = "";
       } else if (index == 1) {
-        // this.modelId = row.StructureInfo.FloorMap
         this.modelId = row.infos.floorMap
-        let pa = { modelId: this.modelId, FloorID: row.id, BuildID: row.buildingId, BuildName: this.curBuildName };
-        this.$router.push({ name: "repetitionGraphy", query: pa });
       } else {
         this.modelId = row.modelId;
-        let pa = { modelId: this.modelId, FloorID: row.id, BuildID: row.buildingId, BuildName: this.curBuildName };
-        this.$router.push({ name: "repetitionGraphy", query: pa });
       }
+      const pa = { modelId: this.modelId, FloorID: row.id, BuildID: row.buildingId, BuildName: this.curBuildName }
+      this.$router.push({ name: "repetitionGraphy", query: pa });
     },
     //  查询建筑信息
     handleBuildQuery() {
       let param = {
         projectId: this.projectId,
-        // Orders: "BuildLocalName asc",
+        Orders: "localName asc",
         pageNumber: 1,
         pageSize: 500
       };

+ 331 - 30
src/views/ready/buildfloor/repetitionGraphy.vue

@@ -3,39 +3,102 @@
   <div id='repetitionGraphy'>
     <div class='buttons'>
       <el-button icon='el-icon-back' size='mini' @click='backRouter'></el-button>
-      <el-button v-if='!isEdit' size='mini' @click='changeGraphy'>替换平面图</el-button>
-      <el-button v-if='(sign||otherSign)&&!isEdit' size='mini' @click='editGraphy'>编辑平面图</el-button>
-      <el-button v-if='isEdit' size='mini' @click='cancel'>取消</el-button>
-      <el-button v-if='isEdit' size='mini' @click='confirm' type='primary'>确认</el-button>
-      <span style='float:right;' v-if='file.FolderName'>当前对应的模型文件:{{ file.FolderName }} - {{ file.FloorName }}</span>
+      <template v-if="!hasModel">
+        <el-upload class='upload-demo' action='string' :http-request='uploadAndSubmit' :show-file-list='false' v-if="step==-1" accept=".jpg,.png">
+          <el-button size="mini">{{hasGraph?'替换平面图图片':'上传平面图图片'}}</el-button>
+        </el-upload>
+        <el-button style='float:right;' size='mini' type='primary' v-if="step==0" @click="nextStep" :disabled="nextStepBtnDisable">下一步</el-button>
+        <el-button style='float:right;' size='mini' type='primary' v-if="step==1" @click="nextStep">保存</el-button>
+        <el-button style='float:right;' size='mini' v-if="step==1" @click="lastStep">上一步</el-button>
+      </template>
+      <template v-else>
+        <el-button v-if='!isEdit' size='mini' @click='changeGraphy'>{{hasGraph?'替换模型文件':'关联模型文件'}}</el-button>
+        <el-button v-if='(sign||otherSign)&&!isEdit' size='mini' @click='editGraphy'>编辑平面图</el-button>
+        <el-button v-if='isEdit' size='mini' @click='cancel'>取消</el-button>
+        <el-button v-if='isEdit' size='mini' @click='confirm' type='primary'>确认</el-button>
+      </template>
+      <span style='float:right;' v-if='file.FolderName'>当前对应的模型文件:{{file.FolderName}} - {{file.FloorName}}</span>
     </div>
     <!-- 展示图片 -->
     <div class='drawImg'>
-      <drawFloor ref='drawFloor' :isEdit='isEdit' :showTools='true' :id='1' @changeSign='changeSign'></drawFloor>
+      <div style="width: 100%;height: 100%;position: relative;" v-if="hasGraph">
+        <drawFloor ref='drawFloor' :isEdit='isEdit' :showTools='true' :id='1' @changeSign='changeSign' @getGraphSuc="getGraphSuc"></drawFloor>
+        <div class="stepContainer" v-if="step>-1">
+          <el-steps :active="step" align-center finish-status="success" process-status="process">
+            <el-step title="设定比例尺" :description="stepDes[0]"></el-step>
+            <el-step title="楼层对齐" :description="stepDes[1]"></el-step>
+          </el-steps>
+        </div>
+        <ul class="floorList" v-if="step==1">
+          <template v-if="floorList.length > 1">
+            <li style="border-bottom:1px solid #ccc;text-align: center;padding: 0">选择对齐楼层</li>
+            <li v-for="t in floorList" :key="t.id">
+              <el-radio v-model="floorRadio" :label="t" @change="changeFloor" :disabled="t.id == FloorID">{{t.localId || t.localName}}</el-radio>
+            </li>
+          </template>
+          <template v-else>
+            <li style="text-align: center;padding: 0">
+              暂无对齐楼层
+            </li>
+          </template>
+        </ul>
+      </div>
+      <div style="width: 100%;height: 100%" v-else>
+        <div class="center" style="padding-top: 300px">
+          <i class="icon-wushuju iconfont"></i>暂无平面图
+        </div>
+      </div>
     </div>
     <!-- 查看图片弹窗 -->
     <checkGraphy ref='checkGraphy' @refresh='refresh' :alreadyRelatedModel='alreadyRelatedModel'></checkGraphy>
+    <!-- 设定比例尺弹窗 -->
+    <setScaleDialog ref="setScaleDialog" @textChange="scaleTextChange"></setScaleDialog>
+    <!-- 退出时弹窗提示 -->
+    <backTips ref='backTips' @back="runBack"></backTips>
   </div>
 </template>
 <script>
 import drawFloor from './drawGraphy/drawFloor'
 import checkGraphy from './drawGraphy/checkGraphy' //查看图片
-import { floorUpdateOutline, floorQueryAndSign } from '@/api/scan/request'
-import { getFileNameById } from '@/api/model/file'
-
+import setScaleDialog from '@/components/ready/buildfloor/setScaleDialog'
+import backTips from '@/components/ready/buildfloor/backTips'
+import { floorUpdateOutline, floorQueryAndSign, manageUpdateFloor } from '@/api/scan/request'
+import { getFileNameById, countModel } from '@/api/model/file'
+import { EditLineItem, SItemStatus, SImageShowType, IconTextItem } from "@saga-web/cad-engine"
+import { SColor } from "@saga-web/draw"
+import { SImageItem } from '@saga-web/graph/lib'
+import { SMathUtil } from "@saga-web/cad-engine/lib/utils/SMathUtil"
 export default {
   components: {
     drawFloor,
     checkGraphy,
+    setScaleDialog,
+    backTips
   },
   data() {
     return {
       modelId: '', //
       isEdit: false, // 是否编辑模式
+      FloorID: '',
       file: {},
       alreadyRelatedModel: [],
       sign: false,
       otherSign: false,
+      hasGraph: false, // 当前楼层是否有平面图
+      hasModel: false, // 项目中时候有模型文件
+      step: -1, // 当前处于第几步 同时为比例尺item判断是否创建的可编辑的依据;能否返回上页的依据
+      key: '', // 当楼层图为图片时图的key
+      stepDes: [
+        '请在图上点击两点绘制线段并标记实际长度',
+        '请移动图片与其他楼层对齐'
+      ], // 描述文字
+      floorList: [], // 当前建筑下所有楼层
+      floorRadio: '', // 当前选中的楼层对象
+      imgService: `/image-service/common/image_get?systemId=dataPlatform&key=`,
+      curImgItem: null, // 对齐的楼层图片
+      scaleItem: null, // 比例尺item
+      baseImgItem: null, // 当前楼层图的图片
+      nextStepBtnDisable: true, // 比例尺item创建标识
     }
   },
   created() {
@@ -43,15 +106,18 @@ export default {
     this.FloorID = this.$route.query.FloorID
     this.BuildID = this.$route.query.BuildID
     this.BuildName = this.$route.query.BuildName
-    if (this.modelId.split('.')[1].toString() == 'png' || this.modelId.split('.')[1].toString() == 'jpg') {
-      return
-    } else {
-      this.init()
+    if (this.modelId != '') {
+      this.hasGraph = true;
+      const temp = this.modelId.split('.');
+      if (temp[1] && (temp[1].toLowerCase() == 'png' || temp[1].toLowerCase() == 'jpg')) {
+        // return
+      } else {
+        this.init()
+      }
     }
-
-  },
-  mounted() {
+    this.getCountModel()
   },
+  mounted() {},
   methods: {
     init() {
       this.getFileName(this.modelId)
@@ -59,6 +125,14 @@ export default {
     },
     // 返回路由
     backRouter() {
+      // 底图为图片  上传完图片后未保存
+      if (this.step > -1) {
+        this.$refs.backTips.showDialog();
+      } else {
+        this.runBack()
+      }
+    },
+    runBack() {
       this.$router.push({ name: 'buildFloor' })
     },
     // 替换模型文件
@@ -88,7 +162,7 @@ export default {
         })
       }
       let pa = {
-        Content: [{ FloorID: this.FloorID, Outline: Outline }],
+        Content: [{ id: this.FloorID, outline: Outline }],
         Projection: ['Outline'],
       }
       floorUpdateOutline(pa, (res) => {
@@ -108,7 +182,12 @@ export default {
     // 替换模型文件成功
     refresh(modelId) {
       this.modelId = modelId
-      this.getFileName(this.modelId)
+      this.hasGraph = true;
+      const temp = this.modelId.split('.');
+      if (temp[1] && temp[1].toLowerCase() != 'png' && temp[1].toLowerCase() != 'jpg') {
+        this.key = '';
+        this.getFileName(this.modelId)
+      }
     },
     // 获取文件夹名称
     getFileName(modelId) {
@@ -123,14 +202,18 @@ export default {
     // 获取楼层
     getFloorData() {
       let floorParam = {
-        PageSize: 1000,
-        Filters: `BuildID='${this.BuildID}'`,
+        pageSize: 1000,
+        filters: `buildingId='${this.BuildID}'`,
+        orders: 'floorSequenceID desc'
       }
       floorQueryAndSign(floorParam, (res) => {
-        this.alreadyRelatedModel = res.Content.map((t) => {
-          if (t.FloorID != this.FloorID) return t.ModelId
+        this.floorList = res.content;
+        // todo
+        this.floorRadio = res.content[0];
+        this.alreadyRelatedModel = res.content.map((t) => {
+          if (t.floorID != this.FloorID) return t.modelId
           this.sign = t.Sign > 0
-          this.FloorName = t.FloorLocalName || t.FloorName
+          this.FloorName = t.localName || t.name
           this.$refs.drawFloor.buildFloorName = `${this.BuildName}-${this.FloorName}`
         }).filter((t) => t)
       })
@@ -138,15 +221,205 @@ export default {
     changeSign(flag) {
       this.otherSign = flag
     },
+    // 统计项目下是否有模型文件
+    getCountModel() {
+      countModel({Filters:"Status in [4]"}, res => {
+        this.hasModel = res.Count > 0
+      })
+    },
+    //上传图片
+    uploadAndSubmit(item) {
+      let file = item.file
+      let reader = new FileReader()
+      let vm = this
+      let fileType = file.name.split('.')
+      let type = fileType[fileType.length - 1]
+      let uploadKey = file.uid
+      reader.onloadend = function () {
+        // 这个事件在读取结束后,无论成功或者失败都会触发
+        if (reader.error) {
+        } else {
+          // document.getElementById("bytesRead").textContent = file.size;
+          // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
+          var xhr = new XMLHttpRequest()
+          xhr.open(
+                    /* method */ 'POST',
+            /* target url */
+            '/image-service/common/image_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&overwrite=true&key=' + uploadKey + '.' + type
+            /*, async, default to true */
+          )
+          //xhr.overrideMimeType("application/octet-stream");
+          xhr.send(reader.result)
+          xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+              if (xhr.status == 200) {
+                vm.key = uploadKey + '.' + type
+                // 将图片展示
+                vm.refresh(uploadKey + '.' + type)
+                // 设置步骤为第一步
+                vm.step = 0;
+              }
+            }
+          }
+        }
+      }
+      reader.readAsArrayBuffer(file)
+    },
+    // 更新楼层key 为图片,同时更新比例尺
+    updateFloorKey() {
+      const scaleItem = this.$refs.drawFloor.scaleItem;
+      // 比例尺坐标处理,当底图被对齐操作后,需要跟随底图改变坐标
+      const line = scaleItem.line.map(t => {
+        return { x: t.x + this.baseImgItem.x, y: t.y + this.baseImgItem.y }
+      })
+      let Param = {
+        content: [{
+          id: this.FloorID,
+          infos: { floorMap: this.key },
+          properties: {
+            X: this.baseImgItem.x,
+            Y: this.baseImgItem.y,
+            Line: line,
+            Text: scaleItem.text
+          }
+        }],
+        // projection: ['infos', 'properties'],
+      }
+      manageUpdateFloor(Param, (res) => {
+        this.$message.success('更新成功')
+        this.step = -1;
+        this.baseImgItem.globalAlpha = 1
+        this.removeLast()
+        this.$refs.drawFloor.fit()
+      })
+    },
+    // 根据modelid初始化
+    initFromModelId(id) {
+      const temp = id.split('.')[1];
+      if (temp && (temp.toLowerCase() == 'png' || temp.toLowerCase() == 'jpg')) {
+        this.$refs.drawFloor.initGraphy(id, 3)
+      } else {
+        this.$refs.drawFloor.initGraphy(id, 1)
+      }
+    },
+    // 上一步
+    lastStep() {
+      this.step = 0;
+      this.$refs.drawFloor.scaleItem.show()
+      this.baseImgItem.globalAlpha = 1
+      this.removeLast()
+    },
+    // 下一步||保存
+    nextStep() {
+      this.baseImgItem = this.$refs.drawFloor.drawMainScene.imgList[0]
+      this.baseImgItem.globalAlpha = 0.5
+      this.baseImgItem.moveable = true;
+      // 下一步
+      if (this.step == 0) {
+        this.step = 1;
+        this.$refs.drawFloor.scaleItem.hide();
+        // 获取楼层列表
+        this.getFloorData()
+      } else if (this.step == 1) {
+        // 保存
+        this.updateFloorKey();
+      }
+    },
+    // 加载图成功 仅在底图为图片时返回成功
+    getGraphSuc() {
+      const scaleItem = this.$refs.drawFloor.scaleItem
+      if (this.step == 0) {
+        scaleItem.status = SItemStatus.Create;
+        this.$refs.drawFloor.drawMainScene.grabItem = scaleItem;
+        scaleItem.connect('changText', this, this.changeText)
+        scaleItem.moveable = true;
+        this.clearScaleData(scaleItem);
+      } else if (this.step == -1) {
+        scaleItem.status = SItemStatus.Normal;
+      }
+    },
+    // 修改比例尺文字
+    changeText(t, e) {
+      this.$refs.setScaleDialog.showDialog(t)
+    },
+    // 文本修改
+    scaleTextChange(v) {
+      if (v > 0) {
+        this.nextStepBtnDisable = false
+      }
+    },
+    // 第二部楼层修改
+    changeFloor(v) {
+      // v->当前改为的楼层对象
+      this.removeLast();
+      if (v.StructureInfo && v.StructureInfo.FloorMap) {
+        const url = this.imgService + v.StructureInfo.FloorMap
+        this.curImgItem = new SImageItem(null, url);
+        this.curImgItem.enabled = false;
+        this.curImgItem.showType = SImageShowType.AutoFit;
+        if (v.Properties) {
+          try {
+            // 计算两个比例尺差距
+            const scaleItem = this.$refs.drawFloor.scaleItem
+            this.curImgItem.zOrder = scaleItem.zOrder - 1;
+            const r = this.calScaleGap(v.Properties, scaleItem);
+            if (r != 1) {
+              this.$message.warning('比例尺相差较大,可以返回上一步修改比例尺')
+            }
+            this.curImgItem.showType == SImageShowType.Full;
+            this.curImgItem.moveTo(v.Properties.X, v.Properties.Y);
+            // this.curImgItem.width = v.Properties.width;
+            // this.curImgItem.height = v.Properties.height;
+          } catch (err) {
+            console.log(err);
+          }
+        }
+        this.$refs.drawFloor.drawMainScene.addItem(this.curImgItem);
+        this.$refs.drawFloor.fit()
+      }
+    },
+    // 清除上一张底图
+    removeLast() {
+      if (this.curImgItem) {
+        this.$refs.drawFloor.drawMainScene.removeItem(this.curImgItem);
+        this.curImgItem = null;
+        this.$refs.drawFloor.view.update()
+      }
+    },
+    // 清空比例尺数据
+    clearScaleData(scaleItem) {
+      scaleItem.line = [];
+      scaleItem.pointChange();
+      scaleItem.text = '0 mm';
+    },
+    // 计算两个比例尺差距
+    calScaleGap(pro, item) {
+      // pro -> 楼层的properties
+      // item -> 当前的比例尺item
+      let result = 1
+      if (pro.Line.length && pro.Text) {
+        try {
+          const proDis = SMathUtil.pointDistance(pro.Line[0].x, pro.Line[0].y, pro.Line[1].x, pro.Line[1].y)
+          const proText = pro.Text.substring(0, pro.Text.length - 3);
+          const proScale = proDis / proText;
+          const itemDis = SMathUtil.pointDistance(item.line[0].x, item.line[0].y, item.line[1].x, item.line[1].y)
+          const itemText = item.text.substring(0, item.text.length - 3);
+          const itemScale = itemDis / itemText;
+          result = (proScale / itemScale).toFixed()
+        } catch (err) {
+          console.log(err);
+        }
+      }
+      return result;
+    }
   },
   watch: {
     modelId(n, o) {
-      if (o && n != o) {
-        console.log(n.split('.')[1])
-        if (n.split('.')[1].toString() == 'png' || n.split('.')[1].toString() == 'jpg') {
-          this.$refs.drawFloor.initGraphy(n, 3)
-        } else {
-          this.$refs.drawFloor.initGraphy(n, 1)
+      if (n != o) {
+        if (n) {
+          this.$nextTick(()=>{
+            this.initFromModelId(n)
+          })
         }
       }
     },
@@ -161,11 +434,39 @@ export default {
   position: relative;
   padding: 10px;
   box-sizing: border-box;
-
   .drawImg {
     width: 100%;
     margin-top: 10px;
     height: calc(100% - 40px);
   }
+  .upload-demo {
+    display: inline-block;
+  }
+  .stepContainer {
+    width: 100%;
+    position: absolute;
+    top: 0;
+    left: 50%;
+    margin-left: -50%;
+    z-index: 9;
+    background-color: #fff;
+  }
+  .floorList {
+    position: absolute;
+    width: 100px;
+    max-height: 250px;
+    overflow-x: hidden;
+    overflow-y: auto;
+    left: 40px;
+    top: 200px;
+    z-index: 10;
+    background: #fff;
+    border: 1px solid #ccc;
+    li {
+      box-sizing: border-box;
+      padding: 0 10px;
+      width: 100%;
+    }
+  }
 }
 </style>