浏览代码

feat: pc端阳光采购搜索页接口对接逻辑完善

cuiyalong 9 月之前
父节点
当前提交
e274e5e251

+ 189 - 0
apps/bigmember_pc/src/assets/js/selector/source.js

@@ -0,0 +1,189 @@
+// 领域数据源
+export const lingyuDataSource = [
+  {
+    label: '货物',
+    value: '',
+    children: [  
+      {  
+        value: 'A01',  
+        label: '房屋和构筑物',  
+        children: [  
+          { value: 'A01010000', label: '房屋' },  
+          { value: 'A01020000', label: '构筑物' },  
+          { value: 'A01030000', label: '土地' }  
+        ]
+      },  
+      {  
+        value: 'A02',  
+        label: '设备',  
+        children: [  
+          { value: 'A02010000', label: '信息化设备' },  
+          { value: 'A02020000', label: '办公设备' },  
+          { value: 'A02030000', label: '车辆' },  
+          { value: 'A02040000', label: '图书档案设备' },  
+          { value: 'A02050000', label: '机械设备' },  
+          { value: 'A02060000', label: '电气设备' },  
+          { value: 'A02070000', label: '雷达、无线电和卫星导航设备' },  
+          { value: 'A02080000', label: '通信设备' },  
+          { value: 'A02090000', label: '广播、电视、电影设备' },  
+          { value: 'A02100000', label: '仪器仪表' },  
+          { value: 'A02110000', label: '电子和通信测量仪器' },  
+          { value: 'A02120000', label: '计量标准器具及量具、衡器' },  
+          { value: 'A02130000', label: '探矿、采矿、选矿和造块设备' },  
+          { value: 'A02140000', label: '石油天然气开采设备' },  
+          { value: 'A02150000', label: '石油和化学工业设备' },  
+          { value: 'A02160000', label: '炼焦和金属冶炼轧制设备' },  
+          { value: 'A02170000', label: '电力工业设备' },  
+          { value: 'A02180000', label: '非金属矿物制品工业设备' },  
+          { value: 'A02190000', label: '核工业设备' },  
+          { value: 'A02200000', label: '航空航天工业设备' },  
+          { value: 'A02210000', label: '工程机械' },  
+          { value: 'A02220000', label: '农业和林业机械' },  
+          { value: 'A02230000', label: '木材采集和加工设备' },  
+          { value: 'A02240000', label: '食品加工设备' },  
+          { value: 'A02250000', label: '饮料加工设备' },  
+          { value: 'A02260000', label: '烟草加工设备' },  
+          { value: 'A02270000', label: '粮油作物和饲料加工设备' },  
+          { value: 'A02280000', label: '纺织设备' },  
+          { value: 'A02290000', label: '缝纫、服饰、制革和毛皮加工设备' },  
+          { value: 'A02300000', label: '造纸和印刷机械' },  
+          { value: 'A02310000', label: '化学药品和中药设备' },  
+          { value: 'A02320000', label: '医疗设备' },  
+          { value: 'A02330000', label: '电工、电子生产设备' },  
+          { value: 'A02340000', label: '安全生产设备' },  
+          { value: 'A02350000', label: '邮政设备' },  
+          { value: 'A02360000', label: '环境污染防治设备' },  
+          { value: 'A02370000', label: '政法、消防、检测设备' },  
+          { value: 'A02380000', label: '水工机械' },  
+          { value: 'A02390000', label: '货币处理设备' },  
+          { value: 'A02400000', label: '殡葬设备及用品' },  
+          { value: 'A02410000', label: '铁路运输设备' },  
+          { value: 'A02420000', label: '水上交通运输设备' },  
+          { value: 'A02430000', label: '航空器及其配套设备' },  
+          { value: 'A02440000', label: '海洋仪器设备' },  
+          { value: 'A02450000', label: '文艺设备' },  
+          { value: 'A02460000', label: '体育设备设施' },  
+          { value: 'A02470000', label: '娱乐设备' }  
+        ]  
+      },  
+      {  
+        value: 'A03',  
+        label: '文物和陈列品',  
+        children: [  
+          { value: 'A03020000', label: '可移动文物' },  
+          { value: 'A03030000', label: '文创衍生品' },  
+          { value: 'A03040000', label: '标本' },  
+          { value: 'A03050000', label: '模型' }  
+        ]  
+      },  
+      {  
+        value: 'A04',  
+        label: '图书和档案',  
+        children: [  
+          { value: 'A04010000', label: '图书' },  
+          { value: 'A04020000', label: '期刊' },  
+          { value: 'A04030000', label: '资料' },  
+          { value: 'A04040000', label: '档案' }  
+        ]  
+      },  
+      {  
+        value: 'A05',  
+        label: '家具和用具',  
+        children: [  
+          { value: 'A05010000', label: '家具' },  
+          { value: 'A05020000', label: '用具' },  
+          { value: 'A05030000', label: '装具' },  
+          { value: 'A05040000', label: '办公用品' }  
+        ]  
+      },  
+      {  
+        value: 'A06',  
+        label: '特种动植物',  
+        children: [  
+          { value: 'A06010000', label: '特种用途动物' },  
+          { value: 'A06020000', label: '特种用途植物' }  
+        ]  
+      },
+      {  
+        value: 'A07',  
+        label: '物资',  
+        children: [  
+          {  
+            value: 'A07010000',  
+            label: '建筑建材'  
+          },  
+          {  
+            value: 'A07020000',  
+            label: '医药品'  
+          },  
+          {  
+            value: 'A07030000',  
+            label: '农林牧渔业产品'  
+          },  
+          {  
+            value: 'A07040000',  
+            label: '矿与矿物'  
+          },  
+          {  
+            value: 'A07050000',  
+            label: '电力、城市燃气、蒸汽和热水、水'  
+          },  
+          {  
+            value: 'A07060000',  
+            label: '食品、饮料和烟草原料'  
+          },  
+          {  
+            value: 'A07070000',  
+            label: '炼焦产品、炼油产品'  
+          },  
+          {  
+            value: 'A07080000',  
+            label: '基础化学品及相关产品'  
+          },  
+          {  
+            value: 'A07090000',  
+            label: '橡胶、塑料、玻璃和陶瓷制品'  
+          },  
+          {  
+            value: 'A07100000',  
+            label: '纸及纸质品'  
+          }  
+        ]  
+      },  
+      {  
+        value: 'A08',  
+        label: '无形资产',  
+        children: [  
+          {  
+            value: 'A08010000',  
+            label: '专利类无形资产'  
+          },  
+          {  
+            value: 'A08020000',  
+            label: '非专利技术类无形资产'  
+          },  
+          {  
+            value: 'A08030000',  
+            label: '著作权类无形资产'  
+          },  
+          {  
+            value: 'A08040000',  
+            label: '资源资质类无形资产'  
+          },  
+          {  
+            value: 'A08050000',  
+            label: '商标权类无形资产'  
+          },  
+          {  
+            value: 'A08060000',  
+            label: '信息数据类无形资产'  
+          },  
+          {  
+            value: 'A08070000',  
+            label: '经营类无形资产'  
+          }  
+        ]  
+      }  
+    ]
+  }
+]

+ 40 - 14
apps/bigmember_pc/src/components/article-item/ArticleItem.vue

@@ -52,11 +52,12 @@
         <div class="tags">
           <span
             class="tag tag-user"
-            v-if="config.tagUserPublishState && article.tagPublishText"
-            >{{article.tagPublishText}}</span
+            v-if="config.tagUserPublishState && article.publicType"
+            >{{article.publicType}}</span
           >
           <span
             class="tag tag-user"
+            v-show="!config.publicType"
             v-if="
               article.site === '剑鱼信息发布平台' ||
               article.spidercode === 'a_jyxxfbpt_gg' ||
@@ -105,8 +106,8 @@
           <span class="tag dpink" v-if="calcBudget && calcBudget !== '0元'">
             {{ calcBudget }}
           </span>
-          <span class="tag tag-user border" v-if="config.tagBidEnd && article.bidEndTime">
-            {{ article.bidEndTime }}
+          <span class="tag border" :class="{'tag-user': !article.signupEnd }" v-if="config.tagSignupEnd && article.signupEnd !== undefined && article.signEndTimeText">
+            {{ article.signupEnd ? '报名已截止' : '报名未截止' }}
           </span>
         </div>
 
@@ -217,10 +218,15 @@
             <i class="l-d-item-label">采购单位联系方式:</i>
             {{ article.buyerPerson }}
             <em v-if="article.buyerPerson">,</em>
-            {{ article.buyerTel }}
+            <template v-if="article.buyerTel === maskText">
+              <i :class="{'highlight-text pointer': article.buyerTel === maskText}" @click.stop="leaveInfo">{{ article.buyerTel }}</i>
+            </template>
+            <template v-else>
+              {{ article.buyerTel }}
+            </template>
             <em
               class="more-tel"
