609 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			609 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<template>
 | 
						||
  <div class="searchMap">
 | 
						||
    <div class="grid-input">
 | 
						||
      <img src="./img/back-icon.png" alt="" class="back-icon" v-if="name && show" @click="show=false">
 | 
						||
      <img src="./img/search-icon.png" alt="" class="search-icon" v-else>
 | 
						||
      <input type="text" class="input" placeholder="请输入姓名、房屋信息" v-model="name" maxlength="10" confirm-type="search"
 | 
						||
             @confirm="search"/>
 | 
						||
      <div class="clear-btn">
 | 
						||
        <img src="./img/del-icon.png" alt="" class="del-icon" v-if="name" @click="clear">
 | 
						||
      </div>
 | 
						||
      <span class="search-btn" @click="search">搜索</span>
 | 
						||
    </div>
 | 
						||
    <div class="search-list" v-if="show">
 | 
						||
      <div class="title border">
 | 
						||
        <img src="./img/search-icon.png" alt="" class="search-icon">{{ name }}
 | 
						||
      </div>
 | 
						||
      <div class="item border" v-for="(item, index) in buildList" :key="index" @click="getBuildingInfo(item)">
 | 
						||
        <img src="./img/user-icon.png" alt="" class="search-icon user-icon">
 | 
						||
        <div class="item-content">
 | 
						||
          <h3>{{ item.residentName }}</h3>
 | 
						||
          <p>{{ item.areaName || '' }}{{ item.createAddress }}</p>
 | 
						||
        </div>
 | 
						||
      </div>
 | 
						||
    </div>
 | 
						||
    <div class="build-btn" @click="toList()">
 | 
						||
      <img src="./img/build-icon.png" alt=""> 楼栋<br/>列表
 | 
						||
    </div>
 | 
						||
    <div class="map-content">
 | 
						||
      <AiTMap v-if="areaId" :areaId="areaId" :map.sync="map" :lib.sync="lib" :ops="ops"
 | 
						||
              :libraries="['service', 'tools']"/>
 | 
						||
    </div>
 | 
						||
    <u-popup v-model="showPop" mode="bottom" border-radius="14">
 | 
						||
      <div class="popup">
 | 
						||
        <div class="bg"></div>
 | 
						||
        <div class="title">{{ detailInfo.house.createAddress || '' }}</div>
 | 
						||
        <p class="address">{{ detailInfo.community.address || '' }}</p>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">所属社区</span>
 | 
						||
          <span class="value">{{ detailInfo.build.areaName }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">所属小区</span>
 | 
						||
          <span class="value">{{ detailInfo.build.communityName }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">房屋类型</span>
 | 
						||
          <span class="value">{{ $dict.getLabel('communityBuildingType', detailInfo.house.buildingType) }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">所属网格</span>
 | 
						||
          <span class="value">{{ detailInfo.community.girdName || '' }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">网格管理员</span>
 | 
						||
          <span class="value">{{ detailInfo.build.girdMemberNames || '' }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">楼栋长</span>
 | 
						||
          <span
 | 
						||
              class="value">{{ detailInfo.build.managerName || '' }}  {{
 | 
						||
              detailInfo.build.managerPhone || ''
 | 
						||
            }}
 | 
						||
            <img :src="$cdn + 'common/phone.png'" alt="" @click="callPhone(detailInfo.build.managerPhone)"
 | 
						||
                 class="phone-icon" v-if="detailInfo.build.managerPhone">
 | 
						||
          </span>
 | 
						||
        </div>
 | 
						||
      </div>
 | 
						||
      <div class="popup-btn" @click="toDetail(detailInfo.build.id)">查看楼栋模型</div>
 | 
						||
    </u-popup>
 | 
						||
    <u-popup v-model="buildPopup" mode="bottom" border-radius="14">
 | 
						||
      <div class="popup">
 | 
						||
        <div class="bg"/>
 | 
						||
        <div class="title">{{ building.createAddress || '' }}</div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">所属社区</span>
 | 
						||
          <span class="value">{{ building.areaName }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">所属小区</span>
 | 
						||
          <span class="value">{{ building.communityName }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">房屋类型</span>
 | 
						||
          <span class="value">{{ $dict.getLabel('communityBuildingType', building.buildingType) }}</span>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">所属网格</span>
 | 
						||
          <span class="value" v-text="building.girdName||''"/>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">网格管理员</span>
 | 
						||
          <span class="value" v-text="building.girdMemberNames||''"/>
 | 
						||
        </div>
 | 
						||
        <div class="info-flex">
 | 
						||
          <span class="label">楼栋长</span>
 | 
						||
          <span
 | 
						||
              class="value">{{ building.managerName || '' }}  {{ building.managerPhone || '' }}
 | 
						||
            <img :src="$cdn + 'common/phone.png'" alt="" @click="callPhone(detailInfo.build.managerPhone)"
 | 
						||
                 class="phone-icon" v-if="detailInfo.build.managerPhone">
 | 
						||
          </span>
 | 
						||
        </div>
 | 
						||
      </div>
 | 
						||
      <div class="popup-btn" @click="toDetail(building.id)">查看楼栋模型</div>
 | 
						||
    </u-popup>
 | 
						||
  </div>
 | 
						||
</template>
 | 
						||
 | 
						||
<script>
 | 
						||
import {mapState} from 'vuex'
 | 
						||
 | 
						||
export default {
 | 
						||
  data() {
 | 
						||
    return {
 | 
						||
      latLngCenter: {},
 | 
						||
      areaId: '',
 | 
						||
      ops: {},
 | 
						||
      lib: null,
 | 
						||
      map: null,
 | 
						||
      markerArr: [],
 | 
						||
      show: false,
 | 
						||
      value: '',
 | 
						||
      ClusterBubble: null,
 | 
						||
      name: '',
 | 
						||
      buildList: [],
 | 
						||
      detailInfo: {
 | 
						||
        house: {},
 | 
						||
        build: {},
 | 
						||
        community: {}
 | 
						||
      },
 | 
						||
      showPop: false,
 | 
						||
      retryMapCount: 0,
 | 
						||
      building: {},
 | 
						||
      buildPopup: false
 | 
						||
    }
 | 
						||
  },
 | 
						||
  computed: {...mapState(['user'])},
 | 
						||
  mounted() {
 | 
						||
    this.areaId = this.user.areaId
 | 
						||
    this.getCenterLatLng().then(points => {
 | 
						||
      this.getMarkerCluster(points)
 | 
						||
    })
 | 
						||
  },
 | 
						||
  onShow() {
 | 
						||
    document.title = "以房找人"
 | 
						||
  },
 | 
						||
  created() {
 | 
						||
    this.$dict.load("communityBuildingType")
 | 
						||
  },
 | 
						||
  methods: {
 | 
						||
    getCenterLatLng() {
 | 
						||
      return this.$http.post(`/app/appdvcpconfig/getCorpLocation`).then(res => {
 | 
						||
        if (res?.data) {
 | 
						||
          this.latLngCenter = res.data
 | 
						||
          return this.getCommunityList()
 | 
						||
        }
 | 
						||
      })
 | 
						||
    },
 | 
						||
    getCommunityList() {
 | 
						||
      return this.$http.post('/app/appcommunitybuildinginfo/listByBuilding', null, {
 | 
						||
        params: {
 | 
						||
          current: 1,
 | 
						||
          size: 1000000,
 | 
						||
          areaId: this.user.areaId
 | 
						||
        }
 | 
						||
      }).then(res => {
 | 
						||
        if (res?.data) {
 | 
						||
          this.buildList = res.data
 | 
						||
          return res.data.map(item => {
 | 
						||
            return {
 | 
						||
              ...item,
 | 
						||
              lnglat: [item.lng, item.lat],
 | 
						||
              buildingNumber: item.name || item.buildingNumber,
 | 
						||
              communityName: item.name || item.communityName,
 | 
						||
            }
 | 
						||
          })
 | 
						||
        }
 | 
						||
      })
 | 
						||
    },
 | 
						||
    getMarkerCluster(points, count = 0) {
 | 
						||
      let {lib: TMap, map} = this
 | 
						||
      if (map) {
 | 
						||
        map.setCenter(this.latLngCenter)
 | 
						||
        let MarkerCluster = new TMap.MarkerCluster({
 | 
						||
          map, gridSize: 60,
 | 
						||
          enableDefaultStyle: false, // 关闭默认样式
 | 
						||
          geometries: points?.map(e => ({
 | 
						||
            position: new TMap.LatLng(e.lat, e.lng),
 | 
						||
            content: `${e.createAddress} | ${e.houseNum}户`,
 | 
						||
            properties: {...e}
 | 
						||
          })) || [],
 | 
						||
          zoomOnClick: true
 | 
						||
        })
 | 
						||
        let geometries = [], marker, markers = []
 | 
						||
        MarkerCluster.on('cluster_changed', () => {
 | 
						||
          if (markers.length) {
 | 
						||
            markers.forEach(function (item) {
 | 
						||
              item.destroy();
 | 
						||
            })
 | 
						||
            markers = [];
 | 
						||
          }
 | 
						||
          geometries = []
 | 
						||
          let clusters = MarkerCluster.getClusters()
 | 
						||
          clusters.forEach((item) => {
 | 
						||
            if (item.geometries.length > 1) {
 | 
						||
              //聚合样式
 | 
						||
              geometries.push({
 | 
						||
                styleId: 'cluster',
 | 
						||
                position: item.center,
 | 
						||
                properties: {...item},
 | 
						||
                content: item.geometries.length.toString() || "0"
 | 
						||
              })
 | 
						||
            } else {
 | 
						||
              //点标记样式
 | 
						||
              // 创建气泡DOM元素
 | 
						||
              class ClusterBubble extends TMap.DOMOverlay {
 | 
						||
                constructor(options) {
 | 
						||
                  super(options);
 | 
						||
                }
 | 
						||
 | 
						||
                onInit(options) {
 | 
						||
                  this.content = options.content;
 | 
						||
                  this.position = options.position;
 | 
						||
                };
 | 
						||
 | 
						||
                onDestroy() {
 | 
						||
                  this.dom.removeEventListener('click', this.onClick);
 | 
						||
                  this.removeAllListeners();
 | 
						||
                }
 | 
						||
 | 
						||
                createDOM() {
 | 
						||
                  let dom = document.createElement('div');
 | 
						||
                  dom.classList.add('marker');
 | 
						||
                  dom.innerText = this.content;
 | 
						||
 | 
						||
                  // 监听点击事件,实现zoomOnClick
 | 
						||
                  this.onClick = this.onClick.bind(this);
 | 
						||
                  // pc端注册click事件,移动端注册touchend事件
 | 
						||
                  dom.addEventListener('click', this.onClick);
 | 
						||
                  dom.addEventListener('touchend', this.onClick);
 | 
						||
                  return dom;
 | 
						||
                };
 | 
						||
 | 
						||
                updateDOM() {
 | 
						||
                  if (!this.map) {
 | 
						||
                    return;
 | 
						||
                  }
 | 
						||
                  // 经纬度坐标转容器像素坐标
 | 
						||
                  let pixel = this.map.projectToContainer(this.position);
 | 
						||
 | 
						||
                  // 使文本框中心点对齐经纬度坐标点
 | 
						||
                  let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
 | 
						||
                  let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
 | 
						||
                  this.dom.style.transform = `translate(${left}, ${top})`;
 | 
						||
                  this.emit('dom_updated');
 | 
						||
                };
 | 
						||
 | 
						||
                onClick() {
 | 
						||
                  this.emit('click');
 | 
						||
                }
 | 
						||
              }
 | 
						||
 | 
						||
              let {content} = item.geometries?.[0] || {},
 | 
						||
                  overlay = new ClusterBubble({map, position: item.center, content})
 | 
						||
              overlay.on('click', () => {
 | 
						||
                this.buildPopup = true
 | 
						||
                this.building = item.geometries?.[0]?.properties || {}
 | 
						||
                console.log(this.building)
 | 
						||
              })
 | 
						||
              markers.push(overlay)
 | 
						||
            }
 | 
						||
          });
 | 
						||
          if (marker) {
 | 
						||
            marker.setGeometries(geometries)
 | 
						||
          } else {
 | 
						||
            marker = new TMap.MultiMarker({
 | 
						||
              map, enableCollision: true, geometries,
 | 
						||
              styles: {
 | 
						||
                cluster: new TMap.MarkerStyle({
 | 
						||
                  width: 48,
 | 
						||
                  height: 48,
 | 
						||
                  anchor: {x: 24, y: 24},
 | 
						||
                  src: this.$cdn + "/map/cluster.png",
 | 
						||
                  color: '#fff',
 | 
						||
                  // direction: 'center',
 | 
						||
                  size: 18
 | 
						||
                })
 | 
						||
              },
 | 
						||
            })
 | 
						||
            marker.on('click', (e) => {
 | 
						||
              let {bounds} = e.geometry.properties
 | 
						||
              map.fitBounds(bounds)
 | 
						||
            })
 | 
						||
          }
 | 
						||
        })
 | 
						||
        return Promise.resolve()
 | 
						||
      } else {
 | 
						||
        if (count < 5) {
 | 
						||
          setTimeout(() => {
 | 
						||
            return this.getMarkerCluster(points, ++count)
 | 
						||
          }, 1000)
 | 
						||
        } else Promise.reject("加载失败")
 | 
						||
      }
 | 
						||
    },
 | 
						||
    clear() {
 | 
						||
      this.name = ''
 | 
						||
    },
 | 
						||
    search() {
 | 
						||
      this.buildList = []
 | 
						||
      this.$http.post('/app/appcommunityhouseinfo/queryHouseByName', null, {
 | 
						||
        params: {
 | 
						||
          current: 1,
 | 
						||
          size: 20,
 | 
						||
          areaId: this.user.areaId,
 | 
						||
          name: this.name
 | 
						||
        }
 | 
						||
      }).then(res => {
 | 
						||
        if (res.code == 0 && res.data.length) {
 | 
						||
          this.show = true
 | 
						||
          this.buildList = res.data
 | 
						||
          const points = res.data.map(item => {
 | 
						||
            return {
 | 
						||
              lnglat: [item.lng, item.lat],
 | 
						||
              id: item.id,
 | 
						||
              corpId: item.corpId,
 | 
						||
              areaName: item.areaName,
 | 
						||
              buildingNumber: item.name || item.buildingNumber,
 | 
						||
              communityName: item.name || item.communityName,
 | 
						||
            }
 | 
						||
          })
 | 
						||
          this.getMarkerCluster(points)
 | 
						||
        } else {
 | 
						||
          this.show = false
 | 
						||
          this.$u.toast('未搜索到结果,请换个关键字重试!')
 | 
						||
        }
 | 
						||
      })
 | 
						||
    },
 | 
						||
    getBuildingInfo(item) {
 | 
						||
      this.$http.post(`/app/appcommunityhouseinfo/queryDetailByIdWithBuilding?buildId=${item.buildingId}&houseId=${item.id}`).then(res => {
 | 
						||
        if (res?.data) {
 | 
						||
          this.show = false
 | 
						||
          this.showPop = true
 | 
						||
          this.detailInfo = res.data
 | 
						||
        }
 | 
						||
      })
 | 
						||
    },
 | 
						||
    toList() {
 | 
						||
      uni.navigateTo({url: './list'})
 | 
						||
    },
 | 
						||
    callPhone(phone) {
 | 
						||
      uni.makePhoneCall({phoneNumber: phone})
 | 
						||
    },
 | 
						||
    toDetail(id) {
 | 
						||
      uni.navigateTo({url: `./detail?id=${id}`})
 | 
						||
    },
 | 
						||
  }
 | 
						||
}
 | 
						||
</script>
 | 
						||
 | 
						||
<style lang="scss" scoped>
 | 
						||
.searchMap {
 | 
						||
  height: 100vh;
 | 
						||
 | 
						||
  .grid-input {
 | 
						||
    width: calc(100% - 64px);
 | 
						||
    height: 88px;
 | 
						||
    background: #FFF;
 | 
						||
    box-shadow: 0 4px 8px 0 rgba(192, 185, 185, 0.5);
 | 
						||
    border-radius: 16px;
 | 
						||
    position: fixed;
 | 
						||
    top: 24px;
 | 
						||
    left: 50%;
 | 
						||
    transform: translateX(-50%);
 | 
						||
    z-index: 99999;
 | 
						||
    padding: 16px 20px;
 | 
						||
    box-sizing: border-box;
 | 
						||
 | 
						||
    .search-icon {
 | 
						||
      width: 48px;
 | 
						||
      height: 48px;
 | 
						||
      margin-right: 16px;
 | 
						||
    }
 | 
						||
 | 
						||
    .input {
 | 
						||
      display: inline-block;
 | 
						||
      padding: 8px 0;
 | 
						||
      height: 32px;
 | 
						||
      line-height: 32px;
 | 
						||
      width: calc(100% - 220px);
 | 
						||
      font-size: 28px;
 | 
						||
      font-family: MicrosoftYaHei;
 | 
						||
      color: #666;
 | 
						||
    }
 | 
						||
 | 
						||
    .back-icon {
 | 
						||
      width: 16px;
 | 
						||
      height: 32px;
 | 
						||
      margin-right: 24px;
 | 
						||
      vertical-align: super;
 | 
						||
    }
 | 
						||
 | 
						||
    .clear-btn {
 | 
						||
      display: inline-block;
 | 
						||
      width: 32px;
 | 
						||
      height: 32px;
 | 
						||
      margin-right: 30px;
 | 
						||
    }
 | 
						||
 | 
						||
    .del-icon {
 | 
						||
      width: 32px;
 | 
						||
      height: 32px;
 | 
						||
      vertical-align: super;
 | 
						||
    }
 | 
						||
 | 
						||
    .search-btn {
 | 
						||
      display: inline-block;
 | 
						||
      width: 80px;
 | 
						||
      height: 32px;
 | 
						||
      line-height: 32px;
 | 
						||
      text-align: right;
 | 
						||
      font-size: 28px;
 | 
						||
      font-family: MicrosoftYaHei;
 | 
						||
      color: #1365DD;
 | 
						||
      border-left: 1px solid #DEDFE0;
 | 
						||
      vertical-align: top;
 | 
						||
      margin-top: 12px;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  .search-list {
 | 
						||
    position: fixed;
 | 
						||
    width: 100%;
 | 
						||
    height: calc(100% - 130px);
 | 
						||
    overflow-y: scroll;
 | 
						||
    top: 128px;
 | 
						||
    left: 0;
 | 
						||
    box-sizing: border-box;
 | 
						||
    z-index: 99999;
 | 
						||
 | 
						||
    .search-icon {
 | 
						||
      width: 36px;
 | 
						||
      height: 36px;
 | 
						||
      margin-right: 16px;
 | 
						||
      vertical-align: sub;
 | 
						||
    }
 | 
						||
 | 
						||
    .title {
 | 
						||
      height: 82px;
 | 
						||
      line-height: 82px;
 | 
						||
      font-size: 26px;
 | 
						||
      font-family: MicrosoftYaHeiSemibold;
 | 
						||
      color: #1365DD;
 | 
						||
      padding-left: 44px;
 | 
						||
      background-color: #fff;
 | 
						||
    }
 | 
						||
 | 
						||
    .item {
 | 
						||
      padding: 22px 44px 24px 44px;
 | 
						||
      background-color: #fff;
 | 
						||
    }
 | 
						||
 | 
						||
    .item-content {
 | 
						||
      display: inline-block;
 | 
						||
      width: 610px;
 | 
						||
      color: #333;
 | 
						||
 | 
						||
      h3 {
 | 
						||
        font-size: 28px;
 | 
						||
        font-family: MicrosoftYaHeiSemibold;
 | 
						||
        line-height: 32px;
 | 
						||
        margin-bottom: 8px;
 | 
						||
      }
 | 
						||
 | 
						||
      p {
 | 
						||
        width: 100%;
 | 
						||
        font-size: 24px;
 | 
						||
        font-family: MicrosoftYaHei;
 | 
						||
        line-height: 32px;
 | 
						||
        overflow: hidden;
 | 
						||
        white-space: nowrap;
 | 
						||
        text-overflow: ellipsis;
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    .user-icon {
 | 
						||
      vertical-align: top;
 | 
						||
    }
 | 
						||
 | 
						||
    .border {
 | 
						||
      border-bottom: 1px solid #DEDFE1;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  .build-btn {
 | 
						||
    width: 80px;
 | 
						||
    height: 160px;
 | 
						||
    background: #FFF;
 | 
						||
    box-shadow: 0 4px 8px 0 rgba(138, 138, 138, 0.5);
 | 
						||
    border-radius: 8px;
 | 
						||
    position: fixed;
 | 
						||
    bottom: 136px;
 | 
						||
    right: 24px;
 | 
						||
    z-index: 99999;
 | 
						||
    padding: 16px 16px 0;
 | 
						||
    box-sizing: border-box;
 | 
						||
    font-size: 24px;
 | 
						||
    font-family: PingFangSC-Medium, PingFang SC;
 | 
						||
    font-weight: 500;
 | 
						||
    color: #666;
 | 
						||
    line-height: 30px;
 | 
						||
 | 
						||
    img {
 | 
						||
      width: 48px;
 | 
						||
      height: 48px;
 | 
						||
      margin-bottom: 8px;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  .map-content {
 | 
						||
    width: 100%;
 | 
						||
    height: 100%;
 | 
						||
  }
 | 
						||
 | 
						||
  .popup {
 | 
						||
    padding: 0 32px 16px;
 | 
						||
 | 
						||
    .bg {
 | 
						||
      width: 64px;
 | 
						||
      height: 10px;
 | 
						||
      background: #CCC;
 | 
						||
      border-radius: 6px;
 | 
						||
      margin: 32px 0 32px 344px;
 | 
						||
    }
 | 
						||
 | 
						||
    .title {
 | 
						||
      font-size: 36px;
 | 
						||
      font-family: PingFang-SC-Heavy, PingFang-SC;
 | 
						||
      font-weight: 800;
 | 
						||
      color: #333;
 | 
						||
      line-height: 50px;
 | 
						||
      margin-bottom: 24px;
 | 
						||
    }
 | 
						||
 | 
						||
    .info-flex {
 | 
						||
      padding: 26px 0 30px 0;
 | 
						||
      width: 100%;
 | 
						||
      border-bottom: 1px solid #D8DDE6;
 | 
						||
      line-height: 40px;
 | 
						||
      font-size: 28px;
 | 
						||
 | 
						||
      .label {
 | 
						||
        display: inline-block;
 | 
						||
        width: 160px;
 | 
						||
        font-weight: 800;
 | 
						||
        color: #333;
 | 
						||
      }
 | 
						||
 | 
						||
      .value {
 | 
						||
        color: #666;
 | 
						||
        font-size: 26px;
 | 
						||
 | 
						||
        .phone-icon {
 | 
						||
          width: 40px;
 | 
						||
          height: 40px;
 | 
						||
          vertical-align: sub;
 | 
						||
          margin-left: 16px;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  .popup-btn {
 | 
						||
    width: 100%;
 | 
						||
    font-size: 32px;
 | 
						||
    font-family: PingFangSC-Medium, PingFang SC;
 | 
						||
    font-weight: 500;
 | 
						||
    height: 112px;
 | 
						||
    line-height: 112px;
 | 
						||
    text-align: center;
 | 
						||
    background: #1365DD;
 | 
						||
    color: #FFF;
 | 
						||
  }
 | 
						||
 | 
						||
  ::v-deep.marker {
 | 
						||
    color: #fff;
 | 
						||
    background: #5088FF;
 | 
						||
    padding: 0 32px;
 | 
						||
    width: fit-content;
 | 
						||
    height: 56px;
 | 
						||
    border-radius: 52px;
 | 
						||
    transform: translate(-50%, -50%);
 | 
						||
    display: flex;
 | 
						||
    align-items: center;
 | 
						||
 | 
						||
    &:before {
 | 
						||
      content: " ";
 | 
						||
      display: block;
 | 
						||
      position: absolute;
 | 
						||
      bottom: 0;
 | 
						||
      left: 50%;
 | 
						||
      width: 0;
 | 
						||
      height: 0;
 | 
						||
      transform: translate(-50%, 100%);
 | 
						||
      border: 12px solid transparent;
 | 
						||
      border-top-color: #5088FF;
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
</style>
 |