Browse Source

feat: 完善移动端首页

zhangyuhan 4 years ago
parent
commit
ddd87f1059

+ 9 - 1
jydocs-mobile/src/api/main.ts

@@ -1,7 +1,7 @@
 import $request from '@/api/index'
 import qs from 'qs'
 
-export function getHome (data: any) {
+export function getHomeHot (data: any) {
   return $request({
     url: '/topList',
     method: 'post',
@@ -9,6 +9,14 @@ export function getHome (data: any) {
   })
 }
 
+export function getHomeActivity (data: any) {
+  return $request({
+    url: '/activityList',
+    method: 'post',
+    data: data
+  })
+}
+
 export function getCashOutInfo (data: any) {
   data = qs.stringify(data)
   return $request({

+ 1 - 0
jydocs-mobile/src/api/mock.ts

@@ -15,6 +15,7 @@ function mock (config: APIStructure) {
       const result = {
         data: mocks[config.url]
       }
+      console.log('[debug]当前mock', result.data)
       Toast.clear()
       try {
         if (result.data.error_msg) {

+ 29 - 1
jydocs-mobile/src/api/mock/activityList.json

@@ -3,7 +3,21 @@
   "error_msg": "",
   "data": [
     {
-      "docId": "NyfuxSR0iUPobdFzNV2y",
+      "docId": "NyfuxSR0iUPobdFzNV2y3",
+      "activityId": 3,
+      "docTitle": "1111",
+      "docSummary": "1111",
+      "docImg": "1111",
+      "price": 11,
+      "costPrice": 11,
+      "docFileSize": 666666666,
+      "docPageSize": 777,
+      "downTimes":5,
+      "sourceUserId":"剑鱼测试",
+      "docFileType": "ppt"
+    },
+    {
+      "docId": "NyfuxSR0iUPobdFzNV2y2",
       "activityId": 3,
       "docTitle": "1111",
       "docSummary": "1111",
@@ -14,6 +28,20 @@
       "docPageSize": 777,
       "downTimes":5,
       "sourceUserId":""
+    },
+    {
+      "docId": "NyfuxSR0iUPobdFzNV2y1",
+      "activityId": 3,
+      "docTitle": "1111",
+      "docSummary": "1111",
+      "docImg": "1111",
+      "price": 11,
+      "costPrice": 11,
+      "docFileSize": 666,
+      "docPageSize": 777,
+      "downTimes":5,
+      "sourceUserId":"",
+      "docFileType": "pdf"
     }
   ]
 }

+ 32 - 2
jydocs-mobile/src/api/mock/topList.json

@@ -3,7 +3,7 @@
   "error_msg": "",
   "data":  [
     {
-      "docId": "RJ82241sM3DyHwrupW7w",
+      "docId": "RJ82241sM3DyHwrupW7w5",
       "docName": "软件单元、组装、确认测试系统-中标候选人公示",
       "price": 359,
       "docFileSize": 387,
@@ -13,7 +13,7 @@
       "docFileType": "其他"
     },
     {
-      "docId": "PImyRKyNohbocfUbhIef",
+      "docId": "PImyRKyNohbocfUbhIef4",
       "docName": "北京精密机电控制设备研究所软件单元、组装、确认测试系统",
       "price": 193,
       "docFileSize": 164,
@@ -21,6 +21,36 @@
       "uploadDate": "2021-03-17 15:46:05",
       "docSummary": "1.招标条件本招标项目:软件单元、组装、确认测试系统已由中国航天科技集团有限公司部门批准建设,项目业主为北京精密机电控制设备研究所,建设资金及出资比例其他资金100.0%,招标人为北京精密机电控制设备研究所。项目已具备招标条件,中科信工程咨",
       "docFileType": "pdf"
+    },
+    {
+      "docId": "PImyRKyNohbocfUbhIef3",
+      "docName": "北京精密机电控制设备研究所软件单元、组装、确认测试系统",
+      "price": 193,
+      "docFileSize": 164,
+      "docPageSize": 3,
+      "uploadDate": "2021-03-17 15:46:05",
+      "docSummary": "1.招标条件本招标项目:软件单元、组装、确认测试系统已由中国航天科技集团有限公司部门批准建设,项目业主为北京精密机电控制设备研究所,建设资金及出资比例其他资金100.0%,招标人为北京精密机电控制设备研究所。项目已具备招标条件,中科信工程咨",
+      "docFileType": "word"
+    },
+    {
+      "docId": "PImyRKyNohbocfUbhIef2",
+      "docName": "北京精密机电控制设备研究所软件单元、组装、确认测试系统",
+      "price": 193,
+      "docFileSize": 164,
+      "docPageSize": 3,
+      "uploadDate": "2021-03-17 15:46:05",
+      "docSummary": "1.招标条件本招标项目:软件单元、组装、确认测试系统已由中国航天科技集团有限公司部门批准建设,项目业主为北京精密机电控制设备研究所,建设资金及出资比例其他资金100.0%,招标人为北京精密机电控制设备研究所。项目已具备招标条件,中科信工程咨",
+      "docFileType": "ppt"
+    },
+    {
+      "docId": "PImyRKyNohbocfUbhIef1",
+      "docName": "北京精密机电控制设备研究所软件单元、组装、确认测试系统",
+      "price": 193,
+      "docFileSize": 164,
+      "docPageSize": 3,
+      "uploadDate": "2021-03-17 15:46:05",
+      "docSummary": "1.招标条件本招标项目:软件单元、组装、确认测试系统已由中国航天科技集团有限公司部门批准建设,项目业主为北京精密机电控制设备研究所,建设资金及出资比例其他资金100.0%,招标人为北京精密机电控制设备研究所。项目已具备招标条件,中科信工程咨",
+      "docFileType": "excel"
     }
   ]
 }

+ 69 - 15
jydocs-mobile/src/store/modules/main.ts

@@ -1,58 +1,111 @@
+import { StoreOptions } from 'vuex'
+import Vue from 'vue'
 import {
-  getHome,
+  getHomeHot,
+  getHomeActivity,
   getCashOutInfo,
   submitCashOutInfo
 } from '@/api/main'
 
-export default {
+interface InterfaceStore<S> extends StoreOptions<S> {
+  namespaced?: boolean;
+}
+type APIStructure = Record<string, any>;
+type modulesOption = InterfaceStore<any>;
+
+function recoveryPageData (key: string, defaultValues = {}) {
+  return sessionStorage.getItem(key) ? JSON.parse(sessionStorage.getItem(key) || '') : defaultValues
+}
+
+function formatData (v: APIStructure) {
+  return {
+    img: v?.docImg,
+    type: v?.docFileType,
+    id: v.docId,
+    title: v?.docName || v?.docTitle,
+    money: v.price,
+    size: v?.docFileSize,
+    page: v?.docPageSize,
+    down: v?.downTimes,
+    contribution: v?.sourceUserId
+  }
+}
+
+const modulesOption: modulesOption = {
   namespaced: true,
   state: {
     // 提现页面数据缓存(用于跳出页面返回时恢复)
-    cashOutInfo: sessionStorage.getItem('partner-cashout') ? JSON.parse(sessionStorage.getItem('partner-cashout') || '') : {},
-    cashOutSuccess: sessionStorage.getItem('partner-cashout-success') ? JSON.parse(sessionStorage.getItem('partner-cashout-success') || '') : {}
+    cashOutInfo: recoveryPageData('partner-cashout'),
+    cashOutSuccess: recoveryPageData('partner-cashout-success'),
+    homePageData: recoveryPageData('jy-docs-home-page')
   },
   mutations: {
     // 保存提现页面数据
-    saveCashOutInfo (state: any, data: any) {
+    saveCashOutInfo (state, data) {
       for (const key in data) {
         state.cashOutInfo[key] = data[key]
       }
       sessionStorage.setItem('partner-cashout', JSON.stringify(data))
     },
     // 清除提现页面数据
-    clearCashOutInfo (state: any) {
+    clearCashOutInfo (state) {
       state.cashOutInfo = {}
       sessionStorage.setItem('partner-cashout', JSON.stringify({}))
     },
     // 保存提现成功数据
-    saveCashOutSuccessInfo (state: any, data: any) {
+    saveCashOutSuccessInfo (state, data) {
       for (const key in data) {
         state.cashOutSuccess[key] = data[key]
       }
       sessionStorage.setItem('partner-cashout-success', JSON.stringify(data))
     },
     // 清除提现成功数据
-    clearCashOutSuccessInfo (state: any) {
+    clearCashOutSuccessInfo (state) {
       state.cashOutSuccess = {}
       sessionStorage.setItem('partner-cashout-success', JSON.stringify({}))
+    },
+    // 保存首页数据
+    saveHomeData (state, data) {
+      for (const key in data) {
+        Vue.set(state.homePageData, key, data[key])
+      }
+      sessionStorage.setItem('jy-docs-home-page', JSON.stringify(state.homePageData))
     }
   },
   actions: {
-    async getHome (state: any, data: any) {
-      try {
-        const res = await getHome(data)
-        return res.data
-      } catch (error) {}
+    // 首页数据
+    async getHome (state) {
+      getHomeHot({ sign: 'new', num: 5 }).then(res => {
+        if (!res.data.error_msg.length) {
+          state.commit('saveHomeData', {
+            new: res.data.data.map((v: APIStructure) => formatData(v))
+          })
+        }
+      })
+      getHomeHot({ sign: 'hot', num: 5 }).then(res => {
+        if (!res.data.error_msg.length) {
+          state.commit('saveHomeData', {
+            hot: res.data.data.map((v: APIStructure) => formatData(v))
+          })
+        }
+      })
+      getHomeActivity({ code: 3, size: 3, num: 1 }).then(res => {
+        if (!res.data.error_msg.length) {
+          state.commit('saveHomeData', {
+            keep: res.data.data.map((v: APIStructure) => formatData(v))
+          })
+        }
+      })
     },
     // 提现查询
-    async getCashOutInfo (state: any, data: any) {
+    async getCashOutInfo (state, data) {
       try {
         const res = await getCashOutInfo(data)
         return res.data
       } catch (error) {}
     },
     // 提现提交
-    async submitCashOutInfo (state: any, data: any) {
+    async submitCashOutInfo (state, data) {
       try {
         const res = await submitCashOutInfo(data)
         return res.data
@@ -61,3 +114,4 @@ export default {
   },
   getters: {}
 }
+export default modulesOption

+ 4 - 1
jydocs-mobile/src/utils/globalFilters.ts

@@ -7,10 +7,13 @@ import {
   formatPrice,
   fen2Yuan,
   addSpaceForBank,
-  addConfusionForBank
+  addConfusionForBank,
+  formatSize
 } from './globalFunctions'
 
 // 注册全局过滤器
+// 文件大小格式化
+Vue.filter('sizeFormatter', formatSize)
 // 时间格式化(同时间格式化函数)
 Vue.filter('dateFormatter', dateFormatter)
 // 时间戳转换 多少秒、多少分、多少小时前、多少天前  超出10天显示年月日

+ 10 - 0
jydocs-mobile/src/utils/globalFunctions.ts

@@ -311,3 +311,13 @@ export function removeSpace (str: string) {
   }
   return str.replace(/\s+/g, '')
 }
+
+export function formatSize (size: string | number, pointLength: number, units: Array<string>) {
+  size = Number(size)
+  let unit: string | undefined = ''
+  units = units || ['B', 'K', 'M', 'G', 'TB']
+  while ((unit = units.shift()) && size > 1024) {
+    size = size / 1024
+  }
+  return (unit === 'B' ? size : size.toFixed(pointLength === undefined ? 2 : pointLength)) + (unit || '')
+}

+ 67 - 60
jydocs-mobile/src/views/Home.vue

@@ -7,7 +7,8 @@
         <h5>最新文档</h5>
       </div>
       <div class="list-group flex-c-c">
-        <div class="list-item flex-r-c" v-for="item in pageData.new" :key="item.id" @click="goContent(item)">
+        <van-skeleton class="van-loading-skeleton line-style" :row="5" :loading="showLoading.new">
+          <div class="list-item flex-r-c" v-for="item in pageData.new" :key="item.id" @click="goContent(item)">
           <div class="flex flex-r-c center left">
             <van-icon :name="'diy-' + item.type" />
             <div class="flex">
@@ -19,6 +20,7 @@
             <span>{{item.money}}</span>
           </div>
         </div>
+        </van-skeleton>
       </div>
     </div>
     <div class="hot-group base-group">
@@ -27,7 +29,8 @@
         <h5>热门下载</h5>
       </div>
       <div class="list-group flex-c-c">
-        <div class="list-item flex-r-c" v-for="item in pageData.new" :key="item.id" @click="goContent(item)">
+        <van-skeleton class="van-loading-skeleton line-style" :row="5" :loading="showLoading.hot">
+          <div class="list-item flex-r-c" v-for="item in pageData.hot" :key="item.id" @click="goContent(item)">
           <div class="flex flex-r-c center left">
             <van-icon :name="'diy-' + item.type" />
             <div class="flex">
@@ -39,6 +42,7 @@
             <span>{{item.money}}</span>
           </div>
         </div>
+        </van-skeleton>
       </div>
     </div>
     <div class="keep-group base-group">
@@ -47,7 +51,11 @@
         <h5>精选推荐</h5>
       </div>
       <div class="list-group card-group flex-c-c">
-        <div class="card-item flex-r-c"  v-for="item in pageData.new" :key="item.id" @click="goContent(item)">
+        <van-skeleton avatar avatar-shape="square" class="van-loading-skeleton card-style"
+            :row="4"
+            :row-width="rowWidth"
+            :loading="showLoading.keep">
+          <div class="card-item flex-r-c"  v-for="item in pageData.keep" :key="item.id" @click="goContent(item)">
           <div class="mini-img-group">
             <img :src="item.img" alt="">
             <van-icon :name="'diy-' + item.type" />
@@ -57,8 +65,12 @@
               <div class="title-text van-multi-ellipsis--l2">{{item.title}}</div>
             </div>
             <div class="flex-c-c info-text">
-              <span>贡献者: dshasjhd</span>
-              <span>贡献者: dshasjhd | dshasjhd | 200k</span>
+              <span v-if="item.contribution">贡献者: {{item.contribution}}</span>
+              <div class="info-text-group flex-r-c center left">
+                <span v-if="item.down">{{item.down}}次下载</span>
+                <span v-if="item.page">共{{item.page}}页</span>
+                <span v-if="item.size">{{item.size | sizeFormatter}}</span>
+              </div>
             </div>
             <div class="money-group flex-r-c center left">
               <van-icon class="s20" name="diy-iconJianYu" />
@@ -66,6 +78,7 @@
             </div>
           </div>
         </div>
+        </van-skeleton>
       </div>
     </div>
   </div>
@@ -74,19 +87,20 @@
 <script lang="ts">
 import { Component, Vue } from 'vue-property-decorator'
 import Search from '@/components/Search.vue'
-// import { Cell, CellGroup, Icon, Dialog, Toast } from 'vant'
-import { Icon } from 'vant'
-import { mapActions } from 'vuex'
-  // import { MixinTop } from '@/utils/mixin-top'
+import { Icon, Skeleton } from 'vant'
+import { mapActions, mapState } from 'vuex'
   @Component({
     name: 'home',
-    // mixins: [MixinTop],
     components: {
-      // [Cell.name]: Cell,
-      // [CellGroup.name]: CellGroup,
       [Icon.name]: Icon,
+      [Skeleton.name]: Skeleton,
       Search
     },
+    computed: {
+      ...mapState('main', {
+        pageData: (state: any) => state.homePageData
+      })
+    },
     methods: {
       ...mapActions({
         ajaxData: 'main/getHome'
@@ -95,52 +109,20 @@ import { mapActions } from 'vuex'
   })
 
 export default class extends Vue {
-    pageData: any = {}
     ajaxData: any
+    pageData: any
+    rowWidth = ['100%', '20%', '40%', '15%']
 
     created () {
-      console.log('111')
-      this.ajaxData().then((res: any) => {
-        console.log(res)
-      })
-      this.pageData = {
-        new: [
-          {
-            img: require('@/assets/images/bgApp.png'),
-            type: 'pdf',
-            id: '1',
-            title: '优化招投标市场营商环境与国企优化招投标市场营商环境与国企...',
-            money: 200000
-          },
-          {
-            type: 'excel',
-            img: require('@/assets/images/bgApp.png'),
-            id: '2',
-            title: '优化招投标市场营商环境与国企优化招投标市场营商环境与国企...',
-            money: 200
-          },
-          {
-            type: 'word',
-            img: require('@/assets/images/bgApp.png'),
-            id: '3',
-            title: '优化招投标市场营商环境与国企优化招投标市场营商环境与国企...',
-            money: 200
-          },
-          {
-            type: 'ppt',
-            img: require('@/assets/images/bgApp.png'),
-            id: '4',
-            title: '优化招投标市场营商环境与国企优化招投标市场营商环境与国企...',
-            money: 200
-          },
-          {
-            type: 'other',
-            img: require('@/assets/images/bgApp.png'),
-            id: '5',
-            title: '优化招投标市场营商环境与国企优化招投标市场营商环境与国企...',
-            money: 200
-          }
-        ]
+      this.ajaxData()
+    }
+
+    get showLoading () {
+      const s = this.pageData
+      return {
+        new: !s?.new,
+        hot: !s?.hot,
+        keep: !s?.keep
       }
     }
 
@@ -161,6 +143,21 @@ export default class extends Vue {
   padding-bottom: 40px;
   box-sizing: border-box;
 
+  ::v-deep .van-loading-skeleton {
+    &.line-style {
+      .van-skeleton__row {
+        width: 100% !important;
+        height: 28px;
+      }
+    }
+    &.card-style {
+      .van-skeleton__avatar {
+        width: 100px !important;
+        height: 124px !important;
+      }
+    }
+  }
+
   @include diy-icon('iconJianYu', 16, 16);
 
   .van-icon-diy-iconJianYu.s20 {
@@ -176,11 +173,6 @@ export default class extends Vue {
   .base-group {
     padding: 4px 19px 4px 16px;
     box-sizing: border-box;
-
-    &.new-group {
-      margin-top: $topSearchHeight;
-    }
-
     .list-group {
       border-radius: 8px;
       background: #FFFFFF;
@@ -205,6 +197,7 @@ export default class extends Vue {
         }
       }
       .card-item {
+        justify-content: flex-start;
         padding: 8px 16px 12px 0;
         box-sizing: border-box;
         border-bottom: 1px solid rgba(0, 0, 0, 0.05);
@@ -234,6 +227,20 @@ export default class extends Vue {
             bottom: 0;
           }
         }
+        .info-text-group {
+          span {
+            display: inline-block;
+            &:last-child {
+              &::after {
+                content: unset;
+              }
+            }
+            &::after {
+              content: "|";
+              padding: 0 8px;
+            }
+          }
+        }
         .info-text {
           color: #9B9CA3;
           font-family: PingFang SC;