-              v-if="article.buyerTel"
+              v-if="article.buyerTel && article.buyerTel !== maskText"
               @click.stop="goPortrayal('buyerDesc', article.buyer, 'contact')"
               >获取更多</em
             >
@@ -311,6 +317,19 @@
             交付地点
           </div>
         </p>
+        <div
+          class="l-d-item"
+          v-if="config.tagSignupEnd && (article.signEndTimeText || article.deliveryLoc)"
+        >
+          <p v-if="article.signEndTimeText">
+            <i class="l-d-item-label">报名截止日期:</i>
+            {{ article.signEndTimeText }}
+          </p>
+          <p v-if="article.deliveryLoc">
+            <i class="l-d-item-label">交付地点:</i>
+            {{ article.deliveryLoc }}
+          </p>
+        </div>
       </div>
     </div>
     <div class="list-item-right">
@@ -546,6 +565,7 @@ export default {
   },
   data() {
     return {
+      maskText: '点击查看',
       sourceMap: {
         1: '个人订阅',
         2: '企业自动分发',
@@ -594,11 +614,17 @@ export default {
       this.$emit('setShow')
     },
     goPortrayal(type, item, position) {
+      if (item === this.maskText) {
+        return this.leaveInfo()
+      }
       // position: 锚点定位参数
       const { url } = getPowerUrl(type, { id: item })
       const params = position ? '?position=' + position : ''
       window.open(url + params)
     },
+    leaveInfo() {
+      this.$emit('leaveInfo')
+    },
     formatBuyer(data) {
       if (!data) return []
       const arr = data.split('、')
@@ -901,14 +927,14 @@ $border-color: #ececec;
     }
     span {
       margin-right: 32px;
-      .l-d-item-label {
-        color: #686868;
-      }
-      a {
-        &:hover,
-        &:focus {
-          color: #2cb7ca;
-        }
+    }
+    .l-d-item-label {
+      color: #686868;
+    }
+    a {
+      &:hover,
+      &:focus {
+        color: #2cb7ca;
       }
     }
   }

+ 1 - 0
apps/bigmember_pc/src/components/collect-info/CollectInfo.vue

@@ -592,6 +592,7 @@ export default {
         pc_article_original_one: '标讯详情页-免费用户获取1次查看原文链接机会',
         pc_article_original_more: '标讯详情页-获取更多查看原文链接机会',
         pc_dzbg_fullreport: '申请免费体验-完整查看市场分析定制报告',
+        pc_sunlightlist_viewdetails: '光直采采购信息列表-查看采购信息详情',
         pc_dzbgxzb_customizedquantity: '市场分析定制报告下载包-定制报告份数'
       },
       sourceTitleTopMap: {

+ 1157 - 0
apps/bigmember_pc/src/components/filter-items/CommonThreeSelector.vue

@@ -0,0 +1,1157 @@
+<template>
+  <Layout
+    ref="layoutRef"
+    :type="type"
+    :placeholder="placeholder"
+    :trigger="trigger"
+    :value="computedVal"
+    @visible="onVisibleChange"
+  >
+    <div slot="empty" class="zhima-bid--wrap dropdown-content--wrap">
+      <div class="dropdown-content--hd" v-if="showSearch">
+        <div class="dropdown-content--hd-item dropdown-content--hd-left">
+          <el-input
+            size="small"
+            clearable
+            placeholder="请输入标签名称搜索"
+            suffix-icon="el-icon-search"
+            v-model="searchContent"
+            @keyup.native="onKeyup"
+            @focus="onFocus"
+            @blur="onBlur"
+            @keydown.native="onKeydown"
+            :class="{ 'input-focus': inputFocus }"
+          >
+          </el-input>
+        </div>
+        <div class="dropdown-content--hd-item dropdown-content--hd-right">
+          <slot name="header-right"></slot>
+        </div>
+      </div>
+      <div class="dropdown-content--bd">
+        <div class="module-container level-1-container">
+          <header class="module-header"></header>
+          <div class="list-empty-container" v-if="searchEmpty">
+            暂无相关选项
+          </div>
+          <div class="module-main">
+            <ul>
+              <li
+                class="module-item"
+                @mouseover="onLevel1MouseOver(level1, pIndex)"
+                @mouseout="onLevel1MouseOut($event)"
+                :class="{ active: pActive === pIndex }"
+                v-for="(level1, pIndex) in level1List"
+                v-show="!level1.searchHide"
+                :key="level1.name"
+              >
+                <el-checkbox
+                  v-model="level1.checked"
+                  :indeterminate="level1.indeterminate"
+                  @change="onProvinceChange($event, level1, pIndex)"
+                ></el-checkbox>
+                <span
+                  class="item-name"
+                  @click.self="onOpenLevel2(level1, pIndex)"
+                  v-html="level1.label"
+                ></span>
+                <i class="el-icon-arrow-right"></i>
+              </li>
+            </ul>
+          </div>
+        </div>
+        <div class="module-container level-2-container">
+          <header class="module-header"></header>
+          <div class="module-main">
+            <ul>
+              <li
+                class="module-item"
+                @mouseover="onLevel2MouseOver(level2, cIndex)"
+                @mouseout="onLevel2MouseOut($event)"
+                :class="{ active: cActive === cIndex }"
+                v-for="(level2, cIndex) in level2List"
+                v-show="!level2.searchHide"
+                :key="level2.name"
+              >
+                <el-checkbox
+                  v-model="level2.checked"
+                  :disabled="level2.disabled"
+                  :indeterminate="level2.indeterminate"
+                  @change="onCitiesChange($event, level2, cIndex)"
+                ></el-checkbox>
+                <span
+                  class="item-name"
+                  @click.self="onOpenLevel3(level2, cIndex)"
+                  v-html="level2.label"
+                ></span>
+                <i class="el-icon-arrow-right"></i>
+              </li>
+            </ul>
+          </div>
+        </div>
+        <div class="module-container level-3-container">
+          <header class="module-header"></header>
+          <div class="module-main">
+            <ul>
+              <li
+                class="module-item"
+                v-for="(level3, index) in level3List"
+                :key="level3 + index"
+                v-show="!level3.searchHide"
+              >
+                <el-checkbox
+                  v-model="level3.checked"
+                  :disabled="level3.disabled"
+                  :indeterminate="level3.indeterminate"
+                  @change="onLevel3Change($event, level3)"
+                ></el-checkbox>
+                <span class="item-name" v-html="level3.label"></span>
+              </li>
+            </ul>
+          </div>
+        </div>
+      </div>
+    </div>
+    <template #suffix-icon>
+      <slot name="suffix-icon">
+        <el-tooltip effect="dark" placement="bottom" v-if="showHelpIcon">
+          <div class="iconfont icon-help pointer zhima-bid--icon"></div>
+          <div slot="content" class="zhima-bid-help-tip" v-html="helpIconText"></div>
+        </el-tooltip>
+      </slot>
+    </template>
+  </Layout>
+</template>
+
+<script>
+import { Tag, Checkbox, Input, Tooltip } from 'element-ui'
+import Layout from '@/components/filter-items/Layout.vue'
+
+export default {
+  name: 'ZhiMaBidSelector',
+  components: {
+    [Tag.name]: Tag,
+    [Input.name]: Input,
+    [Checkbox.name]: Checkbox,
+    [Tooltip.name]: Tooltip,
+    Layout
+  },
+  props: {
+    showSearch: {
+      type: Boolean,
+      default: false
+    },
+    sourceList: {
+      type: Array,
+      default: () => [
+        // {
+        //   label: 'xxx',
+        //   value: 'xxx',
+        //   children: [
+        //     {
+        //       label: 'xx',
+        //       value: 'xx'
+        //     }
+        //   ]
+        // }
+      ]
+    },
+    showHelpIcon: {
+      type: Boolean,
+      default: false
+    },
+    helpIconText: {
+      type: String,
+      default: ''
+    },
+    type: {
+      type: String,
+      default: 'dropdown'
+    },
+    trigger: {
+      type: String,
+      default: 'hover'
+    },
+    placeholder: {
+      type: String,
+      default: ''
+    },
+    // 是否展示level1的全部
+    isHaveAll: {
+      type: Boolean,
+      default: true
+    },
+    value: {
+      type: Object,
+      default: () => {}
+    },
+    formatSourceData: Function,
+  },
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  data() {
+    return {
+      searchContent: '',
+      inputFocus: false,
+      tags: [],
+      pActive: 0,
+      cActive: 0,
+      level1List: [],
+      level2List: [],
+      level3List: [],
+      pTimer: null,
+      cTimer: null
+    }
+  },
+  computed: {
+    computedVal() {
+      let count = this.tags.length
+      const value = this.value
+      if (!value) return ''
+      const emptyObj = Object.keys(value).length === 0
+      if (count <= 0 || emptyObj) {
+        return ''
+      } else {
+        return `${this.placeholder}${count}个`
+      }
+    },
+    showedLevel1List() {
+      return this.level1List.filter((v) => !v.searchHide)
+    },
+    // 是否没有搜索到数据
+    searchEmpty() {
+      if (this.searchContent && this.showedLevel1List.length === 0) {
+        return true
+      } else {
+        return false
+      }
+    }
+  },
+  watch: {
+    value(val) {
+      this.setState(val)
+    },
+    searchContent(n) {
+      // 思路:
+      // 1. 对其显示隐藏做标记,level1、level2和level3则用computed过滤
+      //
+      this.calcMatch(n)
+      this.$nextTick(() => {
+        this.openLevel1First()
+      })
+    }
+  },
+  mounted() {
+    this.refreshSourceList(this.sourceList)
+    this.calcMatch()
+  },
+  methods: {
+    calcMatch(searchValue = '') {
+      this.level1List.forEach((level1) => {
+        // 一级匹配
+        const { searchShow: level1ItemShow } = this.doMatch(searchValue, level1)
+        this.$set(level1, 'searchHide', !level1ItemShow)
+        // 二级匹配
+        level1.children.forEach((level2) => {
+          // 如果一级匹配到了,其子集都要显示
+          const { searchShow: level2ItemShow } = this.doMatch(
+            searchValue,
+            level2
+          )
+          let needHide = !level2ItemShow
+          if (level1ItemShow) {
+            needHide = false
+          }
+          this.$set(level2, 'searchHide', needHide)
+          if (level2ItemShow) {
+            this.$set(level1, 'searchHide', false)
+          }
+
+          level2.children.forEach((level3) => {
+            const { searchShow: level3ItemShow } = this.doMatch(
+              searchValue,
+              level3
+            )
+            let needHide = !level3ItemShow
+            if (level1ItemShow || level2ItemShow) {
+              needHide = false
+            }
+            this.$set(level3, 'searchHide', needHide)
+            if (level3ItemShow) {
+              this.$set(level1, 'searchHide', false)
+              this.$set(level2, 'searchHide', false)
+            }
+          })
+        })
+      })
+    },
+    doMatch(searchValue, item) {
+      let notAll = true
+      if (searchValue) {
+        notAll = item.name !== '全部'
+      }
+
+      const matched = item.name?.includes(searchValue)
+      if (matched && searchValue) {
+        item.label = item.name.replace(
+          searchValue,
+          `<span class="highlight-text">${searchValue}</span>`
+        )
+      } else {
+        item.label = item.name
+      }
+
+      let searchShow = true
+      if (searchValue) {
+        searchShow = notAll && matched
+      }
+
+      return {
+        notAll,
+        matched,
+        searchShow
+      }
+    },
+    onFocus() {
+      this.onKeydown()
+      this.inputFocus = true
+    },
+    onBlur() {
+      this.inputFocus = false
+    },
+    refreshSourceList(list) {
+      if (Array.isArray(list)) {
+        this.initAreaMap(list)
+
+        this.$nextTick(() => {
+          this.calcMatch()
+        })
+      }
+    },
+    // 获取选中的数据列表tag
+    getSelectedTags() {
+      const tagsArr = []
+      this.level1List.forEach((level1) => {
+        if (Array.isArray(level1.children)) {
+          level1.children.forEach((level2) => {
+            if (Array.isArray(level2.children)) {
+              level2.children.forEach((level3) => {
+                if (level3.name !== '全部') {
+                  if (level3.checked) {
+                    tagsArr.push(level3.name)
+                  }
+                }
+              })
+            }
+          })
+        }
+      })
+      this.tags = tagsArr
+      return tagsArr
+    },
+    // 整理城市数据列表
+    initAreaMap(list) {
+      const level1List = this.getStandardData(list)
+      // 如果需要包含全国选项
+      if (this.isHaveAll) {
+        level1List.unshift({
+          name: '全部',
+          label: '全部',
+          checked: false,
+          disabled: false,
+          indeterminate: false,
+          children: []
+        })
+      }
+      level1List.forEach((level1) => {
+        level1.children.unshift({
+          name: '全部',
+          label: '全部',
+          checked: false,
+          disabled: false,
+          indeterminate: false,
+          children: []
+        })
+        level1.children.forEach((level2) => {
+          level2.children.unshift({
+            name: '全部',
+            label: '全部',
+            checked: false,
+            disabled: level2.children.length === 0,
+            indeterminate: false
+          })
+        })
+      })
+      this.level1List = level1List
+
+      // 默认打开第一个城市、区县
+      this.openLevel1First()
+    },
+    openLevel1First(level1List = this.level1List) {
+      // 默认打开第一个城市、区县
+      if (this.searchContent) {
+        // 找到子集第一个hide为false的子集展示
+        const r2 = this.findFirstShowChildren(level1List)
+        this.level2List = r2.list
+        this.pActive = r2.index
+        const r3 = this.findFirstShowChildren(this.level2List)
+        this.level3List = r3.list
+        this.cActive = r3.index
+      } else {
+        this.level2List = level1List[0].children
+        this.level3List = level1List[0].children[0].children
+      }
+    },
+    findFirstShowChildren(levelList) {
+      const findIndex = levelList.findIndex((t) => !t.searchHide)
+      if (findIndex > 0) {
+        return {
+          list: levelList[findIndex]?.children || [],
+          index: findIndex
+        }
+      } else {
+        return {
+          list: [],
+          index: 0
+        }
+      }
+    },
+    /**
+     *  返回需要的数组格式
+     */
+    getStandardData(initData = []) {
+      // 处理成标准字段
+      if (this.formatSourceData) {
+        return this.formatSourceData(initData)
+      }
+      const standardData = initData.map((p) => {
+        return {
+          name: p.label,
+          label: p.label,
+          checked: false,
+          disabled: false,
+          indeterminate: false,
+          children: p.children.map((c) => {
+            return {
+              name: c.label,
+              label: c.label,
+              checked: false,
+              disabled: false,
+              indeterminate: false,
+              children: c.children.map((a) => {
+                return {
+                  name: a.label,
+                  label: a.label,
+                  checked: false,
+                  disabled: false
+                }
+              })
+            }
+          })
+        }
+      })
+      return standardData
+    },
+    /**
+     * 将过滤好的地区数据转换成map格式(根据场景需要转换)
+     * 例:{北京:{北京市:[]}, 河南:{ 郑州市:[新郑市, 登封市、金水区]}}
+     */
+    getCitiesToMap(filterData = this.getStandardData()) {
+      const obj = {}
+      if (filterData.length > 0) {
+        filterData.forEach((province) => {
+          const cityMap = {}
+          province.children.forEach((city) => {
+            cityMap[city.name] = city.children.map((v) => v.name)
+          })
+          obj[province.name] = cityMap
+        })
+      }
+      return obj
+    },
+    // 判断全国、全部全选半选状态
+    getAllCheckBoxSelectedStatus() {
+      if (!this.isHaveAll) return
+      const level1List = this.level1List
+      const allProvinceCount = level1List.filter(
+        (v) => v.name !== '全部'
+      ).length
+      const allSelectedProvinceCount = level1List.filter(
+        (v) => v.name !== '全部' && v.checked
+      ).length
+      const allHalfSelectedProvinceCount = level1List.filter(
+        (v) => v.name !== '全部' && v.indeterminate
+      ).length
+      level1List.forEach((province) => {
+        if (allProvinceCount === allSelectedProvinceCount) {
+          level1List[0].checked = true
+          level1List[0].indeterminate = false
+        } else {
+          level1List[0].indeterminate =
+            allSelectedProvinceCount > 0 || allHalfSelectedProvinceCount > 0
+          const allCityCount = province.children.filter(
+            (v) => v.name !== '全部'
+          ).length
+          const allSelectedCityCount = province.children.filter(
+            (v) => v.name !== '全部' && v.checked
+          ).length
+          const allHalfSelectedCityCount = province.children.filter(
+            (v) => v.name !== '全部' && v.indeterminate
+          ).length
+          province.children.forEach((city) => {
+            if (
+              allCityCount === allSelectedCityCount &&
+              allSelectedCityCount > 0
+            ) {
+              province.children[0].checked = true
+              province.children[0].indeterminate = false
+            } else {
+              province.children[0].indeterminate =
+                allSelectedCityCount > 0 || allHalfSelectedCityCount > 0
+              const allDistrictCount = city.children.filter(
+                (v) => v.name !== '全部'
+              ).length
+              const allSelectedDistrictCount = city.children.filter(
+                (v) => v.name !== '全部' && v.checked
+              ).length
+              const allHalfSelectedDistrictCount = city.children.filter(
+                (v) => v.name !== '全部' && v.indeterminate
+              ).length
+              city.children.forEach((district) => {
+                if (
+                  allDistrictCount === allSelectedDistrictCount &&
+                  allSelectedDistrictCount > 0
+                ) {
+                  city.children[0].checked = true
+                  city.children[0].indeterminate = false
+                } else {
+                  city.children[0].indeterminate =
+                    allSelectedDistrictCount > 0 ||
+                    allHalfSelectedDistrictCount > 0
+                }
+              })
+            }
+          })
+        }
+      })
+    },
+    // 点击省展开城市
+    onOpenLevel2(province, pIndex) {
+      this.cActive = 0
+      this.pActive = pIndex
+      this.level3List = []
+      this.level2List = province.children
+      this.level3List = province.children[0].children
+    },
+    // 点击城市展开区县
+    onOpenLevel3(city, cIndex) {
+      this.cActive = cIndex
+      this.level3List = city.children
+    },
+    onLevel1MouseOut(e) {
+      clearTimeout(this.pTimer)
+      this.pTimer = null
+    },
+    onLevel1MouseOver(level1, pIndex) {
+      if (!this.pTimer) {
+        this.pTimer = setTimeout(() => {
+          this.onOpenLevel2(level1, pIndex)
+        }, 150)
+      }
+    },
+    onLevel2MouseOut(e) {
+      clearTimeout(this.cTimer)
+      this.cTimer = null
+    },
+    onLevel2MouseOver(city, cIndex) {
+      if (!this.cTimer) {
+        this.cTimer = setTimeout(() => {
+          this.onOpenLevel3(city, cIndex)
+        }, 150)
+      }
+    },
+    // 设置全国全选、半选状态
+    setWholeCountryCheckedStatus() {
+      const selectedProvince = this.level1List.filter((province) => {
+        return province.checked && province.name !== '全部'
+      })
+      const allProvince = this.level1List.filter((province) => {
+        return province.name !== '全部'
+      })
+      const selectedIndeterminate = this.level1List.filter((province) => {
+        return province.name !== '全部' && province.indeterminate
+      })
+      if (this.isHaveAll) {
+        // 如果有全国选项 则选中的省份数量(排除全国)等于全部省份数量 则绑定全国选中
+        if (selectedProvince.length === allProvince.length) {
+          this.level1List[0].indeterminate = false
+          this.level1List[0].checked = true
+        } else {
+          // 如果选中全国数量不等于全部省份数量 则全国半选  选中数等于0除外
+          this.level1List[0].checked = false
+          this.level1List[0].indeterminate =
+            selectedIndeterminate.length > 0 || selectedProvince.length > 0
+        }
+      }
+      this.getSelectedTags()
+    },
+    // 设置省全选、半选状态
+    setProvinceCheckedStatus() {
+      // 设置当前省份下城市的全选状态(全选、半选)
+      const currentProvince = this.level1List[this.pActive]
+      const selectedCities = currentProvince.children.filter(
+        (v) => v.checked && v.name !== '全部'
+      )
+      const allCities = currentProvince.children.filter(
+        (v) => v.name !== '全部'
+      )
+      const cityIndeterminate = currentProvince.children.filter(
+        (v) => v.name !== '全部' && v.indeterminate
+      )
+      if (selectedCities.length === allCities.length) {
+        this.level1List[this.pActive].checked = true
+        this.level1List[this.pActive].indeterminate = false
+      } else {
+        this.level1List[this.pActive].checked = false
+        this.level1List[this.pActive].indeterminate =
+          selectedCities.length !== 0 || cityIndeterminate.length > 0
+      }
+      currentProvince.children[0].indeterminate =
+        (selectedCities.length !== allCities.length &&
+          selectedCities.length !== 0) ||
+        cityIndeterminate.length > 0
+      currentProvince.children[0].checked =
+        selectedCities.length === allCities.length
+      this.setWholeCountryCheckedStatus()
+    },
+    setCitiesCheckedStatus() {
+      // 设置当前省份下城市的全选状态(全选、半选)
+      const currentCity = this.level2List[this.cActive]
+      const selectedCountry = currentCity.children.filter(
+        (v) => v.checked && v.name !== '全部'
+      )
+      const allCountry = currentCity.children.filter((v) => v.name !== '全部')
+      if (selectedCountry.length === allCountry.length) {
+        currentCity.checked = true
+        currentCity.indeterminate = false
+      } else {
+        currentCity.checked = false
+        currentCity.indeterminate = selectedCountry.length !== 0
+      }
+      // if (this.isHaveAll) {
+      currentCity.children[0].indeterminate =
+        selectedCountry.length !== allCountry.length &&
+        selectedCountry.length !== 0
+      currentCity.children[0].checked =
+        selectedCountry.length === allCountry.length
+      // }
+      this.setProvinceCheckedStatus()
+    },
+    /**
+     * 提取省份checkbox选择状态方法
+     * checked: checkbox点击状态
+     * province: 当前点击的城市数据
+     */
+    setProvinceChangeCommon(checked, province) {
+      // 全国选中/取消选中
+      if (province.name === '全部' || province.name === '全部') {
+        this.level1List.forEach((first) => {
+          first.checked = checked
+          first.indeterminate = false
+          first.children.forEach((second) => {
+            second.checked = checked
+            second.indeterminate = false
+            second.children.forEach((third) => {
+              third.checked = checked
+              third.indeterminate = false
+            })
+          })
+        })
+      } else {
+        // 省份选中/取消选中
+        province.indeterminate = false
+        province.children.forEach((second) => {
+          second.checked = checked
+          second.indeterminate = false
+          second.children.forEach((third) => {
+            third.checked = checked
+            third.indeterminate = false
+          })
+        })
+      }
+      this.setWholeCountryCheckedStatus()
+    },
+    // 省份选中事件
+    onProvinceChange(checked, province, index) {
+      this.onOpenLevel2(province, index)
+      province.checked = checked
+      this.setProvinceChangeCommon(checked, province)
+      this.onSelectChange()
+    },
+    /**
+     * 提取城市checkbox选择状态方法
+     * checked: checkbox点击状态
+     * city: 当前点击的城市数据
+     */
+    setCitiesChangeCommon(checked, city) {
+      if (city.name === '全部') {
+        // 全部城市选中/取消选中
+        this.level1List.forEach((first, index) => {
+          if (this.pActive === index) {
+            first.checked = checked
+            first.indeterminate = false
+            first.children.forEach((second) => {
+              second.checked = checked
+              second.indeterminate = false
+              second.children.forEach((third) => {
+                third.checked = checked
+                third.indeterminate = false
+              })
+            })
+          }
+        })
+      } else {
+        // 当前城市选中/取消选中
+        city.indeterminate = false
+        city.children.forEach((third) => {
+          third.checked = checked
+          third.indeterminate = false
+        })
+      }
+      this.setProvinceCheckedStatus()
+    },
+    // 城市选中事件
+    onCitiesChange(checked, city, cIndex) {
+      this.onOpenLevel3(city, cIndex)
+      // 选择超出可选区域冒泡事件
+      if (checked) {
+        city.checked = true
+        this.setCitiesChangeCommon(checked, city)
+      } else {
+        // 取消选中
+        city.checked = false
+        this.setCitiesChangeCommon(checked, city)
+      }
+      this.onSelectChange()
+    },
+    setCountryChangeCommon(checked, country) {
+      if (country.name === '全部') {
+        this.level3List.forEach((third) => {
+          third.checked = checked
+          third.indeterminate = false
+        })
+        this.setCitiesCheckedStatus()
+      } else {
+        this.setCitiesCheckedStatus()
+      }
+    },
+    // 区县选中事件
+    onLevel3Change(checked, country) {
+      // 选择超出可选区域冒泡事件
+      if (checked) {
+        country.checked = true
+        this.setCountryChangeCommon(checked, country)
+      } else {
+        country.checked = false
+        this.setCountryChangeCommon(checked, country)
+      }
+      this.onSelectChange()
+    },
+    // 下拉框出现/隐藏时触发
+    onVisibleChange(flag) {
+      if (!flag) {
+        this.$emit('hideSelect', this.getState())
+      } else {
+        this.$emit('showSelect', this.getState())
+      }
+    },
+    getDropdownRef() {
+      const layoutRef = this.$refs.layoutRef
+      if (layoutRef) {
+        const dropdownRef = layoutRef.$refs?.dropdownRef
+        return dropdownRef
+      }
+    },
+    onKeyup() {
+      const dropdownRef = this.getDropdownRef()
+      if (dropdownRef) {
+        dropdownRef.visible = true
+      }
+    },
+    // dropdown的坑点,微软输入法,input输入的时候会失去焦,dropdown会收起,暂且如此处理
+    onKeydown() {
+      const dropdownRef = this.getDropdownRef()
+      if (dropdownRef && dropdownRef.show) {
+        dropdownRef.show()
+      }
+    },
+    onNoPowerLimit(payload) {
+      this.$emit('limit', payload)
+    },
+    onSelectChange() {
+      const state = this.getState()
+      this.$emit('change', state)
+    },
+    // 省市县区三级结构拆分省市(省:[市])和区县(地市:[区县])
+    formatProvinceAndCities(regionMap) {
+      let area = {}
+      const district = {}
+      if (Object.keys(regionMap).length === 0) {
+        area = {}
+      } else {
+        for (const key in regionMap) {
+          if (Object.keys(regionMap[key]).length === 0) {
+            area[key] = []
+          } else {
+            const cities = regionMap[key]
+            const cityArr = []
+            for (const city in cities) {
+              cityArr.push(city)
+              area[key] = cityArr
+              if (cities[city].length > 0) {
+                district[city] = cities[city]
+              }
+            }
+          }
+        }
+      }
+      return { area, district }
+    },
+    // 省市县区map转字符串 应用场景:平铺选择结果需要
+    formatRegionToString(regionMap, mark = '、') {
+      if (!regionMap || !Object.keys(regionMap).length) return '全部'
+      const tagsArr = []
+      for (const province in regionMap) {
+        if (Object.keys(regionMap[province]).length === 0) {
+          tagsArr.push(province)
+        } else {
+          const cityObj = regionMap[province]
+          for (const cKey in cityObj) {
+            if (cityObj[cKey].length === 0) {
+              tagsArr.push(cKey)
+            } else {
+              tagsArr.push(...cityObj[cKey])
+            }
+          }
+        }
+      }
+      return tagsArr.join(mark)
+    },
+    // 获取数据,并整理成前端标准格式
+    getState() {
+      let level1List = JSON.parse(JSON.stringify(this.level1List))
+      const allProvinceCount = level1List.filter(
+        (v) => v.name !== '全部'
+      ).length
+      const allSelectedProvinceCount = level1List.filter(
+        (v) => v.name !== '全部' && v.checked
+      ).length
+      const allCountryChecked = level1List.some(
+        (v) => v.name === '全部' && v.checked
+      )
+      const noSelected = level1List.every((v) => !v.checked && !v.indeterminate)
+      let regionMap = null
+      if (noSelected) {
+        // console.log('no region selected')
+      } else {
+        if (
+          allProvinceCount === allSelectedProvinceCount &&
+          allCountryChecked
+        ) {
+          level1List = []
+        } else {
+          level1List.forEach((province) => {
+            const allCityCount = province.children.filter(
+              (v) => v.name !== '全部'
+            ).length
+            const allSelectedCityCount = province.children.filter(
+              (v) => v.name !== '全部' && v.checked
+            ).length
+            if (allCityCount === allSelectedCityCount) {
+              province.children = []
+            } else {
+              province.children.forEach((city) => {
+                const allDistrictCount = city.children.filter(
+                  (v) => v.name !== '全部'
+                ).length
+                const allSelectedDistrictCount = city.children.filter(
+                  (v) => v.name !== '全部' && v.checked
+                ).length
+                if (allDistrictCount === allSelectedDistrictCount) {
+                  city.children = []
+                }
+              })
+            }
+          })
+        }
+        const formatData = level1List.filter((first) => {
+          return (first.checked || first.indeterminate) && first.name !== '全部'
+        })
+        formatData.forEach((second) => {
+          const secondList = second.children.filter((v) => {
+            return (v.checked || v.indeterminate) && v.name !== '全部'
+          })
+          secondList.forEach((item) => {
+            item.children = item.children.filter((v) => {
+              return v.checked && v.name !== '全部'
+            })
+          })
+          second.children = secondList
+        })
+        regionMap = this.getCitiesToMap(formatData)
+      }
+      return regionMap
+    },
+    setState(data = {}) {
+      this.resetState()
+      if (!data) return
+      if (Object.keys(data).length === 0) {
+        // 选择的全国
+        this.level1List.forEach((province) => {
+          province.checked = true
+          province.indeterminate = false
+          province.children.forEach((city) => {
+            city.checked = true
+            city.indeterminate = false
+            city.children.forEach((country) => {
+              country.checked = true
+              country.indeterminate = false
+            })
+          })
+        })
+      } else {
+        // 选择的省
+        const level1List = this.level1List
+        level1List[0].indeterminate = true
+        level1List.forEach((province) => {
+          for (const key in data) {
+            if (province.name === key) {
+              if (Object.keys(data[key]).length === 0) {
+                // 选择的全省(省下的全部地市)
+                province.checked = true
+                province.children.forEach((city) => {
+                  city.checked = true
+                  city.children.forEach((district) => {
+                    district.checked = true
+                  })
+                })
+              } else {
+                // 选择省下的部分地市
+                province.indeterminate = true
+                province.children.forEach((city) => {
+                  for (const cKey in data[key]) {
+                    if (city.name === cKey) {
+                      if (Object.keys(data[key][cKey]).length === 0) {
+                        // 选择的市下的全部区县
+                        city.checked = true
+                        city.children.forEach((district) => {
+                          district.checked = true
+                        })
+                      } else {
+                        // 选择的市下的部分区县
+                        city.indeterminate = true
+                        city.children.forEach((district) => {
+                          if (data[key][cKey].length === 0) {
+                            district.checked = true
+                          } else {
+                            data[key][cKey].forEach((item) => {
+                              if (item === district.name) {
+                                district.checked = true
+                              }
+                            })
+                          }
+                        })
+                      }
+                    }
+                  }
+                })
+                this.getAllCheckBoxSelectedStatus()
+              }
+            }
+          }
+        })
+      }
+      this.getSelectedTags()
+    },
+    resetState() {
+      this.level1List.forEach((province) => {
+        province.checked = false
+        province.indeterminate = false
+        province.children.forEach((city) => {
+          city.checked = false
+          city.indeterminate = false
+          city.children.forEach((country) => {
+            country.checked = false
+            country.indeterminate = false
+          })
+        })
+      })
+      this.tags = []
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.vip-module {
+  .zhima-bid--icon {
+    color: rgba(201, 143, 55, 1) !important;
+  }
+}
+</style>
+<style lang="scss" scoped>
+::v-deep {
+  .el-dropdown-menu.fixed-dropdown {
+    transform: translate(-20px, 0);
+  }
+  .suffix-icon-container {
+    position: relative;
+    z-index: 99;
+  }
+
+  .input-focus {
+    .el-input__suffix-inner {
+      color: $color_main;
+    }
+  }
+}
+.zhima-bid-help-tip {
+  padding: 2px;
+  line-height: 18px;
+}
+
+.zhima-bid--icon {
+  color: $color_main;
+}
+
+.list-empty-container {
+  padding: 8px;
+}
+
+.dropdown-content--wrap {
+  max-width: 580px;
+  background: #fff;
+  border-radius: 5px;
+  border: 1px solid $color_main;
+  overflow: hidden;
+  .dropdown-content--hd {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 8px;
+    font-size: 14px;
+    line-height: 22px;
+    .dropdown-content--hd-left {
+      margin-right: 12px;
+      flex: 1;
+    }
+    ::v-deep {
+      .el-input__icon {
+        font-size: 16px;
+      }
+    }
+  }
+  .select--result {
+    display: flex;
+    flex-wrap: wrap;
+    padding: 8px 0 0px;
+    max-height: 100px;
+    overflow-y: auto;
+    &::-webkit-scrollbar {
+      width: 4px;
+    }
+  }
+  .dropdown-content--bd {
+    display: flex;
+    align-items: center;
+    border-top: 1px solid #ececec;
+    height: 360px;
+    overflow: hidden;
+  }
+  .level-1-container {
+    min-width: 140px;
+    border-right: 1px solid #ececec;
+  }
+  .level-2-container {
+    min-width: 180px;
+    white-space: nowrap;
+  }
+  .level-3-container {
+    min-width: 220px;
+    white-space: nowrap;
+  }
+  .level-2-container {
+    border-right: 1px solid #ececec;
+  }
+  .module-container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+  }
+  .module-header {
+    // padding: 12px 11px;
+    // color:#999999;
+    // font-size: 14px;
+    // line-height: 22px;
+  }
+  .module-main {
+    flex: 1;
+    overflow-y: scroll;
+  }
+  .module-item {
+    position: relative;
+    display: flex;
+    align-items: center;
+    padding: 4px 8px;
+    min-height: 30px;
+    font-size: 14px;
+    line-height: 22px;
+    color: #1d1d1d;
+    &.active,
+    &:hover {
+      background: #ececec;
+      cursor: pointer;
+    }
+    .item-name {
+      flex: 1;
+      margin-left: 4px;
+      white-space: pre-wrap;
+    }
+  }
+  ::v-deep {
+    .el-tag {
+      width: auto;
+      max-width: unset !important;
+      margin: 0 0 8px 8px;
+      &.el-tag--info {
+        height: 24px;
+        line-height: 22px;
+        background: #f5f6f7;
+        color: #1d1d1d;
+        border: 1px solid#ececec;
+        font-size: 14px;
+      }
+      .el-tag__close.el-icon-close {
+        background: transparent;
+        color: #aaa;
+        font-size: 15px;
+        right: -4px;
+      }
+      &:hover {
+        color: $color-text--highlight;
+        border-color: $color-text--highlight;
+        background: #fff;
+        cursor: pointer;
+        .el-tag__close {
+          color: $color-text--highlight;
+        }
+      }
+    }
+  }
+  .module-main::-webkit-scrollbar {
+    width: 4px;
+  }
+}
+</style>

+ 13 - 1
apps/bigmember_pc/src/components/filter-items/ContactSelector.vue

@@ -43,6 +43,10 @@ export default {
       type: String,
       default: 'winner'
     },
+    allValue: {
+      type: String,
+      default: ''
+    },
     options: {
       type: Array,
       default: () => [
@@ -77,7 +81,15 @@ export default {
     computedVal () {
       if (this.value) {
         const item = this.calcOptions.find(v => v.value === this.value)
-        return item.label
+        if (this.allValue) {
+          if (item.value === this.allValue) {
+            return ''
+          } else {
+            return item.label
+          }
+        } else {
+          return item.label
+        }
       } else {
         return ''
       }

+ 1 - 0
apps/bigmember_pc/src/router/router-interceptors.js

@@ -48,6 +48,7 @@ const powerCheckWhiteList = [
   'recommen-list',
   'business_detail',
   'bidding-search',
+  'sun-search',
   'ent-search',
   'purchase-search',
   'supply-search',

+ 15 - 0
apps/bigmember_pc/src/utils/format/date.js

@@ -37,6 +37,21 @@ export function calcNotExactTime(exact = 'lately7', unit = 'ms') {
       t.end = dayjs().endOf('day').valueOf() // 当天23:59:59时间戳
       break
     }
+    case 'tomorrow': {
+      t.start = dayjs().add(1, 'days').startOf('day').valueOf()
+      t.end = dayjs().add(1, 'days').endOf('day').valueOf()
+      break
+    }
+    case 'next7days': {
+      t.start = dayjs().valueOf()
+      t.end = dayjs().add(7, 'days').endOf('day').valueOf()
+      break
+    }
+    case 'next30days': {
+      t.start = dayjs().valueOf()
+      t.end = dayjs().add(30, 'days').endOf('day').valueOf()
+      break
+    }
     case 'yesterday': {
       t.start = dayjs().startOf('day').valueOf() - durations.day1
       t.end = dayjs().endOf('day').valueOf() - durations.day1

+ 68 - 0
apps/bigmember_pc/src/utils/format/search-bid-filter.js

@@ -806,6 +806,30 @@ export class FilterHistoryViewModel2AjaxModel {
     }
     return result
   }
+   
+  /**
+   * 三级领域格式化
+   *  String area
+   *  String city
+   * returns Object
+   *
+   * {
+   *    aaaa: {
+   *      aabb: [],
+   *      aacc: []
+   *    },
+   *    bbb: {
+   *      ff: [],
+   *      ff: ['hhh'],
+   *      gg: ['kk']
+   *    },
+   *    eee: {}
+   * }
+   * 
+   */
+  static formatLingyu(p = {}, split = ',') {
+    return threeObjToSingle(p, split)
+  }
 }
 
 /**
@@ -1504,6 +1528,50 @@ export class FilterModel2ViewModel {
   }
 }
 
+function threeObjToSingle(obj, split = ',') {
+  const map = {
+    area: '',
+    city: '',
+    district: ''
+  }
+  if (!obj)
+    return map
+  const area = []
+  const city = []
+  let district = []
+  for (const key in obj) {
+    if (typeof obj[key] === 'object') {
+      if (Object.keys(obj[key]).length === 0) {
+        area.push(key)
+      }
+      else {
+        // 城市项
+        const cityItem = obj[key]
+        for (const cKey in cityItem) {
+          // 区县项
+          const districtItem = cityItem[cKey]
+          if (Array.isArray(districtItem)) {
+            if (districtItem.length === 0) {
+              city.push(cKey)
+            }
+            else {
+              const resetArr = districtItem.map((temp) => {
+                return temp
+              })
+              district = district.concat(resetArr)
+            }
+          }
+        }
+      }
+    }
+  }
+  return {
+    first: area.join(split),
+    second: city.join(split),
+    third: district.join(split)
+  }
+}
+
 /**
  * 三级地区对象转换成,单个area、city、district
  */

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

@@ -141,10 +141,10 @@ export function useSearchFilterModel(conf) {
       publishTime: rPublishTime,
       selectType: filterState.value.selectType.join(','),
       subtype: rSubtype,
-      exclusionWords: notkey.join(','), // 排除词
-      buyer: filterState.value.buyer.join(','),
-      winner: filterState.value.winner.join(','),
-      agency: filterState.value.agency.join(','),
+      exclusionWords: notkey?.join(','), // 排除词
+      buyer: filterState.value.buyer?.join(','),
+      winner: filterState.value.winner?.join(','),
+      agency: filterState.value.agency?.join(','),
       industry: !isBidField ? rIndustry : '',
       province: area,
       city,

+ 4 - 2
apps/bigmember_pc/src/views/search/components/SearchHeader.vue

@@ -175,13 +175,15 @@ export default {
       })
     },
     mouseoverHandle () {
-      $('.search-right-wx .search-right-wx-inner').css({
+      const wrapper = this.$querySelector('.search-right-wx')
+      $(wrapper).find('.search-right-wx-inner').css({
         "transform":"scale(1)",
         "transition":"transform 0.8s"
       })
     },
     mouseleaveHandle () {
-      $('.search-right-wx .search-right-wx-inner').css({
+      const wrapper = this.$querySelector('.search-right-wx')
+      $(wrapper).find('.search-right-wx-inner').css({
         "transform":"scale(0)",
         "transition":"transform 0.2s"
       })

+ 37 - 32
apps/bigmember_pc/src/views/search/sun/constant/search-filters.js

@@ -5,7 +5,10 @@ import ContactSelector from '@/components/filter-items/ContactSelector.vue'
 import AttachmentSelector from '@/components/filter-items/AttachmentSelector.vue'
 import IndustrySelector from '@/components/filter-items/IndustrySelector.vue'
 import RegionSelector from '@/components/filter-items/RegionSelector'
+import CommonThreeSelector from '@/components/filter-items/CommonThreeSelector'
 import SelectorWithBasePower from '@/components/filter-items/SelectorWithBasePower.vue'
+import { lingyuDataSource } from '@/assets/js/selector/source'
+import { cloneDeep } from 'lodash'
 import $bus from '@/utils/bus'
 
 function noPower() {
@@ -102,7 +105,7 @@ function createSearchBidBaseSchema(conf = {}) {
     },
     {
       label: '标的名称',
-      value: 'ppa'
+      value: 'purchasing'
     },
   ]
   const freeOptions = defaultScopeOptions
@@ -163,10 +166,10 @@ function createSearchBidBaseSchema(conf = {}) {
       expand: vipUser ? searchScopeExpandVip : searchScopeExpandFree
     },
     {
-      key: 'baomingjiezhizhuangtai',
+      key: 'bmjzzt',
       label: '报名截止状态:',
       defaultVal: '0',
-      _name: 'baomingjiezhizhuangtai',
+      _name: 'bmjzzt',
       _type: 'component',
       labelHeight: '25px',
       labelStyle: {
@@ -186,7 +189,7 @@ function createSearchBidBaseSchema(conf = {}) {
             },
             {
               label: '已截止',
-              value: '-1'
+              value: '2'
             }
           ],
           showHeader: false
@@ -195,10 +198,10 @@ function createSearchBidBaseSchema(conf = {}) {
       },
     },
     {
-      key: 'baomingjiezhiriqi',
+      key: 'signUpEndTime',
       label: '报名截止日期:',
-      defaultVal: 'thisyear',
-      _name: 'baomingjiezhiriqi',
+      defaultVal: '',
+      _name: 'signUpEndTime',
       _type: 'component',
       labelStyle: {
         width: '100px',
@@ -227,7 +230,7 @@ function createSearchBidMoreSchema(filterItems, conf) {
 
   let SearchBidMoreSchema = [
     {
-      key: 'jiaofudidian',
+      key: 'jfArea',
       label: '交付地点',
       defaultVal: '',
       _name: 'type',
@@ -246,7 +249,7 @@ function createSearchBidMoreSchema(filterItems, conf) {
       }
     },
     {
-      key: 'xiangmudiqu',
+      key: 'projectArea',
       label: '项目地区',
       defaultVal: '',
       _name: 'type',
@@ -263,24 +266,25 @@ function createSearchBidMoreSchema(filterItems, conf) {
         }
       }
     },
-    {
-      key: 'lingyu',
-      label: '领域',
-      defaultVal: '',
-      _name: 'type',
-      _type: 'component',
-      expand: {
-        component: RegionSelector,
-        props: {
-          vip: true,
-          showCount: false,
-          placeholder: '领域'
-        },
-        hooks: {
-          limit: noPower
-        }
-      }
-    },
+    // {
+    //   key: 'lingyu',
+    //   label: '领域',
+    //   defaultVal: '',
+    //   _name: 'type',
+    //   _type: 'component',
+    //   expand: {
+    //     component: CommonThreeSelector,
+    //     props: {
+    //       sourceList: lingyuDataSource,
+    //       vip: true,
+    //       showCount: false,
+    //       placeholder: '领域'
+    //     },
+    //     hooks: {
+    //       limit: noPower
+    //     }
+    //   }
+    // },
     {
       key: 'industry',
       label: '行业',
@@ -295,7 +299,7 @@ function createSearchBidMoreSchema(filterItems, conf) {
     {
       key: 'fileExists',
       label: '附件',
-      defaultVal: '',
+      defaultVal: '0',
       _name: 'type',
       _type: 'component',
       expand: {
@@ -306,25 +310,26 @@ function createSearchBidMoreSchema(filterItems, conf) {
     {
       key: 'publisher',
       label: '发布方',
-      defaultVal: '',
+      defaultVal: '0',
       _name: 'type',
       _type: 'component',
       expand: {
         component: ContactSelector,
         props: {
+          allValue: '0',
           placeholder: '发布方',
           options: [
             {
               label: '全部',
-              value: ''
+              value: '0'
             },
             {
               label: '用户发布',
-              value: 'y'
+              value: '1'
             },
             {
               label: '平台发布',
-              value: 'm'
+              value: '2'
             }
           ]
         },

+ 12 - 9
apps/bigmember_pc/src/views/search/sun/index.vue

@@ -11,13 +11,10 @@ import CollectInfo from '@/components/collect-info/CollectInfo.vue'
 import CustomDialog from '@/components/dialog/Dialog.vue'
 import ExportTip from '@/views/portrayal/components/DataExportTip.vue'
 import powerPerson from '@/components/subscribe-manager/powerPerson.vue'
-import BidrenewalDialog from '@/views/BidrenewalDialog/index.vue'
 import Empty from '@/components/common/Empty.vue'
-import recommendCard from './components/recommend-card.vue'
 import { openLinkInWorkspace } from '@/utils/'
 // 导入业务模型
 import { useSearchBidModel, SearchBidModel } from './model/index'
-import { getMsgDistributor } from '@/api/modules/'
 import { useRouter } from 'vue-router/composables'
 
 const router = useRouter()
@@ -59,8 +56,8 @@ const {
   onClickSingleCollect,
   usePowerRef,
   doSubmitDistribute,
-  onJoinBid,
-  BidrenewalDialogRef,
+  // onJoinBid,
+  // BidrenewalDialogRef,
   showPropertyDialog,
   propertyIframeSrc,
   onSingleEmploy,
@@ -97,8 +94,9 @@ const articleRef = ref({
   table: false,
   collect: false,
   push: false,
-  tagUserPublishState: false,
-  tagBidEnd: false,
+  tagUserPublishState: true,
+  tagSignupEnd: true,
+  jfArea: true
 })
 
 const goToBidSearchPage = () => {
@@ -113,6 +111,11 @@ const goToBidSearchPage = () => {
     window.open(url)
   }
 }
+
+const leaveSource = () => {
+  collectElementRef.value.isNeedSubmit('pc_sunlightlist_viewdetails', () => {})
+}
+
 </script>
 
 <template>
@@ -190,7 +193,7 @@ const goToBidSearchPage = () => {
               @onClick="toDetail(item)"
               @tag-click="tagToDetail(item, $event)"
               @onCollect="onClickSingleCollect"
-              @onJoinBid="onJoinBid"
+              @leaveInfo="leaveSource"
               :config="articleRef"
             >
               <template #bi-slot="{ item }"> </template>
@@ -344,7 +347,7 @@ const goToBidSearchPage = () => {
       ref="usePowerRef"
     ></power-person>
     <!-- 参标更新状态弹窗 -->
-    <bidrenewal-dialog ref="BidrenewalDialogRef"> </bidrenewal-dialog>
+    <!-- <bidrenewal-dialog ref="BidrenewalDialogRef"> </bidrenewal-dialog> -->
 
     <!--    物业专版收录-->
     <el-dialog

+ 37 - 29
apps/bigmember_pc/src/views/search/sun/model/base.js

@@ -8,6 +8,7 @@ import  {
   FilterHistoryAjaxModel2ViewModel,
   FilterModel2ViewModel,
   getParam,
+  dateFormatter,
   openLinkInWorkspace,
   InContainer
 } from '@/utils'
@@ -82,7 +83,7 @@ export default function () {
   })
 
   // 获取搜索历史业务数据模型
-  const searchHistoryModel = useSearchHistoryModel({ type: 1 })
+  const searchHistoryModel = useSearchHistoryModel({ type: 6 })
   const { getHistoryQuery, clearHistoryQuery, searchHistoryList } = searchHistoryModel
 
   // 标讯搜索历史列表
@@ -95,14 +96,11 @@ export default function () {
 
   // 是否在工作台内
   // 本地调试,可改为工作台内isInApp = ref(true),  isInWeb = ref(false)   提交记得改回!
-  // const isInApp = ref(InContainer.inApp) // InContainer.inApp
-  // const isInWeb = ref(InContainer.inWeb) // InContainer.inWeb
+  const isInApp = ref(InContainer.inApp) // InContainer.inApp
+  const isInWeb = ref(InContainer.inWeb) // InContainer.inWeb
 
-  const isInApp = ref(true)
-  const isInWeb = ref(false)
-
-  // const isInApp = ref(false)
-  // const isInWeb = ref(true)
+  // isInApp.value = true
+  // isInWeb.value = false
 
   // 是否是渠道商
   const cooperateCode = ref(false)
@@ -139,23 +137,23 @@ export default function () {
   // 缓存存储配置
   const storageConfig = {
     listTab: {
-      key: 'pc_search_bidding_listTabActive',
+      key: 'pc_search_sun_listTabActive',
       _storage: localStorage
     },
     // 筛选条件上次搜索筛选项缓存key
     filter: {
-      key: 'pc_search_bidding_lastFilters',
+      key: 'pc_search_sun_lastFilters',
       _storage: localStorage
     },
     // 页面tab(筛选项的searchGroup)
     searchGroup: {
-      key: 'pc_search_bidding_lastSearchGroup',
+      key: 'pc_search_sun_lastSearchGroup',
       _storage: localStorage
     }
   }
   // 解构基础业务
   const APIModel = useQuickSearchModel({
-    type: 'search-bid'
+    type: 'search-sun'
   })
   /**
    * 列表相关model
@@ -778,15 +776,15 @@ export default function () {
 
     if(isLogin.value) {
       // 获取参标的数据
-      getJoinBidInfo(listIds.value)
+      // getJoinBidInfo(listIds.value)
       // BI 是否批量收录,获取收录数据
-      if(inBIPropertyIframe || inResourceBIIframe) {
-        getEmployData(listIds.value)
-      }
+      // if(inBIPropertyIframe || inResourceBIIframe) {
+      //   getEmployData(listIds.value)
+      // }
       // 个人报告嵌套BI页面
-      if(inInjectBI) {
-        getBidAddInfos()
-      }
+      // if(inInjectBI) {
+      //   getBidAddInfos()
+      // }
 
     }
     list.value = list.value.map(item => {
@@ -803,6 +801,16 @@ export default function () {
       // 收录字段
       that.$set(item, 'isEmploy', false)
 
+      // that.$set(item, 'publicType', '用户发布')
+      // 计算截止时间
+      if (item.signEndTime) {
+        const now = Date.now()
+        const signupEnd = item.signEndTime * 1000 < now
+        const signEndTimeText = dateFormatter(item.signEndTime * 1000, 'yyyy-MM-dd  HH:mm')
+        that.$set(item, 'signupEnd', signupEnd)
+        that.$set(item, 'signEndTimeText', signEndTimeText)
+      }
+
       return item
     })
 
@@ -1136,19 +1144,19 @@ export default function () {
 
   /********参标start *********/
   // 参标只有莱茵有权限
-  const {
-    BidrenewalDialogRef,
-    getJoinBidInfo,
-    onJoinBid
-  } = joinBidActionsModel ()
+  // const {
+  //   BidrenewalDialogRef,
+  //   getJoinBidInfo,
+  //   onJoinBid
+  // } = joinBidActionsModel ()
 
   // 窗口切换刷新参标数据
   document.addEventListener('visibilitychange', function () {
     if (document.visibilityState === 'visible') {
       that.$visited.refreshVisited()
-      if(isLogin.value) {
-        getJoinBidInfo(listIds.value)
-      }
+      // if(isLogin.value) {
+      //   getJoinBidInfo(listIds.value)
+      // }
     }
   })
 
@@ -1601,8 +1609,8 @@ export default function () {
     onClickSingleCollect, // 收藏
     usePowerRef, // 以下分发相关
     doSubmitDistribute,
-    onJoinBid,//以下 参标
-    BidrenewalDialogRef,
+    // onJoinBid,//以下 参标
+    // BidrenewalDialogRef,
     showPropertyDialog,// 以下收录
     propertyIframeSrc,
     onSingleEmploy,

+ 40 - 68
apps/bigmember_pc/src/views/search/sun/model/modules/filter.js

@@ -11,23 +11,23 @@ export function useSearchFilterModel(conf) {
     // 发布时间
     publishTime: 'thisyear',
     // 搜索范围
-    selectType: ['title', 'content'],
+    selectType: ['title', 'purchasing'],
     // 报名截止状态
-    baomingjiezhizhuangtai: '0',
+    bmjzzt: '0',
     // 报名截止时间
-    baomingjiezhiriqi: 'fiveyear',
+    signUpEndTime: '',
     // 交付地点
-    jiaofudidian: {},
+    jfArea: {},
     // 项目地区
-    xiangmudiqu: {},
+    projectArea: {},
     // 领域
     lingyu: {},
     // 行业
     industry: {},
     // 附件
-    fileExists: '',
+    fileExists: '0',
     // 发布方
-    publisher: '',
+    publisher: '0',
   }
 
   // 筛选组件状态
@@ -35,23 +35,23 @@ export function useSearchFilterModel(conf) {
     // 发布时间
     publishTime: 'thisyear',
     // 搜索范围
-    selectType: ['title', 'content'],
+    selectType: ['title', 'purchasing'],
     // 报名截止状态
-    baomingjiezhizhuangtai: '0',
+    bmjzzt: '0',
     // 报名截止时间
-    baomingjiezhiriqi: '',
+    signUpEndTime: '',
     // 交付地点
-    jiaofudidian: {},
+    jfArea: {},
     // 项目地区
-    xiangmudiqu: {},
+    projectArea: {},
     // 领域
     lingyu: {},
     // 行业
     industry: {},
     // 附件
-    fileExists: '',
+    fileExists: '0',
     // 发布方
-    publisher: '',
+    publisher: '0',
   })
   const filterState = ref({})
   filterState.value = filterBase.value
@@ -61,61 +61,33 @@ export function useSearchFilterModel(conf) {
  }
   // 格式化招标采购基础筛选条件
   function getFormatApiBaseParams () {
-    const { publishTime, baomingjiezhizhuangtai, baomingjiezhiriqi, buyerclass, fileExists, publisher } = filterState.value
-    // const { area, city, district } = FilterHistoryViewModel2AjaxModel.formatAreaCity(regionMap)
-    // const rPublishTime = publishTime?.indexOf('_') > -1 ? FilterHistoryViewModel2AjaxModel.formatExactTime(publishTime, '-') :  FilterHistoryViewModel2AjaxModel.formatTime(publishTime, true, '-')
-    // const rIndustry = FilterHistoryViewModel2AjaxModel.formatIndustry(industry)
-    // const rBuyerClass = FilterHistoryViewModel2AjaxModel.formatBuyerClass(buyerclass)
-    // const rSubtype = FilterHistoryViewModel2AjaxModel.formatInfoType(subtype)
-    // const expandTag = {}
-    // if(typeof (_expand) === 'object' && Object.keys(_expand).length > 0) {
-    //   for(let key in _expand) {
-    //     expandTag[key] = filterState.value[key]
-    //     _expand[key] = filterState.value[key]
-    //   }
-    // }
+    const { publishTime, bmjzzt, signUpEndTime, industry, publisher, jfArea, projectArea: pArea, lingyu } = filterState.value
+    const { area: deliveryArea, city: deliveryCity, district: deliveryDistrict } = FilterHistoryViewModel2AjaxModel.formatAreaCity(jfArea)
+    const { area: projectArea, city: projectCity, district: projectDistrict } = FilterHistoryViewModel2AjaxModel.formatAreaCity(pArea)
+    const { first: domainFirstType, second: domainSecondType, third: domainThirdType } = FilterHistoryViewModel2AjaxModel.formatLingyu(lingyu)
+    const rPublishTime = publishTime?.indexOf('_') > -1 ? FilterHistoryViewModel2AjaxModel.formatExactTime(publishTime, '-') :  FilterHistoryViewModel2AjaxModel.formatTime(publishTime, true, '-')
+    const rSignUpEndTime = signUpEndTime?.indexOf('_') > -1 ? FilterHistoryViewModel2AjaxModel.formatExactTime(signUpEndTime, '-') :  FilterHistoryViewModel2AjaxModel.formatTime(signUpEndTime, true, '-')
+    const rIndustry = FilterHistoryViewModel2AjaxModel.formatIndustry(industry)
 
-
-    // // 搜索范围
-    // selectType: ['title', 'content'],
-    // // 报名截止状态
-    // baomingjiezhizhuangtai: '0',
-    // // 报名截止时间
-    // baomingjiezhiriqi: 'fiveyear',
-    // // 交付地点
-    // jiaofudidian: {},
-    // // 项目地区
-    // xiangmudiqu: {},
-    // // 领域
-    // lingyu: {},
-    // // 行业
-    // industry: {},
-    // // 附件
-    // fileExists: '',
-    // // 发布方
-    // publisher: '',
-
-    // const params = {
-    //   bidField: filterState.value.bidField,
-    //   publishTime: rPublishTime,
-    //   selectType: filterState.value.selectType.join(','),
-    //   subtype: rSubtype,
-    //   exclusionWords: notkey.join(','), // 排除词
-    //   buyer: filterState.value.buyer.join(','),
-    //   winner: filterState.value.winner.join(','),
-    //   agency: filterState.value.agency.join(','),
-    //   industry: !isBidField ? rIndustry : '',
-    //   province: area,
-    //   city,
-    //   district,
-    //   buyerClass: !isBidField ? rBuyerClass : '',
-    //   fileExists: filterState.value.fileExists,
-    //   price: filterState.value.price,
-    //   buyerTel: filterState.value.buyertel,
-    //   winnerTel: filterState.value.winnertel,
-    //   ...expandTag
-    // }
-    const params = {}
+    const params = {
+      publishTime: rPublishTime,
+      selectType: filterState.value.selectType.join(','),
+      deadlineStatus: bmjzzt - 0,
+      deadlineTime: rSignUpEndTime, // 排除词
+      domainFirstType,
+      domainSecondType,
+      domainThirdType,
+      deliveryArea,
+      deliveryCity,
+      deliveryDistrict,
+      projectArea,
+      projectCity,
+      projectArea,
+      projectDistrict,
+      industry: rIndustry,
+      publisher: publisher - 0,
+      fileExists: filterState.value.fileExists - 0,
+    }
     return params
   }
   // 格式化物业专版的筛选条件

+ 8 - 0
data/data-models/modules/quick-search/api/search-sun.js

@@ -0,0 +1,8 @@
+import { useRequest } from '../../../api'
+export function ajaxGetSearchSunList(type, data) {
+  return useRequest({
+    url: `/jyapi/jybx/core/purchaseSearch`,
+    method: 'post',
+    data
+  })
+}

+ 3 - 0
data/data-models/modules/quick-search/model/index.js

@@ -5,12 +5,15 @@ import SearchEntListApi from '../plugins/search-ent'
 import SearchSupplyListApi from '../plugins/search-supply'
 import SearchPurchaseListApi from '../plugins/search-purchase'
 import SearchNzjListApi from '../plugins/search-nzj'
+import SearchSunListApi from '../plugins/search-sun'
+
 
 const APIS = {
   'search-bid': SearchBidListApi,
   'search-ent': SearchEntListApi,
   'search-supply': SearchSupplyListApi,
   'search-purchase': SearchPurchaseListApi,
+  'search-sun': SearchSunListApi,
   'search-nzj': SearchNzjListApi
 }
 

+ 26 - 0
data/data-models/modules/quick-search/plugins/search-sun.js

@@ -0,0 +1,26 @@
+import SearchListApiBase from './base'
+import { ajaxGetSearchSunList } from '../api/search-sun'
+
+export default class SearchBidListApi extends SearchListApiBase {
+  constructor(config) {
+    super(config)
+  }
+
+  /**
+   * 覆写请求
+   */
+  async ajaxQuery(params) {
+    const type = params._expand.type
+    delete params._expand
+    return ajaxGetSearchSunList(type, params).then((res) => {
+      let success = res?.error_code === 0
+
+      return {
+        success: success,
+        list: res.data?.list || [],
+        total: res.data?.total || 0,
+        origin: res.data
+      }
+    })
+  }
+}