shenwu 7 месяцев назад
Родитель
Сommit
878d540f4d

+ 3 - 1
src/Hook/useApi.ts

@@ -1,4 +1,4 @@
-import { getShortBookInfoAppListOfPage } from '@src/server/book/short'
+import { getParagraphList, getShortBookInfoAppListOfPage } from '@src/server/book/short'
 /**用于长短篇小说区别,使用不同的接口*/
 function useApi(store) {
     //判断是长篇
@@ -6,6 +6,8 @@ function useApi(store) {
     return {
         /**获取小说列表*/
         getBookPageList: isLong ? getShortBookInfoAppListOfPage : getShortBookInfoAppListOfPage,
+        /**获取小说内容*/
+        getBookContent: isLong ? getParagraphList : getParagraphList,
     }
 
 }

+ 1 - 1
src/app.config.ts

@@ -11,7 +11,7 @@ export default {
     // 'pages/contactus/index',//联系客服
     // 'pages/bookCatalog/index',//书籍目录
     // 'pages/aboutWe/index',//关于我们
-    // 'pages/book/bookArticle/index',//书籍内容 阅读页
+    'pages/book/bookArticle/index',//书籍内容 阅读页
     // 'pages/search/index',//搜索
     // 'pages/indexMore/index', // 更多
     // 'pages/book/bookDetails1/index',//书籍详情

+ 7 - 10
src/app.tsx

@@ -21,7 +21,7 @@ export interface Store {
   userInfo: any,
   indexStore: any,
   bookStore: BookStore,
-  classifyStore:ClassifyStore,
+  classifyStore: ClassifyStore,
 }
 const store: Store = {
   userInfo,
@@ -45,20 +45,17 @@ class App extends Component {
     /**获取状态栏高度 */
     Taro.getSystemInfo({}).then(res => {
       let { system, statusBarHeight } = res
-      indexStore.SET_SYSTEM(system || '')
-      indexStore.SET_NAVBARTOP(statusBarHeight || 0)
+      indexStore.setData({ navBarTop: statusBarHeight, system })//设置navbar高度和当前系统
       setApp({ system })
     })
   }
   async componentDidShow(options) {
-    let { scene } = options//获取当前小程序进入的场景值
-    indexStore.SET_SCENE(scene)
-    if (JSON.stringify(options.query) !== "{}") {
-      let keys = Object.keys(options.query)
-      if (keys?.indexOf('share_sources') !== -1) {
-        indexStore.SET_SHARESOURCES(options.query.share_sources)
-      }
+    let { scene,query } = options//获取当前小程序进入的场景值
+    let bookConfig = Taro.getStorageSync("bookConfig")
+    if (bookConfig) {
+      Book.setData({ bookConfig: JSON.parse(bookConfig) })
     }
+    indexStore.setData({ scene ,query})
   }
   componentDidHide() { }
 

+ 3 - 3
src/components/PupPetry/BookTypeTabs/index.tsx

@@ -17,15 +17,15 @@ type props = {
 }
 
 
-
+/**分类页面顶部分类选择*/ 
 const BookTypeTabs = (props: props) => {
     let { typeValue, typeTabIndex, workDirection } = props
     let [open, setOpen] = useState<boolean>(false)
-
+    //选择
     let selectHandle = useCallback((value: {id:number,name:string}) => {
         classifyStore.setData({ categoryId: value })
     }, [])
-
+    //展示更多
     let openHandle = useCallback(() => {
         setOpen(!open)
     }, [open])

+ 2 - 0
src/components/TopNavBar/index.less

@@ -179,9 +179,11 @@
                 text-overflow: ellipsis;
                 overflow: hidden;
                 font-size: 36px;
+                width: 100rpx;
                 font-family: PingFangSC-Medium, PingFang SC;
                 font-weight: 500;
                 color: #333333;
+                display: inline-block;
             }
         }
     }

+ 21 - 15
src/components/TopNavBar/index.tsx

@@ -1,11 +1,12 @@
 
-import { View, Text, Image, Navigator } from '@tarojs/components'
+import { View, Text, Image } from '@tarojs/components'
 import './index.less'
 import Taro from '@tarojs/taro'
 import { Component } from 'react';
 import searchPng from '../../icon/search.png'
 import { observer, inject } from 'mobx-react'
 import { BookStore } from '@src/store/book';
+import indexStore from '@src/store/index';
 /**顶部自定义导航
  * 
  */
@@ -26,22 +27,17 @@ type Props = {
     isToBack?: boolean,                 // 是否可返回上一页
     zxTitle?: string,                   // 资讯头
     lastRead?: boolean,                 // 是否展示上次阅读
+    isReloadBook?: boolean //是否阅读小说,小说展示小说名称
 }
 
 
 function CustomNavbar(WrappedComponent, props: Props) {
-    let { children, title, color, fontSize, backgroundColor, tab = false, tabVal, tabSelect = "", search = false, searchBack = false, isToBack = false, zxTitle = "", lastRead = false } = props
-    log(zxTitle);
-
+    let { children, title, color, fontSize, backgroundColor, tab = false, tabVal, search = false, searchBack = false, isToBack = false, isReloadBook = false } = props
     interface Page {
         props: {
             store: {
                 indexStore: {
                     navBarTop: number,
-                    openType: number,
-                    isLastRead: boolean,
-                    SET_ISLASTREAD: Function,
-                    lastReadLog: any
                 },
                 bookStore: BookStore
             },
@@ -64,16 +60,26 @@ function CustomNavbar(WrappedComponent, props: Props) {
             let buttonBounding = Taro.getMenuButtonBoundingClientRect()
             log(buttonBounding);
             let { height, top, width } = buttonBounding
-            this.setState({ capsuleWidth: width + 10, navBar: (top - navBarTop) * 2 + height + 8, navBarTop })
+            console.log("navBarTop", top, navBarTop)
+            let navBar = (top - navBarTop) * 2 + height + 8
+            this.setState({ capsuleWidth: width + 10, navBar, navBarTop })
+            indexStore.setData({ navHeight: navBar + navBarTop + 5 })
         }
 
         selectHandle = (value: string | number) => {
             this.props.store.bookStore.setWorkDirection(value as 0 | 1)
         }
-
+        //回上级
         gotoBack = () => {
             Taro.navigateBack()
         }
+        //回主页
+        gotoHome = () => {
+            Taro.switchTab({
+                url: '/pages/index/index'
+            })
+        }
+        // 去搜索页面
         searchBackHandle = () => {
             Taro.navigateTo({
                 url: '/pages/search/index'
@@ -87,6 +93,7 @@ function CustomNavbar(WrappedComponent, props: Props) {
                 log(buttonBounding);
                 let { height, top, width } = buttonBounding
                 this.setState({ capsuleWidth: width + 10, navBar: (top - newNavBarTop) * 2 + height + 8, navBarTop: newNavBarTop })
+
             }
             if (props.store.indexStore.openType === 1) {
                 log(123321);
@@ -97,11 +104,10 @@ function CustomNavbar(WrappedComponent, props: Props) {
         render() {
             const { extraProp, ...passThroughProps } = this.props
             let { navBar, capsuleWidth } = this.state
-            const { indexStore: { navBarTop, openType, },bookStore } = this.props.store
+            const { indexStore: { navBarTop }, bookStore } = this.props.store
             let stateIndex = bookStore.workDirection
-            console.log("stateIndex",stateIndex)
             return <View style={{ height: navBar + navBarTop + 5 }}>
-                <View className='navbarWrap' style={{ paddingTop: navBarTop, height: navBar, backgroundColor: backgroundColor ? backgroundColor : "#FFFFFF" }}>
+                <View className='navbarWrap' style={{ paddingTop: navBarTop + 5, height: navBar, backgroundColor: isReloadBook ? bookStore.bookConfig?.off_on ? "#FFF" : "#000" : "#FFF" }}>
                     <View className='content'>
                         {
                             tab ? <View className="navbar">
@@ -134,13 +140,13 @@ function CustomNavbar(WrappedComponent, props: Props) {
                                                         <Image src={require('../../icon/backBlock.png')} className="searchImg" onClick={() => { }} />
                                                     </View>
                                                     <View className="line" style={{ backgroundColor: color === '#fff' ? '#e9e9e9' : '#e9e9e9' }}></View>
-                                                    <View onClick={() => { }} className="homebt">
+                                                    <View onClick={this.gotoHome} className="homebt">
                                                         <Image src={require('../../icon/homeBlock.png')} className="searchImg" onClick={() => { }} mode='widthFix' />
                                                     </View>
                                                 </View>
                                             </View>
                                         }
-                                        <View className="txt" style={{ color: color ? color : "#333333" }}>{title}</View>
+                                        <View className="txt" style={{ color: color ? color : "#333333", textAlign: isReloadBook ? 'center' : "unset" }}>{isReloadBook ? bookStore.openBookData?.bookName : title}</View>
                                     </View>
                         }
                     </View>

+ 233 - 0
src/components/bookConfigPup/index.less

@@ -0,0 +1,233 @@
+@import "../../globaStyle.less";
+.bottom_pup {
+  width: 750px;
+  height: 520px;
+  background: #ffffff;
+  border-radius: 30px 20px 0px 0px;
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  display: flex;
+  flex-flow: column nowrap;
+  align-items: center;
+  padding-top: 46px;
+  box-sizing: border-box;
+  .bg {
+    .b {
+      background: #f5f6f7;
+      margin-right: 20px;
+    }
+    .h {
+      background: #f5f6ee;
+      margin-right: 20px;
+    }
+    .l {
+      background: #d6e4cc;
+      margin-right: 20px;
+    }
+    .hh {
+      background: url(../../icon/hh.png) no-repeat;
+      background-size: 100% 100%;
+    }
+  }
+  .bg,
+  .size,
+  .lh {
+    height: 70px;
+    margin-bottom: 50px;
+    display: flex;
+    flex-flow: row nowrap;
+    justify-content: space-between;
+    align-items: center;
+    width: 690px;
+    // 文本
+    .txt {
+      width: 60px;
+      height: 40px;
+      font-size: @fs_28;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: @fw_400;
+      color: @cl_666;
+      line-height: 40px;
+    }
+    // 背景色按钮
+    .b,
+    .h,
+    .l,
+    .hh {
+      width: 134px;
+      height: 70px;
+      border-radius: 35px;
+      box-sizing: border-box;
+    }
+    // 按钮通用
+    .btn {
+      display: flex;
+    }
+    // 选中按钮
+    .action {
+      border: 2px solid #999999 !important;
+    }
+    // 字体按钮通用
+    .small,
+    .big {
+      width: 248px;
+      height: 70px;
+      border-radius: 35px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      background: #f5f6f7;
+      color: #333333;
+      position: relative;
+      &::after {
+        background: transparent;
+        font-size: 20px;
+        left: 134px;
+        top: 10px;
+        position: absolute;
+      }
+    }
+    //缩小字体
+    .small {
+      &::after {
+        content: "-";
+      }
+    }
+    //放大字体
+    .big {
+      &::after {
+        content: "+";
+      }
+    }
+    // 字体到最大或最小白色浅色
+    .small.b_q,
+    .big.b_q {
+      background: #fbfbfb;
+      color: #ececec;
+    }
+    // 字体大小数字
+    .number {
+      height: 70px;
+      line-height: 70px;
+      margin: 0 30px;
+    }
+    // 间距按钮通用
+    .x,
+    .z,
+    .d {
+      width: 176px;
+      height: 70px;
+      border-radius: 35px;
+      display: flex;
+      align-items: center;
+      flex-flow: column nowrap;
+      justify-content: center;
+      border: 2px solid #e9e9e9;
+      text {
+        width: 38px;
+        height: 4px;
+        background: #999999;
+        border-radius: 2px;
+        &:last-child {
+          margin-bottom: 0;
+        }
+      }
+    }
+    .x {
+      margin-right: 32px;
+      text {
+        margin-bottom: 8px;
+      }
+    }
+    .z {
+      margin-right: 32px;
+      text {
+        margin-bottom: 8px;
+      }
+    }
+    .d {
+      text {
+        margin-bottom: 14px;
+      }
+    }
+  }
+  .xx {
+    width: 750px;
+    height: 2px;
+    background: #eeeeee;
+    margin-bottom: 12px;
+  }
+  .cd {
+    height: 108px;
+    width: 100%;
+    display: flex;
+    flex-flow: row nowrap;
+    justify-content: space-around;
+    view {
+      display: flex;
+      flex-flow: column nowrap;
+      align-items: center;
+      justify-content: center;
+    }
+    image {
+      width: 56px;
+      height: 56px;
+    }
+    text {
+      width: 48px;
+      height: 34px;
+      font-size: 24px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #999999;
+      line-height: 34px;
+    }
+  }
+}
+.bottom_pup.black {
+  background: #444546;
+  .bg {
+    .hh {
+      background: url(../../icon/bt.png) no-repeat;
+      background-size: 100% 100%;
+    }
+  }
+  .bg,
+  .size,
+  .lh {
+    text {
+      color: #898a8b;
+    }
+  }
+  .xx {
+    background: #505050;
+  }
+  .cd {
+    text {
+      color: #666666;
+    }
+  }
+  .size {
+    .number {
+      color: #686868;
+    }
+    .small,
+    .big {
+      background: #535353;
+      color: #9c9c9c;
+    }
+    // 字体到最大或最小黑色浅色
+    .small.b_q,
+    .big.b_q {
+      background: #3c3c3c;
+      color: #484848;
+    }
+  }
+  // 间距按钮通用
+  .x,
+  .z,
+  .d {
+    border: 2px solid #535353;
+  }
+}

+ 69 - 0
src/components/bookConfigPup/index.tsx

@@ -0,0 +1,69 @@
+import { View, Text, Image, Navigator } from "@tarojs/components";
+import React from "react";
+import './index.less';
+import appInfoStore from "@src/store/appInfo";
+interface BookConfigPupProps {
+    setOff: () => void,//设置开关
+    setSize: (num: number) => void,//设置字体
+    setLh: (str: string) => void,//设置行高
+    setBg: (str: string) => void,//设置背景
+    size: string,
+    off_on: boolean,
+    bg: string,
+    lh: string,
+    booKId?: number, // 书ID
+    chapter?: number  // 章节ID
+}
+function BookConfigPuP(props: BookConfigPupProps) {
+    let { setOff, setSize, setLh, setBg, size, off_on, bg, lh, booKId, chapter } = props
+    let isLong = appInfoStore?.appInfo?.appCategory === 1
+    size = size?.split('_')[1]
+    return <View className={off_on ? 'bottom_pup' : 'bottom_pup black'}>
+        <View className='bg'>
+            <Text className='txt'>背景</Text>
+            <View className='btn'>
+                <Text className={`b ${bg === 'bg_b' && off_on ? 'action' : ''}`} onClick={() => setBg('bg_b')} />
+                <Text className={`h ${bg === 'bg_h' && off_on ? 'action' : ''}`} onClick={() => setBg('bg_h')} />
+                <Text className={`l ${bg === 'bg_l' && off_on ? 'action' : ''}`} onClick={() => setBg('bg_l')} />
+                <Text className={`hh`} onClick={setOff} />
+            </View>
+        </View>
+        <View className='size'>
+            <Text className='txt'>字号</Text>
+            <View className='btn'>
+                <Text className={`small ${size === '15' ? 'b_q' : ''}`} onClick={() => { size !== '15' && setSize(0) }}>A</Text>
+                <Text className='number'>{size}</Text>
+                <Text className={`big ${size === '29' ? 'b_q' : ''}`} onClick={() => { size !== '29' && setSize(1) }}>A</Text>
+            </View>
+        </View>
+        <View className='lh'>
+            <Text className='txt'>间距</Text>
+            <View className='btn'>
+                <View className={`x ${lh === 'lh_72' ? 'action' : ''}`} onClick={() => setLh('lh_72')}>
+                    <Text />
+                    <Text />
+                    <Text />
+                    <Text />
+                </View>
+                <View className={`z ${lh === 'lh_84' ? 'action' : ''}`} onClick={() => setLh('lh_84')}>
+                    <Text />
+                    <Text />
+                    <Text />
+                </View>
+                <View className={`d ${lh === 'lh_96' ? 'action' : ''}`} onClick={() => setLh('lh_96')}>
+                    <Text />
+                    <Text />
+                </View>
+            </View>
+        </View>
+        <View className='xx' />
+        <View className='cd' >
+            <Navigator url='/pages/index/index' openType='switchTab' hoverClass="none"><View><Image src={require('../../icon/sc_h.png')} /> <Text>书城</Text></View></Navigator>
+            <Navigator url={`/pages/book/bookDetails/index?book_id=${booKId}`} hoverClass="none"> <View><Image src={require('../../icon/xq_h.png')} /> <Text>详情</Text></View></Navigator>
+            {/* 长篇小说展示目录按钮 */}
+            {isLong && <Navigator url={`/pages/bookCatalog/index?id=${booKId}&chapter=${chapter}`} hoverClass="none">  <View><Image src={require('../../icon/ml_h.png')} /> <Text>目录</Text></View></Navigator>}
+        </View>
+    </View>
+}
+
+export default React.memo(BookConfigPuP)

+ 6 - 3
src/interceptor.ts

@@ -20,7 +20,7 @@ const requestInterceptor = (chain) => {
         Taro.showLoading({ title: "加载中..." })
     }
     const requestParams = chain.requestParams;
-    requestParams.url = app.apiUrl + requestParams.url
+    requestParams.url = requestParams.url?.match(/^http[s]?:\/\//ig) ? requestParams.url : app.apiUrl + requestParams.url
     // 是登录接口token换成inittoken
     let token = requestParams.url.match(/(\/jsCodeLogin)|(\/appComponent\/list)/ig) ? app.initToken : app.token
     log("请求前拦截", token)
@@ -29,7 +29,7 @@ const requestInterceptor = (chain) => {
         // 打印日志或执行一些清理操作
         console.log("Token 无效,取消请求");
         // 返回一个被拒绝的Promise以中断请求
-        return new Promise(() => {});
+        return new Promise(() => { });
     }
     // 处理参数
     if (requestParams.data?.workDirection) {
@@ -43,7 +43,7 @@ const requestInterceptor = (chain) => {
     if (requestParams.url.includes('/app/bookCategory/list')) {
         if (requestParams.data.workDirection === bookStore.oldWorkDirection) {
             log("阻止参数不变获取分类")
-            return new Promise(() => {});
+            return new Promise(() => { });
         } else {
             //赋值本次的请求
             bookStore.setData({ oldWorkDirection: requestParams.data.workDirection })
@@ -77,6 +77,9 @@ const responseInterceptor = (chain) => {
                 log("token过期,重新登录", data)
                 setApp({ token: "" })
                 await api.loginInit(app.appId)
+                // 重新执行当前请求
+                const newRequestParams = chain.requestParams;
+                // return Taro.request(newRequestParams).then(newResponse => newResponse.data);
                 break;
             default:
                 log("未知错误", data)

+ 4 - 0
src/pages/book/BookArticle/index.config.ts

@@ -0,0 +1,4 @@
+export default {
+  navigationBarTitleText: '首页',
+  navigationStyle: 'custom',
+}

+ 653 - 0
src/pages/book/BookArticle/index.less

@@ -0,0 +1,653 @@
+@import "../../../globaStyle.less";
+.indexAd{
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+  border-radius: 20px;
+  overflow: hidden;
+}
+.book_article {
+  width: 100%;
+  padding: 30px 30px 50px;
+  box-sizing: border-box;
+  min-height: 100vh;
+  display: flex;
+  flex-direction: column;
+  .addBean{
+    position: fixed;
+    width: 90px;
+    height: 44px;
+    right: 30px;
+    top: 130px;
+    background: rgba(0, 0, 0, .79);
+    border-radius: 22px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 24px;
+    font-family: PingFangSC-Medium, PingFang SC;
+    font-weight: 500;
+    color: #FFFFFF;
+    &>image {
+      width: 28px;
+      height: 28px;
+      margin-left: 5px;
+      margin-top: 5px;
+    }
+  }
+  .myBead{
+    position: fixed;
+    top: 208px;
+    right: -182px;
+    width: 248px;
+    height: 84px;
+    background: #FF415B;
+    box-shadow: 0px 4px 8px 0px rgba(255, 110, 124, 0.58);
+    border-radius: 200px 0px 0px 200px;
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    transition: all 1s ease-in 0s;
+    font-size: 28px;
+    font-family: PingFangSC-Medium, PingFang SC;
+    font-weight: 500;
+    color: #FFFFFF;
+    &>image {
+      width: 58px;
+      height: 58px;
+      margin: 13px 0 13px 13px;
+    }
+    &>text{
+      margin-left: 6px;
+    }
+  }
+  .unlockingModel{
+    position: fixed;
+    width: 100%;
+    height: 100vh;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    z-index: 50;
+    display: none;
+    .back {
+      position: absolute;
+      top: 0;
+      left: 0;
+      bottom: 0;
+      right: 0;
+      background-color: rgba(85, 85, 85, .35);
+    }
+    .con{
+      width: 654px;
+      height: 390px;
+      background: #FFFFFF;
+      border-radius: 30px;
+      position: absolute;
+      z-index: 2;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      padding: 60px 0;
+      box-sizing: border-box;
+      .title{
+        font-size: 44px;
+        font-family: PingFangSC-Medium, PingFang SC;
+        font-weight: 600;
+        color: #4F88E3;
+        text-align: center;
+        margin-bottom: 36px;
+      }
+      .ts{
+        font-size: 36px;
+        font-family: PingFangSC-Regular, PingFang SC;
+        font-weight: 400;
+        color: #333333;
+        text-align: center;
+        margin-bottom: 42px;
+      }
+      .bt{
+        width: 334px;
+        height: 80px;
+        background: #4F88E3;
+        border-radius: 40px;
+        margin: 0 auto;
+        color: #FFFFFF;
+        text-align: center;
+        line-height: 80px;
+      }
+    }
+  }
+  .header {
+    margin-bottom: 44px;
+    .up {
+      width: 120px;
+      height: 56px;
+      font-size: @fs_40;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: @fw_400;
+      color: @cl_6E9;
+      line-height: 56px;
+      margin-bottom: 36px;
+    }
+    .bt {
+      .title {
+        width: 100%;
+        height: 60px;
+        font-size: @fs_44;
+        font-family: PingFangSC-Regular, PingFang SC;
+        font-weight: @fw_400;
+        line-height: 60px;
+        &:nth-child(1) {
+          margin-right: 46px;
+        }
+      }
+    }
+    .btns {
+      display: flex;
+      flex-flow: row nowrap;
+      justify-content: space-between;
+      margin-bottom: 30px;
+      .left {
+        width: 186px;
+        height: 52px;
+        border-radius: @r_26;
+        border: 2px solid #949bab;
+        position: relative;
+        line-height: 52px;
+        &::before {
+          content: "";
+          height: 52px;
+          width: 2px;
+          background: @bg_94;
+          opacity: 0.24;
+          position: absolute;
+          top: 0;
+          left: 50%;
+          transform: translateX(-50%);
+        }
+        text {
+          width: 50%;
+          float: left;
+          text-align: center;
+          font-size: @fs_28;
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: @fw_400;
+          color: @cl_94;
+        }
+      }
+      .right {
+        text {
+          width: 128px;
+          height: 52px;
+          border-radius: @r_26;
+          border: 2px solid #949bab;
+          float: left;
+          line-height: 52px;
+          text-align: center;
+          font-size: @fs_28;
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: @fw_400;
+          color: @cl_94;
+          &:nth-child(1) {
+            margin-right: 30px;
+          }
+        }
+      }
+    }
+  }
+  .centent{
+    flex: 1;
+
+    // .cententMarginTop{
+    //   margin-top: 20px;
+    // }
+    // .cententMarginBottom{
+    //   margin-bottom: 20px;
+    // }
+  }
+  .pre {
+    display: block;
+    margin-bottom: 50px;
+  }
+  .nextAdContet{
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: 3;
+    -webkit-box-orient: vertical;
+  }
+  .pre_15 {
+    font-size: @fs_30;
+    text-indent: @fs_30 * 2;
+  }
+  .pre_17 {
+    font-size: @fs_34;
+    text-indent: @fs_34 * 2;
+  }
+  .pre_19 {
+    font-size: @fs_38;
+    text-indent: @fs_38 * 2;
+  }
+  .pre_21 {
+    font-size: @fs_42;
+    text-indent: @fs_42 * 2;
+  }
+  .pre_23 {
+    font-size: @fs_46;
+    text-indent: @fs_46 * 2;
+  }
+  .pre_25 {
+    font-size: @fs_50;
+    text-indent: @fs_50 * 2;
+  }
+  .pre_27 {
+    font-size: @fs_54;
+    text-indent: @fs_54 * 2;
+  }
+  .pre_29 {
+    font-size: @fs_58;
+    text-indent: @fs_58 * 2;
+  }
+  .lh_72 {
+    line-height: @lh_72;
+  }
+  .lh_84 {
+    line-height: @lh_84;
+  }
+  .lh_96 {
+    line-height: @lh_96;
+  }
+  .botton {
+    width: 690px;
+    height: 96px;
+    background-color: #e3eeff;
+    color: #4f88e3;
+    font-size: 36px;
+    line-height: 96px;
+    text-align: center;
+    border-radius: 48px;
+    border: 0;
+  }
+  .bottonVIP {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    background-color: #FF2442 !important;
+    color: #FFFFFF;
+  }
+  .VIPCON {
+    position: relative;
+    .bubble{
+      position: absolute;
+      width: 120px;
+      height: 59px;
+      left: 0;
+      top: -69px;
+      background: #FE8D48;
+      border-radius: 10px;
+      line-height: 59px;
+      text-align: center;
+      font-size: 28px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #FFFFFF;
+      .ears{
+        position: absolute;
+        right: 10px;
+        bottom: -19px;
+        width:0;
+        height:0;
+        border-top: 12px solid #FE8D48;
+        border-left: 16px solid transparent;
+        border-right: -10px solid transparent;
+        border-bottom: 10px solid transparent;
+      }
+    }
+  }
+  .beanBt {
+    .top{
+      height: 90px;
+      background: #4C4C4C;
+      border-radius: 48px;
+      font-size: 32px;
+      font-family: PingFangSC-Medium, PingFang SC;
+      font-weight: 500;
+      color: #FFFFFF;
+      text-align: center;
+      line-height: 90px;
+    }
+    .bottom{
+      display: flex;
+      justify-content: space-between;
+      margin-top: 50px;
+      font-size: 32px;
+      font-family: PingFangSC-Medium, PingFang SC;
+      font-weight: 500;
+      color: #4C4C4C;
+    }
+  }
+  .cir {
+    width: 48px;
+    height: 48px;
+    background: #FFFFFF;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    line-height: 48px;
+    align-items: center;
+    margin-right: 10px;
+    .triangle-right{
+      width: 0;
+      height: 0;
+      border-top: 11px solid transparent;
+      border-left: 18px solid red;
+      border-bottom: 11px solid transparent;
+    }
+  }
+  .action{
+    background: #F6F9FF;
+  }
+}
+.bg_b {
+  background-color: @bg_F5;
+}
+.bg_l {
+  background-color: @bg_D6E;
+}
+.bg_h {
+  background-color: @bg_F5E;
+}
+.bg_hh {
+  background-color: @bg_36;
+}
+.cl_h {
+  color: @cl_333;
+}
+.cl_b {
+  color: @cl_C8;
+}
+.cl_e5 {
+  color: #5e6065 !important;
+}
+.cl_d6 {
+  color: #d6d9e2 !important;
+}
+.book_article.bg_hh{
+  .botton{
+    background: #2A2B2C;
+  }
+  .action{
+    background: #E2E2E2;
+  }
+}
+
+.fbAd{
+  position: fixed;
+  left: 20px;
+  bottom: 220px;
+  z-index: 99;
+  width: 140px;
+  overflow: hidden;
+}
+
+.vipPop{
+  position: fixed;
+  width: 100%;
+  height: 100vh;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  z-index: 1000;
+  // display: none;
+  .back{
+    position: absolute;
+    width: 100%;
+    height: 100vh;
+    background-color: rgba(0, 0, 0, .55);
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+  }
+  .vpCon{
+    position: absolute;
+    width: 100%;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 956px;
+    background: #FFFFFF;
+    border-radius: 30px 30px 0px 0px;
+    padding-bottom: 68px;
+    .vpTitle{
+      font-size: 32px;
+      font-family: PingFangSC-Medium, PingFang SC;
+      font-weight: 600;
+      color: #333333;
+      padding: 30px;
+      .title{
+        font-size: 32px;
+        font-family: PingFangSC-Medium, PingFang SC;
+        font-weight: 600;
+        color: #333333;
+        display: flex;
+        flex-direction: column;
+      }
+      .sm{
+        font-size: 24px;
+        color: #707070;
+      }
+    }
+    .size36{
+      font-size: 36px;
+    }
+    .vpline{
+      height: 2px;
+      background: #EEEEEE;
+    }
+    .lookVideoIs{
+      margin: 10px 14px 28px;
+      position: relative;
+      .lvBack{
+        width: 100%;
+        image{
+          width: 100%;
+        }
+      }
+      .lvContent{
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        height: calc(100% - 20px);
+        display: flex;
+        justify-content: flex-start;
+        align-items: center;
+        padding: 0 34px 0 42px;
+        box-sizing: border-box;
+        image{
+          width: 104px;
+          margin-right: 12px;
+        }
+        .sm{
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+          justify-content: space-around;
+          margin-right: 12px;
+          .top{
+            font-size: 36px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #FFF;
+          }
+        }
+        .bt{
+          width: 158px;
+          height: 60px;
+          background: #FFFFFF;
+          border-radius: 32px;
+          text-align: center;
+          line-height: 60px;
+          font-size: 28px;
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: 400;
+          color: #FF2442;
+        }
+      }
+    }
+    .lookVideo{
+      margin: 10px 30px 50px;
+      background: #FFF0F2;
+      border-radius: 10px;
+      border: 6px solid #FF4E67;
+      height: 212px;
+      padding: 22px;
+      box-sizing: border-box;
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      image{
+        width: 104px;
+        margin-right: 12px;
+      }
+      .sm{
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-around;
+        margin-right: 12px;
+        .top{
+          font-size: 32px;
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: 400;
+          color: #FF0D2E;
+          // margin-bottom: 12px;
+        }
+        .bottom {
+          font-size: 28px;
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: 400;
+          color: #666666;
+        }
+      }
+      .bt{
+        width: 158px;
+        height: 60px;
+        background: #FF2442;
+        border-radius: 32px;
+        text-align: center;
+        line-height: 60px;
+        font-size: 28px;
+        font-family: PingFangSC-Regular, PingFang SC;
+        font-weight: 400;
+        color: #FFFFFF;
+      }
+    }
+    .wid10{
+      height: 10px;
+    }
+    .ktVip{
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 8px;
+      view{
+        font-size: 28px;
+        font-family: PingFangSC-Regular, PingFang SC;
+        font-weight: 400;
+        color: #666666;
+        image{
+          width: 20px;
+        }
+      }
+    }
+    .selectVip{
+      display: flex;
+      justify-content: space-between;
+      margin: 0 30px;
+      &>view{
+        width: 218px;
+        height: 196px;
+        border-radius: 10px;
+        border: 2px solid #FFCCD5;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        position: relative;
+        .top{
+          font-size: 28px;
+          font-family: PingFangSC-Medium, PingFang SC;
+          font-weight: 600;
+          color: #333333;
+        }
+        .center{
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: 400;
+          color: #FF2442;
+          display: flex;
+          align-items: flex-end;
+          text{
+            font-size: 24px;
+            margin-bottom: 4px;
+            margin-right: 6px;
+          }
+          view {
+            font-size: 36px;
+          }
+        }
+        .bottom {
+          font-size: 24px;
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: 400;
+          color: #666666;
+        }
+        .cz{
+          position: absolute;
+          width: 110px;
+          height: 45px;
+          right: -2px;
+          top: -21px;
+          background: linear-gradient(to right, #FF957D , #FF4C4B);
+          border-bottom-left-radius: 10px;
+          border-bottom-right-radius: 5px;
+          border-top-right-radius: 10px;
+          border-top-left-radius: 5px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          image{
+            width: 28px;
+            height: 32px;
+            margin-right: 5px;
+          }
+          text{
+            font-size: 28px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #FFFFFF;
+          }
+        }
+      }
+      .select {
+        background: #FFF0F2;
+        border: 2px solid #FF2442;
+      }
+    }
+    .openingBt{
+      margin: 30px 30px 0;
+      height: 86px;
+      line-height: 86px;
+      // background: linear-gradient(90deg, #FF2442 0%, #FF5E74 100%);
+      background-color: #FFFFFF;
+      border-radius: 48px;
+      text-align: center;
+      color: #FF3E58;
+      border: 2px solid #FF5C77;
+    }
+  }
+}

+ 225 - 0
src/pages/book/BookArticle/index.tsx

@@ -0,0 +1,225 @@
+
+
+import React, { useState, useEffect } from 'react';
+import { View, Text, ScrollView, Button } from '@tarojs/components';
+import { observer, inject } from 'mobx-react';
+import './index.less';
+import TopNavBar from '@src/components/TopNavBar/index';
+import Taro from '@tarojs/taro';
+import BookConfigPuP from '@src/components/bookConfigPup';
+import { BookStore } from '@src/store/book';
+import useApi from '@src/Hook/useApi';
+import { UpLoading } from '@src/components/PupPetry/Loading';
+import { getReadLog, setReadLog } from '@src/utils/loginSto';
+
+interface Config {
+    size: 'pre_15' | 'pre_17' | 'pre_19' | 'pre_21' | 'pre_23' | 'pre_25' | 'pre_27' | 'pre_29' | any;
+    off_on: boolean;
+    bg: 'bg_b' | 'bg_h' | 'bg_l' | 'bg_hh';
+    lh: 'lh_72' | 'lh_84' | 'lh_96';
+}
+
+type PageStateProps = {
+    store: {
+        bookStore: BookStore,
+        indexStore,
+        appInfoStore
+    }
+};
+
+interface BookArticleProps extends PageStateProps { }
+
+const BookArticle: React.FC<BookArticleProps> = ({ store }) => {
+    const [isLoad, setIsLoad] = useState(false)
+    const { bookStore, indexStore, appInfoStore } = store
+    const { openBookData } = bookStore
+    const [bookConfig, setBookConfig] = useState<Config>({ size: 'pre_21', off_on: true, bg: 'bg_b', lh: 'lh_72' });
+    const [pup, setPup] = useState(false);
+    const { getBookContent } = useApi(appInfoStore)
+    const [currentScrollId, setCurrentScrollId] = useState('');
+    useEffect(() => {
+        // ComponentDidMount
+        try {
+            Taro.getStorage({
+                key: 'bookConfig',
+                success: (res) => {
+                    setBookConfig(JSON.parse(res.data));
+                },
+                fail: () => {
+                    setConfig({ size: 'pre_21', off_on: true, bg: 'bg_b', lh: 'lh_72' });
+                }
+            });
+        } catch (e) {
+            console.error('Error loading book config:', e);
+        }
+        //假如存在阅读记录获取对应章节的条数
+        let readLogId = getReadLog(openBookData?.bookId)
+        getBookContent({ pageNum: 1, pageSize:readLogId? Number(readLogId?.split('-')[1]) : 2 }).then(res => {
+            //继续阅读时跳转到上次阅读的段落
+            console.log(readLogId)
+            setCurrentScrollId(readLogId)
+        })
+        return () => {
+            console.log("卸载");
+            reportRead(); // 上报
+        };
+    }, []);
+
+    const reportRead = () => {
+        // 这里可以填写上报逻辑
+    };
+    //设置配置
+    const setConfig = (data: Config) => {
+        if (data) {
+            setBookConfig(data);
+            Taro.setStorage({
+                key: 'bookConfig',
+                data: JSON.stringify(data),
+                success: (res: any) => {
+                    console.log('添加bookConfig===>成功!', res);
+                },
+                fail: (err) => {
+                    console.log('添加bookConfig===>失败', err);
+                }
+            });
+
+            // 控制自义定头部背景
+            store.bookStore.setData({ bookConfig: data });
+        }
+    };
+    /**计算字体 */
+    const setSize = (parms: number) => {
+        let num = bookConfig.size.split('_');
+        if (num[1] && parms) {
+            setConfig({ ...bookConfig, size: num[0] + '_' + (Number(num[1]) + 2) });
+        } else {
+            setConfig({ ...bookConfig, size: num[0] + '_' + (Number(num[1]) - 2) });
+        }
+    };
+    /**设置背景 */
+    const setBg = (bg: 'bg_b' | 'bg_h' | 'bg_l' | 'bg_hh') => {
+        setConfig({ ...bookConfig, bg });
+        if (!bookConfig.off_on) {
+            setOff(bg);
+        }
+    };
+    /**设置行高*/
+    const setLh = (lh: 'lh_72' | 'lh_84' | 'lh_96') => {
+        setConfig({ ...bookConfig, lh });
+    };
+    /**关灯 */
+    const setOff = (bg?: 'bg_b' | 'bg_h' | 'bg_l' | 'bg_hh') => {
+        const newOffOn = !bookConfig.off_on;
+        const newConfig = bg ? { ...bookConfig, bg, off_on: newOffOn } : { ...bookConfig, off_on: newOffOn };
+        setConfig(newConfig);
+        Taro.setNavigationBarColor({
+            frontColor: newOffOn ? '#000000' : '#ffffff',
+            backgroundColor: newOffOn ? '#fff' : '#111111'
+        });
+    };
+    /**菜单 */
+    const togglePup = () => {
+        setPup(!pup);
+    };
+    //设置setNavigationBarColor
+    useEffect(() => {
+        Taro.setNavigationBarColor({
+            frontColor: bookConfig.off_on ? '#000000' : '#ffffff',
+            backgroundColor: bookConfig.off_on ? '#fff' : '#111'
+        });
+    }, [bookConfig.off_on]);
+    const onLoad = async () => {
+        if (openBookData?.contentData) {
+            let { size, current, total, records } = openBookData.contentData
+            if (records.length < total) {
+                console.log("加载")
+                setIsLoad(true)
+                await getBookContent({ pageNum: 1, pageSize: size + 2 }).then(res => {
+                    setIsLoad(false)
+                })
+            } else {
+                Taro.showToast({
+                    title: '没有更多了~~',
+                    duration: 1000,
+                    icon: 'none'
+                })
+            }
+        }
+    }
+    // 计算阅读的位置,存放以备下次阅读的时候跳转到对应位置
+    const handleScroll = () => {
+        const query = Taro.createSelectorQuery();
+        query.selectAll('.shrot-text').boundingClientRect(); // 选择所有子元素
+        query.selectViewport().scrollOffset(); // 获取视口的滚动位置
+        query.exec(res => {
+            const items = res[0]; // 子元素的位置信息
+            const scrollTop = res[1].scrollTop + indexStore.navHeight; // 视口的滚动距离
+            // 遍历所有子元素,判断哪个子元素在可视区域
+            for (let item of items) {
+                if (item.top <= scrollTop && item.bottom >= scrollTop) {
+                    if (openBookData?.bookId) {
+                        setReadLog({ [openBookData.bookId]: item.id })
+                    }
+                    break;
+                }
+            }
+        });
+    };
+    const { size, bg, off_on, lh } = bookConfig;
+    return (
+        <ScrollView
+            lowerThreshold={indexStore.navHeight}
+            refresherTriggered={isLoad}
+            onScrollToLower={onLoad}
+            style={{ height: `calc(100vh - ${indexStore.navHeight}px)` }}
+            scrollY={true}
+            refresherDefaultStyle='black'
+            scrollWithAnimation={true}
+            scrollIntoView={currentScrollId}
+            onScroll={handleScroll}
+        >
+            <View className={`book_article ${off_on ? bg : 'bg_hh'} ${off_on ? 'cl_h' : 'cl_b'}`} onClick={togglePup}>
+                <View className='header'>
+                    <View className='btns'>
+                        <View className='left'>
+                            <Text
+                                onClick={() => { size !== 'pre_15' && setSize(0) }}
+                                className={!off_on ? size === 'pre_15' ? 'cl_e5' : '' : size === 'pre_15' ? 'cl_d6' : ''}
+                            >字小</Text>
+                            <Text
+                                onClick={() => { size !== 'pre_29' && setSize(1) }}
+                                className={!off_on ? size === 'pre_29' ? 'cl_e5' : '' : size === 'pre_29' ? 'cl_d6' : ''}
+                            >字大</Text>
+                        </View>
+                        <View className='right'>
+                            <Text onClick={() => { setOff() }}>{off_on ? '关灯' : '开灯'}</Text>
+                            <Text onClick={togglePup}>菜单</Text>
+                        </View>
+                    </View>
+                </View>
+
+                {
+                    openBookData?.contentData?.records?.map(item => {
+                        let arr = item.paragraphInfo.content?.split(/\s/ig)
+                        return <View
+                            id={'paragraphNo-' + item.paragraphInfo.paragraphNo}
+                            key={item.paragraphInfo.paragraphNo}
+                            className={`pre ${size} ${lh}`}
+                        >
+                            {
+                                arr?.map((str, index) => {
+                                    return <Text className='shrot-text' id={'paragraphNo-' + item.paragraphInfo.paragraphNo + '-' + index} key={index}>{str}</Text>
+                                })
+                            }
+                        </View>
+                    })
+                }
+                {pup && <BookConfigPuP {...bookConfig} off_on={off_on} setOff={setOff} setSize={setSize} setBg={setBg} setLh={setLh} />}
+            </View>
+            {
+                isLoad && <UpLoading />
+            }
+        </ScrollView>
+    );
+};
+export default inject('store')(observer(TopNavBar(BookArticle, { isToBack: true, isReloadBook: true })));

+ 6 - 6
src/pages/book/bookDetails/index.tsx

@@ -3,8 +3,8 @@ import { View, Text, Image, Navigator } from '@tarojs/components'
 import { observer, inject } from 'mobx-react'
 import './index.less'
 import BookHead from '@src/components/PupPetry/BookHead'
-import Taro from '@tarojs/taro'
 import { Store } from '@src/app'
+import Taro from '@tarojs/taro'
 /**书详情 */
 
 type state = {
@@ -17,11 +17,11 @@ interface Props {
 class BookDetails extends Component<Props> {
     state: state = {
     }
-    componentDidUpdate(props) {
-        if (props.store.indexStore.openType === 1) {
-            Taro.setNavigationBarTitle({
-                title: '详情'
-            })
+    componentDidShow(options){
+        let params =  Taro.getCurrentInstance()?.router?.params
+        // 获取书籍详情
+        if(params?.bookId){
+            console.log(params?.bookId)
         }
     }
     render() {

+ 4 - 4
src/pages/classify/index.tsx

@@ -20,7 +20,7 @@ interface Props {
 
 const Index = forwardRef((props: Props) => {
     const { bookStore, appInfoStore, classifyStore } = props.store
-    console.log("appInfoStore",appInfoStore)
+    console.log("appInfoStore", appInfoStore)
     const { getBookPageList } = useApi(appInfoStore)
     const [pageShow, setPageShow] = useState(false)//防止小程序切换页面组件不会被真实卸载,阻止不必要的操作
     // 获取分类列表
@@ -36,7 +36,7 @@ const Index = forwardRef((props: Props) => {
         if (pageShow) {
             let { workDirection } = bookStore
             let { categoryId } = classifyStore
-            classifyStore.categoryId && getList({ workDirection, categoryId:categoryId.id, pageNum: 1, pageSize: 10 })
+            categoryId.id != 0 && classifyStore.categoryId && getList({ workDirection, categoryId: categoryId.id, pageNum: 1, pageSize: 10 })
         }
     }, [appInfoStore.token, bookStore.workDirection, classifyStore.categoryId, pageShow])
     // 使用 useDidShow 代替 onShow
@@ -51,7 +51,7 @@ const Index = forwardRef((props: Props) => {
     const refresh = async () => {
         let { workDirection } = bookStore
         let { categoryId } = classifyStore
-        getList({ workDirection, categoryId:categoryId.id, pageNum: 1, pageSize: 10 })
+        getList({ workDirection, categoryId: categoryId.id, pageNum: 1, pageSize: 10 })
     }
     //下来加载
     const load = () => {
@@ -69,7 +69,7 @@ const Index = forwardRef((props: Props) => {
                 reject()
                 return
             } else {
-                getList({ workDirection, categoryId:categoryId.id, pageNum: 1, pageSize }).then(res => {
+                getList({ workDirection, categoryId: categoryId.id, pageNum: 1, pageSize }).then(res => {
                     console.log("Res", res)
                     resolve(true)
                 })

+ 35 - 4
src/server/book/short/index.tsx

@@ -5,8 +5,8 @@ import bookStore from "@src/store/book";
 interface BookParams {
     workDirection: string,//频道
     categoryId: number,//分类ID
-    pageNum:number,//分页
-    pageSize:number//页数
+    pageNum: number,//分页
+    pageSize: number//页数
 }
 /**
  * 获取短篇小说
@@ -14,13 +14,12 @@ interface BookParams {
 export function getShortBookInfoAppListOfPage(data: BookParams) {
     return new Promise(async (resolve, reject) => {
         try {
-            // 初始化
             Taro.request({
                 url: '/app/shortBookInfo/appListOfPage',
                 method: 'GET',
                 data,
                 success: (res) => {
-                    bookStore.setData({bookList:res.data.data})
+                    bookStore.setData({ bookList: res.data.data })
                     resolve(res)
                 },
                 fail: (err) => {
@@ -32,3 +31,35 @@ export function getShortBookInfoAppListOfPage(data: BookParams) {
         }
     })
 }
+interface ParagraphListParmas {
+    pageSize: number,
+    pageNum: number,
+}
+/**
+ * 短篇小说内容列表获取
+ * */
+export function getParagraphList(data: ParagraphListParmas) {
+    return new Promise(async (resolve, reject) => {
+        Taro.request({
+            url: '/app/shortBookInfo/paragraphList',
+            method: 'GET',
+            data: { ...data, backContent: true, bookId: bookStore.openBookData?.bookId },
+            success: (res) => {
+                bookStore.setData({ openBookData: {...bookStore.openBookData,contentData:res.data.data} })
+                resolve(res)
+            },
+            fail: (err) => {
+                reject(err);
+            }
+        })
+    })
+}
+
+/**
+ * 开始阅读上报
+ * */
+
+
+/**
+ * 阅读中心跳上报
+ * */

+ 5 - 1
src/store/appInfo.tsx

@@ -3,7 +3,7 @@ import { observable } from 'mobx'
 
 type ConfigParamList = {}
 export interface AppInfo {
-    appCategory: 2,//1长篇 2短篇
+    appCategory: 1|2,//1长篇 2短篇
     appName: string,//小程序名称
     appVersion: string,//小程序版本
     configParamList: ConfigParamList[],//小程序配置
@@ -24,6 +24,10 @@ export interface AppInfoStore {
     appComponent?: AppComponent[],
     /**登录后的token*/
     token?: string,//token
+    /**进入的场景*/
+    scene?: number,
+    /**分享值*/ 
+    shareSources?:any,
     /**设置app初始化信息*/
     actionAppInfo: (appInfo: AppInfo) => void
     /**设置登录后的token*/

+ 18 - 2
src/store/book.ts

@@ -1,4 +1,11 @@
 import { observable } from 'mobx'
+
+interface ContentData {
+    current:number,
+    total:number,
+    size:number,
+    records:any[]
+}
 export interface OpenBookData {
     bookId: number,//书ID
     authorName: string,//作者
@@ -7,7 +14,8 @@ export interface OpenBookData {
     picUrl: string,//封面
     bookStatus: number,//完本|连载状态
     wordCount: number,//字数
-    labelInfoList:{name:string}[],//标签
+    labelInfoList: { name: string }[],//标签
+    contentData:ContentData|null //内容数据
 }
 
 interface ClassifyData {
@@ -26,6 +34,13 @@ export interface BookStore {
     oldWorkDirection: "男生" | "女生",
     /**分类列表*/
     classifyData: ClassifyData[],
+    /**阅读背景*/
+    bookConfig: {
+        bg: string,//背景
+        lh: string,//行高
+        off_on: boolean,//开关灯 
+        size: string,//行高
+    }
     /**设置对应数据*/
     setData: (data: { [key: string]: any }) => void
     /**设置当前打开的小说*/
@@ -41,9 +56,10 @@ export interface BookStore {
 const Book: BookStore = observable({
     openBookData: null,
     workDirection: "男生",
-    oldWorkDirection:"男生",
+    oldWorkDirection: "男生",
     classifyData: [],
     bookList: [],
+    bookConfig: { size: 'pre_21', off_on: false, bg: 'bg_b', lh: 'lh_72' },
     setData(data: { [key: string]: any }) {
         if (data) {
             Object.keys(data).forEach(key => {

+ 9 - 90
src/store/index.ts

@@ -3,99 +3,18 @@ import { observable } from 'mobx'
 let interval: NodeJS.Timeout | undefined = undefined
 const Index = observable({
     scene: 0,    // 场景值
-    share_sources: '',  // 分享值
     system: '',  // 系统
-    lastReadLog: {},
-    SET_LASTREADLOG() {
-        // getLastReadLog().then((res: any) => {
-        //     this.lastReadLog = res?.body
-        //     this.SET_ISLASTREAD(true)
-        // })
-    },
-   
-    SET_SHARESOURCES(value: string) {
-        this.share_sources = value
-    },
-
-    SET_SCENE(value: number) {
-        this.scene = value
-    },
-  
-    SET_SYSTEM(value: string) {
-        this.system = value
-    },
-    isLastRead: false,  // 是否展示上次阅读
-    SET_ISLASTREAD(value: boolean) {
-        this.isLastRead = value
-    },
-    navBarTop: 0,
-    SET_NAVBARTOP(value: number) {
-        this.navBarTop = value
-    },
-    openType: undefined,
-    SET_OPENTYPE(value: number) {
-        this.openType = value
-    },
-    zxCon: "",
-    SET_ZXCON(value: string) {
-        this.zxCon = value
-    },
-    userInfo: {
-        is_vip: true
-    },
-    SET_USERINFO() {
-        // getUserInfo().then((res: any) => {
-        //     if(res?.body){
-        //         this.userInfo = res?.body
-        //     }
-        // })
-    },
-    is_read: 1,
-    time: 0,
-    SET_TIME(t: number) {
-        if(this.is_read === 0) {
-            return
-        }
-        this.is_read = 0
-        // let time = setTimeout(()=>{
-        //     this.is_read = 1
-        //     clearTimeout(time)
-        //     log(1111111111, this.is_read);
-        // }, 1000*60*t)
-        this.time = 60 * t
-        interval = setInterval(() => {
-            this.time-=1;
-            // log(this.time);
-            if(this.time == -1){
-                this.is_read = 1
-                interval && clearInterval(interval)
-            }
-        },1000)
-    },
-    RESET_TIME() {
-        log('重置');
-        this.is_read = 1
-        interval && clearInterval(interval as NodeJS.Timeout)
-    },
-    is_cp: true,
-    is_tcp: false,
-    SET_ADTIME() {
-        log('ad', 2222);
-        if(!this.is_cp) {
-            return
+    navBarTop:0,//状态栏高度
+    navHeight:0,//导航栏高度
+    query:null,//本次进入小程序参数
+    setData(data: { [key: string]: any }) {
+        if (data) {
+            Object.keys(data).forEach(key => {
+                console.log(key)
+                this[key] = data[key]
+            })
         }
-        this.is_cp = false
-        log('ad', 4444);
-        let time1 = setTimeout(()=>{
-            this.is_cp = true
-            this.is_tcp = true
-            clearTimeout(time1)
-            log(1111111111, this.is_cp, this.is_tcp);
-        }, 1000*60*3)
     },
-    SET_ISTCP(value) {
-        this.is_tcp = value
-    }
 })
 
 export default Index

+ 20 - 30
src/utils/loginSto/index.ts

@@ -25,40 +25,30 @@ const getLoginSto = () => {
 }
 
 const removeLoginSto = () => {
-  
-}
 
+}
 /**
- * 保存授权wx用户信息
+ * 保存阅读记录
  */
-
-type wxLogin = {
-    nickname?: string,
-    gender?: string,
-    avatarUrl?: string,
-    city?: string,
-    province?: string,
-    country?: string
-}
-
-const wxKey = 'wx-login'
-const setWxLoginSto = (val: wxLogin) => {
-    try {
-        Taro.setStorageSync(wxKey, val)
-    } catch (e) {
-        // Do something when catch error
-    }
+const setReadLog = (val: { [key: string]: string }) => {
+    let readLog = Taro.getStorageSync('readLog')
+    if (!readLog) {
+        readLog = {}
+    } 
+    Object.keys(val).forEach(key => {
+        readLog[key] = val[key]
+    })
+    Taro.setStorageSync("readLog", readLog)
 }
-
-const getWxLoginSto = () => {
-    try {
-        let data = Taro.getStorageSync(wxKey)
-        return data
-    } catch (e) {
-        // Do something when catch error
+/**
+ * 获取阅读记录
+ */
+const getReadLog = (bookId:any) => {
+    let readLog = Taro.getStorageSync('readLog')
+    if (!readLog) {
         return ""
+    }else{
+        return readLog[bookId]
     }
 }
-
-
-export { setLoginSto, getLoginSto, removeLoginSto, setWxLoginSto, getWxLoginSto }
+export { setLoginSto, getLoginSto, removeLoginSto, setReadLog,getReadLog }