BUG 25647
This commit is contained in:
		@@ -3,152 +3,158 @@
 | 
			
		||||
    <div class="grid-select">
 | 
			
		||||
      <span class="label">网格选择</span>
 | 
			
		||||
      <div class="value">
 | 
			
		||||
          <AiTreePicker :ops="treeList" v-model="form.id" @select="handerSelect">
 | 
			
		||||
            <div class="grid-name" :style="{ color: form.girdName ? '' : '#c0c4cc' }">{{form.girdName || '请选择社区居委会'}} <u-icon name="arrow-right" color="#cccccc" size="14"></u-icon></div>
 | 
			
		||||
          </AiTreePicker>
 | 
			
		||||
        <AiTreePicker :ops="treeList" v-model="form.id" @select="handleSelect">
 | 
			
		||||
          <div class="grid-name" :style="{ color: form.girdName ? '' : '#c0c4cc' }">{{ form.girdName || '请选择社区居委会' }}
 | 
			
		||||
            <u-icon name="arrow-right" color="#cccccc" size="14"></u-icon>
 | 
			
		||||
          </div>
 | 
			
		||||
        </AiTreePicker>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="map-content">
 | 
			
		||||
      <AiTMap v-if="areaId" :areaId="areaId" :map.sync="map" :lib.sync="lib" :ops="ops" :libraries="['service', 'tools']"></AiTMap>
 | 
			
		||||
      <AiTMap ref="AiTMap" :map.sync="map" :lib.sync="lib" :libraries="['service', 'tools']"/>
 | 
			
		||||
    </div>
 | 
			
		||||
    <u-popup v-model="show" mode="bottom" border-radius="14">
 | 
			
		||||
      <div class="popup">
 | 
			
		||||
        <div class="bg"></div>
 | 
			
		||||
        <div class="title">{{form.girdName}}</div>
 | 
			
		||||
        <div class="title">{{ form.girdName }}</div>
 | 
			
		||||
        <div class="info-flex">
 | 
			
		||||
          <span class="label">网格类型</span>
 | 
			
		||||
          <span class="value">{{$dict.getLabel('girdType', form.girdType)}}</span>
 | 
			
		||||
          <span class="value">{{ $dict.getLabel('girdType', form.girdType) }}</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="info-flex">
 | 
			
		||||
          <span class="label">网格层级</span>
 | 
			
		||||
          <span class="value">{{$dict.getLabel('girdLevel', form.girdLevel)}}</span>
 | 
			
		||||
          <span class="value">{{ $dict.getLabel('girdLevel', form.girdLevel) }}</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div v-if="form.girdMemberList && form.girdMemberList.length">
 | 
			
		||||
          <div class="info-flex"  v-for="(item, index) in  form.girdMemberList" :key="index">
 | 
			
		||||
          <div class="info-flex" v-for="(item, index) in  form.girdMemberList" :key="index">
 | 
			
		||||
            <span class="label">网格管理员</span>
 | 
			
		||||
            <span class="value">{{item.name}}  {{item.phone}}
 | 
			
		||||
              <img :src="$cdn + 'common/phone.png'" alt="" @click="callPhone(item.phone)" class="phone-icon" v-if="item.phone">
 | 
			
		||||
            <span class="value">{{ item.name }}  {{ item.phone }}
 | 
			
		||||
              <img :src="$cdn + 'common/phone.png'" alt="" @click="callPhone(item.phone)" class="phone-icon"
 | 
			
		||||
                   v-if="item.phone">
 | 
			
		||||
            </span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
    </u-popup>
 | 
			
		||||
 | 
			
		||||
    <div class="footer" @click="view" v-if="form.id && !show">
 | 
			
		||||
    <div class="footer" @click="show=true" v-if="form.id && !show">
 | 
			
		||||
      <div class="btn">查看网格信息</div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { mapState } from 'vuex'
 | 
			
		||||
