瀏覽代碼

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

zhangsiya 1 年之前
父節點
當前提交
1c26b83fb2

+ 26 - 0
apps/bigmember_pc/src/api/modules/search.js

@@ -8,3 +8,29 @@ export function checkBiddingFilterPass(data) {
     data: data
   })
 }
+// 添加筛选条件
+export function addBiddingFilter(data) {
+  return request({
+    url: '/jyapi/jybx/base/addSearchScreen',
+    method: 'post',
+    data
+  })
+}
+
+// 获取已存筛选列表
+export function getBiddingFilterList() {
+  return request({
+    url: '/jyapi/jybx/base/showSearchScreen',
+    method: 'post',
+    noToast: true
+  })
+}
+
+// 删除/批量删除已存筛选
+export function deleteBiddingFilter(data) {
+  return request({
+    url: '/jyapi/jybx/base/delSearchScreen',
+    method: 'post',
+    data
+  })
+}

+ 44 - 0
apps/bigmember_pc/src/assets/style/common.scss

@@ -217,3 +217,47 @@ input[type='number'] {
     transform: translate3d(0, -50%, 0);
   }
 }
+
+/* 删除筛选提示框 */
+.filter-delete-messagebox{
+  width: 420px;
+  border-radius: 8px;
+  padding: 32px;
+  .el-message-box__title{
+    color: #1D1D1D;
+  }
+  .el-message-box__header{
+    padding: 0!important;
+  }
+  .el-message-box__content{
+    padding: 20px 27px 32px;
+  }
+  .el-message-box__message p{
+    font-size: 14px;
+    color: #686868;
+  }
+  .el-message-box__btns{
+    display: flex;
+    flex-direction: row-reverse;
+    justify-content: space-between;
+  }
+  .btn-group.confirm-btn{
+    background: #2cb7ca;
+    margin-right: 52px;
+    border: 0;
+    color: #fff;
+  }
+  .btn-group{
+    width: 132px;
+    height: 36px;
+    padding: 0;
+    border-radius: 6px;
+    font-size: 16px;
+  }
+  .btn-group.confirm-btn:focus{
+    color: #fff;
+  }
+  .btn-group.confirm-btn:hover {
+    color: #fff;
+  }
+}

+ 215 - 0
apps/bigmember_pc/src/views/search/bidding/components/history-filter-dialog.vue

