lianbingjie 3 سال پیش
والد
کامیت
140299ef48

+ 2 - 1
README.md

@@ -1,6 +1,7 @@
 ## 剑鱼大会员PC端
 v1.4.4
 增加消息中心曝光率
+
 ##### 无顶部底部开发
 
 0. ```yarn run serve:alone```
@@ -13,6 +14,6 @@ v1.4.4
 
 2. 修改`systemjs-importmap`中app对应的请求地址
 
-    > 文件地址 /src/web/templates/frontRouter/pc/docs/sess/index.html
+    > 文件地址 /src/web/templates/frontRouter/pc/page_big_pc/sess/index.html
 
 3. 访问`/swordfish/docs/index`

+ 12 - 0
src/App.vue

@@ -40,4 +40,16 @@ export default {
   top: 63px;
   z-index: 99;
 }
+.visited {
+  .visited-hd,
+  td {
+    color: #999!important;
+  }
+  .hover:hover {
+    color: #2cb7ca!important;
+  }
+  .visited-ft {
+    color: #9B9CA3!important;
+  }
+}
 </style>

BIN
src/assets/images/vip/7.png


+ 1 - 1
src/components/article-item/ArticleItem.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="article-item" :class="{'style-for-gray': config.gray, 'style-for-table': config.table }">
     <input v-if="config.collect" @click.stop class="custom-checkbox title-text-checkbox" name="bid-list" type="checkbox" :dataid="article._id">
-    <div class="a-i-left ellipsis" @click="onClick" v-html="calcTitle"></div>
+    <div class="a-i-left ellipsis visited-hd" @click="onClick" v-html="calcTitle"></div>
     <div class="a-i-right">
       <div class="tags">
         <span class="tag" v-if="article.area">{{ article.area }}</span>

+ 36 - 16
src/components/forecast/ForeCast.vue

@@ -82,26 +82,31 @@
         <span style="width:100px;">操作</span>
       </div>
       <ul class="listData_ul" :style="{'padding-bottom': getShowPagination?'': '48px'}">
-        <li class="list_li" style="padding:24px 0 26px;display:flex;align-items: center;cursor: default;" v-for="(item, index) in getMyData.listState.list" :key="index">
+        <li
+          class="list_li"
+          style="padding:24px 0 26px;display:flex;align-items: center;cursor: default;"
+          :class="{ visited: item.visited }"
+          v-for="(item, index) in getMyData.listState.list"
+          :key="index">
           <div style="padding: 0 12px;width:810px;cursor: pointer" @click="goViewEnt(item.s_entId, item)">
-            <div class="list_name ent_li_name">{{item.s_entname}}<span class="red_point" v-if="item.i_apppushunread == 1"></span>
+            <div class="list_name ent_li_name visited-hd">{{item.s_entname}}<span class="red_point" v-if="item.i_apppushunread == 1"></span>
             </div>
             <div class="list_unit">
               <div class="pur_unit">
                 <span class="unit_label">成立日期:</span>
-                <span class="unit_name entname">{{item.l_establishdate?dateFormatter(item.l_establishdate*1000, 'yyyy-MM-dd'):'--'}}</span>
+                <span class="unit_name entname visited-ft">{{item.l_establishdate?dateFormatter(item.l_establishdate*1000, 'yyyy-MM-dd'):'--'}}</span>
               </div>
               <div class="pur_unit">
                 <span class="unit_label">注册资本:</span>
-                <span class="unit_name entname">{{item.f_capital?moneyUnit(item.f_capital*10000):'--'}}</span>
+                <span class="unit_name entname visited-ft">{{item.f_capital?moneyUnit(item.f_capital*10000):'--'}}</span>
               </div>
               <div class="pur_unit">
                 <span class="unit_label">企业地址:</span>
-                <span class="unit_name entname">{{item.s_area?item.s_area:'--'}}{{item.s_city?item.s_city:''}}</span>
+                <span class="unit_name entname visited-ft">{{item.s_area?item.s_area:'--'}}{{item.s_city?item.s_city:''}}</span>
               </div>
               <div class="pur_unit">
                 <span class="unit_label">企业联系方式:</span>
-                <span class="unit_name entname">{{item.s_phone?item.s_phone:'--'}}</span>
+                <span class="unit_name entname visited-ft">{{item.s_phone?item.s_phone:'--'}}</span>
               </div>
             </div>
           </div>
@@ -266,7 +271,7 @@
 <script>
 import { Pagination, Progress, Message, Tooltip, Dialog, Button } from 'element-ui'
 import { mapState } from 'vuex'
-// import { getPushList } from '@/api/modules/'
+import { mixinVisited } from '@/utils/mixins/visited'
 import Empty from '@/components/common/Empty.vue'
 import GroupCard from '@/components/selector/GroupSelector.vue'
 import { moneyUnit, dateFormatter } from '@/utils'
