Jelajahi Sumber

feat: 新增潜在竞争对手/客户页面

zhangyuhan 4 tahun lalu
induk
melakukan
6b3c5c3704

+ 1 - 0
src/api/modules/index.js

@@ -4,3 +4,4 @@ export * from './chart'
 export * from './report'
 export * from './forecast'
 export * from './analysis'
+export * from './potential'

+ 10 - 0
src/api/modules/potential.js

@@ -0,0 +1,10 @@
+import request from '@/api'
+
+// 潜在客户/竞争对手接口
+export function getCorList (data) {
+  return request({
+    url: '/potential/corList',
+    method: 'post',
+    data
+  })
+}

TEMPAT SAMPAH
src/assets/images/icon/top-c.png


TEMPAT SAMPAH
src/assets/images/icon/top-manage.png


TEMPAT SAMPAH
src/assets/images/icon/top-r.png


+ 357 - 0
src/components/push-list/PotentialList.vue

@@ -0,0 +1,357 @@
+<template>
+  <el-card class="potential-list-card">
+    <div class="header-box flex-r-c sb">
+      <span class="card-title">{{title}}</span>
+      <div class="flex-r-c center" v-show="!showEmpty">
+        <div class="link-text" @click="changeSort(0)" :class="{active: listState.sort === 0}">数量排序</div>
+        <div class="link-text" @click="changeSort(1)" :class="{active: listState.sort === 1}">金额排序</div>
+      </div>
+    </div>
+    <div class="info-list" v-loading="listState.loading">
+      <div
+        class="card-list-item"
+        v-for="(item, index) in listState.list"
+        :key="index"
+        @onClick="toDetail(item)">
+        <div class="flex-r-c center sb">
+          <div class="flex-r-c center">
+            <i class="el-icon-jy-icon-company"></i>
+            <span class="text--title">{{item.Buyer}}</span>
+          </div>
+          <span class="text--sm-time">2019-09-30</span>
+        </div>
+        <div class="flex-r-c card-bottom-info">
+            <span class="text--sm-name">项目数量:</span>
+            <span class="text--sm-value">{{ item.PNCount }}</span>
+            <span class="text--sm-name">项目总金额:</span>
+            <span class="text--sm-value">{{ item.Budget | formatMoney }}</span>
+            <span class="text--sm-name">所在地:</span>
+            <span class="text--sm-value">{{item.WProvince}}&nbsp;&nbsp;{{item.WCity}}</span>
+        </div>
+      </div>
+      <empty v-if="showEmpty">
+        <div v-if="isAllFirst">
+          <span>选择条件,立即挖掘</span>
+        </div>
+        <div v-else>
+          <span>暂无匹配信息</span>
+        </div>
+      </empty>
+    </div>
+    <div class="el-pagination-container">
+      <el-pagination
+        background
+        layout="prev, pager, next, ->"
+        :hide-on-single-page="true"
+        :current-page="listState.pageNum"
+        :page-size="listState.pageSize"
+        :total="listState.total"
+        @current-change="onPageChange"
+      >
+      </el-pagination>
+    </div>
+  </el-card>
+</template>
+
+<script>
+import { Pagination, Card, Button } from 'element-ui'
+import Empty from '@/components/common/Empty.vue'
+import { moneyUnit } from '@/utils/'
+import { getCorList } from '@/api/modules/'
+
+export default {
+  name: 'potential-list',
+  components: {
+    [Pagination.name]: Pagination,
+    [Card.name]: Card,
+    [Button.name]: Button,
+    Empty
+  },
+  filters: {
+    formatMoney (value) {
+      return moneyUnit(value)
+    }
+  },
+  props: {
+    title: {
+      type: String,
+      default: '潜在客户'
+    },
+    filters: {
+      type: Object,
+      default () {
+        return {
+          area: '',
+          time: ''
+        }
+      }
+    }
+  },
+  computed: {
+    showEmpty () {
+      return this.listState.list.length === 0 && this.listState.loaded
+    },
+    getFilters () {
+      return this.filters
+    }
+  },
+  data () {
+    return {
+      isAllFirst: false,
+      listState: {
+        loaded: true, // 是否已经搜索过
+        loading: false,
+        pageNum: 1, // 当前页
+        pageSize: 10, // 每页多少条数据
+        total: 0, // 一共多少条数据
+        sort: 0,
+        list: [] // 查询请求返回的数据
+      }
+    }
+  },
+  created () {
+    this.doQuery()
+  },
+  methods: {
+    goManage () {
+      alert('订阅管理')
+      // this.$router.push('')
+    },
+    changeSort (i) {
+      this.listState.sort = i
+      this.doQuery()
+    },
+    // 恢复数据至第一次请求的状态(页码等)
+    resetListState () {
+      const state = {
+        loaded: false,
+        loading: false,
+        pageNum: 1,
+        total: 0,
+        list: []
+      }
+      Object.assign(this.listState, state)
+    },
+    doQuery (filters) {
+      this.resetListState()
+      this.getList(filters)
+    },
+    async getList (filters) {
+      const query = {
+        pagenum: this.listState.pageNum,
+        pageSize: this.listState.pageSize,
+        sort_no: this.listState.sort,
+
+        buyerclass: this.getFilters.buyerclass,
+        industry: this.getFilters.industry,
+        business: this.getFilters.business,
+        pcor: this.getFilters.pcor,
+        searchbool: this.getFilters.searchbool
+      }
+
+      if (filters && Object.keys(filters).length > 0) {
+        Object.keys(filters).forEach(v => {
+          if (typeof filters[v] !== 'undefined') {
+            query[v] = filters[v]
+          }
+        })
+      }
+
+      this.listState.loading = true
+      this.listState.loaded = false
+      // 判断是否无筛选条件
+      this.isAllFirst = false
+      if (query.pagenum === 1 && query.area === '' && query.time === '') {
+        this.isAllFirst = true
+      }
+      const res = await getCorList(query)
+      this.listState.loading = false
+      this.listState.loaded = true
+
+      if (res.error_code === 0) {
+        this.listState.total = res.data.total
+        this.listState.list = res.data.list || []
+      } else {
+        this.listState.total = 0
+        this.listState.list = []
+      }
+    },
+    toDetail (item) {
+      const { _id } = item
+      window.open(`/article/content/${_id}.html`)
+    },
+    onPageChange (p) {
+      this.listState.pageNum = p
+      this.getList()
+    },
+    getMore () {
+      this.$emit('getMore')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  @include diy-icon('edit', 20, 20);
+  @include diy-icon('icon-company', 24, 24);
+  ::v-deep .el-icon-jy-icon-company {
+    margin-right: 8px;
+  }
+  // card样式重置
+  ::v-deep {
+    .el-card__header {
+      margin: 0 40px;
+      padding-left: 0;
+      padding-right: 0;
+    }
+    .el-card__body {
+      padding: 20px 0;
+    }
+    .empty-container {
+      margin-top: 60px;
+    }
+    .get-more {
+      display: flex;
+      .el-icon-arrow-right {
+        margin-left: 4px;
+        order: 2;
+      }
+    }
+  }
+
+  .sub-manager {
+    display: flex;
+    align-items: center;
+    padding: 8px 16px;
+    font-size: 14px;
+    line-height: 24px;
+    color: #1d1d1d;
+    border-color: #E0E0E0;
+    &.el-button:focus,
+    &.el-button:hover {
+      color: inherit;
+      background-color: inherit;
+    }
+  }
+
+  .potential-list-card {
+    .header-box {
+      padding-left: 40px;
+      padding-right: 40px;
+    }
+    .card-title {
+      color: #1d1d1d;
+      line-height: 28px;
+      color: #1D1D1D;
+    }
+    .link-text {
+      font-size: 14px;
+      line-height: 24px;
+      text-decoration-line: underline;
+      color: #1D1D1D;
+      cursor: pointer;
+      & + .link-text {
+        margin-left: 20px;
+      }
+      &:hover,&.active {
+        color: #2CB7CA;
+      }
+    }
+    .text--{
+      &sm-value {
+        color: #1D1D1D;
+      }
+      &title {
+        font-size: 16px;
+        line-height: 24px;
+        color: #1D1D1D;
+      }
+      &sm-time {
+        font-size: 12px;
+        line-height: 20px;
+        color: #999999;
+      }
+    }
+    .card-list-item {
+      padding: 24px 0;
+      padding-left: 40px;
+      padding-right: 40px;
+      box-sizing: border-box;
+      box-shadow: inset 0px -1px 0px rgba(0, 0, 0, 0.05);
+      cursor: pointer;
+      &:hover {
+        background: #F5F6F7;
+        .text--title,
+        .text--sm-value {
+          color: #2CB7CA;
+        }
+      }
+    }
+    .card-bottom-info {
+      margin-top: 12px;
+      justify-content: flex-start;
+      text-align: left;
+      font-size: 14px;
+      line-height: 22px;
+      color: #999999;
+      .text--sm-value {
+        margin-right: 40px;
+        &:last-child {
+          margin-right: 0;
+        }
+      }
+    }
+    .sub-manager {
+      float: right;
+    }
+    .info-list {
+      min-height: 545px;
+      border-top: 1px solid transparent;
+    }
+    .add-key-button {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      margin-top: 32px;
+      padding: 8px 16px;
+      color: #F7F9FA;
+      border-radius: 6px;
+      background-color: #2ABED1;
+      cursor: pointer;
+      .icon-chahao {
+        margin-right: 4px;
+        transform: rotate(-45deg);
+      }
+      .button-text {
+        margin-left: 4px;
+        white-space: nowrap;
+      }
+    }
+    .icon-chahao {
+      position: relative;
+      display: inline-block;
+      width: 14px;
+      height: 14px;
+      &:before,
+      &:after {
+        position: absolute;
+        content: '';
+        background-color: #fff;
+        top: 50%;
+        left: 50%;
+        width: 14px;
+        height: 2px;
+        border-radius: 2px;
+      }
+      &:before {
+        transform: translate(-50%,-50%) rotate(45deg);
+      }
+      &:after {
+        transform: translate(-50%,-50%) rotate(-45deg);
+      }
+    }
+    .el-pagination-container  {
+      margin-right: 40px;
+    }
+  }
+</style>

+ 6 - 0
src/router.js

@@ -18,6 +18,12 @@ export default new Router({
       name: 'sub-push',
       component: () => import('@/views/SubPush.vue')
     },
+    // 潜在客户/对手
+    {
+      path: '/potentialList/:type',
+      name: 'potentialList',
+      component: () => import('@/views/PotentialList.vue')
+    },
     // 周报详情
     {
       path: '/empty-demo',

+ 2 - 5
src/views/Home.vue

@@ -59,12 +59,12 @@ export default {
         },
         {
           text: '潜在客户挖掘',
-          to: '/',
+          to: '/potentialList/c',
           id: 7
         },
         {
           text: '潜在竞争对手 合作伙伴挖掘',
-          to: '/',
+          to: '/potentialList/r',
           id: 8
         }
       ],
@@ -286,9 +286,6 @@ export default {
       return result
     },
     goLink (item) {
-      if (item.to === '/') {
-        return alert('暂未完成')
-      }
       this.$router.push(item.to)
     }
   },

+ 102 - 0
src/views/PotentialList.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="page--potential">
+    <forLayOut :search="false">
+      <div class="flex-r-c center" slot="proname">
+        <i :class="'el-icon-jy-' + getTopInfo.icon"></i>
+        <span class="bidfor_text" >{{getTopInfo.text}}</span>
+      </div>
+      <img class="bidfor_img" :src="getTopInfo.img" :alt="getTopInfo.text" slot="bidImg">
+      <div slot="main">
+        <div  class="border-box">
+          <AreaSelector @onChange="changeArea" ref="areaSelector" selectorType="line"></AreaSelector>
+          <IndustrySelector  selectorType="line"></IndustrySelector>
+          <BuyerclassSelector  selectorType="line"></BuyerclassSelector>
+        </div>
+        <div class="content-list-box">
+          <potential-list :title="getTopInfo.text" :filters="filters" ref="pushList" :showMore="false"></potential-list>
+        </div>
+      </div>
+    </forLayOut>
+  </div>
+</template>
+
+<script>
+import PotentialList from '@/components/push-list/PotentialList.vue'
+import AreaSelector from '@/components/selector/AreaSelector.vue'
+import IndustrySelector from '@/components/selector/IndustrySelector.vue'
+import BuyerclassSelector from '@/components/selector/BuyerclassSelector.vue'
+import forLayOut from '@/components/forecast/ForLayout.vue'
+export default {
+  name: 'Potential',
+  components: {
+    PotentialList,
+    AreaSelector,
+    IndustrySelector,
+    BuyerclassSelector,
+    forLayOut
+  },
+  data () {
+    return {
+      topInfo: {
+        c: {
+          img: require('@/assets/images/item_3.png'),
+          icon: 'top-c',
+          text: '潜在客户挖掘'
+        },
+        r: {
+          img: require('@/assets/images/item_1.png'),
+          icon: 'top-r',
+          text: '潜在竞争对手 / 合作伙伴挖掘'
+        }
+      },
+      filters: {
+        buyerclass: [],
+        industry: [],
+        business: {},
+        sort: 0,
+        pcor: this.$route.params.type.toLocaleUpperCase(),
+        searchbool: 0
+      }
+    }
+  },
+  methods: {
+    changeArea (item) {
+      const area = Object.keys(item).map(v => {
+        if (item[v].length) {
+          return item[v].join(',')
+        }
+        return v
+      })
+      this.filters = {
+        area: area.join(',')
+      }
+      this.$refs.pushList.doQuery(this.filters)
+    }
+  },
+  computed: {
+    getTopInfo () {
+      return this.topInfo[this.$route.params.type || 'c']
+    }
+  },
+  created () {}
+}
+</script>
+
+<style lang="scss" scoped>
+  .page--potential {
+    @include diy-icon('top-c', 36, 36);
+    @include diy-icon('top-r', 34, 28);
+    ::v-deep .bidfor_text{
+      line-height: 36px;
+      margin-left: 8px;
+    }
+    background-color: #fff;
+    .border-box {
+      border: 1px solid #ececec;
+      border-radius: 5px;
+    }
+    .content-list-box {
+      margin-top: 16px;
+    }
+  }
+</style>