xia 4 år sedan
förälder
incheckning
9d356c19e5

+ 1 - 0
.quickapp.preview.json

@@ -0,0 +1 @@
+{}

+ 2 - 2
package.json

@@ -16,9 +16,9 @@
     "babel-eslint": "^10.0.1",
     "eslint": "^5.12.1",
     "eslint-plugin-hybrid": "0.0.5",
-    "hap-toolkit": "^0.6.6",
     "less": "^3.10.3",
-    "less-loader": "^5.0.0"
+    "less-loader": "^5.0.0",
+    "hap-toolkit": "^0.6.6"
   },
   "dependencies": {
     "flyio": "^0.6.14"

+ 1 - 1
src/api/config.js

@@ -7,7 +7,7 @@
  */
 const apiConfig = {
   baseURL: "https://quickapp.leyuee.com/api",
-  //baseURL: "https://kyy.aizhuishu.com/api",
+  //baseURL: "https://quickapptest.leyuee.com/api",
 };
 
 export default apiConfig;

+ 39 - 5
src/api/fly.js

@@ -15,6 +15,9 @@ var fly = new Fly(fetch);
 var qs = require('qs');
 var appInfo = it.getAppInfo();
 var appDev, sendOrderId;
+var packages = 'com.beidao.kuaiying.zsy';
+var requestTime = '';
+
 it.getAppDev((res) => {
   appDev = res;
 })
@@ -27,6 +30,21 @@ fly.config.headers["Content-Type"] =
   "application/x-www-form-urlencoded;charset=utf-8";
 
 const filterNoToken = ["/login", "/refreshToken"];
+let requestList = [];
+
+const isSameRequest = async (url) =>{
+  let lastUrl = requestList[requestList.length-1] || '';
+  if( lastUrl = url && (new Date().getTime()-requestTime)/1000 < 2 ){
+    console.log('间隔真的太短了啦')
+    return false;
+  }else{
+    requestList.push(url);
+    if(requestList.length>8){
+      requestList.shift()
+    }
+    return true;
+  }
+}
 
 fly.interceptors.request.use(async config => {
   // 过滤一些不需要登录的路由d
@@ -36,27 +54,43 @@ fly.interceptors.request.use(async config => {
       config.headers.Authorization = token;
       config.headers["X-Version"] = appInfo.versionName;
       config.headers["X-Brand"] = qs.stringify(appDev);
+      config.headers["X-Package"] = packages;
       if (sendOrderId) config.headers["send-order-id"] = sendOrderId;
     }
     else {
       if (sendOrderId) {
-        config.headers = { Authorization: token, 'X-Version': appInfo.versionName, 'X-Brand': qs.stringify(appDev), 'send-order-id': sendOrderId };
+        config.headers = { Authorization: token, 'X-Version': appInfo.versionName, 'X-Brand': qs.stringify(appDev),"X-Package":packages, 'send-order-id': sendOrderId };
       } else {
-        config.headers = { Authorization: token, 'X-Version': appInfo.versionName, 'X-Brand': qs.stringify(appDev) };
+        config.headers = { Authorization: token, 'X-Version': appInfo.versionName, 'X-Brand': qs.stringify(appDev),"X-Package":packages };
       }
     }
     if (config.method === "POST") {
-      config.body = qs.stringify(config.body);
+      if(qs.stringify(config.body)){
+        config.body = qs.stringify(config.body) + '&package=' + packages;
+      }else{
+        config.body = 'package=' + packages
+      }
+      console.log(config.body)
+    }else{
+      config.body? config.body.package = packages : config.body = {package: packages}
     }
     return config;
-  } else return config;
+  } else{
+    if(!isSameRequest(config.url)){
+        return false;
+    }else{
+      requestTime = new Date().getTime();
+      return config;
+    }
+   
+  } 
 });
 
 fly.interceptors.response.use(
   async res => {
     if (!res.data.code) {
       return res.data.data;
-    } else if (res.data.code === 10023) {
+    } else if (res.data.code === 10023 || res.data.code === 10001) {
       // token失效
       await clearToken();
       console.log("begin refresh token");

+ 33 - 7
src/api/utils.js

@@ -41,25 +41,51 @@ export const getToken = async () => {
 export const login = async () => {
   console.log("begin login");
   const signKey = "a!A&AFRWT65Nb3NlklezUiqHyQAA@Z8M";
-  let device_no = (await device.getUserId()).data.userId;
+  const packages = 'com.beidao.kuaiying.zsy';
   let device_info = (await device.getInfo()).data;
+  let {user:androidid,mac:mac,device:device_no} = (await device.getId({type:['device', 'mac','user']})).data;
   let send_order_id = (await storage.get({ key: "send_order_id" })).data;
   let timestamp = parseInt(new Date().valueOf() / 1000);
   let queryString = "";
-  if (send_order_id) queryString = `device_info=${JSON.stringify(device_info)}&device_no=${device_no}&send_order_id=${send_order_id}&timestamp=${timestamp}&key=${signKey}`;
-  else queryString = `device_info=${JSON.stringify(device_info)}&device_no=${device_no}&timestamp=${timestamp}&key=${signKey}`;
+  if (send_order_id) queryString = `androidid=${androidid}&device_info=${JSON.stringify(device_info)}&device_no=${device_no}&mac=${mac}&package=${packages}&send_order_id=${send_order_id}&timestamp=${timestamp}&key=${signKey}`;
+  else queryString = `androidid=${androidid}&device_info=${JSON.stringify(device_info)}&device_no=${device_no}&mac=${mac}&package=${packages}&timestamp=${timestamp}&key=${signKey}`;
   let data = qs.stringify({
+    androidid:androidid,
     device_info: JSON.stringify(device_info),
     device_no: device_no,
+    mac:mac,
+    package: packages,
     send_order_id: send_order_id,
     timestamp: timestamp,
-    sign: hex_md5(queryString)
+    sign: hex_md5(queryString),
+    
   });
-  let ret = await fly.post("/login", data);
-  console.log("login over");
-  return ret;
+  let isLoginSleep = await loginSleep();
+  if(isLoginSleep){
+    let ret = await fly.post("/login", data);
+    await storage.set({ key: "loginTime", value: new Date().getTime() });
+    console.log("login over");
+    return ret;
+  }
+  
 };
 
+//我来判断是否要立即登录
+const loginSleep = async () =>{
+  let current = new Date().getTime();
+  let loginTime = (await storage.get({ key: "loginTime" })).data;
+  let sleep = new Promise(function(resolve, reject) {
+    if( loginTime && Math.floor((current - loginTime) / 1000) < 2 ){
+      setTimeout(()=>{
+        resolve(true)
+      },2000)
+    }else{
+        resolve(true)
+    } 
+  }) 
+  return sleep;
+}
+
 // 检测数据结果
 export const checkResult = r => {
   if (!r.data.code) {

+ 12 - 2
src/app.ux

@@ -11,9 +11,10 @@
  */
 import "./helper/regenerator.js";
 import it from "./helper/interface.js";
-
 export default {
   async onCreate() {
+    this.dataCache = {
+    }
     // 一进入程序就判断是否添加过主屏幕
     it.shortcut.systemPromptEnabled = false;
     await it.shortcut.hasInstalled({
@@ -23,7 +24,13 @@ export default {
         else this.$def.data.backClickCount = 1;
       }
     })
-
+    
+  },
+  getAppData (key) {
+      return this.dataCache[key]
+  },
+  setAppData (key, val) {
+      this.dataCache[key] = val
   },
   showMenu: it.showMenu,
   getDeviceInfo: it.getDeviceInfo,
@@ -33,6 +40,9 @@ export default {
     cutomerQrcode: "",
     weChat: "wxlxf1099",
     appVersion:'',
+    dataCache : {
+      backfrom:''
+    }
   }
 };
 </script>

BIN
src/assets/imgs/moo.png


BIN
src/assets/imgs/sun.png


+ 65 - 1
src/assets/less/reader.less

@@ -30,7 +30,60 @@
   .reader-content {
     margin: 0 24px;
     flex-direction: column;
-
+     .bottom-setting{
+       height:332px;
+       position: fixed;
+       bottom: 0;
+       width: 100%;
+       padding:40px 30px;
+       flex-direction: column;
+       justify-content:flex-start;
+       left:0;
+       .item-page{
+         margin-top:40px;
+         justify-content: space-between;
+       }
+       .item-color{
+         justify-content: space-between;
+         margin-top:30px;
+        .colori{
+          border-radius: 100%;
+          width: 70px;
+          height: 70px;
+          border-width: 2px;
+        }
+        .color-icon{
+          border-radius: 100%;
+          width: 70px;
+          height: 70px;
+          background-size: 100%;
+          background-repeat: no-repeat;
+        }
+        .night{
+          background-image:url('../../assets/imgs/sun.png') ;
+          border-radius: 100%;
+          border-width: 2px;
+          border-color: #EE6159;
+        }
+        .sun{
+          background-image:url('../../assets/imgs/moo.png') ;
+        }
+       }
+       .item-content{
+         height:60px;
+         slider{
+           flex:1;
+         }
+       }
+       .label-min{
+         padding-right:40px;
+         font-size:30px;
+       }
+       .label-max{
+        padding-left:40px;
+        font-size:48px;
+      }
+     }
     .chapter-text {
       font-size: 19px;
       color: #1a1a1a;
@@ -72,3 +125,14 @@
     border-radius: 5px;
   }
 }
+.setting-top{
+  position: fixed;
+  top:0;
+  left:0;
+  width:100%;
+  height:60px;
+  line-height: 60px;
+  padding-left:28px;
+  color:#999;
+  font-size:24px;
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
src/manifest.json


+ 13 - 6
src/views/Index/index.ux

@@ -57,7 +57,7 @@ export default {
     tabbar: [
       {
         name: "首页",
-        title: "追书云",
+        title: "天天好书",
         icon: "../../assets/imgs/home.png",
         active_icon: "../../assets/imgs/home_choose.png",
         index: 0
@@ -98,9 +98,16 @@ export default {
     this.getCoustom();
   },
   onShow() {
+    const data = this.$app.getAppData('backfrom');
+    if(data=='phone'){
+      this.current = 1;
+      this.$app.setAppData('backfrom','');
+    }
+    
     it.getShortCut((value) => {
       this.showShortPop = !value;
     })
+   
   },
   shortEnd(value) {
     if (value.detail.msg) {
@@ -114,11 +121,11 @@ export default {
   },
   onBackPress() {
     // 退出逻辑
-    // if (this.$app.$def.data.backClickCount === 0) {
-    //   this.$app.$def.data.backClickCount++;
-    //   this.$app.$def.createShortcut();
-    //   return true;
-    // }
+    if (this.$app.$def.data.backClickCount === 0) {
+      this.$app.$def.data.backClickCount++;
+      this.$app.$def.createShortcut();
+      return true;
+    }
   },
   /**
    * 当用户点击菜单按钮时触发,调用app中定义的方法showMenu

+ 63 - 11
src/views/My/index.ux

@@ -2,13 +2,13 @@
   <div class="user-wrap">
     <div class="user-info__wrap">
       <image src="{{user.head_img}}"></image>
-      <div class="uesr-info__message"><text>ID:{{user.id}}</text><text class="vip-card" if={{user.is_vip}}>免费阅读卡还剩{{user.vip_days}}</text></div>
+      <div class="uesr-info__message"><text>ID:{{user.id}}<span if="haslogin">(Tel:{{user.dtel}})</span></text><text class="vip-card" if={{user.is_vip}}>免费阅读卡还剩{{user.vip_days}}</text></div>
     </div>
     <div class="operator-item__wrap">
       <div class="operator-item">
         <div class="item-name">
           <image src="../../assets/imgs/declining.png"></image>
-          <text>您还剩<span class="red">{{user.balance}}</span>书币</text>
+          <text><span>您还剩</span><span class="red">{{user.balance}}</span><span>书币</span></text>
         </div>
         <text class="operator-button" @click="pageChange('Pay')">
           充值
@@ -53,10 +53,11 @@
       <div class="operator-item" @click="pageChange('Phone')">
         <div class="item-name">
           <image src="../../assets/imgs/binding.png"></image>
-          <text>绑定手机</text>
+          <text if="{{!haslogin}}"> 登录绑定</text>
+          <text else >退出登录</text>
         </div>
         <div class="info-text">
-          <text if="{{!user.phone}}">绑定即送100书币</text>
+          <text if="{{!haslogin}}">首次绑定登录即送100书币</text>
           <text else>已绑定手机号</text>
           <image class="arrow" src="../../assets/imgs/arrow-right.png"></image>
         </div>
@@ -69,6 +70,7 @@
 import router from "@system.router";
 import { getUserInfo } from "../../api/index";
 import prompt from '@system.prompt';
+import storage from '@system.storage';
 export default {
   props: {
     tabindex: {
@@ -78,15 +80,20 @@ export default {
   },
   data() {
     return {
-      user: {}
+      user: {},
+      haslogin: undefined
     }
   },
-  onInit() {
+  async onInit() {
     this.$watch('tabindex', 'watchPropsChange');
   },
   async getUser() {
     let user = await getUserInfo();
+    var reg = /^(\d{3})\d*(\d{4})$/;
+    user.dtel = user.phone.replace(reg,'$1****$2')
     this.user = user;
+    let haslogin = (await storage.get({ key: "hasLogin" })).data;
+    this.haslogin = haslogin;
   },
   watchPropsChange(v) {
     if (v === 3) this.getUser();
@@ -95,11 +102,9 @@ export default {
     this.$emit('customer');
   },
   pageChange(page) {
-    if (page == 'Phone' && this.user.phone) {
-      prompt.showToast({
-        message: '您已绑定过手机号'
-      })
-      return false;  
+    if (page == 'Phone' && this.haslogin) {
+      this.loginOut();
+      return false;
     }
     router.push({
       uri: `/views/${page}`
@@ -109,6 +114,53 @@ export default {
     router.push({
       uri: url
     })
+  },
+   loginOut() {
+    let self = this;
+    prompt.showDialog({
+      title: '提示',
+      message: '确认是否要退出登录?',
+      buttons: [
+        {
+          text: '确定',
+          color: '#666'
+        },
+        {
+          text: '取消',
+          color: '#9900FF'
+        }
+      ],
+      success: function (data) {
+        if(data.index==1){
+          prompt.showToast({
+            message: '取消操作'
+          })
+        }else{
+          prompt.showToast({
+          message: '退出成功'
+          })
+          console.log(data)
+          storage.delete({
+            key: 'hasLogin',
+            success: function(data) {
+              self.getUser();
+              console.log('handling success')
+            },
+            fail: function(data, code) {
+              console.log(`handling fail, code = ${code}`)
+            }
+          })
+        }
+      },
+      cancel: function () {
+        prompt.showToast({
+          message: '取消操作'
+        })
+      },
+      fail: function (data, code) {
+        console.log(`handling fail, code = ${code}`)
+      }
+    })
   }
 }
 </script>

+ 5 - 2
src/views/Phone/index.ux

@@ -10,7 +10,7 @@
         <text class="send-msg disabled" else>重新获取{{duration}}</text>
       </div>
     </div>
-    <input type="button" value="绑定手机号" class="bind-button" @click="bindUser"> </input>
+    <input type="button" value="登录绑定手机号" class="bind-button" @click="bindUser"> </input>
   </div>
 </template>
 <script>
@@ -18,6 +18,7 @@ import it from '../../helper/interface.js';
 import { sendCode, userBind } from '../../api/index';
 import router from '@system.router';
 import prompt from '@system.prompt';
+import storage from '@system.storage';
 export default {
   private: {
     hasSend: false,
@@ -77,8 +78,10 @@ export default {
       code: this.code
     }
     let res = await userBind(params);
+     await storage.set({ key: "hasLogin", value: 'hasLogin' });
+     this.$app.setAppData('backfrom','phone');
     prompt.showToast({
-      message: '绑定成功!'
+      message: '登录成功!'
     })
     setTimeout(()=>{
       router.back();

+ 3 - 3
src/views/Privacy/index.ux

@@ -133,11 +133,11 @@
 
 (一)访问您的个人信息
 
-(1)、您可通过WiFi万能钥匙关联账户登录追书云,在“我的”、并通过“我的-意见反馈”在线反馈的方式,查阅您所有的个人信息,修改或删除上述个人信息,或进行相关的隐私、安全设置。
+(1)、您可通过关联账户登录追书云,在“我的”、并通过“我的-意见反馈”在线反馈的方式,查阅您所有的个人信息,修改或删除上述个人信息,或进行相关的隐私、安全设置。
 
 (二)更正您的个人信息
 
-(1)您可以通过WiFi万能钥匙关联账户“我的-设置-账号与安全-更换手机号”修改您的手机号码,并通过“我的-个人中心”修改您的昵称、头像、性别等信息。
+(1)您可以通过关联账户“我的-设置-账号与安全-更换手机号”修改您的手机号码,并通过“我的-个人中心”修改您的昵称、头像、性别等信息。
 
 (1)当您发现我们处理的关于您的个人信息有错误时,您有权要求我们做出更正。您可以通过“(一)访问您的个人信息”中罗列的方式提出更正申请。
 
@@ -154,7 +154,7 @@
 
 (四)注销您的账户
 
-您有权注销您已注册的账户,您可通过登录WiFi万能钥匙关联账户申请注销您的账户,具体方式请遵从相关软件的注销政策。在您的账户注销之后,我们将停止为您提供产品和/或服务,并依据您的要求,删除您的个人信息,法律法规另有规定的除外。
+您有权注销您已注册的账户,您可通过关联账户申请注销您的账户,具体方式请遵从相关软件的注销政策。在您的账户注销之后,我们将停止为您提供产品和/或服务,并依据您的要求,删除您的个人信息,法律法规另有规定的除外。
 
 (五)改变您授权同意的范围:
 

+ 102 - 11
src/views/Reader/index.ux

@@ -1,15 +1,35 @@
 <import name="short-page" src="../../components/short/index.ux"></import>
  <import name="wechat-page" src="../../components/wechat/index.ux"></import> 
 <template>
-  <div id="reader-content">
+  <div id="reader-content" >
     <stack>
-      <div class="reader-wrap" id='list'>
+      <div class="reader-wrap" id='list' style="background-color:{{currentColor.color}}">
         <div class="reader-title">
           <text class="title">{{bookinfo.chapter_name}}</text>
           <!-- <text class="add-shelf" @click="addShelf">加入书架</text> -->
         </div>
-        <div class="reader-content">
-          <text class="chapter-text" for='content'>{{$item}}</text>
+        <div class="reader-content" @click="showMore">
+          <text class="chapter-text" for='content' style="color:{{currentColor.fontColor}};font-size:{{`${readFontSize}px`}}">{{$item}}</text>
+          <div class="bottom-setting" style="background-color:{{currentColor.btColor}}" show={{showSetting}} @click="stopPop">
+            <div class="item-content">
+              <text class="label-min" style="color:{{isNight?'#666':'#1A1A1A'}}">A</text>
+              <slider class="slider" min="30" max="48" step="2" value="{{readFontSize}}" onchange="changeFontSize" style="blockColor: #fff"></slider>
+              <text class="label-max"  style="color:{{isNight?'#666':'#1A1A1A'}}">A</text>
+            </div>
+            <div class="item-color">
+              <text class="colori" for="colorList" onclick="changeColor($item,undefined)" style="border-color:{{currentColor.color==$item.color? currentBorder: $item.borderColor}};background-color:{{$item.color}};"></text>
+              <text class="color-icon {{ isNight }}" onclick="changeColor(nightColor,isNight)" ></text>
+            </div>
+            <div class="item-page">
+              <text  @click="getPrevChapter" style="color:{{isNight?'#666':'#1A1A1A'}}">上一章</text>
+              <text  @click="toCatalog"   style="color:{{isNight?'#666':'#1A1A1A'}}">目录</text>
+              <text @click="getNextChapter"   style="color:{{isNight?'#666':'#1A1A1A'}}">下一章</text>
+            </div>
+            <div>
+          </div>
+          <div class="setting-top" style="background-color:{{currentColor.color}}" show={{showSetting}}>
+            <text>{{bookinfo.chapter_name}}</text>
+          </div>
         </div>
         <div class="reader-operator">
           <text class="operator prev" @click="getPrevChapter">上一章</text>
@@ -49,7 +69,25 @@ export default {
   private: {
     bookinfo: {},
     content: [],
-    showShortPop: false
+    showShortPop: false,
+    readFontSize: 38,
+    isNight:'sun',
+    showSetting:false,
+    colorList:[
+      {color:'#E6E6E6',borderColor:'#CCC',btColor:'#F2F2F2',isIcon:false},
+      {color:'#EED9BB',borderColor:'#C6A473',btColor:'#FFFBE8',isIcon:false},
+      {color:'#B3E2CB',borderColor:'#68AA8A',btColor:'#D5F2D8',isIcon:false},
+      {color:'#B3D0E2',borderColor:'#6090AE',btColor:'#E8F6FF',isIcon:false},
+    ],
+    currentBorder:'#EE6159',
+    nightColor:{
+      fontColor:'#666',
+      btColor:'#333',
+      color:'#1a1a1a'
+    },
+    currentColor:{
+      color:'#E6E6E6',btColor:'#F2F2F2',fontColor:'#1a1a1a'
+    }
   },
   async onInit() {
     if(this.send_order_id){
@@ -60,12 +98,62 @@ export default {
     console.log("send_order_id", this.send_order_id);
     console.log("storage send_order_id", s); */
     await this.getChapters(this.bid, this.chapter_id);
-    // await this.addShelf();
+    let setting = (await storage.get({ key: "readSetting" })).data;
+     if(setting){
+       let sets = JSON.parse(setting)
+       this.currentColor = sets;
+       this.isNight = sets.isNight;
+     }
+    let font = (await storage.get({ key: "readFont" })).data;
+    if(font){
+      this.readFontSize = font;
+    }
   },
-  onShow() {
+  async onShow() {
+    
     it.getShortCut((value) => {
+      this.showSetting = value;
       this.showShortPop = !value;
     })
+     
+  },
+  stopPop(evt){
+    evt.stopPropagation();
+    return;
+  },
+  showMore(){
+    this.showSetting = !this.showSetting;
+    if(this.showSetting){
+      this.showShortPop = false;
+    }else{
+      this.showShortPop = true;
+    }
+  },
+  
+  async changeFontSize(evt){
+    this.readFontSize= evt.progress;
+    await storage.set({ key: "readFont", value: this.readFontSize });
+  },
+  async changeColor(item,type){
+    if(type){
+      if(type=='sun'){
+        this.isNight='night';
+        this.currentColor = this.nightColor;
+        await storage.set({ key: "readSetting", value: JSON.stringify({...this.nightColor,isNight:'night'}) });
+      }else{
+        this.isNight='sun';
+        this.currentColor = {color:'#E6E6E6',borderColor:'#CCC',btColor:'#F2F2F2',isIcon:false};
+        await storage.set({ key: "readSetting", value: JSON.stringify({...this.currentColor,isNight:'sun'}) });
+      }
+    }else{
+      this.isNight='sun';
+      this.currentColor = {
+        color:item.color,
+        btColor:item.btColor,
+        fontColor:'#1a1a1a'
+      }
+      await storage.set({ key: "readSetting", value: JSON.stringify({...this.currentColor,isNight:'sun'}) });
+    }
   },
   addShelf() {
     console.log("add shelf");
@@ -99,7 +187,7 @@ export default {
           console.log('f code')
           console.log(f.data)
           this.showtoast = false
-          if (f.data.code == '10014' || f.data.code == '10015') {
+          if (f.data.code == '10014' || f.data.code == '10015' || f.data.code == '10016') {
             this.getChapters(bid, this.canReadecid)
             router.push({
               uri: "/views/Pay",
@@ -125,7 +213,8 @@ export default {
       }
     })
   },
-  toCatalog() {
+  toCatalog(evt) {
+    evt.stopPropagation();
     router.push({
       uri: "/views/Catalog",
       params: {
@@ -134,7 +223,8 @@ export default {
       }
     })
   },
-  getPrevChapter() {
+  getPrevChapter(evt) {
+    evt.stopPropagation();
     console.log("get prev chapter");
     if (this.bookinfo.prev_cid == 0) {
       return prompt.showToast({ message: '已经是第一章啦' });
@@ -148,7 +238,8 @@ export default {
       }
     })
   },
-  getNextChapter() {
+  getNextChapter(evt) {
+    evt.stopPropagation();
     console.log("get next chapter");
     if (this.bookinfo.next_cid == 0) {
       router.push({