xgwangman 4 years ago
parent
commit
218dfbf924

+ 1 - 0
jydocs-back/config.json

@@ -33,5 +33,6 @@
       ]
     }
   },
+  "indexSearchTag": ["全部","招标","法律法规","行业报告","测试"],
   "shareUrl": "https://web-jydev-wky.jianyu360.cn/swordfish/docs/index/content/%s"
 }

+ 2 - 1
jydocs-back/config/config.go

@@ -17,7 +17,8 @@ type appConfig struct {
 		Points  rpcConfig `json:"points"`  //剑鱼积分rpc接口
 		JyFile  rpcConfig `json:"jyFile"`  //剑鱼文件rpc接口
 	} `json:"rpcServers"` //rpc服务配置
-	ShareUrl string `json:"shareUrl"`
+	IndexSearchTag []string `json:"indexSearchTag"`
+	ShareUrl       string   `json:"shareUrl"`
 }
 
 type rpcConfig struct {

+ 1 - 1
jydocs-back/go.mod

@@ -4,7 +4,7 @@ go 1.13
 
 require (
 	app.yhyue.com/moapp/jyPoints v0.0.0-20210319072011-5430a201e0aa
-	app.yhyue.com/moapp/jy_docs v0.0.0-20210319063914-d48d51e0cc46
+	app.yhyue.com/moapp/jy_docs v0.0.0-20210322023024-a4be186876a3
 	app.yhyue.com/moapp/jybase v0.0.0-20210319015107-fe59d2046cf8
 	app.yhyue.com/moapp/jyfs v0.0.0-20210319011832-6cf539ddc5cd
 	github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67

+ 10 - 0
jydocs-back/go.sum

@@ -11,6 +11,8 @@ app.yhyue.com/moapp/jyPoints v0.0.0-20210318074134-d0acc7d915bf h1:Idufrw6D2Kr2G
 app.yhyue.com/moapp/jyPoints v0.0.0-20210318074134-d0acc7d915bf/go.mod h1:nz39UQcXwZV90vOC7rIfos4LgrjGDcywHo96rdywdzk=
 app.yhyue.com/moapp/jyPoints v0.0.0-20210319020458-484a38074edd h1:O/QPSt7jIG5KKshbGhQnbcFTL/Hbu5SL7EpQuTYiDCQ=
 app.yhyue.com/moapp/jyPoints v0.0.0-20210319020458-484a38074edd/go.mod h1:nz39UQcXwZV90vOC7rIfos4LgrjGDcywHo96rdywdzk=
+app.yhyue.com/moapp/jyPoints v0.0.0-20210319072011-5430a201e0aa h1:SsH/bCryyvPUuorQqBPBDWFlz8jAO94DTvIb0mjfiEg=
+app.yhyue.com/moapp/jyPoints v0.0.0-20210319072011-5430a201e0aa/go.mod h1:ZuQoeKgip9OrJPRDpXkv4XOHV/oFIqL1aK+tcfIN+KQ=
 app.yhyue.com/moapp/jy_docs v0.0.0-20210317071040-be6d030d6122 h1:KzsaloFf6dT2JdcshC4CvYMFPVrpF1dD/pQ1H0wRAHk=
 app.yhyue.com/moapp/jy_docs v0.0.0-20210317071040-be6d030d6122/go.mod h1:PfrdcgOFwgvShGRVjDaMnv5masAd8Hl0URHFARyeqZ8=
 app.yhyue.com/moapp/jy_docs v0.0.0-20210317080833-0136e1a73ba8 h1:xizJ4BYH42vmYrgteaPNPcwF7/9G7uJO6uGgeuRDrwk=
@@ -39,6 +41,12 @@ app.yhyue.com/moapp/jy_docs v0.0.0-20210319051808-4dbf6fa54ca3 h1:s1VG+J/YGo+z6+
 app.yhyue.com/moapp/jy_docs v0.0.0-20210319051808-4dbf6fa54ca3/go.mod h1:jfOmPb/ZELpHsA39HDAhCkBPUH/3Jaix7JhzPzcmK6A=
 app.yhyue.com/moapp/jy_docs v0.0.0-20210319060022-e324f5108395 h1:JE5AFxIg6h111Iobzbvdu+lTIWFeY6sFCQkr8qKC+Eg=
 app.yhyue.com/moapp/jy_docs v0.0.0-20210319060022-e324f5108395/go.mod h1:jfOmPb/ZELpHsA39HDAhCkBPUH/3Jaix7JhzPzcmK6A=
+app.yhyue.com/moapp/jy_docs v0.0.0-20210319063914-d48d51e0cc46 h1:PoSBG2//3NYHwMpu0n9RtN9CZteMvnBv/SrnleSraC4=
+app.yhyue.com/moapp/jy_docs v0.0.0-20210319063914-d48d51e0cc46/go.mod h1:jfOmPb/ZELpHsA39HDAhCkBPUH/3Jaix7JhzPzcmK6A=
+app.yhyue.com/moapp/jy_docs v0.0.0-20210322014639-b4fe40444b05 h1:Dy0xuYezteDAkrAuZjc759487JOLavqnvSiPcBpPZVw=
+app.yhyue.com/moapp/jy_docs v0.0.0-20210322014639-b4fe40444b05/go.mod h1:jfOmPb/ZELpHsA39HDAhCkBPUH/3Jaix7JhzPzcmK6A=
+app.yhyue.com/moapp/jy_docs v0.0.0-20210322023024-a4be186876a3 h1:5BhmeUgOf9lA8lXifqMcIJ70v+vMpPBEQfZvZbzySMA=
+app.yhyue.com/moapp/jy_docs v0.0.0-20210322023024-a4be186876a3/go.mod h1:jfOmPb/ZELpHsA39HDAhCkBPUH/3Jaix7JhzPzcmK6A=
 app.yhyue.com/moapp/jybase v0.0.0-20210317020927-18b0165f5ff9 h1:LVIuqXMqcclMwBbSmqEzXi0nIEiir+a2GpWAqksmfzk=
 app.yhyue.com/moapp/jybase v0.0.0-20210317020927-18b0165f5ff9/go.mod h1:29ShuI8y7qEyg2KviHSx1iamiCioBKdTMm2ndVzWAhk=
 app.yhyue.com/moapp/jybase v0.0.0-20210318061912-f5594310c8fe h1:RSQIrriyi534CCrI/sSLGW+Rd0X/0W4VDDXIalHVo8c=
@@ -56,6 +64,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
 github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
+github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67 h1:x98/gnpyNAiuvg/gX3KgdfKxnZj3t9pIl3BCVJg3qwg=
+github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67/go.mod h1:g1VZ0nbzBvfsWw22gNVOxWxJxpBR+CBiFNK2n2ogeUo=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=

+ 1 - 0
jydocs-back/rpc/stdDocRpc.go

@@ -84,6 +84,7 @@ func GeActivityList(userId string, code, pageNum, pageSize int64) ([]*stdlib.Doc
 		ActivityId: code,
 		PageNum:    pageNum,
 		PageSize:   pageSize,
+		UserId:     userId,
 	})
 	if err != nil {
 		log.Printf("%s GeActivityList call error %v\n", userId, err)

+ 22 - 7
jydocs-back/servers/stdDoc.go

@@ -14,11 +14,12 @@ import (
 
 type StdDoc struct {
 	*xweb.Action
-	search       xweb.Mapper `xweb:"/search"`       //检索文库
-	detail       xweb.Mapper `xweb:"/detail"`       //文库详情
-	content      xweb.Mapper `xweb:"/content"`      //文库内容
-	topList      xweb.Mapper `xweb:"/topList"`      //最新文档&热门下载
-	activityList xweb.Mapper `xweb:"/activityList"` //活动文库(精品推荐、兑换榜)
+	search       xweb.Mapper `xweb:"/search"`         //检索文库
+	indexTag     xweb.Mapper `xweb:"/indexTag"`       //首页搜索标签
+	detail       xweb.Mapper `xweb:"/detail"`         //文库详情
+	getDoc       xweb.Mapper `xweb:"/get(Show|Down)"` //文库在线查看 or 下载
+	topList      xweb.Mapper `xweb:"/topList"`        //最新文档&热门下载
+	activityList xweb.Mapper `xweb:"/activityList"`   //活动文库(精品推荐、兑换榜)
 }
 
 func (stdDoc *StdDoc) Search() {
@@ -36,6 +37,9 @@ func (stdDoc *StdDoc) Search() {
 		if keyWord == "" {
 			return nil, fmt.Errorf("检索内容不能为空")
 		}
+		if tag == "全部" {
+			tag = ""
+		}
 		list, total, err := rpc.GetDocQuery(userId, keyWord, tag, pageNum, pageSize, sort)
 		if err != nil {
 			return nil, err
@@ -51,6 +55,10 @@ func (stdDoc *StdDoc) Search() {
 	stdDoc.ServeJson(NewResult(rData, errMsg))
 }
 
+func (stdDoc *StdDoc) IndexTag() {
+	stdDoc.ServeJson(NewResult(config.JyDocsAppConfig.IndexSearchTag, nil))
+}
+
 func (stdDoc *StdDoc) Detail() {
 	userId := common.ObjToString(stdDoc.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
@@ -64,6 +72,8 @@ func (stdDoc *StdDoc) Detail() {
 		}
 		//ossId清除
 		detail.OssPdfId = ""
+		detail.OssDocId = ""
+		detail.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, detail.PreviewImgId)
 		return map[string]interface{}{
 			"status": common.If(isBuy, 1, 0),
 			"detail": detail,
@@ -75,9 +85,10 @@ func (stdDoc *StdDoc) Detail() {
 	stdDoc.ServeJson(NewResult(rData, errMsg))
 }
 
-func (stdDoc *StdDoc) Content() {
+func (stdDoc *StdDoc) GetDoc(sign string) {
 	userId := common.ObjToString(stdDoc.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
+		log.Println(sign)
 		docId := stdDoc.GetString("docId")
 		if docId == "" {
 			return nil, fmt.Errorf("参数异常")
@@ -89,7 +100,11 @@ func (stdDoc *StdDoc) Content() {
 		if !isBuy {
 			return nil, fmt.Errorf("请先兑换文档")
 		}
-		url, err := rpc.GetFileContext(userId, detail.OssPdfId)
+		fileId := detail.OssPdfId
+		if sign == "Down" {
+			fileId = detail.OssDocId
+		}
+		url, err := rpc.GetFileContext(userId, fileId)
 		if err != nil {
 			return nil, err
 		}

+ 7 - 1
jydocs-back/servers/userDoc.go

@@ -9,6 +9,7 @@ import (
 	"jy-docs/public"
 	"jy-docs/rpc"
 	"log"
+	"time"
 )
 
 type UserDoc struct {
@@ -127,7 +128,12 @@ func (userDoc *UserDoc) DocBuy() {
 		if err != nil {
 			return nil, err
 		}
-		return "success", nil
+		return map[string]interface{}{
+			"code":    docId,
+			"balance": userPoint - docPoint,
+			"payTime": time.Now().Unix(),
+			"payWay":  "剑鱼币",
+		}, nil
 	}()
 	if errMsg != nil {
 		log.Printf("%s UserDoc docBuy err:%s\n", userId, errMsg.Error())

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

@@ -18,24 +18,32 @@ export function getHomeActivity (data: any) {
   })
 }
 
-export function getCashOutInfo (data: any) {
-  data = qs.stringify(data)
+export function getIndexTags () {
   return $request({
-    url: '/buy',
-    method: 'post',
-    data: data
+    url: '/indexTag',
+    method: 'GET'
   })
 }
 
-export function submitCashOutInfo (data: any) {
+export function doSearchDocs (data: any) {
   data = qs.stringify(data)
   return $request({
-    url: '/distribution/cashout/submit',
-    method: 'post',
+    url: '/search',
+    method: 'POST',
     data
   })
 }
 
+// 我的文库
+export function getMyLibList (data: any) {
+  data = qs.stringify(data)
+  return $request({
+    url: '/user/list',
+    method: 'get',
+    params: data
+  })
+}
+
 export function getDetails (data: any) {
   console.log(data)
   // data = qs.stringify(data)
@@ -102,10 +110,20 @@ export function getShare (data: any) {
 
 // 文库购买
 export function getDocPay (data: any) {
-  //   data = qs.stringify(data)
+  data = qs.stringify(data)
   return $request({
     url: '/user/buy',
     method: 'post',
     params: data
   })
 }
+
+// 剑鱼积分详情
+export function getListDetail (data: any) {
+  data = qs.stringify(data)
+  return $request({
+    url: '/getList',
+    method: 'post',
+    params: data
+  })
+}

+ 11 - 0
jydocs-mobile/src/api/mock/indexTag.json

@@ -0,0 +1,11 @@
+{
+  "error_code": 0,
+  "error_msg": "",
+  "data": [
+    "全部",
+    "招标",
+    "法律法规",
+    "行业报告",
+    "测试"
+  ]
+}

+ 5 - 1
jydocs-mobile/src/components/Recharge.vue

@@ -29,7 +29,7 @@
         </div>
         <div class="recharge_footer">
             <button class="j-button-cancel btn_active" @click="closePopup()">取消</button>
-            <button class="j-button-sure btn_active">去充值</button>
+            <button class="j-button-sure btn_active" @click="buyMoney">去充值</button>
         </div>
     </van-popup>
 </template>
@@ -57,6 +57,10 @@ export default class extends Vue {
     closePopup () {
       this.show = false
     }
+
+    buyMoney () {
+        this.$router.push({path: '/', query: {id: this.detailData.docId}})
+    }
 }
 </script>
 

+ 1 - 1
jydocs-mobile/src/components/RechargeHave.vue

@@ -84,7 +84,7 @@ export default class extends Vue {
     }
 
     exchange () {
-      console.log('99999')
+      this.$router.push({path: '/purchase', query: {id: this.detailData.docId}})
     }
 }
 </script>

+ 5 - 0
jydocs-mobile/src/components/Search.vue

@@ -19,8 +19,13 @@ import { Icon, Search } from 'vant'
   })
 export default class Empty extends Vue {
     @Prop({ default: 'input' }) type?: string | undefined;
+    @Prop({ default: '' }) defalultValue?: string | undefined;
     input = ''
 
+    created () {
+      this.input = this.defalultValue
+    }
+
     onSearch () {
       this.$emit('submit', this.input)
     }

+ 20 - 13
jydocs-mobile/src/components/docs-card/Card.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="doc-container" @click="clickCard">
+  <div class="doc-container van-hairline--bottom" @click="clickCard">
     <div class="docs-card oneline" v-if="cardType === 'oneline'" key="docs-card">
       <div class="docs-header flex-r-c center">
         <van-icon :name="docTypeIcon" />
@@ -7,7 +7,7 @@
         <Price :price="price" />
       </div>
     </div>
-    <div class="docs-card image flex-r-c" v-if="cardType === 'image'" key="docs-card">
+    <div class="docs-card image flex-r-c" v-else-if="cardType === 'image'" key="docs-card">
       <div class="image-container">
         <img v-lazy="imageSrc" />
         <van-icon class="doc-type-icon" :name="docTypeIcon" />
@@ -27,7 +27,7 @@
             </div>
           </div>
           <div class="card-info-item price">
-            <Price :price="price" />
+            <slot name="price"><Price :price="price" /></slot>
           </div>
         </div>
       </div>
@@ -48,7 +48,7 @@
           >{{ item }}</span>
         </div>
         <div class="c-f-right flex-r-c">
-          <Price :price="price" />
+          <slot name="price"><Price :price="price" /></slot>
         </div>
       </div>
     </div>
@@ -58,7 +58,7 @@
 import { Component, Vue, Prop } from 'vue-property-decorator'
 import Price from '@/components/docs-card/Price.vue'
 import { Icon } from 'vant'
-import { replaceKeyword } from '@/utils/globalFunctions'
+import { replaceKeyword, docTypeConvert } from '@/utils/globalFunctions'
 
 @Component({
   name: 'docs-card',
@@ -71,20 +71,28 @@ import { replaceKeyword } from '@/utils/globalFunctions'
 export default class DocsCard extends Vue {
   @Prop({ default: '' }) title!: string;
   @Prop({ default: '' }) cardType?: string | undefined; // oneline, image
-  @Prop({ default: [] }) highlightKey?: Array<string> | undefined;
   @Prop({ default: '' }) desc?: string | undefined;
   @Prop({ default: 'pdf' }) docType?: string | undefined; // 文档类型
-  @Prop({ default: [] }) subInfo?: Array<string> | undefined;
   @Prop({ default: '' }) imageSrc?: string | undefined;
   @Prop({ default: '' }) uploader?: string | undefined;
-  @Prop({ default: 0 }) price?: string | number | undefined;
+  @Prop({ default: 0 }) price?: string | number;
 
-  created () {
-    console.log(123)
-  }
+  @Prop({
+    type: Array,
+    default () {
+      return []
+    }
+  }) subInfo?: Array<string>;
+
+  @Prop({
+    type: Array,
+    default () {
+      return []
+    }
+  }) highlightKey?: Array<string>;
 
   get docTypeIcon () {
-    return `diy-${this.docType}`
+    return `diy-${docTypeConvert(this.docType)}`
   }
 
   get hightLightTitle () {
@@ -130,7 +138,6 @@ export default class DocsCard extends Vue {
     .d-title {
       margin-left: 4px;
       font-size: 16px;
-      line-height: 24px;
       color: #171826;
     }
   }

+ 21 - 5
jydocs-mobile/src/router/modules/main.ts

@@ -2,7 +2,7 @@ export default [
   {
     path: '/search',
     name: 'search',
-    component: () => import(/* webpackChunkName: "test" */ '@/views/Search.vue'),
+    component: () => import('@/views/Search.vue'),
     meta: {
       title: '剑鱼文库'
     }
@@ -10,15 +10,15 @@ export default [
   {
     path: '/purchasesuccess',
     name: 'purchasesuccess',
-    component: () => import(/* webpackChunkName: "test" */ '@/views/purchase/purchasesuccess.vue'),
+    component: () => import('@/views/purchase/purchasesuccess.vue'),
     meta: {
       title: '剑鱼文库'
     }
   },
   {
-    path: '/purchase',
+    path: '/purchase/:id',
     name: 'purchase',
-    component: () => import(/* webpackChunkName: "test" */ '@/views/purchase/purchase.vue'),
+    component: () => import('@/views/purchase/purchase.vue'),
     meta: {
       title: '剑鱼文库'
     }
@@ -26,9 +26,25 @@ export default [
   {
     path: '/details/:id',
     name: 'details',
-    component: () => import(/* webpackChunkName: "test" */ '@/views/details/details.vue'),
+    component: () => import('@/views/details/details.vue'),
     meta: {
       title: '文库详情'
     }
+  },
+  {
+    path: '/user/library',
+    name: 'userLibrary',
+    component: () => import('@/views/user/Library.vue'),
+    meta: {
+      title: '我的文库'
+    }
+  },
+  {
+    path: '/onlineterm',
+    name: 'onlineterm',
+    component: () => import('@/views/purchase/onlineterm.vue'),
+    meta: {
+      title: '剑鱼标讯线上服务条款'
+    }
   }
 ]

+ 58 - 39
jydocs-mobile/src/store/modules/main.ts

@@ -3,15 +3,17 @@ import Vue from 'vue'
 import {
   getHomeHot,
   getHomeActivity,
-  getCashOutInfo,
-  submitCashOutInfo,
+  doSearchDocs,
+  getMyLibList,
   getDetails,
   getShow,
   getDown,
+  getListDetail,
   getRemove,
   getAdd,
   getCoin,
-  getDocPay
+  getDocPay,
+  getIndexTags
 } from '@/api/main'
 
 interface InterfaceStore<S> extends StoreOptions<S> {
@@ -70,42 +72,43 @@ function formatData (v: APIStructure) {
 const modulesOption: modulesOption = {
   namespaced: true,
   state: {
-    // 提现页面数据缓存(用于跳出页面返回时恢复)
-    cashOutInfo: recoveryPageData('partner-cashout'),
-    cashOutSuccess: recoveryPageData('partner-cashout-success'),
-    homePageData: recoveryPageData('jy-docs-home-page')
+    // 页面数据缓存(用于跳出页面返回时恢复)
+    homePageData: recoveryPageData('jy-docs-home-page'),
+    searchPageData: recoveryPageData('jy-docs-search-page'),
+    userLib: recoveryPageData('jy-docs-user-lib')
   },
   mutations: {
-    // 保存提现页面数据
-    saveCashOutInfo (state, data) {
+    // 保存首页数据
+    saveHomeData (state, data) {
       for (const key in data) {
-        state.cashOutInfo[key] = data[key]
+        Vue.set(state.homePageData, key, data[key])
       }
-      sessionStorage.setItem('partner-cashout', JSON.stringify(data))
-    },
-    // 清除提现页面数据
-    clearCashOutInfo (state) {
-      state.cashOutInfo = {}
-      sessionStorage.setItem('partner-cashout', JSON.stringify({}))
+      sessionStorage.setItem('jy-docs-home-page', JSON.stringify(state.homePageData))
     },
-    // 保存提现成功数据
-    saveCashOutSuccessInfo (state, data) {
+    // 我的文库页面数据
+    saveSearchPageState (state, data) {
+      console.log(data)
       for (const key in data) {
-        state.cashOutSuccess[key] = data[key]
+        state.searchPageData[key] = data[key]
       }
-      sessionStorage.setItem('partner-cashout-success', JSON.stringify(data))
+      sessionStorage.setItem('jy-docs-search-page', JSON.stringify(data))
     },
     // 清除提现成功数据
-    clearCashOutSuccessInfo (state) {
-      state.cashOutSuccess = {}
-      sessionStorage.setItem('partner-cashout-success', JSON.stringify({}))
+    clearSearchPageState (state) {
+      state.searchPageData = {}
+      sessionStorage.setItem('jy-docs-search-page', JSON.stringify({}))
     },
-    // 保存首页数据
-    saveHomeData (state, data) {
+    // 我的文库页面数据
+    saveMyLibState (state, data) {
       for (const key in data) {
-        Vue.set(state.homePageData, key, data[key])
+        state.userLib[key] = data[key]
       }
-      sessionStorage.setItem('jy-docs-home-page', JSON.stringify(state.homePageData))
+      sessionStorage.setItem('jy-docs-user-lib', JSON.stringify(data))
+    },
+    // 清除提现成功数据
+    clearMyLibState (state) {
+      state.userLib = {}
+      sessionStorage.setItem('jy-docs-user-lib', JSON.stringify({}))
     }
   },
   actions: {
@@ -133,31 +136,32 @@ const modulesOption: modulesOption = {
         }
       })
     },
-    // 文库购买
-    async getDocPay (state, data) {
+    // 文库查询
+    async doSearchDocs (state, data) {
       try {
-        const res = await getDocPay(data)
+        const res = await doSearchDocs(data)
         return res.data
       } catch (error) {}
     },
-    // 提现查询
-    async getCashOutInfo (state, data) {
+    // 我的文库查询
+    async getMyLibList (state, data) {
       try {
-        const res = await getCashOutInfo(data)
+        const res = await getMyLibList(data)
         return res.data
       } catch (error) {}
     },
-    // 提现提交
-    async submitCashOutInfo (state, data) {
+    // 详情
+    async getDetails (state, data) {
       try {
-        const res = await submitCashOutInfo(data)
+        const res = await getDetails(data)
+        console.log(res)
         return res.data
       } catch (error) {}
     },
-    // 详情
-    async getDetails (state, data) {
+    // 剑鱼积分详情
+    async getListDetail (state, data) {
       try {
-        const res = await getDetails(data)
+        const res = await getListDetail(data)
         console.log(res)
         return res.data
       } catch (error) {}
@@ -176,6 +180,13 @@ const modulesOption: modulesOption = {
         return res.data
       } catch (error) {}
     },
+    // 文库购买
+    async getDocPay (state, data) {
+      try {
+        const res = await getDocPay(data)
+        return res.data
+      } catch (error) {}
+    },
     // 文库收藏
     async getAdd (state, data) {
       try {
@@ -199,6 +210,14 @@ const modulesOption: modulesOption = {
         console.log(res)
         return res.data
       } catch (error) {}
+    },
+    // 剑鱼币
+    async getIndexTags () {
+      try {
+        const res = await getIndexTags()
+        console.log(res)
+        return res.data
+      } catch (error) {}
     }
   },
   getters: {}

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

@@ -322,6 +322,21 @@ export function formatSize (size: string | number, pointLength: number, units: A
   }
   return (unit === 'B' ? size : size.toFixed(pointLength === undefined ? 2 : pointLength)) + (unit || '')
 }
+
+// 文件类型转换
+export function docTypeConvert (docType = 'pdf') {
+  const typeMap: any = {
+    doc: 'word',
+    docx: 'word',
+    xls: 'excel',
+    xlsx: 'excel',
+    ppt: 'ppt',
+    pdf: 'pdf'
+  }
+  const type = typeMap[docType]
+  return type || docType // map中不存在的,则返回原始类型
+}
+
 /**
  * 通用关键字高亮替换
  * @param {String} value 要高亮的字符串

+ 314 - 138
jydocs-mobile/src/views/Search.vue

@@ -1,170 +1,346 @@
 <template>
-  <div class="pages--search" :data-top="Offset">
-    <search ref="getH" id="mySearch" key="search-page" @input="goSearchInput" @submit="goSearch"></search>
-    <van-sticky :offset-top="Offset">
-      <van-tabs v-model="active"
-          title-active-color="#2ABED1"
-          title-inactive-color="#5F5E64"
-          color="#2ABED1"
-        >
-        <van-tab :title="item.label" :name="item.type" v-for="item in tabs" :key="item.type"></van-tab>
+  <div class="pages--search">
+    <div class="j-header">
+      <search id="mySearch" key="search-page" :defalultValue="listState.value" @input="onInput" @submit="doSearch"></search>
+      <van-tabs v-model="docsTypeConf.active"
+        v-if="docsTypeConf.list.length"
+        title-active-color="#2ABED1"
+        title-inactive-color="#5F5E64"
+        color="#2ABED1"
+        @change="docTypeChange"
+      >
+        <van-tab v-for="(item, index) in docsTypeConf.list" :key="index" :title="item.label" :name="item.type"></van-tab>
       </van-tabs>
-    </van-sticky>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
-    <h1>4544454545454</h1>
+      <div class="sort-list flex-r-c center">
+        <div
+          class="sort-list-item flex-r-c center flex"
+          :class="{
+            active: item.active,
+            reverse: item.sort
+          }"
+          v-for="(item, index) in sortTypeList"
+          :key="index"
+          @click="sortAndSearch(item, index)"
+        >
+          <span class="s-i-label">{{ item.label }}</span>
+          <van-icon name="down" class="s-i-icon" />
+        </div>
+      </div>
+    </div>
+    <div class="j-main" ref="scrollWrap">
+      <van-list
+        v-model="listState.loading"
+        :finished="listState.finished"
+        :offset="listState.offset"
+        @load="getList"
+        class="more-list calc-height-1px"
+        ref="vanList"
+      >
+        <div>
+          <Card
+            v-for="(item, index) in listState.list"
+            :key="index"
+            :title="item.docName"
+            :desc="item.docSummary"
+            :docType="item.docFileType"
+            :highlightKey="highlightKey"
+            :price="item.price"
+            :subInfo="calcSubInfo(item)"
+            @onClick="toDocDetail(item)"
+          />
+        </div>
+        <Empty v-if="listState.list.length === 0 && listState.loaded">暂无数据</Empty>
+      </van-list>
+    </div>
   </div>
 </template>
 
 <script lang="ts">
 import { Component, Vue } from 'vue-property-decorator'
+import { Tabs, Tab, Icon, List } from 'vant'
 import Search from '@/components/Search.vue'
-import { Tabs, Tab, Icon, Sticky } from 'vant'
-// import { mapActions } from 'vuex'
-  // import { MixinTop } from '@/utils/mixin-top'
-  @Component({
-    name: 'home',
-    // mixins: [MixinTop],
-    components: {
-      [Tab.name]: Tab,
-      [Tabs.name]: Tabs,
-      [Sticky.name]: Sticky,
-      [Icon.name]: Icon,
-      Search
+import Card from '@/components/docs-card/Card.vue'
+import Empty from '@/components/common/Empty.vue'
+import { mapState, mapMutations, mapActions } from 'vuex'
+import { dateFormatter } from '@/utils/globalFunctions'
+
+@Component({
+  name: 'home',
+  components: {
+    [Tab.name]: Tab,
+    [Tabs.name]: Tabs,
+    [List.name]: List,
+    [Icon.name]: Icon,
+    Search,
+    Card,
+    Empty
+  },
+  methods: {
+    ...mapState('main', {
+      searchState: (state: any) => state.searchPageData
+    }),
+    ...mapMutations({
+      saveSearchState: 'main/saveSearchPageState',
+      clearSearchState: 'main/clearSearchPageState'
+    }),
+    ...mapActions({
+      doSearchRquesst: 'main/doSearchDocs',
+      getIndexTags: 'main/getIndexTags'
+    })
+  }
+})
+
+export default class extends Vue {
+  protected searchState: any
+  protected saveSearchState: any
+  protected clearSearchState: any
+
+  protected doSearchRquesst: any
+  protected getIndexTags: any
+
+  docsTypeConf = {
+    active: '',
+    list: []
+  }
+
+  sortTypeList = [
+    {
+      type: 'tSort',
+      label: '上传时间',
+      sort: 0,
+      active: true
+    },
+    {
+      type: 'dSort',
+      label: '下载次数',
+      sort: 0,
+      active: false
     },
-    methods: {
-      // ...mapActions({
-      //   ajaxData: 'main/getHome'
-      // })
+    {
+      type: 'vSort',
+      label: '浏览人数',
+      sort: 0,
+      active: false
     }
-  })
+  ]
 
-export default class extends Vue {
-    // protected ajaxData: any
-    pageData: any = {}
-    searchTop = 54
-    active = 'all1'
-    searchInput = ''
-    tabs = [
-      {
-        type: 'all1',
-        label: '全部'
-      },
-      {
-        type: 'all2',
-        label: '招标'
-      },
-      {
-        type: 'all3',
-        label: '法律法规'
-      },
-      {
-        type: 'all4',
-        label: '行业报告'
-      }
-    ]
-
-    created () {
-      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
-          }
-        ]
-      }
+  listState ={
+    value: '',
+    loaded: false, // 是否首次加载完成
+    loading: false,
+    finished: true,
+    pageNum: 1,
+    pageSize: 10,
+    offset: 80,
+    scrollTop: 0,
+    total: 0,
+    list: []
+  }
+
+  get activeSortType () {
+    return this.sortTypeList.find(item => {
+      return item.active
+    })
+  }
+
+  get highlightKey () {
+    return this.listState.value.split(/\s+/)
+  }
+
+  created () {
+    const y = this.reStoreState()
+    if (!y) {
+      this.getTags()
     }
+  }
+
+  mounted () {
+    this.onFocus()
+  }
 
-    mounted () {
-      this.onFocus()
-      const tempI = (this.$refs.getH as Vue).$el as HTMLDivElement
-      this.searchTop = tempI.offsetHeight
+  onFocus () {
+    const dom = document.querySelector('#mySearch input') as HTMLInputElement
+    if (dom) {
+      this.$nextTick(() => {
+        setTimeout(() => {
+          dom.focus()
+        }, 200)
+      })
     }
+  }
 
-    get Offset () {
-      const tempN = document.querySelector('.j-header.jy-app-header') as HTMLDivElement
-      if (tempN) {
-        return tempN.offsetHeight - 1 + this.searchTop
-      } else {
-        return 0
-      }
+  // 恢复数据至第一次请求的状态(页码等)
+  resetListState () {
+    const state = {
+      loading: false,
+      finished: true,
+      pageNum: 1,
+      total: 0,
+      list: []
     }
+    Object.assign(this.listState, state)
+  }
+
+  onInput (search: string) {
+    this.listState.value = search
+  }
 
-    onFocus () {
-      const tempN = document.querySelector('#mySearch input') as HTMLInputElement
-      if (tempN) {
-        this.$nextTick(() => {
-          tempN.focus()
-          setTimeout(() => {
-            tempN.focus()
-          }, 200)
-        })
+  docTypeChange () {
+    if (!this.listState.value) return
+    this.resetListState()
+    this.listState.finished = false
+    this.getList()
+  }
+
+  sortAndSearch (item: any) {
+    if (item.active) {
+      // 改变sort
+      // item.sort = item.sort ? 0 : 1
+    } else {
+      this.sortTypeList.forEach(s => {
+        s.active = false
+      })
+      item.active = true
+    }
+    if (!this.listState.value) return
+    this.resetListState()
+    this.listState.finished = false
+    this.getList()
+  }
+
+  doSearch () {
+    this.resetListState()
+    this.listState.finished = false
+    this.getList()
+  }
+
+  toDocDetail (item: any) {
+    const { docId: id } = item
+    this.saveState()
+    this.$router.push({
+      name: 'details',
+      params: { id }
+    })
+  }
+
+  async getTags () {
+    const { data } = await this.getIndexTags()
+    if (Array.isArray(data)) {
+      const list: any = data.map(item => {
+        return {
+          type: item,
+          label: item
+        }
+      })
+      this.docsTypeConf.list = list
+      if (data.length) {
+        const i: any = this.docsTypeConf.list[0]
+        this.docsTypeConf.active = i.type
       }
     }
+    return data
+  }
 
-    goSearch (search: any) {
-      console.log(search)
+  async getList () {
+    if (!this.listState.value) return
+    const query = {
+      keyWord: this.listState.value,
+      tag: this.docsTypeConf.active === '全部' ? '' : this.docsTypeConf.active,
+      sort: this.activeSortType?.type,
+      num: this.listState.pageNum,
+      size: this.listState.pageSize
+    }
+    console.log('搜索参数:', query)
+    this.listState.loading = true
+    const { data } = await this.doSearchRquesst(query)
+    this.listState.loading = false
+    this.listState.loaded = true
+    if (data && Array.isArray(data.list)) {
+      this.listState.pageNum += 1
+      this.listState.total = data.total
+      this.listState.list = this.listState.list.concat(data.list)
+    } else {
+      this.listState.finished = true
     }
 
-    goSearchInput (search: string) {
-      this.searchInput = search
+    // 数据请求完成(根据页码计算,当前页是否是最后一页)
+    // 请求完成后,页码就变为了下一页的页面,所以这里要-1
+    const isLastPage = (this.listState.pageNum - 1) * this.listState.pageSize >= this.listState.total
+    if (isLastPage) {
+      this.listState.finished = true
     }
+  }
+
+  calcSubInfo (item: any) {
+    const { uploadDate, downTimes } = item
+    return [dateFormatter(uploadDate, 'yyyy/MM/dd'), `${downTimes}次下载`]
+  }
 
-    goContent (item: any) {
-      console.log(item)
+  reStoreState () {
+    const listInfo = this.searchState()
+    if (!listInfo || Object.keys(listInfo).length === 0) {
+      return false
+    } else {
+      for (const key in listInfo) {
+        this.$data[key] = listInfo[key]
+      }
+      this.$nextTick(() => {
+        const wrapper: any = this.$refs.scrollWrap
+        wrapper.scrollTop = this.listState.scrollTop
+      })
+      return true
     }
+  }
+
+  saveState () {
+    const wrapper: any = this.$refs.scrollWrap
+    this.listState.scrollTop = wrapper.scrollTop
+    const d = {
+      docsTypeConf: this.docsTypeConf,
+      sortTypeList: this.sortTypeList,
+      listState: this.listState
+    }
+    console.log(d)
+    this.saveSearchState(d)
+  }
 }
 </script>
 <style scoped lang="scss">
 .pages--search {
-  background: #F5F6F7;
-  padding-bottom: 40px;
+  background-color: #F5F6F7;
   box-sizing: border-box;
+  ::v-deep .van-tabs {
+    width: 100%;
+    font-size: 14px;
+    line-height: 20px;
+  }
+
+  .j-header {
+    flex-direction: column;
+  }
+
+  .sort-list {
+    width: 100%;
+    font-size: 14px;
+    line-height: 20px;
+    .sort-list-item {
+      padding: 12px 16px;
+      &.active {
+        color: #2ABED1;
+      }
+      &.reverse {
+        .s-i-icon {
+          transform: rotate(180deg);
+        }
+      }
+      .s-i-label {
+        margin-right: 4px;
+      }
+      .s-i-icon {
+        font-weight: bold;
+        transition: transform .2 ease;
+      }
+    }
+  }
 }
 </style>

+ 84 - 0
jydocs-mobile/src/views/purchase/onlineterm.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="onlineterm">
+    <div class="j-main">
+      <div class="content">
+          <div class="content_title">剑鱼文库线上购买及服务条款</div>
+          <div class="content_text">
+            <p>感谢使用剑鱼文库,请您仔细阅读以下条款,如果您对本协议的任何条款表示异议,您可以选择暂不进入;进入文库代表您已认可本协议下全部规定,并愿意守约。</p>
+            <p>第一章 总则</p>
+            第1条 剑鱼标讯:指由北京剑鱼信息技术有限公司运营并管理的产品,产品形态包括www.jianyu360.com网站、剑鱼标讯微信公众号、剑鱼标讯APP等,剑鱼标讯为其用户提供招标信息产品与服务。剑鱼文库所有权、经营权、管理权均属剑鱼标讯。
+            第2条 凡是注册用户和浏览用户均为剑鱼文库用户(以下统称“用户”)。
+            第3条 本服务条款是北京剑鱼信息技术有限公司及剑鱼标讯与您就剑鱼文库的相关事项所订立的有效合约。
+            <p>第二章 用户守则</p>
+            第4条 用户的言行不得违反《计算机信息网络国际联网安全保护管理办法》、《互联网信息服务管理办法》、《互联网电子公告服务管理规定》、《维护互联网安全的决定》、《互联网新闻信息服务管理规定》等相关法律规定。
+            第5条 不得在剑鱼文库传播或以其它方式传送含有下列内容之一的信息: 1) 反对宪法所确定的基本原则的; 2) 危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的; 3) 损害国家荣誉和利益的; 4) 煽动民族仇恨、民族歧视、破坏民族团结的; 5) 破坏国家宗教政策,宣扬邪教和封建迷信的; 6) 散布谣言,扰乱社会秩序,破坏社会稳定的; 7) 散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的; 8) 侮辱或者诽谤他人,侵害他人合法权利的; 9) 煽动非法集会、结社、游行、示威、聚众扰乱社会秩序的;10)以非法民间组织名义活动的;11)含有虚假、有害、胁迫、侵害他人隐私、骚扰、侵害、中伤、粗俗、猥亵、或其它道德上令人反感的内容; 12) 含有中国法律、法规、规章、条例以及任何具有法律效力之规范所限制或禁止的其它内容的。
+            第6条 用户应承担一切因其个人的行为而直接或间接导致的民事或刑事法律责任,因用户行为给剑鱼标讯造成损失的,用户应负责赔偿。
+            第7条 剑鱼标讯拥有对违反本协议的用户进行处理的权力,直至禁止其在剑鱼文库文库下载文档、视频、音频。
+            第8条 任何用户发现文库文档、视频、音频内容涉嫌侮辱或者诽谤他人、侵害他人合法权益的或违反文库协议的,有权到剑鱼文库客服处进行申诉下线。
+            <p>第三章 权利声明</p>
+            第9条 剑鱼文库的用户可以为介绍、评论、研究等目的,在合理的范围内适当引用他人已经发表的作品,但应当注明作者姓名、作品名称,并不得侵犯著作权人及其他权利人的合法权益。
+            第10条 当权利人发现剑鱼文库的内容侵犯其合法权益时,权利人应事先向剑鱼标讯提出异议,剑鱼文库将依据相关的法律法规对作品进行相应的处理。
+            第11条 用户从剑鱼文库中获得的信息,未经事先许可,用户不得以盈利为目的自己或提供给第三方进行使用(符合法律规定的“合理使用”条件的除外)。否则,一切法律后果由该用户或第三方自负。
+            第12条 未经剑鱼标讯事先许可,禁止使用任何机器人、蜘蛛、其他自动设备,或手动程序来监视或复制剑鱼文库网页或其所包含的任何内容。否则,剑鱼标讯有权依法追究法律责任。
+            <p>第四章 隐私保护</p>
+            第13条  您在使用剑鱼文库的过程中,不会披露任何您的个人信息和下载使用信息,但以下情况除外:
+            (1)事先获得您的授权;
+            (2)根据法律、法规、法律程序的要求或政府主管部门的强制性要求;
+            (3)在法律要求的范围内,为维护公共利益和剑鱼文库合法利益,例如查找、预防、处理欺诈或安全方面的问题;
+            (4)符合相关服务条款或使用协议的规定。
+            <p>第五章 免责声明</p>
+            第14条 鉴于剑鱼文库以非人工检索方式、根据您键入的关键字自动显示搜索内容,除剑鱼文库注明之服务条款外,其他一切因使用剑鱼文库而可能遭致的意外、疏忽、侵权及其造成的损失,剑鱼文库对其概不负责,亦不承担任何法律责任。
+            第15条 任何通过使用剑鱼文库内容,链接到第三方网页均系他人制作或提供,您可能从搜索结果获得资讯及享用服务,剑鱼文库对其合法性概不负责,亦不承担任何法律责任。
+            第16条 剑鱼文库搜索结果根据您键入的关键字自动搜索获得并生成,不代表剑鱼文库赞成搜索结果显示的内容或立场。
+            第17条 您应该对使用文库搜索的结果自行承担风险。剑鱼文库不做任何形式的保证:不保证搜索结果满足您的要求,不保证搜索服务不中断,不保证搜索结果的安全性、正确性、及时性、合法性。因网络状况、通讯线路、第三方网站等任何原因而导致您不能正常使用剑鱼文库,剑鱼文库不承担任何法律责任。
+            <p>第六章 附则</p>
+            第18条 剑鱼文库如因系统维护或升级等而需暂停服务时,将事先公告。
+            第19条 剑鱼文库有权根据中华人民共和国法律、法规及规范性文件的变化以及互联网及自身业务的发展情况,不断修改和完善包括文库协议在内的相关条款。
+            第20条 本协议未涉及的问题参见国家有关法律法规,当本协议与国家法律法规冲突时,以国家法律法规为准。
+            <p>第七章 法律适用及争议解决</p>
+            第21条 本使用条款受中华人民共和国法律管辖。
+            第22条 在执行本使用条款程中如发生纠纷,双方应及时协商解决。协商不成时,任何一方可直接向北京拓普及剑鱼标讯所在地人民法院提起诉讼。
+            第23条 在法院审理期间,除提交法院审理的事项外,本服务条款其他部分仍应继续履行。
+          </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import { Component, Vue } from 'vue-property-decorator'
+
+@Component({
+  name: 'onlineterm',
+  components: {
+  }
+})
+
+export default class extends Vue {
+}
+</script>
+
+<style lang="scss">
+  .onlineterm {
+      .content{
+          padding: 12px 16px 0 16px;
+          text-align: justify;
+          .content_title{
+            color: #171826;
+            font-weight: medium;
+            font-size: 13px;
+            line-height: 20px;
+            letter-spacing: 0px;
+            text-align: left;
+          }
+          .content_text{
+            margin-top: 12px;
+            color: #5F5E64;
+            font-weight: medium;
+            font-size: 12px;
+            line-height: normal;
+            letter-spacing: 0px;
+            text-align: left;
+          }
+      }
+  }
+</style>

+ 84 - 8
jydocs-mobile/src/views/purchase/purchase.vue

@@ -19,6 +19,20 @@
           </div>
         </div>
       </div>
+      <div class="rechargehave_pay_content">
+        <div class="pay_title">
+          支付方式
+        </div>
+        <div class="jianyu_pay">
+          <div class="jy_pay_left">
+            <span class="jy_money">剑鱼币</span>
+            <span class="jy_tip">(剩余{{response.balance}}剑鱼币)</span>
+          </div>
+          <div class="jy_pay_icon">
+            <img src="../../assets/icon/checked.png" class="icon_right_option" />
+          </div>
+        </div>
+      </div>
       <div class="docs_phone">
         <!-- <van-cell-group>
           <van-field v-model="tel" type="number" label="手机号码" placeholder="请输入手机号码" />
@@ -45,7 +59,7 @@
         </div>
       </div>
       <div class="readly">
-        <van-checkbox v-model="checked" checked-color="#2ABED1" >我已阅读,理解并接受<a href="javascript:;" class="clause" @click="clause()">《剑鱼伙伴服务条款》</a></van-checkbox>
+        <van-checkbox v-model="checked" checked-color="#2ABED1" >我已阅读并同意<a href="javascript:;" class="clause" @click="clause()">《剑鱼文库线上购买及服务条款》</a><a href="javascript:;" class="clause" @click="clause2()">《剑鱼标讯产品与服务线上购买服务条款》</a></van-checkbox>
       </div>
       <div class="apply_footer">
         <button class="apply_button" :disabled="!this.checked" @click="exchange()">确定兑换</button>
@@ -71,15 +85,18 @@ const regPhoneExg = /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|1
   methods: {
     ...mapActions({
       getDocPay: 'main/getDocPay',
-      getDetails: 'main/getDetails'
+      getDetails: 'main/getDetails',
+      getListDetail: 'main/getListDetail'
     })
   }
 })
 export default class extends Vue {
   protected getDocPay!: any
   protected getDetails!: any
+  protected getListDetail!: any
   checked = false
   tel = ''
+  query: any
   $router: any
   response = {
     docName: '',
@@ -87,16 +104,19 @@ export default class extends Vue {
     downTimes: '',
     docFileSize: '',
     docPageSize: '',
-    previewImgId: ''
+    previewImgId: '',
+    balance: ''
   }
 
   created () {
+    this.query = location.href.split('/')[location.href.split('/').length - 1] // 获取id
+    console.log(this.query)
     this.getWordInfor()
   }
 
   // 文档信息
-  getWordInfor () {
-    this.getDetails({ docId: '4f6c00ba-8882-11eb-8699-0050568f51e7' }).then((res: any) => {
+  async getWordInfor () {
+    this.getDetails({ docId: this.query }).then((res: any) => {
       console.log(res)
       const item = res.data.detail
       if (res.error_code === 0) {
@@ -108,13 +128,21 @@ export default class extends Vue {
         this.response.previewImgId = item.previewImgId
       }
     })
+
+    this.getListDetail({ B: true }).then((res) => {
+      console.log(res)
+      if (res.error_code === 0) {
+        this.response.balance = res.points.balance
+      }
+    })
   }
 
   // 确定兑换
   exchange () {
-    this.getDocPay({ docId: '4f6c00ba-8882-11eb-8699-0050568f51e7', phone: '18439509554' }).then((res: any) => {
+    this.getDocPay({ docId: this.query, phone: this.tel }).then((res: any) => {
       console.log(res)
-      if (res.data === 'success') {
+      if (res.error_code === 0) {
+        sessionStorage.setItem('paydata', JSON.stringify(res.data))
         this.$router.push('/purchasesuccess')
       }
     })
@@ -132,9 +160,16 @@ export default class extends Vue {
     message: '手机号格式错误'
   }]
 
-  // 剑鱼标讯服务条款
+  // 剑鱼文库线上购买及服务条款
   clause () {
+    this.$router.push('/onlineterm')
+  }
+
+  // 剑鱼标讯产品与服务线上购买服务条款
+  clause2 () {
+    // app:https://app-a2.jianyu360.com/jyapp/front/staticPage/dataExport_serviceterms.html
     // this.$router.push('/readme')
+    // wx:https://www.jianyu360.com/front/staticPage/wx-serviceterms.html
   }
 }
 </script>
@@ -202,6 +237,47 @@ export default class extends Vue {
           }
         }
       }
+      .rechargehave_pay_content{
+        padding: 0 16px;
+        margin-top: 8px;
+        width: 100%;
+        height: 100px;
+        box-sizing: border-box;
+        border-bottom: 1px solid rgba($color: #000000, $alpha: 0.05);
+        background: #ffffff;
+        .pay_title{
+          margin-top: 16px;
+          width: 100%;
+          height: 24px;
+          color: #171826;
+          font-size: 16px;
+          line-height: 24px;
+        }
+        .jianyu_pay{
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-top: 24px;
+          width: 100%;
+          height: 20px;
+          color: #171826;
+          font-size: 14px;
+          line-height: 20px;
+          .jy_pay_left{
+              .jy_tip{
+                  color: #2abed1;
+              }
+          }
+          .jy_pay_icon{
+              width: 24px;
+              height: 24px;
+              .icon_right_option{
+                  width: 100%;
+                  height: 100%;
+              }
+          }
+        }
+      }
       .docs_phone {
         padding: 15px 0;
         width: 100%;

+ 38 - 4
jydocs-mobile/src/views/purchase/purchasesuccess.vue

@@ -16,15 +16,15 @@
         <div class="infor_group">
           <div class="infor_cell">
             <div class="infor_title">支付方式</div>
-            <div class="infor_value">剑鱼币支付</div>
+            <div class="infor_value">{{payinfor.payWay}}支付</div>
           </div>
           <div class="infor_cell">
             <div class="infor_title">兑换时间</div>
-            <div class="infor_value">2019/07/31 16:29:57</div>
+            <div class="infor_value">{{payinfor.payTime}}</div>
           </div>
           <div class="infor_cell">
             <div class="infor_title">流水编号</div>
-            <div class="infor_value">6489798765465465</div>
+            <div class="infor_value">{{payinfor.code}}</div>
           </div>
         </div>
       </div>
@@ -37,6 +37,7 @@
 
 <script lang="ts">
 import { Component, Vue } from 'vue-property-decorator'
+import { dateFormatter } from '../../utils/globalFunctions'
 // import { mapState } from 'vuex'
 
 @Component({
@@ -48,11 +49,29 @@ export default class extends Vue {
   count = 3
   timer: any
   $router: any
+  payinfor = {
+    payTime: '',
+    payWay: '',
+    code: ''
+  }
 
   created () {
     this.setCountDown()
+    this.setSession()
+  }
+
+  setSession () {
+    let paydata = sessionStorage.getItem('paydata')
+    console.log(paydata)
+    if (paydata) {
+      paydata = JSON.parse(paydata)
+      this.payinfor.payTime = dateFormatter(paydata.payTime * 1000, 'yyyy-MM-dd HH:mm:ss')
+      this.payinfor.payWay = paydata.payWay
+      this.payinfor.code = paydata.code
+    }
   }
 
+  // 倒计时
   setCountDown () {
     if (!this.timer) {
       this.timer = setInterval(() => {
@@ -61,11 +80,26 @@ export default class extends Vue {
         } else {
           clearInterval(this.timer)
           this.timer = null
-          this.$router.push('/home')
+          this.$router.replace({
+            name: 'details',
+            params: {
+              id: this.payinfor.code
+            }
+          })
         }
       }, 1000)
     }
   }
+
+  // 查看文档按钮
+  complete () {
+    this.$router.replace({
+      name: 'details',
+      params: {
+        id: this.payinfor.code
+      }
+    })
+  }
 }
 </script>
 <style lang="scss">

+ 119 - 0
jydocs-mobile/src/views/user/Library.vue

@@ -0,0 +1,119 @@
+<template>
+  <div class="user-library">
+    <van-tabs
+      :title-active-color="tabConf.titleActiveColor"
+      :title-inactive-color="tabConf.titleInactiveColor"
+      :line-width="tabConf.lineWidth"
+      :color="tabConf.color"
+      v-model="tabActive"
+    >
+      <van-tab title="我的文库" name="0">
+        <van-list
+          v-model="myLibListState.loading"
+          :finished="myLibListState.finished"
+          finished-text="没有更多了"
+          @load="onLoad('0')"
+        >
+          00000
+        </van-list>
+      </van-tab>
+
+      <van-tab title="文库收藏" name="1">
+        <van-list
+          v-model="myCollectionListState.loading"
+          :finished="myCollectionListState.finished"
+          finished-text="没有更多了"
+          @load="onLoad('1')"
+        >
+          1111
+        </van-list>
+      </van-tab>
+    </van-tabs>
+  </div>
+</template>
+<script lang="ts">
+import { Component, Vue } from 'vue-property-decorator'
+import { Tabs, Tab, List } from 'vant'
+import { mapActions, mapState } from 'vuex'
+
+@Component({
+  name: 'user-library',
+  components: {
+    [Tabs.name]: Tabs,
+    [Tab.name]: Tab,
+    [List.name]: List
+  },
+  computed: {
+    ...mapState('main', {
+      userLibInfo: (state: any) => state.userLib
+    })
+  },
+  methods: {
+    ...mapActions({
+      getList: 'main/getMyLibList'
+    })
+  }
+})
+
+export default class UserLibrary extends Vue {
+  getList: any
+
+  tabActive = '0'
+
+  tabConf = {
+    titleActiveColor: '#2ABED1',
+    titleInactiveColor: '#5F5E64',
+    lineWidth: '24',
+    color: '#2ABED1'
+  }
+
+  myLibListState = {
+    loading: false,
+    finished: false,
+    pageNum: 1,
+    pageSize: 10,
+    offset: 80,
+    scrollTop: 0,
+    list: []
+  }
+
+  myCollectionListState = {
+    loading: false,
+    finished: false,
+    pageNum: 1,
+    pageSize: 10,
+    offset: 80,
+    scrollTop: 0,
+    list: []
+  }
+
+  created () {
+    this.tabActive = this.$route.query.tab as string
+    this.getList({})
+  }
+
+  onLoad (tab: string) {
+    console.log(tab)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.user-library {
+  ::v-deep {
+    .van-tabs__wrap {
+      height: 48px;
+    }
+    .van-tabs__line {
+      bottom: 18px;
+    }
+    .van-tabs {
+      width: 100%;
+    }
+    .van-tab {
+      font-size: 16px;
+      line-height: 20px;
+    }
+  }
+}
+</style>

+ 2 - 10
jydocs-mobile/vue.config.js

@@ -46,19 +46,11 @@ module.exports = {
     disableHostCheck: true,
     proxy: {
       '^/dev/api': {
-        target: 'http://app207-jytest.jianyu360.cn',
+        target: 'http://192.168.20.180:821',
         changeOrigin: true,
         logLevel: 'debug',
         pathRewrite: {
-          '^/dev/api': ''
-        }
-      },
-      '^/distribution': {
-        target: 'http://app207-jytest.jianyu360.cn',
-        changeOrigin: true,
-        logLevel: 'debug',
-        pathRewrite: {
-          '^/distribution': '/distribution'
+          '^/dev/api': '/jydocs'
         }
       },
       '^/jydocs': {

+ 11 - 0
jydocs-pc/src/api/mock/indexTag.json

@@ -0,0 +1,11 @@
+{
+  "error_code": 0,
+  "error_msg": "",
+  "data": [
+    "全部",
+    "招标",
+    "法律法规",
+    "行业报告",
+    "测试"
+  ]
+}

+ 7 - 0
jydocs-pc/src/api/modules/home.js

@@ -17,6 +17,13 @@ export function getHomeHot (data) {
   })
 }
 
+export function getSearchTag () {
+  return request({
+    url: '/indexTag',
+    method: 'post'
+  })
+}
+
 export function getHomeActivity (data) {
   return request({
     url: '/activityList',

+ 22 - 20
jydocs-pc/src/components/Search.vue

@@ -7,7 +7,7 @@
                 clearable>
             <el-button @click="submitSearch" slot="append" icon="el-icon-jy-search"></el-button>
         </el-input>
-        <el-tabs v-model="type">
+        <el-tabs v-model="type" v-show="tabs.length">
           <el-tab-pane v-for="item in tabs" :key="item.type" :label="item.label" :name="item.type"></el-tab-pane>
         </el-tabs>
     </div>
@@ -15,6 +15,9 @@
 
 <script>
 import { Input, Button, Tabs, TabPane } from 'element-ui'
+import { getSearchTag } from '../api/modules/home'
+import { recoveryPageData } from '../utils'
+
 export default {
   name: 'Search-Input',
   props: {
@@ -29,28 +32,13 @@ export default {
   data () {
     return {
       input: '',
-      type: 'all',
-      tabs: [
-        {
-          type: 'all',
-          label: '全部'
-        },
-        {
-          type: '招标',
-          label: '招标'
-        },
-        {
-          type: '法律法规',
-          label: '法律法规'
-        },
-        {
-          type: '行业报告',
-          label: '行业报告'
-        }
-      ]
+      type: '全部',
+      tabs: []
     }
   },
   beforeMount () {
+    this.tabs = recoveryPageData('jy-docs-search-tags-pc')
+    this.getTags()
     const qUrl = this.$route.query
     qUrl && qUrl.type && (this.type = qUrl.type)
     if (qUrl && qUrl.text) {
@@ -62,6 +50,20 @@ export default {
     }
   },
   methods: {
+    async getTags () {
+      getSearchTag().then(res => {
+        if (!res.data.error_msg.length) {
+          this.tabs = res.data.data.map(v => {
+            return {
+              type: v,
+              label: v
+            }
+          })
+          this.type = this.tabs[0].type
+          sessionStorage.setItem('jy-docs-search-tags-pc', JSON.stringify(this.tabs))
+        }
+      })
+    },
     submitSearch () {
       if (!this.input.length) {
         return

+ 4 - 0
jydocs-pc/src/utils/globalFunctions.js

@@ -328,3 +328,7 @@ export function replaceKeyword (value, oldChar, newChar) {
   }
   return value
 }
+
+export function recoveryPageData (key, defaultValues = {}) {
+  return sessionStorage.getItem(key) ? JSON.parse(sessionStorage.getItem(key) || '') : defaultValues
+}

+ 11 - 12
jydocs-pc/src/views/Content.vue

@@ -144,7 +144,7 @@ export default {
           this.collectd = res.data.data.docCang
         }
       })
-      getCoin({B: true}).then(res => {
+      getCoin({ B: true }).then(res => {
         console.log(res)
         if (res.data.error_code === 0) {
           this.coinNum = res.data.data.data.points.balance
@@ -152,9 +152,9 @@ export default {
             this.btnName = '下载文档'
           } else {
             if (this.coinNum < this.datas.price) {
-                this.btnName = '立即充值'
+              this.btnName = '立即充值'
             } else {
-                this.btnName = '立即兑换'
+              this.btnName = '立即兑换'
             }
           }
         }
@@ -222,21 +222,20 @@ export default {
       // this.setTop();
     },
     loadFile () {
-        console.log('11212')
-    //   if (this.buyed) {
+      if (this.buyed) {
         getDown({ docId: this.docIds }).then(res => {
           console.log(res.data)
           if (res.data.error_code === 0) {
             window.location.href = res.data.data
           }
         })
-    //   } else {
-    //     if (this.coinNum < this.datas.price) {
-          
-    //     } else {
-          
-    //     }
-    //   }
+      } else {
+        if (this.coinNum < this.datas.price) {
+          this.$router.push({path: '/', query: {id: this.detailData.docId}})
+        } else {
+          this.$router.push({path: '/purchase', query: {id: this.detailData.docId}})
+        }
+      }
     },
     fileType (val) {
       if (val === 1) {

+ 1 - 3
jydocs-pc/src/views/Home.vue

@@ -125,9 +125,7 @@ import { ajaxGetTest } from '../api/modules/user'
 import { Button } from 'element-ui'
 import SearchInput from '../components/Search'
 import { getHomeActivity, getHomeHot } from '../api/modules/home'
-function recoveryPageData (key, defaultValues = {}) {
-  return sessionStorage.getItem(key) ? JSON.parse(sessionStorage.getItem(key) || '') : defaultValues
-}
+import { recoveryPageData } from '../utils'
 
 function checkType (type) {
   let typeStr = ''

+ 2 - 2
jydocs-pc/src/views/Search.vue

@@ -106,7 +106,7 @@ export default {
       })
     },
     highlightKey () {
-      return [this.searchQuery.text]
+      return this.searchQuery.text.split(/\s+/)
     }
   },
   methods: {
@@ -136,7 +136,7 @@ export default {
       if (!this.searchQuery.text) return
       const query = {
         keyWord: this.searchQuery.text,
-        tag: this.searchQuery.type === 'all' ? '' : this.searchQuery.type,
+        tag: this.searchQuery.type === '全部' ? '' : this.searchQuery.type,
         sort: this.activeSortList.type,
         num: this.listState.pageNum,
         size: this.listState.pageSize

+ 2 - 1
jydocs-pc/src/views/purchase/purchase.vue

@@ -120,7 +120,8 @@ export default {
       console.log(111)
       getDocPays({ docId: '4f6c00ba-8882-11eb-8699-0050568f51e7', phone: '18439509554' }).then((res) => {
         console.log(res)
-        if (res.data === 'success') {
+        if (res.error_code === 0) {
+          sessionStorage.setItem('paydata', JSON.stringify(res.data))
           this.$router.push('/purchasesuccess')
         }
       })