地区组件改造完成
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <section class="AiAreaPicker">
 | 
					  <section class="AiAreaPicker">
 | 
				
			||||||
    <ai-search-popup mode="bottom" ref="areaSelector">
 | 
					    <ai-search-popup mode="bottom" ref="areaSelector" length="85%">
 | 
				
			||||||
      <div slot="btn" @tap="handleInit">
 | 
					      <div slot="btn" @tap="handleInit">
 | 
				
			||||||
        <slot v-if="$slots.default"/>
 | 
					        <slot v-if="$slots.default"/>
 | 
				
			||||||
        <div v-else class="areaSelector">
 | 
					        <div v-else class="areaSelector">
 | 
				
			||||||
@@ -10,14 +10,31 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="areaSelector">
 | 
					      <div class="areaSelector">
 | 
				
			||||||
        <div class="fixedTop">
 | 
					        <div class="fixedTop">
 | 
				
			||||||
          <span v-for="(area, i) in fullArea" :key="area.id" v-text="area.name" :class="{ current: area.id == index }"
 | 
					          <b>选择地区</b>
 | 
				
			||||||
                @click="selectNode(area, i)"/>
 | 
					          <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>
 | 
					        </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>
 | 
				
			||||||
      <div class="pendingItem flexRow" flex v-for="op in list" :key="op.id">
 | 
					      <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" @tap="handleSelect(op)"/>
 | 
					        <div class="fill" :class="{ self: index == op.id }" v-html="op.name"/>
 | 
				
			||||||
        <u-icon v-if="index != op.id" name="arrow-right" color="#ddd" @click="getChild(op)"/>
 | 
					        <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>
 | 
					      </div>
 | 
				
			||||||
    </ai-search-popup>
 | 
					    </ai-search-popup>
 | 
				
			||||||
  </section>
 | 
					  </section>
 | 
				
			||||||