@@ -0,0 +1,215 @@
+<script setup>
+import { SearchBidModel } from '../model'
+import { computed } from 'vue'
+
+const { filterHistoryList: filterData, onHasToggle, onDeleteFilter, onSelectedFilter} = SearchBidModel
+
+ const props = defineProps({
+   visible: {
+     type: Boolean,
+     default: false
+    }
+ })
+
+// 关键词
+function formatToSpace (keywords, additionalWords, wordsModeText) {
+  let str = ''
+  if (additionalWords) {
+    if(keywords) {
+      str += ','
+    }
+    str += additionalWords.replace(/,/g, ",")  +'(' + wordsModeText + ')'
+  }
+  return str
+}
+
+const emit = defineEmits(['before-close'])
+function beforeClose () {
+  emit('before-close')
+}
+
+</script>
+
+<template>
+  <!-- 已存筛选弹框 -->
+  <el-dialog
+    custom-class="filter-dialog has-filter-dialog"
+    title="已存筛选条件"
+    :close-on-click-modal="true"
+    :close-on-press-escape="false"
+    width="750"
+    :center="true"
+    :visible.sync="visible"
+    :before-close='beforeClose'
+  >
+    <div class="filter-data-container">
+      <div v-for="item in filterData" class="filter-data-list">
+        <div class="f-l-title">
+          <div style="display: flex;align-items: center;flex:1;">
+            <i class="iconfont icon-xiala" :class="{ 'is-reverse': item.open}" @click="onHasToggle(item)"></i>
+            <span class="f-l-title-text" @click="onSelectedFilter(item)">
+              {{ item.keywords }}
+              <span v-if="item.additionalWords">{{ formatToSpace(item.keywords, item.additionalWords, item.wordsModeText) }}</span>
+            </span>
+          </div>
+          <i class="iconfont icon-delete" @click="onDeleteFilter(item)"></i>
+        </div>
+        <div class="has-search-model">搜索模式:{{ item.searchModeText}}</div>
+        <el-collapse-transition :collapse-transition="false">
+          <div v-show="item.open">
+            <div class="f-l-content" @click="onSelectedFilter(item)">
+              <p class="f-l-c-item">搜索范围:<em class="i-value">{{ item.scopeText }}</em></p>
+              <p class="f-l-c-item" v-if="item.industry">行业:<em class="i-value">{{ item.industryText }}</em></p>
+              <p class="f-l-c-item">
+                <span v-if="item.minprice || item.maxprice">价格区间:<em class="i-value">{{ item.price }}</em></span>
+                <span v-if="item.publishTimeText">发布时间:<em class="i-value">{{ item.publishTimeText }}</em></span>
+                <span v-if="item.fileExists != 0">附件:<em class="i-value">{{ item.fileExists }}</em></span>
+              </p>
+              <p class="f-l-c-item" v-if="item.regionMap">项目地区:<em class="i-value">{{ item.regionMap }}</em></p>
+              <p class="f-l-c-item" v-if="item.subtype">信息类型:<em class="i-value">{{ item.infoTypeText }}</em></p>
+              <p class="f-l-c-item" v-if="item.buyerclass">采购单位类型:<em class="i-value">{{ item.buyerClassText }}</em></p>
+              <p class="f-l-c-item">
+                <span v-if="item.buyertel == 'y'">采购单位联系方式:<em class="i-value">{{ item.buyerTelText }}</em></span>
+                <span v-if="item.winnertel == 'y'">中标单位联系方式:<em class="i-value">{{ item.winnerTelText }}</em></span>
+                <span v-if="item.notkey">排除词:<em class="i-value">{{ item.notkey }}</em></span>
+              </p>
+              <p class="f-l-c-item" v-if="item.buyer">采购单位:<em class="i-value">{{ item.buyer }}</em></p>
+              <p class="f-l-c-item" v-if="item.winner">中标企业:<em class="i-value">{{ item.winner }}</em></p>
+              <p class="f-l-c-item" v-if="item.agency">招标代理机构:<em class="i-value">{{ item.agency }}</em></p>
+            </div>
+          </div>
+        </el-collapse-transition>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+
+<style lang='scss' scoped>
+
+::v-deep {
+  .filter-dialog{
+    padding: 32px;
+    border-radius: 8px!important;
+    & ::-webkit-scrollbar {
+      /*滚动条整体样式*/
+      width: 2px!important;
+    }
+  }
+  .el-dialog{
+    width: 750px !important;
+  }
+  .el-dialog__body{
+    padding: 0;
+  }
+}
+.filter-dialog{
+  .el-dialog__header {
+    padding: 0;
+    .el-dialog__title{
+      color: #1D1D1D;
+    }
+  }
+  .el-dialog__body{
+    width: 686px;
+    overflow: hidden;
+  }
+  .filter-data-container{
+    max-height: 400px;
+    overflow-y: scroll;
+    width: 694px;
+  }
+  .filter-data-container {
+    max-height: 400px;
+    overflow-y: scroll;
+    width: 694px;
+
+    .f-l-title{
+      padding: 8px 0 2px;
+    }
+    .f-l-content {
+      padding: 12px 0;
+      border-top: 1px dashed #ddd;
+      font-size: 12px;
+      color: #686868;
+      cursor: pointer;
+    }
+
+    .filter-data-list{
+      margin-top: 12px;
+      padding: 0 16px;
+      background: #F5F6F7;
+      border-radius: 4px;
+      .has-search-model{
+        padding:0 0 8px 22px;
+        font-size: 12px;
+        line-height: 18px;
+      }
+      .f-l-title{
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        cursor: pointer;
+        font-size: 14px;
+        min-height: 22px;
+        color: #1D1D1D;
+        .f-l-title-text{
+          flex: 1;
+          text-align: justify;
+          font-size: 14px;
+          line-height: 22px;
+          max-width: 582px;
+        }
+      }
+      .f-l-title:hover {
+        .f-l-title-text{
+          color: #2cb7ca;
+        }
+        .icon-xiala{
+          color: #2cb7ca;
+        }
+        .icon-delete{
+          font-size: 18px;
+          color: #2cb7ca;
+        }
+      }
+      .f-l-c-item{
+        margin-top: 8px;
+        line-height: 18px;
+        span {
+          margin-right: 16px;
+        }
+        .i-value {
+          color: #1D1D1D;
+        }
+      }
+    }
+  }
+}
+.has-filter-dialog{
+  .el-dialog__headerbtn{
+    font-size: 18px;
+    top: 34px;
+    right: 32px;
+  }
+}
+
+.icon-xiala{
+  display: inline-block;
+  font-size: 18px;
+  flex-shrink: 0;
+  transform: rotate(0deg);
+  transition: transform .5s;
+  margin-right: 4px;
+  cursor: pointer;
+  &.is-reverse{
+    transform: rotate(180deg);
+  }
+}
+.icon-delete {
+  display: inline-block;
+  font-size:22px;
+  color:#aeaeae;
+  cursor: pointer;
+}
+
+</style>

