地区组件改造完成
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <section class="AiAreaPicker">
 | 
			
		||||
    <ai-search-popup mode="bottom" ref="areaSelector">
 | 
			
		||||
    <ai-search-popup mode="bottom" ref="areaSelector" length="85%">
 | 
			
		||||
      <div slot="btn" @tap="handleInit">
 | 
			
		||||
        <slot v-if="$slots.default"/>
 | 
			
		||||
        <div v-else class="areaSelector">
 | 
			
		||||
@@ -10,14 +10,31 @@
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="areaSelector">
 | 
			
		||||
        <div class="fixedTop">
 | 
			
		||||
          <span v-for="(area, i) in fullArea" :key="area.id" v-text="area.name" :class="{ current: area.id == index }"
 | 
			
		||||
                @click="selectNode(area, i)"/>
 | 
			
		||||
          <b>选择地区</b>
 | 
			
		||||
          <em>选择区域</em>
 | 
			
		||||
          <div class="selectedArea" v-if="hasSelected">
 | 
			
		||||
            <p v-for="area in fullArea" :key="area.id" v-text="area.name"/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div/>
 | 
			
		||||
          <span v-if="all" v-text="`全国`" @click="selectNode({}, -1)"/>
 | 
			
		||||
          <span v-for="(area,i) in fullArea" :key="area.id" v-text="area.levelLabel" @click="selectNode(area, i)"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <span v-text="currentArea.name"/>
 | 
			
		||||
        <!--用来作为占位的-->
 | 
			
		||||
        <div class="fixedPlaceholder">
 | 
			
		||||
          <b>选择地区</b>
 | 
			
		||||
          <em>选择区域</em>
 | 
			
		||||
          <div class="selectedArea" v-if="hasSelected"/>
 | 
			
		||||
          <span v-text="'行政区域'"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!--end-->
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="pendingItem flexRow" flex v-for="op in list" :key="op.id">
 | 
			
		||||
        <div class="fill" :class="{ self: index == op.id }" v-html="op.name" @tap="handleSelect(op)"/>
 | 
			
		||||
        <u-icon v-if="index != op.id" name="arrow-right" color="#ddd" @click="getChild(op)"/>
 | 
			
		||||
      <div class="pendingItem flexRow" flex v-for="op in pending" :key="op.id" @tap="getChild(op)">
 | 
			
		||||
        <div class="fill" :class="{ self: index == op.id }" v-html="op.name"/>
 | 
			
		||||
        <u-icon v-if="index == op.id" name="checkbox-mark" color="#4181FF"/>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="bottomBtns">
 | 
			
		||||
        <div @click="closePopup">取消</div>
 | 
			
		||||
        <div class="primary fill" @click="handleSelect(currentArea)">确定</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </ai-search-popup>
 | 
			
		||||
  </section>
 | 
			
		||||
