浏览代码

Merge branch 'feature/v1.0.36' into dev/1.0.36_zsy

zhangsiya 1 年之前
父节点
当前提交
2b6d269652

+ 6 - 0
apps/bigmember_pc/src/assets/js/selector.js

@@ -1022,3 +1022,9 @@ export const wordsModeList = [
   }
 ]
 
+// 热门省份
+export const hotAndAllProvinceList = {
+  // '#': ['全国'],
+  hot: ['全国', '北京', '广东', '山东', '河南', '浙江', '江苏', '陕西', '上海', '四川', '湖北', '福建', '河北', '安徽', '湖南', '辽宁', '江西', '山西'],
+  other: ['云南', '新疆', '重庆', '广西', '吉林', '贵州', '天津', '甘肃', '黑龙江', '内蒙古', '宁夏', '海南', '青海', '西藏', '香港', '澳门', '台湾']
+}

+ 789 - 0
apps/bigmember_pc/src/components/filter-items/RegionCollapseSelector.vue

@@ -0,0 +1,789 @@
+<template>
+  <div
+    class="selector-content region-selector-content"
+    key="s-content"
+  >
+    <div class="selected-list" v-if="showSelectedList">
+      <el-tag
+        type="plain"
+        :closable="!singleChoice"
+        v-for="tag in selectedTagList"
+        :key="tag"
+        @close="tagClose(tag)"
+        >{{ tag }}</el-tag
+      >
+    </div>
+    <div class="select-list" ref="selectList">
+      <div
+        class="index-item"
+        :data-index="key"
+        :ref="'index-item-' + key"
+        v-for="(item, key) in provinceListMap"
+        :key="key"
+      >
+        <div
+          class="j-button-item"
+          v-for="(province, ii) in item"
+          :class="{
+            bgc: onlyProvince,
+            expand: province.expanded && province.canExpanded,
+            active: provinceButtonActive(province),
+            country: province.name === '全国',
+            hidden: !moreStatus && key === 'other',
+            [province.selectedState]: !showSelectedList
+          }"
+          :key="ii * 2"
+          @click="changeExpandStateForLine($event, province)"
+        >
+          {{ province.name }}
+        </div>
+      </div>
+      <div class="city-list" ref="cityList" v-show="expandedCitiesShow">
+        <div class="city-list-content">
+          <div
+            v-if="!onlyCity"
+            class="city-item province"
+            :class="{
+              active: expandedProvince.selectedState === 'checked'
+            }"
+            @click="clickProvinceInCityListForLine(expandedProvince)"
+          >
+            {{ expandedProvince.name }}
+          </div>
+          <div
+            class="city-item city"
+            :class="{
+              active: city.selected
+            }"
+            v-for="(city, iii) in expandedProvince.children"
+            :key="iii"
+            @click="changeCityStateForLine(expandedProvince, city)"
+          >
+            {{ city.city }}
+          </div>
+        </div>
+        <div class="city-list-footer">
+          <button class="confirm" @click="confirmCitySelected">确定</button>
+          <button class="cancel" @click="cancelCitySelected">取消</button>
+        </div>
+      </div>
+      <div slot="expand" class="is-expand" @click="toggleMoreStatus">
+        <span>{{ moreStatus ? '收起' : '展开' }}</span>
+        <i class="el-icon-arrow-down" :class="{'is-reverse': moreStatus}"></i>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { Tag } from 'element-ui'
+import chinaMapJSON from '@/assets/js/china_area.js'
+import { hotAndAllProvinceList } from '@/assets/js/selector.js'
+import { getRandomString } from '@/utils/'
+export default {
+  name: 'RegionLineSelector',
+  props: {
+    onlyProvince: {
+      type: Boolean,
+      default: false
+    },
+    // 是否仅能选择城市
+    onlyCity: {
+      type: Boolean,
+      default: false
+    },
+    // 是否单选
+    singleChoice: {
+      type: Boolean,
+      default: false
+    },
+    beforeTabClick: Function,
+    // 是否显示选择结果
+    showSelectedList: {
+      type: Boolean,
+      default: true
+    },
+    // 刚进入页面需要被选中的城市数据
+    value: {
+      type: Object,
+      default() {
+        return {}
+      }
+    }
+  },
+  components: {
+    [Tag.name]: Tag,
+  },
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  data() {
+    return {
+      // 省份与字母IndexBar对照表
+      provinceListMapExp: hotAndAllProvinceList,
+      provinceListMap: {},
+      // indexBar数据
+      indexList: [],
+      provinceExp: {
+        name: '',
+        // 展开状态
+        expanded: false,
+        // 是否可以展开
+        canExpanded: false,
+        // 选中状态: half(半选)、checked(全选)、''(未选中)、checkeddisabled(全选不能点击)、nonedisabled(未选不能点击)
+        selectedState: '',
+        children: [],
+        id: ''
+      },
+      // line状态下,当前被展开省的省份列表
+      expandedProvince: {
+        children: []
+      },
+      selectedCity: {},
+      selectedTagList: [],
+      moreStatus: false
+    }
+  },
+  computed: {
+    expandedCitiesShow() {
+      if (!this.expandedProvince) return false
+      return this.expandedProvince.children.length
+    }
+  },
+  watch: {
+    value(newVal, oldVal) {
+      this.setState(newVal)
+    }
+  },
+  created() {
+    this.initIndexBarAndAreaMap()
+    this.setState(this.value)
+  },
+  methods: {
+    toggleMoreStatus() {
+      this.moreStatus = !this.moreStatus
+      for (const key in this.provinceListMap) {
+        this.provinceListMap[key].forEach((item) => {
+          item.expanded = false
+        })
+      }
+      this.expandedProvince = {
+        children: []
+      }
+    },
+    getAllItem() {
+      var p = {}
+      if (this.provinceListMap['hot']) {
+        p = this.provinceListMap['hot'][0]
+      }
+      return p
+    },
+    // 整理城市数据列表(并初始化indexBar数据)
+    initIndexBarAndAreaMap(provinceMap = {}) {
+      // 整理数据得到indexListMap(),同时获得indexList
+      const provinceListMap = {}
+      const indexList = []
+      const pMap =
+        Object.keys(provinceMap).length === 0
+          ? this.provinceListMapExp
+          : provinceMap
+      if (Object.keys(provinceMap).length !== 0) {
+        this.provinceListMapExp = provinceMap
+      }
+      for (const key in pMap) {
+        const areaArr = []
+        indexList.push(key)
+        pMap[key].forEach((pName) => {
+          const provinceExp = JSON.parse(JSON.stringify(this.provinceExp))
+
+          provinceExp.name = pName
+          provinceExp.id = `ap-${getRandomString(8).toLowerCase()}`
+
+          if (pName !== '全国') {
+            let cities = []
+            if (!this.onlyProvince) {
+              cities = this.getCitiesFromJSONMap(pName)
+            }
+            // 筛选掉直辖市和特别行政区(台湾省也不不需要展开)
+            if (cities.ProRemark === '省份' || cities.ProRemark === '自治区') {
+              if (cities.ProID === 32) {
+                provinceExp.children = []
+                provinceExp.canExpanded = false
+              } else {
+                cities.city.forEach((c) => {
+                  // 将市区重组成一个新的对象
+                  return provinceExp.children.push({
+                    city: c.name,
+                    selected: false,
+                    canSelected: true,
+                    id: `ac-${getRandomString(8).toLowerCase()}`
+                  })
+                })
+              }
+            } else {
+              provinceExp.children = []
+              provinceExp.canExpanded = false
+            }
+          }
+
+          provinceExp.canExpanded = provinceExp.children.length !== 0
+          areaArr.push(provinceExp)
+        })
+
+        provinceListMap[key] = areaArr
+      }
+
+      this.provinceListMap = provinceListMap
+      this.indexList = indexList
+
+      // 给provinceListMap赋值
+      for (const k in provinceListMap) {
+        this.$set(this.provinceListMap, k, provinceListMap[k])
+      }
+      this.getAllItem().selectedState = 'checked'
+    },
+    // 循环chinaMapJSON,找到对应省下面对应的市
+    getCitiesFromJSONMap(provinceName) {
+      return chinaMapJSON.find((item) => item.name.indexOf(provinceName) !== -1)
+    },
+    // 控制城市盒子展开和收起(card)
+    changeExpandState(e, province) {
+      if (!province.canExpanded) return
+      province.expanded = !province.expanded
+    },
+    // 控制城市盒子展开和收起(line)
+    changeExpandStateForLine(e, province) {
+      const beforeTabClick = this.beforeTabClick
+      if (beforeTabClick) {
+        const pass = beforeTabClick(e, province)
+        if (!pass) {
+          return
+        }
+      }
+      if (province.name === this.expandedProvince.name) return
+      // 循环,将其他全部置为false
+      for (const key in this.provinceListMap) {
+        this.provinceListMap[key].forEach((item) => {
+          item.expanded = false
+        })
+      }
+      this.expandedProvince = {
+        children: []
+      }
+      province.expanded = true
+      // 省份数据与原数据分离(点击确定覆盖原数据,点击取消则不保存数据)
+      this.expandedProvince = JSON.parse(JSON.stringify(province))
+      // 如果直接点击直辖市
+      if (province.children.length === 0) {
+        if (province.name === '全国') {
+          this.setState()
+        } else {
+          if (this.singleChoice) {
+            this.setState()
+          }
+          this.getAllItem().selectedState = ''
+          if (this.showSelectedList) {
+            this.provinceListMap['hot'][0].selectedState = ''
+            this.expandedProvince.selectedState = 'checked'
+          } else {
+            var checked = this.expandedProvince.selectedState
+            if (checked === 'checked') {
+              this.expandedProvince.selectedState = ''
+            } else {
+              this.expandedProvince.selectedState = 'checked'
+            }
+          }
+        }
+        this.confirmCitySelected()
+      } else {
+        var hasCitySelected = this.expandedProvince.children.some(function (v) {
+          return v.selected
+        })
+        if (!hasCitySelected) {
+          this.expandedProvince.selectedState = 'checked'
+        }
+        this.moveTheCityContainer(e)
+      }
+    },
+    moveTheCityContainer(e) {
+      const selectList = this.$refs.selectList
+      const cityList = this.$refs.cityList
+      const { lineFirstDom, clickLine } = this.getDomInfo(e.target)
+
+      if (clickLine >= lineFirstDom.length) {
+        selectList.appendChild(cityList) // 往列表末尾插入元素
+      } else if (clickLine <= 1) {
+        selectList.insertBefore(cityList, lineFirstDom[1])
+      } else {
+        selectList.insertBefore(cityList, lineFirstDom[clickLine])
+      }
+    },
+    getDomInfo(dom) {
+      const indexDOMList = [] // 所有索引项dom数组(索引项下有每个省份的按钮)
+      const indexTopList = [] // 每个元素距离顶部高度数组
+      const tolerance = [] // 行间距差值
+      const lineFirstDom = [
+        // 每行的第一个dom
+        ...this.$refs[`index-item-${this.indexList[0]}`]
+      ]
+      this.indexList.forEach((item) => {
+        const ref = this.$refs[`index-item-${item}`]
+        if (ref && ref[0]) {
+          indexDOMList.push(ref[0])
+          indexTopList.push(parseInt(ref[0].getBoundingClientRect().top))
+        }
+      })
+      for (let i = 0; i < indexTopList.length; i++) {
+        if (indexTopList[i + 1] > indexTopList[i]) {
+          tolerance.push(indexTopList[i + 1] - indexTopList[i])
+          lineFirstDom.push(indexDOMList[i + 1])
+        }
+      }
+
+      // 求平均值,谁的值大于平均值,就在哪一行
+      let insetedLine = 0
+      const avg =
+        tolerance.length > 0
+          ? tolerance.reduce((prev, item) => prev + item) / tolerance.length
+          : 0
+      for (let j = 0; j < tolerance.length; j++) {
+        if (tolerance[j] > avg) {
+          insetedLine = j + 1
+        }
+      }
+
+      // clickDOMIndex: 点击dom在indexDOMList的索引
+      const clickDOMIndex = indexDOMList.findIndex(
+        (item) => item === dom.parentNode
+      ) // dom是点击的按钮
+      const indexTopSet = Array.from(new Set(indexTopList))
+      const clickLine =
+        indexTopSet.findIndex((item) => item === indexTopList[clickDOMIndex]) +
+        1
+
+      return {
+        lineFirstDom, // 每行的第一个dom
+        indexTopList, // 每个元素距离顶部高度数组
+        indexTopSet, // indexTopList去重后的数组(里面是每一行距离顶部的高度)
+        tolerance, // 行间距差值
+        clickLine, // 通过传入的dom计算出的当前点击的哪一行
+        insetedLine // 点击按钮前cityList在哪一行
+      }
+    },
+    // 城市选择按钮点击事件(line)
+    // 根据城市的选择情况判断省份的选择情况
+    changeCityStateForLine(province, city) {
+      if (this.singleChoice) {
+        this.setState()
+      }
+
+      this.getAllItem().selectedState = ''
+      province.selectedState = ''
+
+      if (this.singleChoice) {
+        // 单选情况下,需要先将其他选项取消掉
+        province.children.forEach((item) => (item.selected = false))
+      }
+      city.selected = !city.selected
+      // 判断省份的选择状态
+      let count = 0
+      const cityLength = province.children.length
+      if (cityLength) {
+        province.children.forEach((v) => {
+          // 前提是可点击的
+          if (v.canSelected && v.selected) {
+            count++
+          }
+        })
+      }
+      if (count === cityLength) {
+        // line状态下 ,城市全部选中,则只选中省份即可
+        province.selectedState = 'checked'
+        province.children.forEach((item) => (item.selected = false))
+      }
+    },
+    // 省份点击事件(城市列表中的省份按钮)(line)
+    clickProvinceInCityListForLine(province) {
+      if (this.singleChoice) {
+        this.setState()
+        this.getAllItem().selectedState = ''
+      }
+      const state = province.selectedState
+      province.children.forEach((v) => (v.selected = false))
+      if (state === 'checked') {
+        province.selectedState = ''
+      } else {
+        province.selectedState = 'checked'
+      }
+    },
+    // 检查是否所有省份按钮被全选中
+    // 全部被全选->返回true
+    checkAllProvinceState() {
+      const stateArr = []
+      for (const key in this.provinceListMap) {
+        this.provinceListMap[key].forEach((item) => {
+          if (item.name !== '全国') {
+            if (item.selectedState === '') {
+              stateArr.push('unchecked')
+            } else if (item.selectedState === 'checked') {
+              stateArr.push('checked')
+            } else {
+              stateArr.push('other')
+            }
+          }
+        })
+      }
+      // 统计不同状态的个数
+      const counter = {
+        checked: 0,
+        unchecked: 0,
+        other: 0
+      }
+      for (let i = 0; i < stateArr.length; i++) {
+        const k = stateArr[i]
+        if (counter[k]) {
+          counter[k] += 1
+        } else {
+          counter[k] = 1
+        }
+      }
+      return {
+        state: stateArr,
+        allSelected: counter.checked === stateArr.length,
+        noSelected: counter.unchecked === stateArr.length
+      }
+    },
+    setAllNoSelected() {
+      for (const key in this.provinceListMap) {
+        this.provinceListMap[key].forEach((item) => {
+          item.selectedState = ''
+          item.children.forEach((iitem) => {
+            iitem.selected = false
+          })
+        })
+      }
+    },
+    // 初始化选中城市数据(card/line共用)
+    setState(data = {}) {
+      // 设置全国
+      if (!data || Object.keys(data).length === 0) {
+        // 其他全部设置不选中,全国设置选中
+        for (const key in this.provinceListMap) {
+          this.provinceListMap[key].forEach((item) => {
+            item.selectedState = ''
+            item.children.forEach((iitem) => {
+              iitem.selected = false
+            })
+            if (item.name === '全国') {
+              item.selectedState = 'checked'
+            }
+          })
+        }
+      } else {
+        // 先将所有城市选择取消
+        this.setState()
+        // 设置某几个省份被选中
+        for (const key in this.provinceListMap) {
+          this.provinceListMap[key].forEach((item) => {
+            const selectCityArr = data[item.name]
+            if (Array.isArray(selectCityArr)) {
+              if (selectCityArr.length === 0) {
+                // 全省被选中
+                item.children.forEach((iitem) => {
+                  iitem.selected = false
+                })
+
+                item.selectedState = 'checked'
+              } else {
+                // 省份中的某些市被选中
+                item.children.forEach((iitem) => {
+                  if (selectCityArr.indexOf(iitem.city) !== -1) {
+                    iitem.selected = true
+                  }
+                })
+                // item.selectedState = 'half'
+              }
+            }
+
+            if (item.name === '全国') {
+              item.selectedState = ''
+            }
+          })
+        }
+      }
+      this.getSelectedTagList(data)
+    },
+    // 获取当前选中城市数据
+    getState() {
+      const counter = {}
+      // 判断是否全国被选中
+      if (this.getAllItem().selectedState === 'checked') {
+        return counter
+      }
+
+      // 全国没有被选中,排除循环全国
+      for (const key in this.provinceListMap) {
+        // if (key === '#') continue
+        this.provinceListMap[key].forEach((item) => {
+          // 当前省份下被选中的城市数量
+          const selectedCityArr = []
+          const cityTotalCount = item.children.length
+          item.children.forEach((iitem) => {
+            if (iitem.selected && iitem.canSelected) {
+              selectedCityArr.push(iitem.city)
+            }
+          })
+          
+          // 先看是否有城市被选,再看是否省份被选
+          if (selectedCityArr.length) {
+            counter[item.name] = selectedCityArr
+          } else {
+            if (item.selectedState === 'checked') {
+              counter[item.name] = []
+            }
+          }
+          
+        })
+      }
+      return counter
+    },
+    provinceButtonActive(province) {
+      if (this.onlyProvince) {
+        return province.selectedState === 'checked'
+      } else {
+        return province.selectedState === 'checked' && province.name === '全国'
+      }
+    },
+    confirmCitySelected() {
+      // 统计时候有城市被选中了
+      const cityLength = this.expandedProvince.children.length
+      let count = 0
+      if (cityLength) {
+        const selectedCityArr = this.expandedProvince.children.filter((v) => {
+          return v.canSelected && v.selected
+        })
+        count = selectedCityArr.length
+        // 判断是否仅能够选中城市
+        if (this.onlyCity) {
+          if (count === 0) {
+            return this.$toast('还未选择城市,请选择')
+          }
+        }
+      }
+      if (this.showSelectedList) {
+        if (
+          this.expandedProvince.selectedState !== 'checked' &&
+          cityLength !== 0 &&
+          count === 0
+        ) {
+          return
+        }
+      }
+
+      var beforeChange = this.beforeChange
+      if (beforeChange) {
+        var pass = beforeChange(this.expandedProvince)
+        if (!pass) {
+          return
+        }
+      }
+      // 替换赋值
+      for (const key in this.provinceListMap) {
+        // if (key === '#') continue
+        const res = this.provinceListMap[key].find((item) => {
+          if (item.name === this.expandedProvince.name) {
+            Object.assign(item, this.expandedProvince)
+            this.getAllItem().selectedState = ''
+          }
+          return item.name === this.expandedProvince.name
+        })
+        if (res) {
+          break
+        }
+      }
+      this.selectedCity = this.getState()
+
+      this.getSelectedTagList(this.selectedCity)
+      this.cancelCitySelected()
+      this.$emit('change', this.selectedCity)
+    },
+    cancelCitySelected() {
+      const selected = this.getState()
+      if (selected) {
+        this.setState(selected)
+      }
+      for (const key in this.provinceListMap) {
+        this.provinceListMap[key].forEach((item) => {
+          item.expanded = false
+        })
+      }
+      this.expandedProvince = {
+        children: []
+      }
+    },
+    getSelectedTagList(v) {
+      const privinceArr = []
+      let cityArr = []
+      for (const key in v) {
+        const item = v[key]
+        if (Array.isArray(item)) {
+          if (item.length === 0) {
+            privinceArr.push(key)
+          } else {
+            cityArr = cityArr.concat(item)
+          }
+        }
+      }
+      this.selectedTagList = privinceArr.concat(cityArr)
+    },
+    tagClose(name) {
+      this.cancelCitySelected()
+      if (name === '全国') {
+        this.selectedTagList = []
+        return
+      }
+      for (const key in this.selectedCity) {
+        const index = this.selectedCity[key].indexOf(name)
+        if (name === key) {
+          delete this.selectedCity[key]
+          break
+        } else if (index !== -1) {
+          this.selectedCity[key].splice(index, 1)
+          if (this.selectedCity[key].length === 0) {
+            delete this.selectedCity[key]
+          }
+        }
+      }
+      this.setState(this.selectedCity)
+      this.confirmCitySelected()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.region-selector-content {
+  padding-right: 32px;
+  .el-tag--plain {
+    color: $color-text--highlight;
+    border-color: $color-text--highlight;
+    .el-tag__close {
+      color: $color-text--highlight;
+      &:hover {
+        color: #fff;
+        background-color: $color-text--highlight;
+      }
+    }
+  }
+  .el-tag {
+    margin: 4px 6px;
+    height: 28px;
+    line-height: 26px;
+  }
+  .select-list {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    padding-right: 72px;
+    .index-item {
+      display: flex;
+      flex-wrap: wrap;
+      .index-bar {
+        margin-left: 10px;
+        margin-right: 5px;
+        color: #999;
+      }
+    }
+    .j-button-item {
+      display: inline-block;
+      margin: 2px 5px;
+      padding: 1px 6px;
+      line-height: 20px;
+      border-radius: 4px;
+      font-size: 14px;
+      text-align: center;
+      background-color: #fff;
+      cursor: pointer;
+      box-sizing: border-box;
+      &:hover {
+        color: $color-text--highlight;
+      }
+      &.active {
+        color: #fff;
+        background-color: $color-text--highlight;
+        border: 1px solid $color-text--highlight;
+      }
+      &.expand {
+        background-color: #f5f5fb;
+        border: 1px solid #e0e0e0;
+        border-bottom-color: transparent;
+        border-bottom-left-radius: 0;
+        border-bottom-right-radius: 0;
+        position: relative;
+        z-index: 2;
+      }
+      
+    }
+  }
+  .city-list {
+    margin-top: -4px;
+    padding: 12px 20px;
+    width: 100%;
+    background-color: #f5f5fb;
+    border-radius: 4px;
+    border: 1px solid #e0e0e0;
+    .city-item {
+      display: inline-block;
+      margin: 0 4px 4px;
+      padding: 4px 8px;
+      border-radius: 4px;
+      cursor: pointer;
+      &.active {
+        color: #fff;
+        background-color: $color-text--highlight;
+      }
+    }
+    .city-list-footer {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      margin-top: 12px;
+      button {
+        padding: 4px 16px;
+        font-size: 14px;
+        line-height: 18px;
+        color: #1d1d1d;
+        background-color: #fff;
+        cursor: pointer;
+        border-radius: 4px;
+        border: 1px solid #e0e0e0;
+        &.confirm {
+          margin-right: 15px;
+          color: #fff;
+          background-color: #2cb7ca;
+          border-color: #2cb7ca;
+        }
+      }
+    }
+  }
+  .is-expand{
+    position: absolute;
+    top: 2px;
+    right: 0;
+    display: inline-block;
+    font-size: 14px;
+    line-height: 22px;
+    color: #686868;
+    cursor: pointer;
+    i{
+      margin-left: 2px;
+      transform: rotate(0deg);
+      transition: transform .3s;
+    }
+    .is-reverse{
+      transform: rotate(180deg);
+    }
+  }
+}
+</style>

+ 0 - 1
apps/bigmember_pc/src/components/selector/SelectorCard.vue

@@ -84,7 +84,6 @@ export default {
     position: relative;
     display: flex;
     flex: 1;
-    margin-left: -5px;
 
     &::v-deep {
       .fw-bold {

+ 1 - 2
apps/bigmember_pc/src/components/selector/TagSelector.vue

@@ -3,7 +3,7 @@
     <div slot="header" class="s-header" v-if="showHeader">
       <slot name="header">开标状态:</slot>
     </div>
-    <div class="tag-container">
+    <div class="selector-content tag-container">
       <button
         v-for="(item, index) in sourceList"
         :key="index"
@@ -58,7 +58,6 @@ export default {
   }
   .tag-container {
     display: flex;
-    margin-left: -5px;
   }
   .j-button-item {
     display: flex;

+ 5 - 0
apps/bigmember_pc/src/components/selector/TimeSelector.vue

@@ -47,6 +47,10 @@ export default {
     return {}
   },
   created() {},
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
   methods: {
     setState(data) {
       return this.$refs.content.setState(data)
@@ -63,6 +67,7 @@ export default {
     },
     onChange(state) {
       this.$emit('onChange', state)
+      this.$emit('change', state)
     }
   }
 }

+ 1 - 1
apps/bigmember_pc/src/views/search/components/search-schema-filter.vue

@@ -62,7 +62,7 @@ const getPrefix = {
           {{ item.label }}
         </slot>
       </div>
-      <div>
+      <div class="flex-1">
         <!-- @component 自定义组件  -->
         <!-- @input @change 兼容不同组件的输出  -->
         <Component

+ 1 - 0
apps/bigmember_pc/src/views/search/layout/search-list.vue

@@ -47,6 +47,7 @@ const canShowPagination = computed(() => {
   if (props.listState.loading && props.listState.pageNum === 1) {
     return false
   }
+  if (!props.list.length) return false
   return props.listState.total > 0
 })
 </script>

+ 4 - 7
apps/bigmember_pc/src/views/search/supply/constant/search-filters.js

@@ -1,5 +1,5 @@
 import SearchScopeSelector from '@/components/filter-items/SearchScopeSelector.vue'
-import AreaSelector from '@/components/selector/AreaSelector.vue'
+import RegionCollapseSelector from '@/components/filter-items/RegionCollapseSelector.vue'
 import TimeSelector from '@/components/selector/TimeSelector.vue'
 import TagSelector from '@/components/selector/TagSelector.vue'
 
@@ -35,17 +35,14 @@ const SearchSupplyBaseSchema = [
     }
   },
   {
-    key: 'selectArea',
+    key: 'regionMap',
     label: '选择区域:',
     defaultVal: [],
     _name: 'type',
     _type: 'component',
     expand: {
-      component: AreaSelector,
-      props: {
-        selectorType: 'line',
-        showKey: false
-      },
+      component: RegionCollapseSelector,
+      props: {},
       hooks: {}
     }
   },

+ 20 - 14
apps/bigmember_pc/src/views/search/supply/index.vue

@@ -7,7 +7,6 @@ import {
   showFilter,
   loginFlag,
   goToPublish,
-  mixinVisited,
   filterState,
   searchTabs,
   inputKeywordsState,
@@ -20,24 +19,20 @@ import {
 import {
   SearchSupplyBaseSchema
 } from './constant/search-filters'
-import { onMounted, ref } from 'vue'
 
-const { refreshVisited, pathVisiting, createPathItem } = mixinVisited()
-onMounted(() => {
-  refreshVisited()
-})
 
 function goDetail(item) {
+  // 一切都好进供应搜索点击列表需要登录,其他不需要登录
+  if (!loginFlag) {
+    const cookieInfo = document.cookie.split('; ');
+    const isPass = cookieInfo.some(item => item.indexOf('channelCode') > -1)
+    if (isPass) {
+      window.location.href = '/notin/page'
+      return
+    }
+  }
   const { id } = item
-  item.visited = true
-  pathVisiting(
-    createPathItem(
-      '/demand/detail',
-      `id=${id}`
-    )
-  )
   const routerUrl = `/swordfish/page_web_pc/demand/detail/${id}?matchKey=${inputKeywordsState.value.input}`
-
   window.open(routerUrl)
 }
 </script>
@@ -92,6 +87,7 @@ function goDetail(item) {
           :tags='item.tags'
           :time="item.time"
           :visited="item.visited"
+          v-visited:demand="item.id"
           @onClick="goDetail(item)"
         >
         </supply-article-item>
@@ -109,10 +105,17 @@ function goDetail(item) {
     .toggle-filter{
       cursor: pointer;
       color: #686868;
+      .icon-zhankai{
+        display: inline-block;
+        margin-left: 2px;
+        transform: rotate(0deg);
+        transition: transform .3s;
+      }
       .rotate180 {
         transform: rotate(180deg);
       }
     }
+    
     ::v-deep{
       .el-badge__content {
         padding: 0 6px;
@@ -128,6 +131,9 @@ function goDetail(item) {
       .el-badge__content--danger{
         background-color: #fb483d;
       }
+      .selector-content{
+        margin-left: -5px;
+      }
     }
   }
   .search-header-container{

+ 16 - 6
apps/bigmember_pc/src/views/search/supply/model/index.js

@@ -3,9 +3,7 @@ import useQuickSearchModel from '@jy/data-models/modules/quick-search/model'
 import { useSearchFilterModel } from './modules/filter'
 import { showFilter, loginFlag, goToPublish } from './modules/search-header'
 import { replaceKeyword, dateFromNow } from '@/utils'
-import { mixinVisited } from '@/utils/mixins/visited-setup.js'
 
-const { pathVisited, createPathItem } = mixinVisited()
 // 解构基础业务
 const APIModel = useQuickSearchModel({
   type: 'search-supply'
@@ -65,6 +63,11 @@ const formatList = computed(() => {
         value: item.province
       })
     }
+    if (item.city && item.city.replace('市', '') !== item.province) {
+      tags.push({
+        value: item.city.replace('市', '')
+      })
+    }
     return {
       id: item.id,
       title: replaceKeyword(item.title, inputKeywordsState.value.input, [
@@ -76,14 +79,21 @@ const formatList = computed(() => {
         '</span>'
       ]) : '',
       time: dateFromNow(item.publish_time * 1000),
-      tags: tags,
-      visited: false
+      tags: tags
     }
   })
 })
 
+// 页码总数只在第一页返回-记录保存
+const pageInfo = reactive({
+  total: 0
+})
 // search-list 组件所需参数
 const searchListProps = computed(() => {
+  if (listState.pageNum === 1) {
+    pageInfo.total = listState.total
+  }
+  listState.total = pageInfo.total
   return {
     showSelect: false,
     headerActions: [],
@@ -118,12 +128,13 @@ function getParams(params = {}) {
     {
       searchType: 'title',
       keywords: inputKeywordsState.value.input || '',
-      pageNum: listState.pageNum,
+      pageIndex: listState.pageNum,
       pageSize: listState.pageSize
     },
     getFormatAPIParams(),
     params
   )
+  console.log(result, 'result')
   return result
 }
 
@@ -131,7 +142,6 @@ export {
   showFilter,
   loginFlag,
   goToPublish,
-  mixinVisited,
   // 列表
   list,
   doQuery,

+ 32 - 4
apps/bigmember_pc/src/views/search/supply/model/modules/filter.js

@@ -8,21 +8,49 @@ export function useSearchFilterModel() {
     status: 0,
     province: '',
     city: '',
-    time: ''
+    time: '',
+    regionMap: {}
   })
 
   function getFormatAPIParams() {
+    const { province, city } = getProvinceCity()
     const params = {
       searchType: filterState.value.searchType.toString(),
       status: filterState.value.status.toString(),
-      province: filterState.value.province,
-      city: filterState.value.city,
-      time: filterState.value.time
+      province: province.toString(),
+      city: city.toString(),
+      time: getFilterTime(filterState.value.time)
     }
 
     return params
   }
 
+  function getFilterTime(time) {
+    const { start, end } = time
+    if (start && end) {
+      return `${parseInt(start / 1000)}-${parseInt(end / 1000)}`
+    } else {
+      return ''
+    }
+  }
+
+  function getProvinceCity() {
+    const regionMap = filterState.value.regionMap
+    const province = []
+    const city = []
+    for (const key in regionMap) {
+      if (regionMap[key].length === 0) {
+        province.push(key)
+      } else {
+        city.push(...regionMap[key])
+      }
+    }
+    return {
+      province,
+      city
+    }
+  }
+
   return {
     filterState,
     getFormatAPIParams

+ 3 - 8
packages/pc-ui/src/packages/article-item/supply-article-item.vue

@@ -1,9 +1,9 @@
 <template>
-  <div class="article-item-container supply-article-item" :class="{ 'visited': visited }">
+  <div class="article-item-container supply-article-item"  @click.stop="onClick">
     <div class="article-item-header">
       <slot name="prefix"></slot>
     </div>
-     <div class="article-item-content" :class="{ line: !detail, 'tags-bottom': tagsPosition === 'bottom' }" @click.stop.prevent="onClick">
+     <div class="article-item-content" :class="{ line: !detail, 'tags-bottom': tagsPosition === 'bottom' }">
       <div class="a-i-c-top visited-hd">
         <div class="ellipsis" v-html="calcTitle"></div>
         <div class="tags" v-if="tagsPosition === 'bottom'">
@@ -70,11 +70,6 @@ export default {
       type: Array,
       default: () => []
     },
-    // 已读
-    visited: {
-      type: Boolean,
-      default: false
-    },
     tagsPosition: {
       type: String,
       default: 'right'
@@ -116,7 +111,7 @@ export default {
     display: flex;
     align-items: center;
     justify-content: space-between;
-    padding: 18px 36px;
+    padding: 18px 26px;
     width: 100%;
     cursor: pointer;