Browse Source

feat: 新增订阅推送历史卡片

cuiyalong 4 năm trước cách đây
mục cha
commit
f60a54ecd1

+ 5 - 7
src/api/index.js

@@ -1,6 +1,5 @@
 import axios from 'axios'
 import mock from '@/api/mock'
-import qs from 'qs'
 
 console.log('[debug]当前环境:', process.env)
 const service = axios.create({
@@ -9,12 +8,6 @@ const service = axios.create({
 
 service.interceptors.request.use(config => {
   // 在请求发送之前做一些事
-  if (config.method === 'post' || config.method === 'POST') {
-    if (typeof config.data !== 'string') {
-      config.data = qs.stringify(config.data)
-    }
-  }
-  // 获取插入token
   return config
 }, function (error) {
   // 当出现请求错误是做一些事
@@ -22,6 +15,11 @@ service.interceptors.request.use(config => {
   return Promise.reject(error)
 })
 
+// 添加一个返回拦截器
+service.interceptors.response.use(response => {
+  return response.data
+})
+
 const useMock = process.env.NODE_ENV === 'development' && process.env.VUE_APP_MOCK === 'true'
 
 export default useMock ? mock : service

+ 2 - 2
src/api/modules/home.js

@@ -9,10 +9,10 @@ export function getSearchTag (params) {
   })
 }
 
-export function getHomeActivity (data) {
+export function getPushList (data) {
   data = qs.stringify(data)
   return request({
-    url: '/activityList',
+    url: '/subscribe/push/list',
     method: 'post',
     data: data
   })

BIN
src/assets/images/icon/edit.png


+ 26 - 9
src/assets/style/reset-ele.scss

@@ -1,15 +1,32 @@
 @import './_mixin';
 @import './_variables';
 
-.big-member-page .el-pagination.is-background .el-pager {
-  li {
-    background-color: #fff;
-    border: 1px solid rgba($color: #000, $alpha: 0.05);
+.big-member-page {
+  // 分页样式重置
+  .el-pagination-container {
+    margin-top: 28px;
+    padding-bottom: 60px;
+    text-align: right;
   }
-
-  li:not(.disabled).active,
-  li:not(.disabled):hover {
-    color: #fff;
-    background-color: $color-text--highlight;
+  .el-pagination.is-background .el-pager {
+    li {
+      background-color: #fff;
+      border: 1px solid rgba($color: #000, $alpha: 0.05);
+    }
+  
+    li:not(.disabled).active,
+    li:not(.disabled):hover {
+      color: #fff;
+      background-color: $color-text--highlight;
+    }
+  }
+  
+  // button默认颜色重置
+  .el-button {
+    display: flex;
+    align-items: center;
+    padding: 8px 16px;
+    font-size: 14px;
+    line-height: 24px;
   }
 }

+ 31 - 40
src/components/article-item/ArticleItem.vue

@@ -1,16 +1,16 @@
 <template>
-  <div class="article-item">
-    <div class="a-i-left ellipsis">{{ index }}. {{ title }}</div>
+  <div class="article-item" @click="onClick">
+    <div class="a-i-left ellipsis" v-html="calcTitle"></div>
     <div class="a-i-right">
       <div class="tags">
-        <span class="tag" v-if="area">{{ area }}</span>
-        <span class="tag orange" v-if="type">{{ type }}</span>
-        <span class="tag green" v-if="buyerclass">{{ buyerclass }}</span>
-        <span class="tag dpink" v-if="calcBudget">{{ calcBudget }}</span>
+        <span class="tag" v-if="article.area">{{ article.area }}</span>
+        <span class="tag orange" v-if="article.type">{{ article.type }}</span>
+        <span class="tag green" v-if="article.buyerclass">{{ article.buyerclass }}</span>
+        <span class="tag dpink" v-if="article.calcBudget">{{ article.calcBudget }}</span>
       </div>
       <div class="time-container">
         <span class="el-icon-jy-time"></span>
-        <span class="time-text">{{ dateFromNow(publishtime) }}</span>
+        <span class="time-text">{{ dateFromNow(article.publishtime * 1000) }}</span>
       </div>
     </div>
   </div>
@@ -18,7 +18,7 @@
 
 <script>
 import { Tag } from 'element-ui'
-import { moneyUnit, dateFromNow } from '@/utils/'
+import { moneyUnit, dateFromNow, replaceKeyword } from '@/utils/'
 export default {
   name: 'article-item',
   components: {
@@ -29,44 +29,35 @@ export default {
       type: [String, Number],
       default: '1'
     },
-    // 标题
-    title: {
-      type: String,
-      default: ''
-    },
-    // 区域
-    area: {
-      type: String,
-      default: ''
-    },
-    // 类型
-    type: {
-      type: String,
-      default: ''
-    },
-    // 行业
-    buyerclass: {
-      type: String,
-      default: ''
-    },
-    // 金额
-    budget: {
-      type: Number,
-      default: 0
-    },
-    // 时间
-    publishtime: {
-      type: Number,
-      default: 0
+    article: {
+      type: Object,
+      default () {
+        return {
+          title: '', // 标题
+          area: '', // 区域
+          type: '', // 类型
+          buyerclass: '', // 行业
+          budget: '', // 金额
+          publishtime: 0, // 时间
+          matchkeys: [] // 高亮的关键词
+        }
+      }
     }
   },
   computed: {
     calcBudget () {
-      return moneyUnit(this.budget)
+      return moneyUnit(this.article.budget)
+    },
+    calcTitle () {
+      const hightLightedTitle = replaceKeyword(this.article.title, this.article.matchkeys, ['<span class="highlight-text">', '</span>'])
+      return `${this.index}. ${hightLightedTitle}`
     }
   },
   methods: {
-    dateFromNow
+    dateFromNow,
+    onClick () {
+      this.$emit('onClick')
+    }
   }
 }
 </script>
@@ -112,7 +103,7 @@ export default {
       &:not(:last-of-type) {
         margin-right: 4px;
       }
-      
+
       &.orange {
         background-color: #FFBA00;
       }

+ 3 - 23
src/components/common/Empty.vue

@@ -33,7 +33,6 @@ export default {
     flex: 1;
     padding: 16px;
     box-sizing: border-box;
-    background-color: rgba(245, 244, 249, 1);
 
     .empty-content-position {
       display: flex;
@@ -48,30 +47,11 @@ export default {
 
     .empty-main {
       @extend .empty-content-position;
+      margin-top: 10px;
       text-align: center;
-    }
-
-    .max-width70 {
-      width: 70%;
-    }
-
-    .max-width80 {
-      width: 80%;
-    }
-
-    .tip-text {
-      color: #5F5E64;
+      color: #999;
       font-size: 14px;
-      line-height: 20px;
-      text-align: center;
-    }
-
-    .tip-sub-text {
-      color: #9B9CA3;
-      font-size: 13px;
-      line-height: 20px;
-      margin-top: 6px;
-      text-align: center;
+      line-height: 22px;
     }
 
     .el-image {

+ 218 - 0
src/components/push-list/PushList.vue

@@ -0,0 +1,218 @@
+<template>
+  <el-card class="push-list-card">
+    <div slot="header" class="clearfix">
+      <span class="card-title">订阅推送</span>
+      <el-button class="sub-manager" type="plain" icon="el-icon-jy-edit">订阅管理</el-button>
+    </div>
+    <div class="push-list" v-loading="listState.loading">
+      <article-item
+        v-for="(item, index) in listState.list"
+        :key="index"
+        :index="index + 1"
+        :article="item"
+        @onClick="toDetail(item)"
+      />
+      <empty v-if="listState.list.length === 0 && listState.loaded">
+        <span>订阅关键词,接收最新招投标信息</span>
+        <div class="add-key-button">
+          <span class="icon-chahao"></span>
+          <span class="button-text">订阅关键词</span>
+        </div>
+      </empty>
+    </div>
+    <div class="el-pagination-container">
+      <el-pagination
+        background
+        layout="prev, pager, next, ->, total"
+        :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 ArticleItem from '@/components/article-item/ArticleItem.vue'
+import { getPushList } from '@/api/modules/'
+
+export default {
+  name: 'push-list',
+  components: {
+    [Pagination.name]: Pagination,
+    [Card.name]: Card,
+    [Button.name]: Button,
+    ArticleItem,
+    Empty
+  },
+  props: {
+    filters: {
+      type: Object,
+      default () {
+        return {
+          area: '',
+          time: ''
+        }
+      }
+    }
+  },
+  computed: {},
+  data () {
+    return {
+      listState: {
+        loaded: true, // 是否已经搜索过
+        loading: false,
+        pageNum: 1, // 当前页
+        pageSize: 10, // 每页多少条数据
+        total: 0, // 一共多少条数据
+        list: [] // 查询请求返回的数据
+      }
+    }
+  },
+  created () {
+    this.doQuery()
+  },
+  methods: {
+    // 恢复数据至第一次请求的状态(页码等)
+    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,
+        area: this.filters.area,
+        time: this.filters.time
+      }
+
+      if (filters && Object.keys(filters).length > 0) {
+        query.area = filters.area
+        query.time = filters.time
+      }
+
+      this.listState.loading = true
+      this.listState.loaded = false
+      const res = await getPushList(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()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  @include diy-icon('edit', 20, 20);
+  // card样式重置
+  ::v-deep {
+    .el-card__header {
+      margin: 0 40px;
+      padding-left: 0;
+      padding-right: 0;
+    }
+    .el-card__body {
+      padding: 20px 40px;
+    }
+    .el-button {
+      color: #1d1d1d;
+      border-color: #E0E0E0;
+      &.el-button:focus,
+      &.el-button:hover {
+        color: inherit;
+        border-color: #E0E0E0;
+        background-color: inherit;
+      }
+    }
+    .empty-container {
+      margin-top: 60px;
+    }
+  }
+
+  .push-list-card {
+    .card-title {
+      font-size: 24px;
+      color: #1d1d1d;
+      line-height: 36px;
+    }
+    .sub-manager {
+      float: right;
+    }
+    .push-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);
+      }
+    }
+  }
+</style>

+ 2 - 2
src/utils/globalFunctions.js

@@ -257,7 +257,7 @@ export function moneyUnit (m, type = 'string', lv = 0) {
         }
       }
 
-      var result = num / Math.pow(10000, lv);
+      var result = num / Math.pow(10000, lv)
 
       if (result > 10000 && lv < 2) {
         return this.test(num, type, lv + 1)
@@ -297,7 +297,7 @@ export function moneyUnit (m, type = 'string', lv = 0) {
  *
  * 批量高亮-----
  * 比如:要将 - `剑鱼标讯工具函数` 字符串中的 `工具` `剑鱼` 高亮
- * 则此时 value -> `剑鱼标讯工具函数批量高亮`
+ * 则此时 value -> `剑鱼标讯工具函数`批量高亮
  *        oldChar -> ['工具', '剑鱼']
  *        newChar -> ['<span class="highlight-text">', '</span>']
  *