@@ -57,12 +74,19 @@ export default {
 | 
			
		||||
    locationIcon() {
 | 
			
		||||
      return this.$cdn + this.icon
 | 
			
		||||
    },
 | 
			
		||||
    pending() {
 | 
			
		||||
      return this.list.map(e => ({...e, levelLabel: this.levelLabels[e.type]}))
 | 
			
		||||
    },
 | 
			
		||||
    hasSelected() {
 | 
			
		||||
      return this.fullArea?.length > 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      fullArea: [{name: '全部', id: 0}],
 | 
			
		||||
      fullArea: [],
 | 
			
		||||
      index: '',
 | 
			
		||||
      list: [],
 | 
			
		||||
      levelLabels: ["省", "市", "县/区", "镇/街道", "村/社区"]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
@@ -73,31 +97,28 @@ export default {
 | 
			
		||||
  methods: {
 | 
			
		||||
    getFullArea() {
 | 
			
		||||
      let areaId = this.areaId || (this.all ? '' : this.$areaId)
 | 
			
		||||
      areaId &&
 | 
			
		||||
      this.$http
 | 
			
		||||
      .post('/admin/area/getAllParentAreaId', null, {
 | 
			
		||||
      return areaId && this.$http.post('/admin/area/getAllParentAreaId', null, {
 | 
			
		||||
        withoutToken: true,
 | 
			
		||||
        params: {areaId},
 | 
			
		||||
      })
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
      }).then((res) => {
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          res.data.forEach(e => {
 | 
			
		||||
            e.levelLabel = this.levelLabels[e.type]
 | 
			
		||||
          })
 | 
			
		||||
          if (res.data.length > 1) {
 | 
			
		||||
            this.fullArea = res.data.reverse().slice(this.dataRange)
 | 
			
		||||
          } else {
 | 
			
		||||
            this.fullArea = res.data
 | 
			
		||||
          }
 | 
			
		||||
          this.fullArea.unshift({name: '全部', id: 0})
 | 
			
		||||
          return this.fullArea
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getChildAreas(id) {
 | 
			
		||||
      id &&
 | 
			
		||||
      this.$http
 | 
			
		||||
      .post('/admin/area/queryAreaByParentId', null, {
 | 
			
		||||
      id && this.$http.post('/admin/area/queryAreaByParentId', null, {
 | 
			
		||||
        withoutToken: true,
 | 
			
		||||
        params: {id},
 | 
			
		||||
      })
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
      }).then((res) => {
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          this.list = res.data
 | 
			
		||||
          let self = this.fullArea.find((e) => e.id == this.index)
 | 
			
		||||
@@ -113,18 +134,18 @@ export default {
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleSelect(op) {
 | 
			
		||||
      if (op.id != this.index) {
 | 
			
		||||
        this.fullArea.push(op)
 | 
			
		||||
        this.index = op.id
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit('select', op)
 | 
			
		||||
      this.$emit('update:name', this.currentArea.name)
 | 
			
		||||
      this.$refs.areaSelector?.handleSelect()
 | 
			
		||||
      this.closePopup()
 | 
			
		||||
    },
 | 
			
		||||
    getChild(op) {
 | 
			
		||||
      this.fullArea.push(op)
 | 
			
		||||
      this.index = op.id
 | 
			
		||||
      this.getChildAreas(op.id)
 | 
			
		||||
      if (op.id != this.index) {
 | 
			
		||||
        if (op.type < 5 && (/0{3}$/g.test(this.index)||!this.index)) {
 | 
			
		||||
          this.fullArea.push(op)
 | 
			
		||||
          this.getChildAreas(op.id)
 | 
			
		||||
        }
 | 
			
		||||
        this.index = op.id
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    selectNode(area, i) {
 | 
			
		||||
      this.fullArea.splice(i + 1, this.fullArea.length - i)
 | 
			
		||||
@@ -137,15 +158,16 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    handleInit() {
 | 
			
		||||
      this.index = this.currentArea.id
 | 
			
		||||
      if (this.all && !this.currentArea.id) this.getProvinces()
 | 
			
		||||
      else this.getChildAreas(this.currentArea.id)
 | 
			
		||||
      this.index = this.areaId
 | 
			
		||||
      this.getFullArea().then(() => {
 | 
			
		||||
        if (this.all && !this.currentArea.id) this.getProvinces()
 | 
			
		||||
        else this.getChildAreas(this.currentArea.id)
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.index = this.areaId
 | 
			
		||||
    this.getFullArea()
 | 
			
		||||
  },
 | 
			
		||||
    closePopup() {
 | 
			
		||||
      this.$refs.areaSelector?.handleSelect()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@@ -158,21 +180,57 @@ export default {
 | 
			
		||||
    span {
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      color: #333;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      line-height: 112px;
 | 
			
		||||
      margin-right: 80px;
 | 
			
		||||
      position: relative;
 | 
			
		||||
 | 
			
		||||
      &:first-of-type:before {
 | 
			
		||||
        content: '';
 | 
			
		||||
        padding: 0;
 | 
			
		||||
      }
 | 
			
		||||
      &:last-of-type {
 | 
			
		||||
        margin-right: 0;
 | 
			
		||||
 | 
			
		||||
      &:before {
 | 
			
		||||
        color: #333;
 | 
			
		||||
        content: '/';
 | 
			
		||||
        padding: 0 16px;
 | 
			
		||||
        &:after {
 | 
			
		||||
          content: " ";
 | 
			
		||||
          display: block;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          bottom: -26px;
 | 
			
		||||
          left: 50%;
 | 
			
		||||
          transform: translate(-50%, 100%);
 | 
			
		||||
          width: 40px;
 | 
			
		||||
          height: 8px;
 | 
			
		||||
          background: #4181FF;
 | 
			
		||||
          border-radius: 4px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .current {
 | 
			
		||||
      color: #3f8df5;
 | 
			
		||||
    b {
 | 
			
		||||
      display: block;
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      line-height: 96px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    em {
 | 
			
		||||
      font-style: normal;
 | 
			
		||||
      font-size: 24px;
 | 
			
		||||
      font-weight: 400;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
      line-height: 34px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .selectedArea {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      width: fit-content;
 | 
			
		||||
      padding: 0 32px;
 | 
			
		||||
      height: 80px;
 | 
			
		||||
      background: #ECF2FF;
 | 
			
		||||
      border-radius: 40px;
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      font-family: PingFangSC-Medium, PingFang SC;
 | 
			
		||||
      font-weight: 500;
 | 
			
		||||
      color: #4181FF !important;
 | 
			
		||||
      margin: 16px 0 32px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .fixedTop {
 | 
			
		||||
@@ -184,30 +242,26 @@ export default {
 | 
			
		||||
      border-bottom: 4px solid #f5f5f5;
 | 
			
		||||
      z-index: 1;
 | 
			
		||||
      text-align: start;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
      padding: 0 32px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep.u-drawer-content {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    border-radius: 32px 32px 0 0;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    padding: 0 32px 90px;
 | 
			
		||||
 | 
			
		||||
    .areaSelector {
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      border-bottom: 16px solid #f5f5f5;
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        line-height: 100px;
 | 
			
		||||
      }
 | 
			
		||||
      border-bottom: 1px solid #f5f5f5;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep.pendingItem {
 | 
			
		||||
    color: #333;
 | 
			
		||||
    margin-left: 32px;
 | 
			
		||||
    padding-right: 32px;
 | 
			
		||||
    height: 104px;
 | 
			
		||||
    border-bottom: 1px solid #ddd;
 | 
			
		||||
    text-align: start;
 | 
			
		||||
 | 
			
		||||
    .self {
 | 
			
		||||
@@ -215,6 +269,33 @@ export default {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep.bottomBtns {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    width: 100vw;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    height: 88px;
 | 
			
		||||
    font-size: 34px;
 | 
			
		||||
    font-family: PingFangSC-Medium, PingFang SC;
 | 
			
		||||
    font-weight: 500;
 | 
			
		||||
    color: #3671EE;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
 | 
			
		||||
    & > div {
 | 
			
		||||
      padding: 0 92px;
 | 
			
		||||
      line-height: 88px;
 | 
			
		||||
      border-top: 1px solid #A0C0FF;
 | 
			
		||||
 | 
			
		||||
      &.primary {
 | 
			
		||||
        color: #fff;
 | 
			
		||||
        background: #4181FF;
 | 
			
		||||
        border-color: #4181FF;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .location {
 | 
			
		||||
    width: 28px;
 | 
			
		||||
    height: 80px;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <section class="AiSearchPopup">
 | 
			
		||||
    <u-popup v-model="show" length="100%" closeable :mode="mode">
 | 
			
		||||
    <u-popup v-model="show" :length="length" closeable :mode="mode">
 | 
			
		||||
      <slot v-if="$slots.default"/>
 | 
			
		||||
      <div class="searchPane" v-else>
 | 
			
		||||
        <div class="title">{{ title }}</div>
 | 
			
		||||
@@ -24,7 +24,8 @@ export default {
 | 
			
		||||
    placeholder: {default: "请搜索"},
 | 
			
		||||
    ops: {default: () => ({label: 'label', search: 'name'})},
 | 
			
		||||
    url: String,
 | 
			
		||||
    mode: {default: "right"}
 | 
			
		||||
    mode: {default: "right"},
 | 
			
		||||
    length: {default: "100%"}
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
@@ -33,6 +34,11 @@ export default {
 | 
			
		||||
      list: []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    show(v) {
 | 
			
		||||
      !v && this.$emit('close')
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    getList() {
 | 
			
		||||
      this.url && this.$instance.post(this.url, null, {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								src/main.js
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/main.js
									
									
									
									
									
								
							@@ -33,7 +33,18 @@ const app = new Vue({
 | 
			
		||||
  ...App
 | 
			
		||||
});
 | 
			
		||||
store.dispatch("agentSign").then(config => {
 | 
			
		||||
  store.commit("getConfig", {...config, latlng: [config.lat, config.lng]})
 | 
			
		||||
  app.$mount();
 | 
			
		||||
  const init = (c = 0) => {
 | 
			
		||||
    if (config) {
 | 
			
		||||
      store.commit("getConfig", {...config, latlng: [config.lat, config.lng]})
 | 
			
		||||
      app.$mount();
 | 
			
		||||
    } else {
 | 
			
		||||
      if (c < 5) {
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          init(++c)
 | 
			
		||||
        }, 300)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  init()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user