import {mapState} from 'vuex'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      areaId: '',
 | 
			
		||||
      ops: {},
 | 
			
		||||
      lib: '',
 | 
			
		||||
      lib: null,
 | 
			
		||||
      map: null,
 | 
			
		||||
      show: false,
 | 
			
		||||
      form: {girdName: '', id: ''},
 | 
			
		||||
      treeList: [],
 | 
			
		||||
      showSelect: false,
 | 
			
		||||
      editor: null,
 | 
			
		||||
      polygons: []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: { ...mapState(['user']) },
 | 
			
		||||
  computed: {...mapState(['user'])},
 | 
			
		||||
  created() {
 | 
			
		||||
    this.$dict.load('girdType', 'girdLevel')
 | 
			
		||||
    this.areaId = this.user.areaId
 | 
			
		||||
    this.getTreeList()
 | 
			
		||||
    this.getLeafNodes()
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    callPhone(phone) {
 | 
			
		||||
      uni.makePhoneCall({ phoneNumber: phone })
 | 
			
		||||
    },
 | 
			
		||||
    handerSelect(e) {
 | 
			
		||||
      console.log(e)
 | 
			
		||||
      this.form = e
 | 
			
		||||
      this.initMap(e.points)
 | 
			
		||||
    },
 | 
			
		||||
    initMap(points) {
 | 
			
		||||
      if(points && points.length) {
 | 
			
		||||
        //初始化地图
 | 
			
		||||
        this.$nextTick(() =>{
 | 
			
		||||
        let {lib: TMap, map} = this
 | 
			
		||||
        var center = new TMap.LatLng(points[0].lat, points[0].lng)
 | 
			
		||||
        map.setCenter(center)
 | 
			
		||||
        map.setZoom(15)
 | 
			
		||||
 | 
			
		||||
        console.log(points)
 | 
			
		||||
        var simplePath = []
 | 
			
		||||
 | 
			
		||||
        points.map((item) => {
 | 
			
		||||
          var info = new TMap.LatLng(item.lat, item.lng)
 | 
			
		||||
          simplePath.push(info)
 | 
			
		||||
        })
 | 
			
		||||
			
 | 
			
		||||
        // 初始化几何图形及编辑器
 | 
			
		||||
        this.editor = new TMap.tools.GeometryEditor({
 | 
			
		||||
          map, // 编辑器绑定的地图对象
 | 
			
		||||
          overlayList: [ // 可编辑图层
 | 
			
		||||
            {
 | 
			
		||||
              overlay: new TMap.MultiPolygon({
 | 
			
		||||
                map,
 | 
			
		||||
                styles: {
 | 
			
		||||
                  highlight: new TMap.PolygonStyle({
 | 
			
		||||
                    color: 'rgba(255, 255, 0, 0.6)'
 | 
			
		||||
                  })
 | 
			
		||||
                },
 | 
			
		||||
                geometries: [
 | 
			
		||||
                  {
 | 
			
		||||
                    paths: simplePath
 | 
			
		||||
                  },
 | 
			
		||||
                ]
 | 
			
		||||
              }),
 | 
			
		||||
              id: 'polygon',
 | 
			
		||||
              selectedStyleId: 'highlight'
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          actionMode: TMap.tools.constants.EDITOR_ACTION.INTERACT, // 编辑器的工作模式
 | 
			
		||||
          activeOverlayId: 'polygon', // 激活图层
 | 
			
		||||
          selectable: true, // 开启点选功能
 | 
			
		||||
          snappable: true // 开启吸附
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
      })
 | 
			
		||||
      }else {
 | 
			
		||||
        return this.$u.toast('该网格未绘制')
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    getTreeList() {
 | 
			
		||||
      this.$http.post(`/app/appgirdinfo/listAll`).then((res) => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
    getLeafNodes() {
 | 
			
		||||
      this.$http.post(`/app/appgirdinfo/queryGirdMemberGirdsById`).then((res) => {
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          let arr = []
 | 
			
		||||
          this.treeList = res.data
 | 
			
		||||
          res.data.forEach(e => {
 | 
			
		||||
            if (e.points?.length > 0) {
 | 
			
		||||
              arr.push(e.points.map(p => [p.lng, p.lat]))
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
          this.renderGridMap(arr)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    view() {
 | 
			
		||||
      this.show = true
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    renderGridMap(paths, count = 0) {
 | 
			
		||||
      let {map, lib: TMap, $refs: {AiTMap: {fitBounds}}} = this
 | 
			
		||||
      if (TMap) {
 | 
			
		||||
        const colors = ["#A194F4", "#7CBDF3", "#F3A57D", "#62D063", "#58DBDA", "#F7D151"]
 | 
			
		||||
        if (this.polygons.length > 0) {
 | 
			
		||||
          this.polygons.forEach(e => e.destroy())
 | 
			
		||||
          this.polygons = []
 | 
			
		||||
        }
 | 
			
		||||
        let bounds = []
 | 
			
		||||
        paths.forEach((path, i) => {
 | 
			
		||||
          let color = colors[i % colors.length]
 | 
			
		||||
          let polygon = new TMap.MultiPolygon({
 | 
			
		||||
            map, styles: {
 | 
			
		||||
              default: new TMap.PolygonStyle({
 | 
			
		||||
                showBorder: true,
 | 
			
		||||
                borderColor: color,
 | 
			
		||||
                borderWidth: 2,
 | 
			
		||||
                color: this.$colorUtils.Hex2RGBA(color, 0.1),
 | 
			
		||||
                borderDashArray: [10, 10]
 | 
			
		||||
              })
 | 
			
		||||
            },
 | 
			
		||||
            geometries: [{paths: path.map(e => new TMap.LatLng(e[1], e[0]))}]
 | 
			
		||||
          })
 | 
			
		||||
          this.polygons.push(polygon)
 | 
			
		||||
          bounds.push(fitBounds(path.map(e => new TMap.LatLng(e[1], e[0]))))
 | 
			
		||||
        })
 | 
			
		||||
        bounds = bounds.reduce((a, b) => {
 | 
			
		||||
          return fitBounds([
 | 
			
		||||
            a.getNorthEast(),
 | 
			
		||||
            a.getSouthWest(),
 | 
			
		||||
            b.getNorthEast(),
 | 
			
		||||
            b.getSouthWest(),
 | 
			
		||||
          ]);
 | 
			
		||||
        });
 | 
			
		||||
        map.fitBounds(bounds, {padding: 100})
 | 
			
		||||
      } else {
 | 
			
		||||
        if (count < 5) {
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            this.renderGridMap(paths, ++count)
 | 
			
		||||
          }, 1000)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    callPhone(phone) {
 | 
			
		||||
      uni.makePhoneCall({phoneNumber: phone})
 | 
			
		||||
    },
 | 
			
		||||
    handleSelect(e) {
 | 
			
		||||
      if (e?.points?.length > 0) {
 | 
			
		||||
        this.form = e
 | 
			
		||||
        let path = e.points?.map(p => [p.lng, p.lat]) || []
 | 
			
		||||
        this.renderGridMap([path])
 | 
			
		||||
      } else {
 | 
			
		||||
        this.$u.toast("所选网格没有标绘!")
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
::v-deep uni-page-body{
 | 
			
		||||
::v-deep uni-page-body {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
ai-tree-picker{
 | 
			
		||||
 | 
			
		||||
ai-tree-picker {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.detail {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  .grid-select{
 | 
			
		||||
 | 
			
		||||
  .grid-select {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    padding: 34px 32px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
@@ -157,32 +163,39 @@ ai-tree-picker{
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    line-height: 44px;
 | 
			
		||||
    color: #333;
 | 
			
		||||
    .label{
 | 
			
		||||
 | 
			
		||||
    .label {
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      width: 140px;
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
    }
 | 
			
		||||
    .value{
 | 
			
		||||
 | 
			
		||||
    .value {
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
      .u-icon{
 | 
			
		||||
 | 
			
		||||
      .u-icon {
 | 
			
		||||
        margin-left: 8px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .map-content{
 | 
			
		||||
 | 
			
		||||
  .map-content {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: calc(100% - 112px);
 | 
			
		||||
  }
 | 
			
		||||
  .popup{
 | 
			
		||||
 | 
			
		||||
  .popup {
 | 
			
		||||
    padding: 0 32px 16px;
 | 
			
		||||
    .bg{
 | 
			
		||||
 | 
			
		||||
    .bg {
 | 
			
		||||
      width: 64px;
 | 
			
		||||
      height: 10px;
 | 
			
		||||
      background: #CCC;
 | 
			
		||||
      border-radius: 6px;
 | 
			
		||||
      margin: 32px 0 32px 344px;
 | 
			
		||||
    }
 | 
			
		||||
    .title{
 | 
			
		||||
 | 
			
		||||
    .title {
 | 
			
		||||
      font-size: 36px;
 | 
			
		||||
      font-family: PingFang-SC-Heavy, PingFang-SC;
 | 
			
		||||
      font-weight: 800;
 | 
			
		||||
@@ -190,22 +203,26 @@ ai-tree-picker{
 | 
			
		||||
      line-height: 50px;
 | 
			
		||||
      margin-bottom: 24px;
 | 
			
		||||
    }
 | 
			
		||||
    .info-flex{
 | 
			
		||||
 | 
			
		||||
    .info-flex {
 | 
			
		||||
      padding: 26px 0 30px 0;
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      border-bottom: 1px solid #D8DDE6;
 | 
			
		||||
      line-height: 40px;
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
      .label{
 | 
			
		||||
 | 
			
		||||
      .label {
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        width: 160px;
 | 
			
		||||
        font-weight: 800;
 | 
			
		||||
        color: #333;
 | 
			
		||||
      }
 | 
			
		||||
      .value{
 | 
			
		||||
 | 
			
		||||
      .value {
 | 
			
		||||
        color: #666;
 | 
			
		||||
        font-size: 26px;
 | 
			
		||||
        .phone-icon{
 | 
			
		||||
 | 
			
		||||
        .phone-icon {
 | 
			
		||||
          width: 40px;
 | 
			
		||||
          height: 40px;
 | 
			
		||||
          vertical-align: sub;
 | 
			
		||||
@@ -215,10 +232,12 @@ ai-tree-picker{
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.grid-name{
 | 
			
		||||
 | 
			
		||||
.grid-name {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
.footer{
 | 
			
		||||
 | 
			
		||||
.footer {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
@@ -231,10 +250,11 @@ ai-tree-picker{
 | 
			
		||||
  height: 112px;
 | 
			
		||||
  line-height: 112px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  .btn{
 | 
			
		||||
 | 
			
		||||
  .btn {
 | 
			
		||||
    flex: 2;
 | 
			
		||||
    background: #1365DD;
 | 
			
		||||
    color: #FFF;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,6 @@ const calcAge = (code) => {
 | 
			
		||||
  return Math.ceil($moment().year() - $moment(birthday).year())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  dict,
 | 
			
		||||
  confirm,
 | 
			
		||||
@@ -52,5 +51,27 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  hideLoading: () => {
 | 
			
		||||
    uni.hideLoading()
 | 
			
		||||
  },
 | 
			
		||||
  colorUtils: {
 | 
			
		||||
    Hex2RGBA(color, alpha = 1) {
 | 
			
		||||
      let hex = 0;
 | 
			
		||||
      if (color.charAt(0) == "#") {
 | 
			
		||||
        if (color.length == 4) {
 | 
			
		||||
          //检测诸如#FFF简写格式
 | 
			
		||||
          color = "#" + color.charAt(1).repeat(2) +
 | 
			
		||||
              color.charAt(2).repeat(2) +
 | 
			
		||||
              color.charAt(3).repeat(2);
 | 
			
		||||
        }
 | 
			
		||||
        hex = parseInt(color.slice(1), 16);
 | 
			
		||||
      }
 | 
			
		||||
      let r = hex >> 16 & 0xFF;
 | 
			
		||||
      let g = hex >> 8 & 0xFF;
 | 
			
		||||
      let b = hex & 0xFF;
 | 
			
		||||
      return `rgba(${r},${g},${b},${alpha})`;
 | 
			
		||||
    },
 | 
			
		||||
    RGBtoHex(r, g, b) {
 | 
			
		||||
      let hex = r << 16 | g << 8 | b;
 | 
			
		||||
      return "#" + hex.toString(16);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -59,10 +59,10 @@ export default {
 | 
			
		||||
      this.$emit('update:map', this.tmap)
 | 
			
		||||
      this.areaId && this.getMapArea()
 | 
			
		||||
    },
 | 
			
		||||
    getMapArea() {
 | 
			
		||||
      let {mapLib, areaId, tmap: map} = this, keyword = areaId.substring(0, 6)
 | 
			
		||||
      const fitBounds = (latLngList) => {
 | 
			
		||||
        // 由多边形顶点坐标数组计算能完整呈现该多边形的最小矩形范围
 | 
			
		||||
    fitBounds(latLngList, count = 0) {
 | 
			
		||||
      // 由多边形顶点坐标数组计算能完整呈现该多边形的最小矩形范围
 | 
			
		||||
      let {mapLib: TMap} = this
 | 
			
		||||
      if (TMap) {
 | 
			
		||||
        if (latLngList.length === 0) {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
@@ -80,7 +80,14 @@ export default {
 | 
			
		||||
            new TMap.LatLng(boundsS, boundsW),
 | 
			
		||||
            new TMap.LatLng(boundsN, boundsE)
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        if (count < 5) {
 | 
			
		||||
          this.fitBounds(latLngList, ++count)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    getMapArea() {
 | 
			
		||||
      let {mapLib, areaId, tmap: map} = this, keyword = areaId.substring(0, 6)
 | 
			
		||||
      let polygons = new TMap.MultiPolygon({map, geometries: []});
 | 
			
		||||
      new mapLib.service.District({
 | 
			
		||||
        polygon: 2,
 | 
			
		||||
@@ -93,14 +100,14 @@ export default {
 | 
			
		||||
            level.forEach((place) => {
 | 
			
		||||
              let bounds = [];
 | 
			
		||||
              let newGeometries = place.polygon.map((polygon, index) => {
 | 
			
		||||
                bounds.push(fitBounds(polygon)); // 计算能完整呈现行政区边界的最小矩形范围
 | 
			
		||||
                bounds.push(this.fitBounds(polygon)); // 计算能完整呈现行政区边界的最小矩形范围
 | 
			
		||||
                return {
 | 
			
		||||
                  id: `${place.id}_${index}`,
 | 
			
		||||
                  paths: polygon, // 将得到的行政区划边界用多边形标注在地图上
 | 
			
		||||
                };
 | 
			
		||||
              });
 | 
			
		||||
              bounds = bounds.reduce((a, b) => {
 | 
			
		||||
                return fitBounds([
 | 
			
		||||
                return this.fitBounds([
 | 
			
		||||
                  a.getNorthEast(),
 | 
			
		||||
                  a.getSouthWest(),
 | 
			
		||||
                  b.getNorthEast(),
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user