@@ -274,6 +279,7 @@ import { setFollowEnt, setCancelEnt, changeEntGroup } from '@/api/modules'
 export default {
   props: ['type', 'title', 'mydata', 'myDataObj', 'resData', 'myPolicydata', 'potenObj', 'potenResult', 'entSearch', 'entSearchRes'],
   name: 'listData',
+  mixins: [mixinVisited],
   components: {
     [Pagination.name]: Pagination,
     [Progress.name]: Progress,
@@ -337,7 +343,18 @@ export default {
   },
   watch: {
     'myDataObj.list' (newVal) {
-      this.getMyData.listState.list = newVal
+      this.getMyData.listState.list = newVal.map(item => {
+        const visited = this.pathVisited(
+          this.createPathItem(
+            '/ent_portrait/*',
+            `id=${item.s_entId}`
+          )
+        )
+        return {
+          ...item,
+          visited
+        }
+      })
       this.getEntListTips()
     },
     mydata (newVal, oldVal) {
@@ -486,12 +503,6 @@ export default {
     // 企业搜索
     entSearchData (list) {
       if (list && list.length !== 0) {
-        // const that = this
-        // list.forEach(function (item) {
-        //   console.log(that.getFollow(item.s_id))
-        //   // let isfollow = that.getFollow(item.s_id)
-        //   // item.isentFollow = isfollow
-        // })
         this.listState.list = list
         this.listState.total = list.length
       } else {
@@ -580,6 +591,15 @@ export default {
       if (item.i_apppushunread) {
         item.i_apppushunread = null
       }
+      if (this.type === 'entintel') {
+        item.visited = true
+        this.pathVisiting(
+          this.createPathItem(
+            '/ent_portrait/*',
+            `id=${id}`
+          )
+        )
+      }
       const routeUrl = this.$router.resolve({
         path: `/ent_portrait/${id}`
       })
@@ -705,10 +725,10 @@ export default {
       location.href = '/jylab/entSearch/index.html'
     },
     getEntListTips () {
-      if (!this.myDataObj.match && !this.myDataObj.group && this.myDataObj.initTotal === 0) {
+      if (this.myDataObj && !this.myDataObj.match && !this.myDataObj.group && this.myDataObj.initTotal === 0) {
         this.tips = '暂无企业情报信息,前往企业搜索关注企业'
         this.tipimages = require('@/assets/images/empty/jy-back.png')
-      } else if (this.myDataObj.list.length === 0 && this.myDataObj.initTotal !== 0) {
+      } else if (this.myDataObj && this.myDataObj.list.length === 0 && this.myDataObj.initTotal !== 0) {
         this.tips = '暂无匹配数据'
         this.tipimages = require('@/assets/images/empty/jy-back.png')
       }

+ 14 - 5
src/components/home/HomeList.vue

@@ -10,21 +10,30 @@
       </div>
     </div>
     <div class="h-content" v-loading="loading" v-if="!reportModule && getlist.length !== 0  && model !== 'model-4'">
-      <div class="h-content-l" :class="getlist.length-1===index&&getlist.length>=5?'lastLine':''" v-for="(item, index) in getlist" :key="index">
-        <div class="h-title-l" @click="getDetail(item)">{{item.projectName}}<span class="red-spot" v-if="spotRedShow && item.unread && item.unread !== 0"></span></div>
+      <div
+        class="h-content-l hover"
+        :class="{ lastLine: getlist.length - 1 === index && getlist.length >= 5, visited: item.visited }"
+        v-for="(item, index) in getlist" :key="index">
+        <div class="h-title-l visited-hd hover" @click="getDetail(item)">{{item.projectName}}<span class="red-spot" v-if="spotRedShow && item.unread && item.unread !== 0"></span></div>
         <div class="h-time-r">{{dateFormatter(item.publishtime*1000, 'yyyy-MM-dd')}}</div>
       </div>
     </div>
     <div class="h-content" v-loading="loading"  v-if="!reportModule && getlist.length !== 0 && model === 'model-4'">
       <PoverTimeLine @show="thisAnnouncement(item)" v-for="(item, index) in getlist" :key="index" :stepList="item.stepList" poperWidth="470">
-        <div class="h-content-l" :class="getlist.length-1===index&&getlist.length>=5?'lastLine':''" slot="content">
-          <div class="h-title-l" @click="getDetail(item)">{{item.projectName}}<span class="red-spot" v-if="spotRedShow && item.unread && item.unread !== 0"></span></div>
+        <div
+          class="h-content-l"
+          :class="{ lastLine: getlist.length - 1 === index && getlist.length >= 5, visited: item.visited }"
+          slot="content">
+          <div class="h-title-l visited-hd hover" @click="getDetail(item)">{{item.projectName}}<span class="red-spot" v-if="spotRedShow && item.unread && item.unread !== 0"></span></div>
           <div class="h-time-r">{{dateFormatter(item.publishtime*1000, 'yyyy-MM-dd')}}</div>
         </div>
       </PoverTimeLine>
     </div>
     <div class="h-content report-content" v-loading="loading" v-if="reportModule && getlist.length !== 0">
-      <div class="h-content-l" v-for="(item, index) in getlist" :key="index">
+      <div
+        class="h-content-l"
+        v-for="(item, index) in getlist"
+        :key="index">
         <div class="h-title-l r-title-l" @click="getDetail(item)">
           <span class="report-round" :class="timeSection==='周'?'yellow':'blue'">{{timeSection}}</span>
           <span>{{dateFormatter(item.startdate*1000, 'MM月dd日')}}-{{dateFormatter(item.enddate*1000, 'MM月dd日')}}</span>

+ 45 - 3
src/components/push-list/ProjectProgressList.vue

@@ -14,7 +14,7 @@
         @show="thisAnnouncement(item)">
         <template v-slot:content>
           <article-item
-            :class="item.i_apppushunread !== 0 && item.i_apppushunread? 'item_class' : ''"
+            :class="{ item_class: item.i_apppushunread !== 0 && item.i_apppushunread, visited: item.visited }"
             :index="(listState.pageSize * (listState.pageNum - 1)) +  index + 1"
             :article="sortItemInfo(item)"
             @onClick="toDetail(item, index)"
@@ -56,9 +56,11 @@ import Empty from '@/components/common/Empty.vue'
 import ArticleItem from '@/components/article-item/ArticleItem.vue'
 import { dateFromNow, dateFormatter, replaceKeyword } from '@/utils/'
 import { getFollowProjectList, setFollowRemove30Day, showAnnouncement } from '@/api/modules/'
+import { mixinVisited } from '@/utils/mixins/visited'
 import PoverTimeLine from '@/components/time-line/PoverTimeLine.vue'
 export default {
   name: 'project-list',
+  mixins: [mixinVisited],
   components: {
     [Pagination.name]: Pagination,
     [Card.name]: Card,
@@ -148,7 +150,18 @@ export default {
       const start = this.listState.pageSize * (this.listState.pageNum - 1)
       const end = this.listState.pageSize * this.listState.pageNum
       thisList = this.thisDataList.slice(start, end)
-      this.listState.list = thisList
+      this.listState.list = thisList.map(item => {
+        const visited = this.pathVisited(
+          this.createPathItem(
+            '/pro_follow_detail/*',
+            `id=${item.sid}`
+          )
+        )
+        return {
+          ...item,
+          visited
+        }
+      })
     },
     areaItem (name) {
       this.activeArea = name
@@ -157,7 +170,18 @@ export default {
       const start = this.listState.pageSize * (this.listState.pageNum - 1)
       const end = this.listState.pageSize * this.listState.pageNum
       thisList = this.thisDataList.slice(start, end)
-      this.listState.list = thisList
+      this.listState.list = thisList.map(item => {
+        const visited = this.pathVisited(
+          this.createPathItem(
+            '/pro_follow_detail/*',
+            `id=${item.sid}`
+          )
+        )
+        return {
+          ...item,
+          visited
+        }
+      })
     }
   },
   methods: {
@@ -221,6 +245,17 @@ export default {
 
       if (res.error_code === 0) {
         this.listState.total = res.data.total
+        if (Array.isArray(res.data.List)) {
+          res.data.List.forEach(item => {
+            const visited = this.pathVisited(
+              this.createPathItem(
+                '/pro_follow_detail/*',
+                `id=${item.sid}`
+              )
+            )
+            this.$set(item, 'visited', visited)
+          })
+        }
         this.listState.list = res.data.List || []
       } else {
         this.listState.total = 0
@@ -229,6 +264,13 @@ export default {
     },
     toDetail (item, index) {
       const { sid, fid } = item
+      item.visited = true
+      this.pathVisiting(
+        this.createPathItem(
+          '/pro_follow_detail/*',
+          `id=${sid}`
+        )
+      )
       const link = this.$router.resolve({
         path: '/pro_follow_detail',
         query: {

+ 22 - 2
src/components/push-list/PushList.vue

@@ -31,6 +31,7 @@
       <article-item
         class="list-item"
         v-for="(item, index) in listState.list"
+        :class="{ visited: item.visited }"
         :key="index"
         :index="(listState.pageSize * (listState.pageNum - 1)) +  index + 1"
         :article="item"
@@ -67,7 +68,7 @@
         </tr>
         </thead>
         <tbody>
-        <tr v-for="(item, index) in tableList" :key="index + '_' + item._id" @click="toDetail(item)">
+        <tr v-for="(item, index) in tableList" :class="{ visited: item.visited }" :key="index + '_' + item._id" @click="toDetail(item)">
           <td width="48">{{ index + 1 }}</td>
           <td width="315" class="tt-l" v-html="calcTitle(item, index)"></td>
           <td width="84">{{ item.type }}</td>
@@ -131,9 +132,11 @@ import Empty from '@/components/common/Empty.vue'
 import ArticleItem from '@/components/article-item/ArticleItem.vue'
 import { getPushList, getExportPushList } from '@/api/modules/'
 import { moneyUnit, dateFromNow, replaceKeyword } from '@/utils/'
+import { mixinVisited } from '@/utils/mixins/visited'
 /* eslint-disable */
 export default {
   name: 'push-list',
+  mixins: [mixinVisited],
   components: {
     [Pagination.name]: Pagination,
     [Card.name]: Card,
@@ -326,7 +329,17 @@ export default {
       const res = await getPushList(query)
       this.listState.loading = false
       this.listState.loaded = true
-      console.log(res, 'res')
+      if (Array.isArray(res.data)) {
+        res.data.forEach(item => {
+          const visited = this.pathVisited(
+            this.createPathItem(
+              '/article/content/*.html',
+              `id=${item._id}`
+            )
+          )
+          this.$set(item, 'visited', visited)
+        })
+      }
       if (query.pageNum === 1) {
         this.tableList = res.data || []
       }
@@ -343,6 +356,13 @@ export default {
     },
     toDetail (item) {
       const { _id } = item
+      item.visited = true
+      this.pathVisiting(
+        this.createPathItem(
+          '/article/content/*.html',
+          `id=${_id}`
+        )
+      )
       window.open(`/article/content/${_id}.html`)
     },
     onPageChange (p) {

+ 17 - 1
src/store/user.js

@@ -19,7 +19,9 @@ export default {
     // 业务范围是否全部删除
     isDeleteAllScope: defaultLocalPageData('bigmember-login-clear-DELETE_SCOPE', false),
     // 采购内容是否全部删除
-    isDeleteAllBuyClass: defaultLocalPageData('bigmember-login-clear-DELETE_BUY_CLASS', false)
+    isDeleteAllBuyClass: defaultLocalPageData('bigmember-login-clear-DELETE_BUY_CLASS', false),
+    // 用户访问灰显记录列表
+    visitedList: defaultLocalPageData('visited-path-list', [])
   }),
   mutations: {
     setUserInfo (state, info) {
@@ -54,6 +56,20 @@ export default {
     clearBuyClass (state, data) {
       state.isDeleteAllScope = data
       localStorage.setItem('bigmember-login-clear-DELETE_BUY_CLASS', data)
+    },
+    refreshVisited (state) {
+      const expiresTime = 3 * 24 * 60 * 60 * 1000
+      const now = Date.now()
+      const list = JSON.parse(localStorage.getItem('visited-path-list')) || []
+      state.visitedList = list.filter(item => {
+        return now - item.timestamp <= expiresTime
+      })
+      localStorage.setItem('visited-path-list', JSON.stringify(state.visitedList))
+    },
+    // 访问添加 visitedList
+    addVisited (state, list) {
+      state.visitedList = list
+      localStorage.setItem('visited-path-list', JSON.stringify(state.visitedList))
     }
   },
   actions: {

+ 28 - 0
src/utils/functions/syncSessionStorage.js

@@ -0,0 +1,28 @@
+const syncKey = 'syncSessionStorage'
+const sessKey = 'sessionStorage'
+// 实时同步 sessionStorage 的 key
+const syncKeyList = ['visited-path-list']
+
+// 新打开一个tab标签页并通知其他标签页同步sessionStorage的数据到本标签页
+if (!sessionStorage.length) {
+  // 这个调用能触发storage事件,从而达到共享数据的目的
+  localStorage.setItem(syncKey, Date.now())
+}
+
+window.addEventListener('storage', function (e) {
+  if (e.key === syncKey) {
+    // 已存在的标签页会收到这个事件
+    localStorage.setItem(sessKey, JSON.stringify(sessionStorage))
+    localStorage.removeItem(sessKey)
+  } else if (e.key === sessKey && !sessionStorage.length) {
+    // 新开启的标签页会收到这个事件
+    const data = JSON.parse(e.newValue)
+    for (const k in data) {
+      sessionStorage.setItem(k, data[k])
+    }
+  } else if (syncKeyList.indexOf(e.key) !== -1) {
+    // if (e.newValue) {
+    //   sessionStorage.setItem(e.key, e.newValue)
+    // }
+  }
+})

+ 1 - 0
src/utils/index.js

@@ -1,4 +1,5 @@
 import './globalDirectives'
 import './globalFilters'
+import './functions/syncSessionStorage'
 
 export * from './globalFunctions'

+ 0 - 0
src/utils/mixins.js → src/utils/mixins/index.js


+ 69 - 0
src/utils/mixins/visited.js

@@ -0,0 +1,69 @@
+import { mapState } from 'vuex'
+
+class VisitedPathItem {
+  constructor (path, search) {
+    this.path = path
+    this.search = search
+    this.timestamp = Date.now()
+  }
+}
+
+export const mixinVisited = {
+  computed: {
+    ...mapState({
+      visitedList: state => state.user.visitedList
+    })
+  },
+  created () {
+    this.$store.commit('user/refreshVisited')
+  },
+  methods: {
+    createPathItem (path, search) {
+      return new VisitedPathItem(path, search)
+    },
+    // 从判断 path 是否访问过
+    // 参数path为 VisitedPathItem new 出来的实例
+    pathVisitedIndex (path) {
+      const list = this.visitedList
+      let sameIndex = -1
+      if (list) {
+        for (let i = 0; i < list.length; i++) {
+          const same = this.comparePath(list[i], path)
+          if (same) {
+            sameIndex = i
+            break
+          }
+        }
+      }
+      return sameIndex
+    },
+    comparePath (basePath, newPath) {
+      const pathSame = basePath.path === newPath.path
+      const searchSame = basePath.search === newPath.search
+
+      return pathSame && searchSame
+    },
+    pathVisited (path) {
+      return this.pathVisitedIndex(path) !== -1
+    },
+    // 保存一条历史
+    // 参数path为 VisitedPathItem new出来的实例
+    pathVisiting (path) {
+      if (!path) return
+      // 判断是否重复
+      const index = this.pathVisitedIndex(path)
+      const visitedList = JSON.parse(JSON.stringify(this.visitedList))
+      if (index >= 0) {
+        // 已存在
+        const itemArr = visitedList.splice(index, 1)
+        const item = itemArr[0]
+        item.timestamp = Date.now()
+        visitedList.unshift(item)
+      } else {
+        visitedList.unshift(path)
+      }
+      // 全量替换
+      this.$store.commit('user/addVisited', visitedList)
+    }
+  }
+}

+ 2 - 2
src/views/bid-forecast/BidForecastLimit.vue

@@ -218,7 +218,7 @@ export default {
       if (getcity.length !== 0) {
         aloneCity = getcity[0]
       } else {
-        aloneCity = ''
+        aloneCity = Object.keys(data.area)[0] + ''
       }
       const item = {
         appVersion: '',
@@ -236,7 +236,7 @@ export default {
       const res = await getForWData(item)
       if (res.error_code === 0) {
         // -1:预测失败;0:默认;1:有未查看得预测数据并返回id;2:正在预测中
-        if (res.data.status === 1) {
+        if (res.data.status === 1 || res.data.status === 3) {
           this.fid = res.data.id
           this.getProForWResult(res.data.id)
         } else if (res.data.status === 2) {

+ 23 - 5
src/views/ent-intel/MyClient.vue

@@ -27,18 +27,19 @@
             </div>
             <div class="l-tbody" v-loading="loading" element-loading-background="#fff" v-if="client.list && client.list.length > 0">
               <ul class="items">
-                <li class="item" v-for="(item, index) in client.list" :key="'00' + index">
+                <li class="item" :class="{ visited: item.visited }" v-for="(item, index) in client.list" :key="'00' + index">
                   <div class="item-info w-800">
-                    <div class="info-name" @click="goUnit(item.name)">{{item.name}}</div>
+                    <div class="info-name visited-hd" @click="goUnit(item)">{{item.name}}</div>
                     <div class="info-other">
                       <span class="other-list" v-if="item.province">
                         <i class="area-icon"></i>
-                        <em class="text-label">所在地:</em>{{item.province}}
+                        <em class="text-label">所在地:</em>
+                        <span class="visited-ft">{{item.province}}</span>
                       </span>
                       <span class="other-list" v-if="item.buyerclass">
                         <i class="type-icon"></i>
                         <em class="text-label">采购单位类型:</em>
-                        {{item.buyerclass}}
+                        <span class="visited-ft">{{item.buyerclass}}</span>
                       </span>
                     </div>
                   </div>
@@ -83,10 +84,12 @@ import { Input, Button, Pagination } from 'element-ui'
 import forLayOut from '@/components/forecast/ForLayout.vue'
 import TabHeader from '@/components/common/TabHeader.vue'
 import Empty from '@/components/common/Empty.vue'
+import { mixinVisited } from '@/utils/mixins/visited'
 import { mapState } from 'vuex'
 import { followClientList, setStatusCustomer } from '@/api/modules'
 export default {
   name: 'ent-intel',
+  mixins: [mixinVisited],
   components: {
     [Input.name]: Input,
     [Button.name]: Button,
@@ -142,6 +145,13 @@ export default {
             if (v.followdate) {
               v.followdate = v.followdate.replace(/\//g, '-')
             }
+            const visited = this.pathVisited(
+              this.createPathItem(
+                '/unit_portrayal/*',
+                `id=${v.name}`
+              )
+            )
+            this.$set(v, 'visited', visited)
           })
           this.client.list = res.data.list
           this.client.total = res.data.count
@@ -165,7 +175,15 @@ export default {
     clearHandle () {
       this.getClientList()
     },
-    goUnit (name) {
+    goUnit (item) {
+      var name = item.name
+      item.visited = true
+      this.pathVisiting(
+        this.createPathItem(
+          '/unit_portrayal/*',
+          `id=${item.name}`
+        )
+      )
       const routeUrl = this.$router.resolve({
         path: `/unit_portrayal/${name}`
       })

+ 25 - 1
src/views/portrayal/components/DynamicList.vue

@@ -33,6 +33,7 @@
     <div class="info-list" v-show="!isTable&&!showEmpty">
       <portrayal-article-item
         class="list-item"
+        :class="{ visited: item.visited }"
         v-for="(item, index) in listState.list"
         :key="index"
         :index="(listState.pageSize * (listState.pageNum - 1)) +  index + 1"
@@ -57,7 +58,7 @@
         </tr>
         </thead>
         <tbody>
-        <tr v-for="(item, index) in tableList" :key="index + '_' + item.id" @click="toDetail(item)">
+        <tr v-for="(item, index) in tableList" :class="{ visited: item.visited }" :key="index + '_' + item.id" @click="toDetail(item)">
           <td width="48">{{ (listState.pageNum - 1) * listState.pageSize + index + 1 }}</td>
           <td width="315" class="tt-l">{{ item.title }}</td>
           <td width="84">{{ item.bidstatus }}</td>
@@ -120,10 +121,12 @@ import Empty from '@/components/common/Empty.vue'
 import PortrayalArticleItem from './DynamicListItem.vue'
 import { dateFormatter, moneyUnit } from '@/utils/'
 import { mapState } from 'vuex'
+import { mixinVisited } from '@/utils/mixins/visited'
 import { getNewMsg, getPortrayalSearchExportId, getSvipNewMsg, getUnitDt, getVipUnitDt } from '@/api/modules'
 /* eslint-disable */
 export default {
   name: 'portrayal-dynamic-list',
+  mixins: [mixinVisited],
   components: {
     [Pagination.name]: Pagination,
     [Card.name]: Card,
@@ -420,6 +423,20 @@ export default {
         if (this.listState.pageNum === 1) {
           this.listState.total = res.data.count
         }
+        try {
+          res.data.list = res.data.list.map(item => {
+            const visited = this.pathVisited(
+              this.createPathItem(
+                '/article/content/*.html',
+                `id=${item.id}`
+              )
+            )
+            return {
+              ...item,
+              visited
+            }
+          })
+        } catch (error) {}
         this.listState.list = res.data.list.map(v => {
           v.collection = 0
           return v
@@ -435,6 +452,13 @@ export default {
       }
     },
     toDetail (item) {
+      item.visited = true
+      this.pathVisiting(
+        this.createPathItem(
+          '/article/content/*.html',
+          `id=${item.id}`
+        )
+      )
       window.open(`/article/content/${item.id}.html`)
     },
     onPageChange (p) {

+ 1 - 1
src/views/portrayal/components/DynamicListItem.vue

@@ -3,7 +3,7 @@
     <input @click.stop class="custom-checkbox title-text-checkbox" name="bid-list" type="checkbox" :dataid="article.id">
     <div class="item-right">
       <div class="row-1">
-        <div class="a-i-left ellipsis" @click="onClick" v-html="calcTitle"></div>
+        <div class="a-i-left ellipsis visited-hd" @click="onClick" v-html="calcTitle"></div>
         <i class="icon-collect" @click.stop="collectChange(article, $event)" :class="{'checked': article.collection}"
            :dataid="article.id"></i>
       </div>

+ 30 - 3
src/views/portrayal/components/ProActive.vue

@@ -4,8 +4,8 @@
       {{title}}
     </div>
     <div class="pro_ul" v-if="!isShow">
-      <div class="pro_list" v-for="(item, index) in getList" :key="index">
-        <div class="pro_li_title" @click="setLink(item)">{{item.projectname || item.title}}</div>
+      <div class="pro_list" :class="{ visited: item.visited }" v-for="(item, index) in getList" :key="index">
+        <div class="pro_li_title visited-hd" @click="setLink(item)">{{item.projectname || item.title}}</div>
         <div class="pro_li_info">
           <div class="li_left">
             <span class="tags">{{item.area}}</span>
@@ -38,9 +38,11 @@
 import { Pagination } from 'element-ui'
 import Empty from '@/components/common/Empty'
 import { moneyUnit, dateFormatter } from '@/utils'
+import { mixinVisited } from '@/utils/mixins/visited'
 export default {
   props: ['projectData', 'title', 'type', 'isactive'],
   name: 'proactive',
+  mixins: [mixinVisited],
   components: {
     [Pagination.name]: Pagination,
     Empty
@@ -84,7 +86,18 @@ export default {
     dateFormatter,
     initData (obj) {
       if (obj.proActiveList && obj.proActiveList.length !== 0) {
-        this.listState.list = obj.proActiveList
+        this.listState.list = obj.proActiveList.map(item => {
+          const visited = this.pathVisited(
+            this.createPathItem(
+              '/article/content/*.html',
+              `id=${item.id}`
+            )
+          )
+          return {
+            ...item,
+            visited
+          }
+        })
         this.listState.total = obj.count
         this.isShow = false
       } else if (obj.buyerHistroyList && obj.buyerHistroyList !== 0) {
@@ -96,7 +109,14 @@ export default {
       }
     },
     setLink (data) {
+      data.visited = true
       if (data.title && data.id) {
+        this.pathVisiting(
+          this.createPathItem(
+            '/article/content/*.html',
+            `id=${data.id}`
+          )
+        )
         window.open(`/article/content/${data.id}.html`, '_blank')
         return
       }
@@ -107,6 +127,13 @@ export default {
           // fid: data._id
         }
       })
+      this.pathVisiting(
+        this.createPathItem(
+          '/pro_follow_detail/*',
+          `id=${data.infoid}`
+        )
+      )
+
       return window.open(routeUrl.href, '_blank')
     },
     onPageChange (p) {

+ 20 - 3
src/views/portrayal/components/UnitList.vue

@@ -2,8 +2,8 @@
   <div class="dynamic" v-show="domShow">
     <div class="d-title">招标动态</div>
     <div class="d-content" v-if="showDt">
-      <div class="d-list" v-for="item in dt.list" :key="item.id" @click="goDetail(item.id)">
-        <div class="d-title">{{item.title}}</div>
+      <div class="d-list" :class="{ visited: item.visited }" v-for="item in dt.list" :key="item.id" @click="goDetail(item)">
+        <div class="d-title visited-hd">{{item.title}}</div>
         <div class="d-info">
           <p class="i-main">
             <span v-if="item.area" class="i-area">{{item.area}}</span>
@@ -59,9 +59,11 @@ import { getUnitDt, getVipUnitDt } from '@/api/modules/'
 import { moneyUnit } from '@/utils/'
 import Empty from '@/components/common/Empty'
 import { Pagination, Dialog, Button } from 'element-ui'
+import { mixinVisited } from '@/utils/mixins/visited'
 import { mapState } from 'vuex'
 export default {
   name: 'dynamic',
+  mixins: [mixinVisited],
   components: {
     [Pagination.name]: Pagination,
     [Dialog.name]: Dialog,
@@ -202,6 +204,13 @@ export default {
           res.data.list.forEach((v, i) => {
             v.firsttime = new Date(Number(v.firsttime + '000')).pattern('yyyy/MM/dd')
             v.bidamount = v.bidamount ? moneyUnit(v.bidamount) : ''
+            const visited = this.pathVisited(
+              this.createPathItem(
+                '/article/content/*.html',
+                `id=${v.id}`
+              )
+            )
+            this.$set(v, 'visited', visited)
           })
           this.showDt = true
           if (res.data.count >= 0) {
@@ -248,7 +257,15 @@ export default {
       this.dt.pageNum = currentPage
       this.getUnitDtFn(this.bidataparams)
     },
-    goDetail (id) {
+    goDetail (item) {
+      const id = item.id
+      item.visited = true
+      this.pathVisiting(
+        this.createPathItem(
+          '/article/content/*.html',
+          `id=${id}`
+        )
+      )
       return window.open('/article/content/' + id + '.html')
     },
     closeDialog (data) {

+ 2 - 2
src/views/reportData/pageMonth.vue

@@ -21,8 +21,8 @@
             </div>
             <div class="data_line"></div>
             <div class="data_item">
-              <p class="item_handle">数据来源:已为您推送的招标项目信息</p>
-              <p class="item_handle">项目预算/项目规模:少量预算金额、中标金额未公开或为空的项目,将通过剑鱼标讯预测模型进行填补,可能会与实际项目预算、项目规模略有差距;</p>
+              <p class="item_handle">数据来源:基于您当前订阅条件所关联的招标项目数据;</p>
+              <p class="item_handle">项目预算/项目规模:少量预算金额、中标金额未公开或为空的项目,在计算项目总预算、总规模时不参与统计;</p>
               <p class="item_handle">项目重复统计:一个招标项目可能同属于多个关键词组,故各关键词组的数据统计之和可能大于整体市场的统计。</p>
             </div>
           </div>

+ 2 - 2
src/views/reportData/pageWeek.vue

@@ -41,8 +41,8 @@
           </div>
           <div class="data_line"></div>
           <div class="data_item">
-            <p class="item_handle">数据来源:已为您推送的招标项目信息</p>
-            <p class="item_handle">项目预算/项目规模:少量预算金额、中标金额未公开或为空的项目,将通过剑鱼标讯预测模型进行填补,可能会与实际项目预算、项目规模略有差距;</p>
+            <p class="item_handle">数据来源:基于您当前订阅条件所关联的招投标公告数据;</p>
+            <p class="item_handle">项目预算/项目规模:少量预算金额、中标金额未公开或为空的项目,在计算项目总预算、总规模时不参与统计;</p>
             <p class="item_handle">项目重复统计:一个招标项目可能同属于多个关键词组,故各关键词组的数据统计之和可能大于整体市场的统计。</p>
           </div>
         </div>

+ 54 - 7
src/views/work-desktop/WorkDesktop.vue

@@ -65,8 +65,10 @@ import HomePotenList from '@/components/home/HomePotenList.vue'
 import { dateFormatter, replaceKeyword } from '@/utils/'
 import { getPushList, getProjectHistory, getDeskFollowList, getEntCollectionList, getFollowProjectList, getReportList, getIndexCorList, setStatusCustomer, setFollowEnt, setRemoveEnt, setRemoveCustomer } from '@/api/modules/'
 import { mapState } from 'vuex'
+import { mixinVisited } from '@/utils/mixins/visited'
 export default {
   name: 'work-desktop',
+  mixins: [mixinVisited],
   components: {
     UserInfo,
     CommonUse,
@@ -112,8 +114,16 @@ export default {
     initData () {
       // 订阅信息
       getPushList({ pageNum: 1, pageSize: 5, format: 'table', area: '', time: '' }).then(res => {
-        console.log(res)
-        if (res && res.data) {
+        if (res && Array.isArray(res.data)) {
+          res.data.forEach(item => {
+            const visited = this.pathVisited(
+              this.createPathItem(
+                '/article/content/*.html',
+                `id=${item._id}`
+              )
+            )
+            this.$set(item, 'visited', visited)
+          })
           this.getList = res.data
           this.$refs.sublist1.haskey = res.haskey
           this.$refs.sublist1.isSubCount = this.info.isSubCount
@@ -125,12 +135,19 @@ export default {
       // 企业情报监控
       getDeskFollowList({ pageNum: 0, pageSize: 5 }).then(res => {
         if (res.error_code === 0 && res.data) {
-          if (res.data.list) {
+          if (Array.isArray(res.data.list)) {
             this.entList = res.data.list.map(item => {
+              const visited = this.pathVisited(
+                this.createPathItem(
+                  '/ent_portrait/*',
+                  `id=${item.s_entId}`
+                )
+              )
               return Object.assign(item, {
                 _id: item.s_entId,
                 projectName: item.s_entname,
                 publishtime: item.l_lastpushtime,
+                visited,
                 unread: item.i_apppushunread
               })
             })
@@ -154,9 +171,16 @@ export default {
       }).then(res => {
         if (res && res.error_code === 0 && res.data) {
           this.collectionList = res.data.res.map(item => {
+            const visited = this.pathVisited(
+              this.createPathItem(
+                '/article/content/*.html',
+                `id=${item._id}`
+              )
+            )
             return Object.assign(item, {
               _id: item._id,
               projectName: item.title,
+              visited,
               publishtime: item.publishtime
             })
           })
@@ -175,9 +199,16 @@ export default {
         if (res.error_code === 0 && res.data) {
           if (!res.data.List) return
           this.followList = res.data.List.map(item => {
+            const visited = this.pathVisited(
+              this.createPathItem(
+                '/pro_follow_detail/*',
+                `id=${item.sid}`
+              )
+            )
             return Object.assign(item, {
               projectName: item.title,
               publishtime: item.l_lastpushtime,
+              visited,
               unread: item.i_apppushunread
             })
           })
@@ -346,19 +377,35 @@ export default {
     },
     // 点击标题跳转
     getDetail (data) {
-      console.log(data)
+      data.item.visited = true
       let link = ''
       switch (data.model) {
         case 'model-1':
+        case 'model-3':
+          this.pathVisiting(
+            this.createPathItem(
+              '/article/content/*.html',
+              `id=${data.item._id}`
+            )
+          )
           link = '/article/content/' + data.item._id + '.html'
           break
         case 'model-2':
+          this.pathVisiting(
+            this.createPathItem(
+              '/ent_portrait/*',
+              `id=${data.item._id}`
+            )
+          )
           link = this.resolveLink('/ent_portrait/' + data.item._id)
           break
-        case 'model-3':
-          link = '/article/content/' + data.item._id + '.html'
-          break
         case 'model-4':
+          this.pathVisiting(
+            this.createPathItem(
+              '/pro_follow_detail/*',
+              `id=${data.item.sid}`
+            )
+          )
           link = this.resolveLink('/pro_follow_detail?sid=' + data.item.sid + '&fid=' + data.item.fid)
           break
         case 'model-week':