瀏覽代碼

投标决策分析

TANGSHIZHE 4 年之前
父節點
當前提交
6bf3638b5e

+ 0 - 1
public/index.html

@@ -28,7 +28,6 @@
   <style>
     .big-member-page {
       margin: 0 auto;
-      width: 1200px;
     }
   </style>
   <body style="background-color: #f2f2f4;">

+ 36 - 15
src/components/forecast/ForLayout.vue

@@ -8,7 +8,6 @@
         </div>
         <div class="bidfor_search" v-if="search">
            <SearchInput @submit="getRecovery" :onlySelect="searchConfig.select" :ajaxType="searchConfig.type"></SearchInput>
-<!--          <SearchInput @submit="getRecovery"></SearchInput>-->
         </div>
         <slot name="bidImg"></slot>
       </div>
@@ -23,7 +22,7 @@
 import { Icon } from 'element-ui'
 import { mapState } from 'vuex'
 import SearchInput from '@/components/input/SearchInput.vue'
-import { getProjectList } from '@/api/modules'
+import { getProjectList, getFollowAssociationList } from '@/api/modules'
 export default {
   name: 'j-container',
   props: {
@@ -63,19 +62,41 @@ export default {
     getRecovery (data) {
       console.log(data, 'x')
       this.type = 1
-      // 中标预测、投标决策分析列表
-      getProjectList({ pName: data.text }).then(res => {
-        console.log(res)
-        if (res.error_code === 0) {
-          // 中标企业预测
-          this.$store.commit('forcast/setList', res.data)
-          this.$store.commit('forcast/setType', this.type)
-          // 投标决策分析
-          this.$store.commit('forcast/setPolicyList', res.data)
-          // 企业情报
-          this.$store.commit('forcast/setEntFollowSearch', res.data)
-        }
-      })
+      console.log(!data.data)
+      if (this.searchConfig.type === 'follow') {
+        getFollowAssociationList({ entName: data.text }).then(res => {
+          if (res && res.error_msg === '' && res.data) {
+            // 企业情报
+            this.$store.commit('forcast/setEntFollowSearch', res.data)
+            this.$store.commit('forcast/setType', this.type)
+          }
+        })
+      } else if (this.searchConfig.type === 'bidfor') {
+        // 中标预测、投标决策分析列表
+        getProjectList({ pName: data.text }).then(res => {
+          console.log(res)
+          if (res.error_code === 0) {
+            // 中标企业预测
+            if (data.events === 'onEnter') {
+              this.$store.commit('forcast/setList', res.data)
+              this.$store.commit('forcast/setType', this.type)
+            }
+            const result = [data.data]
+            this.$store.commit('forcast/setHistoryList', result)
+            this.$router.push(`/bidforlimit/${data.data.s_id}/${data.data.sourceinfoid}`)
+          }
+        })
+      } else if (this.searchConfig.type === 'bidpolicy') {
+        // 中标预测、投标决策分析列表
+        getProjectList({ pName: data.text }).then(res => {
+          console.log(res)
+          if (res.error_code === 0) {
+            // 投标决策分析
+            this.$store.commit('forcast/setType', this.type)
+            this.$store.commit('forcast/setPolicyList', res.data)
+          }
+        })
+      }
     }
   }
 }

+ 10 - 6
src/components/forecast/ForLimit.vue

@@ -166,7 +166,7 @@ export default {
     },
     // 地区
     getCitys () {
-      this.area = this.$refs.areaSelector.getSelectedCity()
+      return this.$refs.areaSelector.getSelectedCity()
     },
     getAssociation (pname) {
       getBidAssociation({ name: pname }).then(res => {
@@ -181,8 +181,7 @@ export default {
       })
     },
     startFore () {
-      this.getCitys()
-      // [{ key: ['医药'], appendkey: [], notkey: [] }]
+      this.area = this.getCitys()
       const arr = []
       this.content.forEach(function (item) {
         const conList = {
@@ -212,9 +211,14 @@ export default {
     padding: 32px 40px;
     width: 1200px;
     background: #ffffff;
-    // ::v-deep .index-item:first-child{
-    //   display: none;
-    // }
+    ::v-deep {
+      .s-line .select-list {
+        .country,
+        .city-list .province {
+          display: none;
+        }
+      }
+    }
     input::placeholder{
       font-size: 14px;
       font-weight: 400;

+ 64 - 20
src/components/forecast/ForeCast.vue

@@ -89,14 +89,18 @@
     <ul class="listData_ul" v-if="type=='entintelRes'">
       <li class="list_li res_li" v-for="(item, index) in listState.list" :key="index">
         <div class="list_name">
-          <div class="list_name_left" @click="goViewEnt(item.s_id)">
+          <div class="list_name_left" @click="goViewEnt(item.entId)">
             <span class="icon_company"></span>
-            <span class="list_pur_name">{{item.projectname}}</span>
+            <span class="list_pur_name">{{item.entName}}</span>
           </div>
-          <div class="list_btn">
+          <div class="list_btn" v-if="item.isFollow==''" @click="setFollow(item.entId, item.isFollow)">
             <span class="icon_grey"></span>
             <span class="notice">关注</span>
           </div>
+          <div class="list_btn_follow" v-else-if="item.isFollow=='1'" @click="setFollow(item.entId, item.isFollow)">
+            <span class="icon_heart_red"></span>
+            <span class="notice">已关注</span>
+          </div>
         </div>
       </li>
     </ul>
@@ -168,7 +172,7 @@ import { Pagination, Progress } from 'element-ui'
 // import { getPushList } from '@/api/modules/'
 import Empty from '@/components/common/Empty.vue'
 import { moneyUnit, dateFormatter } from '@/utils'
-import { getfollowCheck } from '@/api/modules'
+import { setFollowEnt, setCancelEnt } from '@/api/modules'
 export default {
   props: ['type', 'title', 'mydata', 'myDataObj', 'resData', 'myPolicydata', 'potenObj', 'potenResult', 'entSearch'],
   name: 'listData',
@@ -186,7 +190,8 @@ export default {
         pageSize: 10, // 每页多少条数据
         total: 0, // 一共多少条数据
         list: [] // 查询请求返回的数据
-      }
+      },
+      isFollow: '1'
     }
   },
   created () {
@@ -341,8 +346,43 @@ export default {
         this.listState.total = 0
       }
     },
+    // 关注
+    setFollow (id, num) {
+      if (num === '') {
+        setFollowEnt({ entId: id }).then(res => {
+          if (res.error_code === 0) {
+            if (res.data === 'success') {
+              this.entSearch.forEach(function (item, i) {
+                if (id === item.entId) {
+                  item.isFollow = '1'
+                }
+              })
+            }
+          }
+        })
+      } else {
+        setCancelEnt({ entId: id }).then(res => {
+          if (res.error_code === 0) {
+            if (res.data === 'success') {
+              this.entSearch.forEach(function (item, i) {
+                if (id === item.entId) {
+                  item.isFollow = ''
+                }
+              })
+            }
+          }
+        })
+      }
+    },
     goBidForcast (id, sid) {
       this.$router.push(`/bidforlimit/${id}/${sid}`)
+      const result = []
+      this.mydata.forEach(function (item, i) {
+        if (id === item.s_id) {
+          result.push(item)
+        }
+      })
+      this.$store.commit('forcast/setHistoryList', result)
     },
     goForcast (id, sid) {
       this.$router.push(`/analysis/result/${id}/${sid}`)
@@ -374,21 +414,6 @@ export default {
         }
       })
     },
-    // 查询项目是否关注
-    // getFollow (id) {
-    //   getfollowCheck({ entId: id }).then(res => {
-    //     console.log(res)
-    //     if (res.error_code === 0) {
-    //       let num = 0
-    //       if (res.data.followed) {
-    //         num = 1
-    //       } else {
-    //         num = 0
-    //       }
-    //       return num
-    //     }
-    //   })
-    // },
     onPageChange (p) {
       this.listState.pageNum = p
     }
@@ -658,6 +683,25 @@ export default {
             }
           }
         }
+        .list_btn_follow{
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          width: 82px;
+          height: 36px;
+          color: #686868;
+          font-size: 14px;
+          .icon_heart_red{
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-right: 4px;
+            width: 16px;
+            height: 16px;
+            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAACBElEQVRYR+3Xv0scQRTA8e+TC0TwTwiYkBQ2IvYBx1QJJIVgkUAE90QI2KQR0qmEkBSBpAlpEvcKwRSCTUC7G8E/QEFQKy/gnxA0kGMn7HLIJW7mx7q3WNw0V9zMm8+9fftmTrhmQ66Zhz7I9UT6Gbpyhszq5ARiZgGF4VYn4BHCdxJpyFzzuHsT03hwlyR5gfAYuI2hhnAKaBL5KHPNfRvqv4/MfFJDDPIZ4bklwC/gHS3eZHOGWQJeIdQsa75xxrws6J95c3JBHcwWwn1XirPvDRvZpzDtOX+Xcx7lofJBsVoHnnoFLzrJsCZ1PfPv8ksg83VyjAGzV3SfoHVGlNSbO91rLoNiFQNpEVcxGhLpyAU6yd6OakZLIn3HDlpVvx1vSXlUQ1vq+oYrQ+fAzfJ2tUTyBB0CIxWBDqSuR10Z+gC8rAQkvJdZvWgHfVH3GOCwgjpKu/y4RPrICsoab6zeZkdAb8eyRHrF2Rgz0JKqMcy691EQCk+Pmh88kxXd9gL1FGXBpPtaL2ilZ8qBcYJKzZQHxgtUCsoT4w3qQm12boIhZbxNiyd5BZwXJOiSb2KVHimbwENP0TYwJZFOe47XCAJ1epQvKhgT9Mi6f55HpgphCoMcmSqMuRLoAiW8JiH929NGWMOwGFIz3p3aqwJ7MCm4qHtg+CtkH+TKcD9Drgz9AS0gsyVs0KiWAAAAAElFTkSuQmCC) no-repeat;
+            background-size: contain;
+          }
+        }
       }
       &:hover{
         background: none;

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

@@ -225,6 +225,7 @@ export default {
     }
     .selector-card-header {
       margin-right: 10px;
+      min-width: 100px;
     }
     .selector-content {
       position: relative;

+ 2 - 0
src/store/forcast.js

@@ -18,6 +18,8 @@ export default {
     // 中标企业预测
     setList (state, list) {
       state.list = list
+    },
+    setHistoryList (state, list) {
       state.historyList = list.concat(state.historyList)
       localStorage.setItem('bigmember-BID_DATA', JSON.stringify(state.historyList))
     },

+ 1 - 1
src/views/bid-forecast/BidForecast.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="bid-forcast">
-    <forLayOut>
+    <forLayOut :searchConfig="{ type: 'bidfor'}">
       <span class="icon_ai" slot="icon"></span>
       <span class="bidfor_text" slot="proname">中标企业预测</span>
       <img class="bidfor_img" src="@/assets/images/item_7.png" alt="" slot="bidImg">

+ 51 - 12
src/views/bid-policy/AnalysisResult.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="analysis-result">
-    <ForLimit :baseInfo="baseInfo" @getLimit="getLimit"></ForLimit>
+    <PolicyLimit :baseInfo="baseInfo" @dataList="getLimit"></PolicyLimit>
     <div class="digest" v-show="proShow">
       <div class="digest_head">项目摘要</div>
       <ul class="digest_ul">
@@ -48,7 +48,7 @@
 <script>
 import AnalysisChart from '../portrayal/components/AnalysisChart'
 import AnalysisDetailList from '../portrayal/components/AnalysisDetailList'
-import ForLimit from '@/components/forecast/ForLimit'
+import PolicyLimit from './components/PolicyLimit'
 import Empty from '@/components/common/Empty'
 import { Tabs, TabPane } from 'element-ui'
 // 该页面需要调用的接口
@@ -59,7 +59,7 @@ export default {
     [Tabs.name]: Tabs,
     [TabPane.name]: TabPane,
     AnalysisChart,
-    ForLimit,
+    PolicyLimit,
     AnalysisDetailList,
     Empty
   },
@@ -106,15 +106,54 @@ export default {
       const res = await getProjectInfo(data)
       if (res.error_code === 0 && res.data) {
         if (res.data.s_subscopeclass) {
-          if (res.data.s_subscopeclass.indexOf('_') > -1) {
-            res.data.s_subscopeclass = res.data.s_subscopeclass.substring(0, res.data.s_subscopeclass.indexOf('_'))
-          }
+          res.data.s_subscopeclass = this.initIndustryData(res.data.s_subscopeclass.split(','))
+          console.log(res.data.s_subscopeclass)
         }
         this.baseInfo = res.data
       } else {
         console.log(res.error_code)
       }
     },
+    // 处理数据为行业选择页面所需格式
+    initIndustryData (data) {
+      console.log(data)
+      var arr = []
+      var obj = {}
+      if (data) {
+        data.forEach(function (item) {
+          item = item.split('_')
+          // obj[item[0]] = item[1]
+          arr.push({
+            key: item[0],
+            val: item[1]
+          })
+        })
+        var tempArr = []
+        var newArr = []
+        for (var i = 0; i < arr.length; i++) {
+          if (tempArr.indexOf(arr[i].key) === -1) {
+            newArr.push({
+              key: arr[i].key,
+              child: [arr[i].val]
+            })
+            tempArr.push(arr[i].key)
+          } else {
+            for (var j = 0; j < newArr.length; j++) {
+              if (newArr[j].key === arr[i].key) {
+                newArr[j].child.push(arr[i].val)
+                break
+              }
+            }
+          }
+        }
+        for (var t = 0; t < newArr.length; t++) {
+          obj[newArr[t].key] = newArr[t].child
+        }
+        return obj
+      } else {
+        return '请选择行业'
+      }
+    },
     // 获取筛选条件
     getLimit (data) {
       this.getResult(data)
@@ -124,12 +163,12 @@ export default {
       const data = {
         appVersion: '',
         area: item.area,
-        buyer: item.buyer,
-        buyerClass: [],
-        buyerContent: item.buyerContent,
-        industry: '',
-        maxPrice: '',
-        minPrice: '',
+        buyer: '',
+        buyerClass: item.buyer,
+        buyerContent: item.scope,
+        industry: item.industry,
+        maxPrice: item.range.minPrice,
+        minPrice: item.range.maxPrice,
         mobileModel: '',
         pid: this.baseInfo.id,
         pname: this.baseInfo.projectname,

+ 1 - 1
src/views/bid-policy/BidPolicy.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="bid-policy">
-    <forLayOut>
+    <forLayOut :searchConfig="{ type: 'bidpolicy'}">
       <span class="icon_toubiao" slot="icon"></span>
       <span class="bidfor_text" slot="proname">投标决策分析</span>
       <img class="bidfor_img" src="@/assets/images/item_5.png" alt="" slot="bidImg">

+ 293 - 0
src/views/bid-policy/components/PolicyLimit.vue

@@ -0,0 +1,293 @@
+<template>
+  <div class="policy-limit">
+    <div class="limit_head">
+      <div class="limit_top">
+        <span class="limit_head_name">万邦达休息</span>
+        <span></span>
+      </div>
+      <div class="limit_bot"></div>
+    </div>
+    <div class="limit_content">
+      <IndustrySelector ref="industrySel" :initIndustry="baseInfo.s_subscopeclass" selectorType="line">
+        <div slot="header">行业分类:</div>
+      </IndustrySelector>
+      <AreaSelector ref="areaSelector" selectorType="line" :initCityMap="backArea">
+        <div slot="header">选择区域:</div>
+      </AreaSelector>
+      <BusinessScopeSelector ref="scopeSelector" :initList="baseInfo.buyerContent" selectorType="line">
+        <div slot="header">采购内容:</div>
+      </BusinessScopeSelector>
+      <BuyerclassSelector ref="buyerSelector" :initCate="baseInfo.buyerclass"  selectorType="line">
+        <div slot="header">采购单位类型:</div>
+      </BuyerclassSelector>
+      <div class="limit_money_section">
+        <div class="section_label">金额区间:</div>
+        <div class="section_option">
+          <div class="section_option_type">
+            <div class="no_section" :class="moneySec?'sec_active':''" @click="getSection(0)">不限</div>
+            <div class="custom_section" :class="!moneySec?'sec_active':''" @click="getSection(1)">自定义</div>
+          </div>
+          <div class="el_section">
+            <el-input
+              class="sec_ipt"
+              :disabled="moneySec"
+              placeholder="请输入金额"
+              @input="getValue"
+              v-model="input">
+              <i slot="suffix" class="el-input__icon">
+                万元
+              </i>
+            </el-input>
+            <span class="sline"> - </span>
+            <el-input
+              class="sec_ipt"
+              :disabled="moneySec"
+              placeholder="请输入金额"
+              @input="getValue2"
+              v-model="input2">
+              <i slot="suffix" class="el-input__icon">
+                万元
+              </i>
+            </el-input>
+          </div>
+        </div>
+      </div>
+      <div class="startAnsy">
+        <button class="startBtn" @click="StartAnsisy()">开始分析</button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import AreaSelector from '@/components/selector/AreaSelector.vue'
+import IndustrySelector from '@/components/selector/IndustrySelector.vue'
+import BuyerclassSelector from '@/components/selector/BuyerclassSelector.vue'
+import BusinessScopeSelector from '@/components/selector/BusinessScopeSelector.vue'
+import { Input } from 'element-ui'
+export default {
+  props: ['baseInfo'],
+  name: 'policy-limit',
+  components: {
+    AreaSelector,
+    IndustrySelector,
+    BuyerclassSelector,
+    BusinessScopeSelector,
+    [Input.name]: Input
+  },
+  data () {
+    return {
+      input: '',
+      input2: '',
+      backArea: {},
+      moneySec: true,
+      range: {
+        maxPrice: '',
+        minPrice: ''
+      }
+    }
+  },
+  watch: {
+    baseInfo (newVal, oldVal) {
+      if (newVal) {
+        console.log(newVal)
+        if (newVal.area && newVal.area !== '') {
+          const p = this.getAreaInfo(newVal.area)
+          this.backArea = p
+        }
+      }
+    }
+  },
+  methods: {
+    // 判断省市
+    getAreaInfo (name) {
+      const info = {
+        level: 0,
+        province: '',
+        city: ''
+      }
+      const maplist = this.$refs.areaSelector.$refs.content.provinceListMap
+      for (const key in maplist) {
+        maplist[key].forEach(item => {
+          if (name === item.name) {
+            info.level = 1
+            info.province = item.name
+          }
+          item.children.forEach(iitem => {
+            if (name === iitem.city) {
+              info.level = 2
+              info.province = item.name
+              info.city = iitem.city
+            }
+          })
+        })
+      }
+      if (info.level === 1) {
+        return { [info.province]: [] }
+      } else if (info.level === 2) {
+        return { [info.province]: [info.city] }
+      }
+    },
+    getValue (val) {
+      this.range.minPrice = Number(val)
+    },
+    getValue2 (val) {
+      this.range.maxPrice = Number(val)
+    },
+    getSection (num) {
+      console.log(num)
+      if (num === 0) {
+        this.moneySec = true
+        this.range.minPrice = ''
+        this.range.maxPrice = ''
+      } else {
+        this.moneySec = false
+        this.range.minPrice = this.input
+        this.range.maxPrice = this.input2
+      }
+      console.log(this.range.minPrice, this.range.maxPrice)
+    },
+    // 开始分析
+    StartAnsisy () {
+      // 处理行业数据
+      const instudys = this.$refs.industrySel.getSelected()
+      let ComArr = []
+      for (var item in instudys) {
+        let inStr = ''
+        let inArr = ''
+        console.log(item)
+        instudys[item].forEach(function (data) {
+          console.log(data)
+          inStr = item + '_' + data
+          inArr += inStr + ','
+        })
+        console.log(inArr)
+        ComArr += inArr
+      }
+      const industryStr = ComArr.split(',').slice(0, ComArr.split(',').length - 1) + ''
+      // 处理采购内容数据
+      const scopeArr = this.$refs.scopeSelector.getState()
+      const newScopearr = []
+      if (scopeArr.length !== 0) {
+        scopeArr.forEach(function (item) {
+          const conList = {
+            key: [item],
+            appendkey: [],
+            notkey: []
+          }
+          newScopearr.push(conList)
+        })
+      } else {
+        const conList = {
+          key: [],
+          appendkey: [],
+          notkey: []
+        }
+        newScopearr.push(conList)
+      }
+      const dataList = {
+        industry: industryStr,
+        area: this.$refs.areaSelector.getSelectedCity(),
+        scope: newScopearr,
+        buyer: this.$refs.buyerSelector.getSelected(),
+        range: this.range
+      }
+      this.$emit('dataList', dataList)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.policy-limit{
+  margin: 32px auto;
+  padding: 32px 40px;
+  width: 1200px;
+  background: #ffffff;
+  ::v-deep .selector-card{
+    padding: 12px 0;
+  }
+  .limit_head{
+    padding-bottom: 20px;
+    width: 100%;
+    font-size: 18px;
+    font-weight: 400;
+    color: #1d1d1d;
+    line-height: 28px;
+    border-bottom: 1px solid #ececec;
+  }
+  .limit_money_section{
+    display: flex;
+    align-items: center;
+    width: 100%;
+    height: 60px;
+    .section_label{
+      width: 100px;
+      margin-right: 10px;
+    }
+    .section_option{
+      display: flex;
+      // justify-content: space-between;
+      align-items: center;
+      .section_option_type{
+        display: flex;
+        .no_section, .custom_section{
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          margin-right: 8px;
+          padding: 2px 6px;
+          height: 24px;
+          font-size: 14px;
+          font-family: Microsoft YaHei, Microsoft YaHei-Regular;
+          font-weight: 400;
+          line-height: 20px;
+        }
+        .sec_active{
+          background: #2CB7CA;
+          color: #ffffff;
+          border-radius: 4px;
+        }
+      }
+      .el_section{
+        display: flex;
+        align-items: center;
+        .sec_ipt.el-input.el-input--suffix{
+          width: 200px;
+          height: 36px;
+          ::v-deep{
+            .el-input__inner{
+              width: 200px;
+              height: 36px;
+              border: 1px solid #ececec;
+              border-radius: 23px;
+            }
+            .el-input__icon{
+              line-height: 36px;
+            }
+          }
+        }
+        .sline{
+          margin: 0 10px;
+        }
+      }
+    }
+  }
+  .startAnsy{
+    margin-top: 20px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 46px;
+    .startBtn{
+      width: 180px;
+      height: 46px;
+      background: #2cb7ca;
+      border-radius: 6px;
+      color: #ffffff;
+      font-size: 16px;
+    }
+  }
+}
+</style>

+ 1 - 1
src/views/ent-intel/EntIntel.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="ent-intel">
-    <forLayOut :searchConfig="{select: true, type: 'follow'}">
+    <forLayOut :searchConfig="{ type: 'follow'}">
       <span class="icon_ent" slot="icon"></span>
       <span class="bidfor_text" slot="proname">企业情报</span>
       <img class="bidfor_img" src="@/assets/images/item_2.png" alt="" slot="bidImg">