@@ -57,12 +74,19 @@ export default {
 | 
				
			|||||||
    locationIcon() {
 | 
					    locationIcon() {
 | 
				
			||||||
      return this.$cdn + this.icon
 | 
					      return this.$cdn + this.icon
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    pending() {
 | 
				
			||||||
 | 
					      return this.list.map(e => ({...e, levelLabel: this.levelLabels[e.type]}))
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    hasSelected() {
 | 
				
			||||||
 | 
					      return this.fullArea?.length > 0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      fullArea: [{name: '全部', id: 0}],
 | 
					      fullArea: [],
 | 
				
			||||||
      index: '',
 | 
					      index: '',
 | 
				
			||||||
      list: [],
 | 
					      list: [],
 | 
				
			||||||
 | 
					      levelLabels: ["省", "市", "县/区", "镇/街道", "村/社区"]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  watch: {
 | 
					  watch: {
 | 
				
			||||||
@@ -73,31 +97,28 @@ export default {
 | 
				
			|||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    getFullArea() {
 | 
					    getFullArea() {
 | 
				
			||||||
      let areaId = this.areaId || (this.all ? '' : this.$areaId)
 | 
					      let areaId = this.areaId || (this.all ? '' : this.$areaId)
 | 
				
			||||||
      areaId &&
 | 
					      return areaId && this.$http.post('/admin/area/getAllParentAreaId', null, {
 | 
				
			||||||
      this.$http
 | 
					 | 
				
			||||||
      .post('/admin/area/getAllParentAreaId', null, {
 | 
					 | 
				
			||||||
        withoutToken: true,
 | 
					        withoutToken: true,
 | 
				
			||||||
        params: {areaId},
 | 
					        params: {areaId},
 | 
				
			||||||
      })
 | 
					      }).then((res) => {
 | 
				
			||||||
      .then((res) => {
 | 
					 | 
				
			||||||
        if (res?.data) {
 | 
					        if (res?.data) {
 | 
				
			||||||
 | 
					          res.data.forEach(e => {
 | 
				
			||||||
 | 
					            e.levelLabel = this.levelLabels[e.type]
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
          if (res.data.length > 1) {
 | 
					          if (res.data.length > 1) {
 | 
				
			||||||
            this.fullArea = res.data.reverse().slice(this.dataRange)
 | 
					            this.fullArea = res.data.reverse().slice(this.dataRange)
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            this.fullArea = res.data
 | 
					            this.fullArea = res.data
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          this.fullArea.unshift({name: '全部', id: 0})
 | 
					          return this.fullArea
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getChildAreas(id) {
 | 
					    getChildAreas(id) {
 | 
				
			||||||
      id &&
 | 
					      id && this.$http.post('/admin/area/queryAreaByParentId', null, {
 | 
				
			||||||
      this.$http
 | 
					 | 
				
			||||||
      .post('/admin/area/queryAreaByParentId', null, {
 | 
					 | 
				
			||||||
        withoutToken: true,
 | 
					        withoutToken: true,
 | 
				
			||||||
        params: {id},
 | 
					        params: {id},
 | 
				
			||||||
      })
 | 
					      }).then((res) => {
 | 
				
			||||||
      .then((res) => {
 | 
					 | 
				
			||||||
        if (res?.data) {
 | 
					        if (res?.data) {
 | 
				
			||||||
          this.list = res.data
 | 
					          this.list = res.data
 | 
				
			||||||
          let self = this.fullArea.find((e) => e.id == this.index)
 | 
					          let self = this.fullArea.find((e) => e.id == this.index)
 | 
				
			||||||
@@ -113,18 +134,18 @@ export default {
 | 
				
			|||||||
      })
 | 
					      })
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    handleSelect(op) {
 | 
					    handleSelect(op) {
 | 
				
			||||||
      if (op.id != this.index) {
 | 
					 | 
				
			||||||
        this.fullArea.push(op)
 | 
					 | 
				
			||||||
        this.index = op.id
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      this.$emit('select', op)
 | 
					      this.$emit('select', op)
 | 
				
			||||||
      this.$emit('update:name', this.currentArea.name)
 | 
					      this.$emit('update:name', this.currentArea.name)
 | 
				
			||||||
      this.$refs.areaSelector?.handleSelect()
 | 
					      this.closePopup()
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getChild(op) {
 | 
					    getChild(op) {
 | 
				
			||||||
      this.fullArea.push(op)
 | 
					      if (op.id != this.index) {
 | 
				
			||||||
      this.index = op.id
 | 
					        if (op.type < 5 && (/0{3}$/g.test(this.index)||!this.index)) {
 | 
				
			||||||
      this.getChildAreas(op.id)
 | 
					          this.fullArea.push(op)
 | 
				
			||||||
 | 
					          this.getChildAreas(op.id)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.index = op.id
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    selectNode(area, i) {
 | 
					    selectNode(area, i) {
 | 
				
			||||||
      this.fullArea.splice(i + 1, this.fullArea.length - i)
 | 
					      this.fullArea.splice(i + 1, this.fullArea.length - i)
 | 
				
			||||||
@@ -137,15 +158,16 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    handleInit() {
 | 
					    handleInit() {
 | 
				
			||||||
      this.index = this.currentArea.id
 | 
					      this.index = this.areaId
 | 
				
			||||||
      if (this.all && !this.currentArea.id) this.getProvinces()
 | 
					      this.getFullArea().then(() => {
 | 
				
			||||||
      else this.getChildAreas(this.currentArea.id)
 | 
					        if (this.all && !this.currentArea.id) this.getProvinces()
 | 
				
			||||||
 | 
					        else this.getChildAreas(this.currentArea.id)
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					    closePopup() {
 | 
				
			||||||
  created() {
 | 
					      this.$refs.areaSelector?.handleSelect()
 | 
				
			||||||
    this.index = this.areaId
 | 
					    }
 | 
				
			||||||
    this.getFullArea()
 | 
					  }
 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -158,21 +180,57 @@ export default {
 | 
				
			|||||||
    span {
 | 
					    span {
 | 
				
			||||||
      cursor: pointer;
 | 
					      cursor: pointer;
 | 
				
			||||||
      color: #333;
 | 
					      color: #333;
 | 
				
			||||||
 | 
					      font-weight: bold;
 | 
				
			||||||
 | 
					      line-height: 112px;
 | 
				
			||||||
 | 
					      margin-right: 80px;
 | 
				
			||||||
 | 
					      position: relative;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:first-of-type:before {
 | 
					      &:last-of-type {
 | 
				
			||||||
        content: '';
 | 
					        margin-right: 0;
 | 
				
			||||||
        padding: 0;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:before {
 | 
					        &:after {
 | 
				
			||||||
        color: #333;
 | 
					          content: " ";
 | 
				
			||||||
        content: '/';
 | 
					          display: block;
 | 
				
			||||||
        padding: 0 16px;
 | 
					          position: absolute;
 | 
				
			||||||
 | 
					          bottom: -26px;
 | 
				
			||||||
 | 
					          left: 50%;
 | 
				
			||||||
 | 
					          transform: translate(-50%, 100%);
 | 
				
			||||||
 | 
					          width: 40px;
 | 
				
			||||||
 | 
					          height: 8px;
 | 
				
			||||||
 | 
					          background: #4181FF;
 | 
				
			||||||
 | 
					          border-radius: 4px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .current {
 | 
					    b {
 | 
				
			||||||
      color: #3f8df5;
 | 
					      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 {
 | 
					    .fixedTop {
 | 
				
			||||||
@@ -184,30 +242,26 @@ export default {
 | 
				
			|||||||
      border-bottom: 4px solid #f5f5f5;
 | 
					      border-bottom: 4px solid #f5f5f5;
 | 
				
			||||||
      z-index: 1;
 | 
					      z-index: 1;
 | 
				
			||||||
      text-align: start;
 | 
					      text-align: start;
 | 
				
			||||||
      padding: 0 16px;
 | 
					      padding: 0 32px;
 | 
				
			||||||
 | 
					      box-sizing: border-box;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ::v-deep.u-drawer-content {
 | 
					  ::v-deep.u-drawer-content {
 | 
				
			||||||
    position: fixed;
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    border-radius: 32px 32px 0 0;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    padding: 0 32px 90px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .areaSelector {
 | 
					    .areaSelector {
 | 
				
			||||||
      padding: 0 16px;
 | 
					 | 
				
			||||||
      box-sizing: border-box;
 | 
					      box-sizing: border-box;
 | 
				
			||||||
      border-bottom: 16px solid #f5f5f5;
 | 
					      border-bottom: 1px solid #f5f5f5;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      span {
 | 
					 | 
				
			||||||
        line-height: 100px;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ::v-deep.pendingItem {
 | 
					  ::v-deep.pendingItem {
 | 
				
			||||||
    color: #333;
 | 
					    color: #333;
 | 
				
			||||||
    margin-left: 32px;
 | 
					 | 
				
			||||||
    padding-right: 32px;
 | 
					 | 
				
			||||||
    height: 104px;
 | 
					    height: 104px;
 | 
				
			||||||
    border-bottom: 1px solid #ddd;
 | 
					 | 
				
			||||||
    text-align: start;
 | 
					    text-align: start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .self {
 | 
					    .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 {
 | 
					  .location {
 | 
				
			||||||
    width: 28px;
 | 
					    width: 28px;
 | 
				
			||||||
    height: 80px;
 | 
					    height: 80px;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <section class="AiSearchPopup">
 | 
					  <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"/>
 | 
					      <slot v-if="$slots.default"/>
 | 
				
			||||||
      <div class="searchPane" v-else>
 | 
					      <div class="searchPane" v-else>
 | 
				
			||||||
        <div class="title">{{ title }}</div>
 | 
					        <div class="title">{{ title }}</div>
 | 
				
			||||||
@@ -24,7 +24,8 @@ export default {
 | 
				
			|||||||
    placeholder: {default: "请搜索"},
 | 
					    placeholder: {default: "请搜索"},
 | 
				
			||||||
    ops: {default: () => ({label: 'label', search: 'name'})},
 | 
					    ops: {default: () => ({label: 'label', search: 'name'})},
 | 
				
			||||||
    url: String,
 | 
					    url: String,
 | 
				
			||||||
    mode: {default: "right"}
 | 
					    mode: {default: "right"},
 | 
				
			||||||
 | 
					    length: {default: "100%"}
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
@@ -33,6 +34,11 @@ export default {
 | 
				
			|||||||
      list: []
 | 
					      list: []
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  watch: {
 | 
				
			||||||
 | 
					    show(v) {
 | 
				
			||||||
 | 
					      !v && this.$emit('close')
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    getList() {
 | 
					    getList() {
 | 
				
			||||||
      this.url && this.$instance.post(this.url, null, {
 | 
					      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
 | 
					  ...App
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
store.dispatch("agentSign").then(config => {
 | 
					store.dispatch("agentSign").then(config => {
 | 
				
			||||||
  store.commit("getConfig", {...config, latlng: [config.lat, config.lng]})
 | 
					  const init = (c = 0) => {
 | 
				
			||||||
  app.$mount();
 | 
					    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