+ 87 - 79
apps/bigmember_pc/src/views/search/bidding/components/save-filter-dialog.vue

@@ -9,6 +9,7 @@ const props = defineProps({
     default: false
   }
 })
+// 关键词
 const additionalWordsCon = computed (() => {
   let str = ''
   if (currentFilter.value.additionalWords) {
@@ -85,88 +86,95 @@ function confirmHandle () {
   </el-dialog>
 </template>
 
+
 <style lang="scss" scoped>
-.filter-dialog{
-  padding: 32px;
-  border-radius: 8px!important;
-}
-.filter-dialog > .el-dialog__header {
-  padding: 0;
-}
-.filter-dialog > .el-dialog__header > .el-dialog__title{
-  color: #1D1D1D;
-}
-.save-filter-dialog > .el-dialog__body{
-  padding: 0 0 32px!important;
-}
-.filter-dialog .filter-save-item{
-  display: flex;
-  margin-top: 20px;
-  line-height: 18px;
-}
 
-.filter-dialog .btn-group,
-.filter-messagebox .btn-group{
-  width: 132px;
-  height: 36px;
-  padding: 0;
-  border-radius: 6px;
-  font-size: 16px;
-}
-.filter-dialog .btn-group.confirm-btn,
-.filter-messagebox .btn-group.confirm-btn{
-  background: #2cb7ca;
-  margin-right: 52px;
-  border: 0;
-  color: #fff;
-}
-.filter-dialog .btn-group.confirm-btn:hover,
-.filter-dialog .btn-group.confirm-btn:focus,
-.filter-messagebox .btn-group.confirm-btn:hover,
-.filter-dialog .btn-group.confirm-btn:focus{
-  color: #fff;
-}
-.filter-data-container{
-  max-height: 400px;
-  overflow-y: scroll;
-  width: 694px;
-}
-.filter-dialog ::-webkit-scrollbar {
-  /*滚动条整体样式*/
-  width: 8px!important;
+::v-deep {
+  .filter-dialog{
+    padding: 32px;
+    border-radius: 8px!important;
+  }
+  .el-dialog{
+    width: 750px !important;
+  }
 }
 
-.filter-save-item .save-label{
-  min-width: 60px;
-  text-align: right;
-  color: #636467;
-  font-size: 12px;
-}
-.filter-save-item .save-value {
-  margin-left: 8px;
-  flex: 1;
-  color: #1D1D1D;
-  text-align: left;
-  font-size: 12px;
-}
-.filter-save-item .save-value-bg{
-  margin-bottom: 8px;
-  margin-right: 8px;
-  padding: 6px 8px;
-  background: #F5F6F7;
-  border-radius: 4px;
-  font-size: 12px;
-  color: #1D1D1D;
-  line-height: 18px;
-}
-.filter-save-item .save-value-bg > span{
-  color: #636467;
-}
-.filter-save-item .search_model{
-  margin-top: 4px;
-  font-size: 12px;
-  line-height: 18px;
-  color: #686868;
-}
+.filter-dialog{
+  width: 750px;
+  .el-dialog__header {
+    padding: 0;
+    .el-dialog__title{
+      color: #1D1D1D;
+    }
+  }
+  &.save-filter-dialog {
+    .el-dialog__body {
+      padding: 0 0 32px!important;
+    }
+  }
+  .btn-group {
+    width: 132px;
+    height: 36px;
+    padding: 0;
+    border-radius: 6px;
+    font-size: 16px;
+  }
+  .btn-group.confirm-btn {
+    background: #2cb7ca;
+    margin-right: 52px;
+    border: 0;
+    color: #fff;
+  }
+  .btn-group.confirm-btn:hover,
+  .btn-group.confirm-btn:focus {
+    color: #fff;
+  }
+  .btn-group.cancel-btn:hover{
+    background: unset;
+    border-color: #DCDFE6;
+    color: #606266;
+  }
+  .filter-save-item{
+    display: flex;
+    margin-top: 20px;
+    line-height: 18px;
+
+    .save-label{
+      min-width: 60px;
+      text-align: right;
+      color: #636467;
+      font-size: 12px;
+    }
+
+    .save-value {
+      margin-left: 8px;
+      flex: 1;
+      color: #1D1D1D;
+      text-align: left;
+      font-size: 12px;
+    }
 
+    .save-value-bg{
+      margin-bottom: 8px;
+      margin-right: 8px;
+      padding: 6px 8px;
+      background: #F5F6F7;
+      border-radius: 4px;
+      font-size: 12px;
+      color: #1D1D1D;
+      line-height: 18px;
+
+      & > span{
+        color: #636467;
+      }
+    }
+
+    .search_model{
+      margin-top: 4px;
+      font-size: 12px;
+      line-height: 18px;
+      color: #686868;
+    }
+  }
+}
 </style>

+ 21 - 2
apps/bigmember_pc/src/views/search/bidding/components/search-filter-header.vue

@@ -1,11 +1,24 @@
 <script setup>
 import { ref } from 'vue'
 import SaveFilterDialog from '../components/save-filter-dialog.vue'
+import HistoryFilterDialog from '../components/history-filter-dialog.vue'
 import { SearchBidModel } from '../model/index'
-const { onSaveFilter, saveFilterDialogVisible, saveFilterCancel, saveFilterConfirm} = SearchBidModel
+const {
+  onSaveFilter,
+  onHasFilter,
+  saveFilterDialogVisible,
+  historyFilterDialogVisible,
+  historyFilterCount,
+  saveFilterCancel,
+  saveFilterConfirm
+} = SearchBidModel
 const fixedTop = ref(false)
 const showFilter = ref(true)
 function toggleFilter() {}
+
+function closeHistoryFilterDialog () {
+  historyFilterDialogVisible.value = false
+}
 </script>
 
 <template>
@@ -20,7 +33,7 @@ function toggleFilter() {}
       </div>
       <div class="f-h-action nologin-hide">
 <!--        <span class="action-item reset-item" @click="onResetFilter">重置筛选条件</span>-->
-<!--        <span class="action-item has-item" @click="onHasFilter">已存筛选条件 ${filterCounts}</span>-->
+        <span class="action-item has-item" @click="onHasFilter">已存筛选条件 {{ historyFilterCount || ''}}</span>
         <span class="action-item save-item" @click="onSaveFilter">保存筛选条件</span>
       </div>
     </div>
@@ -30,6 +43,12 @@ function toggleFilter() {}
       @cancel='saveFilterCancel'
       @confirm='saveFilterConfirm'
     ></save-filter-dialog>
+    <history-filter-dialog
+      v-if='historyFilterDialogVisible'
+      :visible="historyFilterDialogVisible"
+      @before-close='closeHistoryFilterDialog'
+    >
+    </history-filter-dialog>
   </div>
 </template>
 

+ 27 - 11
apps/bigmember_pc/src/views/search/bidding/model/base.js

@@ -189,12 +189,20 @@ export default function () {
    * 保存、重置筛选条件部分
    **/
   const {
-    checkFilterPass,
-    filterSaveParams,
-    viewFilterParams,
-    saveFilterDialogVisible,
-    saveFilterCancel,
-    saveFilterConfirm
+    filterSaveParams, // 保存format后的筛选条件
+    viewFilterParams, // 保存提示框查看筛选条件
+    historyFilterCount, // 已存筛选条件个数
+    filterHistoryList, // 已存筛选条件列表
+    saveFilterDialogVisible, // 保存筛选条件弹窗
+    historyFilterDialogVisible, //已存筛选条件弹窗
+    saveFilterConfirm, // 确认保存筛选条件
+    saveFilterCancel, // 取消保存筛选条件
+    getFilterHistoryList, // 已存筛选条件列表
+    onHasFilter, // 已存筛选条件操作
+    checkFilterPass, // 检测是否可以保存筛选条件
+    onHasToggle, // 展开收起
+    onDeleteFilter, // 删除单条已存筛选条件
+    onSelectedFilter
   } = saveFilterActionsModel()
 
   /**
@@ -210,6 +218,7 @@ export default function () {
     await checkFilterPass(config)
   }
 
+
   return {
     searchModelOptions,
     searchListProps,
@@ -224,11 +233,18 @@ export default function () {
     doChangeSelect,
     doChangePageNum,
     doChangePageSize,
-    onSaveFilter, // 保存筛选条件
-    filterSaveParams, // 保存format后的筛选条件
-    viewFilterParams, // 保存提示框查看筛选条件
-    saveFilterDialogVisible, // 保存筛选条件弹窗
+    onSaveFilter, // 以下存筛选条件相关
+    onHasFilter,
+    filterSaveParams,
+    viewFilterParams,
+    historyFilterCount,
+    filterHistoryList,
+    saveFilterDialogVisible,
+    historyFilterDialogVisible,
     saveFilterConfirm,
-    saveFilterCancel
+    saveFilterCancel,
+    onHasToggle,
+    onDeleteFilter,
+    onSelectedFilter
   }
 }

+ 145 - 10
apps/bigmember_pc/src/views/search/bidding/model/modules/save-filter-actions.js

@@ -1,7 +1,15 @@
-import { computed, reactive, ref, getCurrentInstance } from 'vue'
-import { checkBiddingFilterPass } from '@/api/modules'
+import { computed, ref, getCurrentInstance } from 'vue'
+import { checkBiddingFilterPass, addBiddingFilter, getBiddingFilterList, deleteBiddingFilter } from '@/api/modules'
 import  { FilterHistoryViewModel2AjaxModel, FilterHistoryAjaxModel2ViewModel} from '@/utils'
 import { showToast } from '@/components/toast'
+import { MessageBox } from 'element-ui'
+import { useStore } from '@/store'
+
+const getters = useStore().getters
+
+const isFree = computed(() => {
+  return useStore().getters['user/isFree']
+})
 
 const saveConfig = {
   savedFilterListMaxCount: 10 //筛选条件保存条数最大值
@@ -9,9 +17,22 @@ const saveConfig = {
 
 export function saveFilterActionsModel () {
    const { savedFilterListMaxCount: maxCount } = saveConfig
+   // 已存筛选列表
+   let filterHistoryList = ref([])
+   // 保存筛选条件框展示与否
    const saveFilterDialogVisible = ref(false)
+  // 查看已保存的历史筛选条件
+   const historyFilterDialogVisible = ref(false)
+   // 当前保存的筛选条件多返回的ID
+   const currentFilterParamsKey = ref('')
+  // 当前保存的筛选条件
    let filterSaveParams = ref({})
+  // 视图可视筛选条件
    let viewFilterParams = ref({})
+  // 已存搜索条件个数
+   const historyFilterCount = computed(() => {
+     return filterHistoryList.value.length
+   })
 
   // 检测筛选条件是否可保存
    async function checkFilterPass (config) {
@@ -23,15 +44,14 @@ export function saveFilterActionsModel () {
      if (!searchvalue && !additionalWords && !industry && !hasOneKey) {
        return showToast('请先输入关键词')
      }
-
-     // if(maxCount) {
-     //   return showToast(`对不起,最多可保存${maxCount}个筛选条件。`)
-     // }
+     if(historyFilterCount.value > maxCount) {
+       return showToast(`对不起,最多可保存${maxCount}个筛选条件。`)
+     }
      const { data: id, error_code: code = 0, error_msg: msg } = await checkBiddingFilterPass(filterSaveParams.value)
      if(code === 0) {
+       currentFilterParamsKey.value = id
        viewFilterParams.value = FilterHistoryAjaxModel2ViewModel.formatAll(filterSaveParams.value)
        saveFilterDialogVisible.value = true
-
      } else {
       if (msg) {
         if (msg.includes('无用户身份')) {
@@ -49,16 +69,131 @@ export function saveFilterActionsModel () {
   }
 
   // 确定保存筛选条件操作
-  function saveFilterConfirm () {
-    console.log(33333)
+  async function saveFilterConfirm () {
+    try {
+      const params = {
+        ...filterSaveParams.value,
+        inkey: currentFilterParamsKey.value
+      }
+      const { error_code: code = 0, error_msg: msg } = await addBiddingFilter(params)
+      if (code === 0) {
+        saveFilterDialogVisible.value = false
+        showToast('保存成功')
+        getFilterHistoryList()
+      } else {
+        if (msg) {
+          showToast(msg)
+        }
+      }
+    } catch (error) {
+    }
+  }
+  // 获取已存筛选条件
+  async function  getFilterHistoryList() {
+    try {
+        const { data, error_code: code, error_msg: msg } = await getBiddingFilterList()
+      if (code === 0) {
+        const resData = data || []
+        const arr = resData.map((item, index) => {
+          return {
+            ...FilterHistoryAjaxModel2ViewModel.formatAll(item),
+            id: item.id,
+            inKey: item.inKey,
+            isPay: item.isPay,
+            open: index === 0
+          }
+        })
+        filterHistoryList.value = arr
+      } else {
+        if (msg) {
+          showToast(msg)
+        }
+      }
+    } catch (error) {
+    }
+  }
+   getFilterHistoryList()
+
+  /**
+   * 获取已保存的筛选条件
+   * @returns {Promise<void>}
+   */
+  async function onHasFilter () {
+    historyFilterDialogVisible.value = true
+  }
+  // 已存筛选条件弹窗,单条展开收起
+  function onHasToggle (item) {
+    filterHistoryList.value.forEach(function(v) {
+      v.open = false
+    })
+    item.open = !item.open
+  }
+
+  function onDeleteFilter (item) {
+    console.log(item)
+    MessageBox.confirm('确定删除该筛选条件吗?', '删除', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      center: true,
+      showClose: false,
+      customClass: 'filter-delete-messagebox',
+      confirmButtonClass: 'btn-group confirm-btn',
+      cancelButtonClass: 'btn-group cancel-btn'
+    }).then(function() {
+      const params = {
+        id: item.id
+      }
+      deleteBiddingFilter(params).then(res => {
+        const { error_code: code} = res
+        if(code === 0) {
+          showToast('删除成功')
+          getFilterHistoryList()
+        }
+      })
+    }).catch(function() {})
+  }
+  // 恢复筛选条件
+  function onSelectedFilter (item) {
+      const { isPay } = item
+      // 恢复选中状态
+      if (isFree && isPay) {
+        MessageBox.confirm('已存筛选条件包含仅限会员用户可用的筛选条件,如需使用请开通超级订阅', '',{
+          confirmButtonText: '开通超级订阅',
+          cancelButtonText: '使用免费条件',
+          center: true,
+          showClose: false,
+          customClass: 'filter-delete-messagebox',
+          confirmButtonClass: 'btn-group confirm-btn',
+          cancelButtonClass: 'btn-group cancel-btn',
+        })
+        .then(() => {
+          // this.$router.push({
+          //   path: '/common/order/create/svip'
+          // })
+        })
+        .catch((action) => {
+          // if (action === 'cancel') {
+          //   this.restoreFilter(card)
+          // }
+        })
+      } else {
+
+      }
   }
 
   return {
     saveFilterDialogVisible,
+    historyFilterDialogVisible,
     filterSaveParams,
     viewFilterParams,
+    historyFilterCount,
     checkFilterPass,
     saveFilterCancel,
-    saveFilterConfirm
+    saveFilterConfirm,
+    filterHistoryList,
+    onHasFilter,
+    onHasToggle,
+    onDeleteFilter,
+    onSelectedFilter
   }
 }