index.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. // index.js
  2. const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
  3. const testCover = '/assets/images/bg-book.png'
  4. import {
  5. getBannerList,
  6. getCardNovels,
  7. getBrowsingHistory,
  8. getNovelDetail
  9. } from '../../api/api'
  10. import {
  11. goToBookDetail, SendEvent
  12. } from '../../utils/util'
  13. import { apple } from '../../config/config'
  14. const app = getApp()
  15. let interstitialAd = null
  16. Page({
  17. data: {
  18. isLoggedIn: false,
  19. // 轮播配置
  20. indicatorDots: true,
  21. autoplay: true,
  22. interval: 3000,
  23. duration: 500,
  24. cardNovels: [],
  25. bannerList: [], // 添加banner列表数据
  26. // 性别选项
  27. gender: 'male', // male or female
  28. // 主编推荐数据
  29. recommendBooks: [], // 主编推荐数据
  30. // 推荐书籍列表
  31. bookList: [],
  32. // 全网热推
  33. hotBooks: [], // 全网热推数据
  34. // 强力推荐
  35. showStrongRecommend: false, // 控制强力推荐模块显示/隐藏
  36. strongBooks: [],
  37. // 最近阅读书籍
  38. recentBook: null, // 最近阅读的书籍
  39. showRecentBook: false, // 是否显示最近阅读
  40. isRecentBookHidden: false, // 最近阅读是否隐藏
  41. recentBookAnimation: {}, // 最近阅读动画数据
  42. motto: 'Hello World',
  43. userInfo: {
  44. avatarUrl: defaultAvatarUrl,
  45. nickName: '',
  46. },
  47. hasUserInfo: false,
  48. canIUseGetUserProfile: wx.canIUse('getUserProfile'),
  49. canIUseNicknameComp: wx.canIUse('input.type.nickname'),
  50. share_count: 1,
  51. },
  52. onLoad(options) {
  53. console.log('入参options:', options)
  54. const promotionid = options.promotionId;
  55. console.log('传入promotionid:', promotionid)
  56. this.interstitalLoad()
  57. this.autoLogin(promotionid);
  58. // 创建动画实例
  59. this.recentBookAnimator = wx.createAnimation({
  60. duration: 300,
  61. timingFunction: 'ease',
  62. });
  63. const scene = wx.getStorageSync('scene');
  64. const bookId = parseInt(options.novelId);
  65. const jump = options.jump;// 跳转类型 1-不进阅读器
  66. console.log('传入jump:', jump)
  67. console.log('scene:', scene)
  68. console.log('传入novelId:', bookId)
  69. if (bookId && this.data.share_count === 1 && (scene === 1008 || scene === 1007) && jump !== 1) {
  70. getNovelDetail(bookId).then(res => {
  71. this.setData({
  72. share_count: 2
  73. })
  74. goToBookDetail({
  75. bookId,
  76. wxBookId: res.wxBookId
  77. })
  78. })
  79. } else if (bookId && this.data.share_count === 2) {
  80. setTimeout(() => {
  81. this.interstitalPlayFn()
  82. }, 1000)
  83. }
  84. },
  85. onShow() {
  86. // 每次页面显示时检查是否需要更新数据
  87. if (this.data.isLoggedIn) {
  88. this.checkAndUpdateGender();
  89. // 每次页面显示时获取最近阅读
  90. this.getRecentReadBook();
  91. }
  92. },
  93. onTabItemTap(item) {
  94. console.log(item.index)
  95. setTimeout(() => {
  96. this.interstitalPlayFn()
  97. }, 1000)
  98. // tabBar 点击时检查是否需要更新数据
  99. if (this.data.isLoggedIn) {
  100. this.checkAndUpdateGender();
  101. }
  102. },
  103. // 插屏广告加载
  104. interstitalLoad() {
  105. let adId = apple.ads.insertAdId
  106. interstitialAd = wx.createInterstitialAd({
  107. adUnitId: adId
  108. })
  109. interstitialAd.onLoad(() => {
  110. console.log('书城页插屏广告onLoad')
  111. })
  112. interstitialAd.onError((err) => {
  113. console.log('书城页插屏广告onError', err)
  114. })
  115. interstitialAd.onClose(() => {
  116. console.log('书城页插屏广告onClose')
  117. })
  118. },
  119. // 插屏广告展示
  120. interstitalPlayFn() {
  121. if (interstitialAd) {
  122. interstitialAd.show().catch((err) => {
  123. console.error('书城页插屏显示错误', err)
  124. })
  125. }
  126. },
  127. // 页面滚动触发
  128. onPageScroll(e) {
  129. // 清除之前的定时器
  130. if (this.scrollTimer) {
  131. clearTimeout(this.scrollTimer);
  132. this.scrollTimer = null;
  133. }
  134. // 滚动时隐藏最近阅读
  135. if (e.scrollTop > 300 && !this.data.isRecentBookHidden && this.data.showRecentBook) {
  136. this.hideRecentBook();
  137. }
  138. // 设置滑动停止后的定时器
  139. this.lastScrollTop = e.scrollTop;
  140. this.scrollTimer = setTimeout(() => {
  141. // 2秒后检查是否已经停止滚动
  142. if (this.lastScrollTop === e.scrollTop && this.data.isRecentBookHidden && this.data.showRecentBook) {
  143. this.showRecentBook();
  144. }
  145. }, 1500); // 2秒后执行
  146. },
  147. // 隐藏最近阅读
  148. hideRecentBook() {
  149. // 计算移动距离,只漏出10px
  150. const windowWidth = wx.getSystemInfoSync().windowWidth;
  151. const rpxToPx = windowWidth / 750; // rpx到px的转换比例
  152. const btnWidth = 90 * rpxToPx; // 悬浮按钮宽度,90rpx转换为px
  153. const moveX = -(btnWidth + 35); // 只漏出10px
  154. this.recentBookAnimator.translateX(moveX).step();
  155. this.setData({
  156. recentBookAnimation: this.recentBookAnimator.export(),
  157. isRecentBookHidden: true
  158. });
  159. },
  160. // 显示最近阅读
  161. showRecentBook() {
  162. this.recentBookAnimator.translateX(0).step();
  163. this.setData({
  164. recentBookAnimation: this.recentBookAnimator.export(),
  165. isRecentBookHidden: false
  166. });
  167. },
  168. // 点击隐藏的最近阅读
  169. toggleRecentBook() {
  170. if (this.data.isRecentBookHidden) {
  171. // 隐藏状态点击展开
  172. this.showRecentBook();
  173. } else {
  174. // 展开状态点击跳转
  175. this.goToRecentBook();
  176. }
  177. },
  178. // 自动登录
  179. async autoLogin(promotionid) {
  180. try {
  181. // 检查是否已经登录
  182. const token = wx.getStorageSync('accessToken');
  183. if (token) {
  184. this.setData({
  185. isLoggedIn: true
  186. });
  187. // 获取性别设置并加载数据
  188. this.initGenderAndLoadData();
  189. // 获取最近阅读记录
  190. this.getRecentReadBook();
  191. return;
  192. }
  193. // 未登录,执行登录
  194. const res = await getApp().login(promotionid);
  195. this.setData({
  196. isLoggedIn: true
  197. });
  198. // 登录成功后获取性别设置并加载数据
  199. this.initGenderAndLoadData();
  200. // 获取最近阅读记录
  201. this.getRecentReadBook();
  202. } catch (error) {
  203. console.error('登录失败:', error);
  204. // 登录失败也尝试加载数据,使用默认性别
  205. this.initGenderAndLoadData();
  206. }
  207. },
  208. // 初始化性别设置并加载数据
  209. initGenderAndLoadData() {
  210. // 获取保存的性别设置,如果没有则使用默认值
  211. const gender = wx.getStorageSync('gender') || 'male';
  212. this.setData({
  213. gender
  214. });
  215. // 加载所有数据
  216. this.loadAllData();
  217. },
  218. // 检查并更新性别,如果有变化则重新加载数据
  219. checkAndUpdateGender() {
  220. const savedGender = wx.getStorageSync('gender') || 'male';
  221. if (savedGender !== this.data.gender) {
  222. this.setData({
  223. gender: savedGender
  224. });
  225. this.loadAllData();
  226. }
  227. },
  228. // 获取最近阅读的书籍
  229. async getRecentReadBook() {
  230. try {
  231. const historyList = await getBrowsingHistory();
  232. if (Array.isArray(historyList) && historyList.length > 0) {
  233. // 取第一本作为最近阅读
  234. const recentBook = historyList[0];
  235. this.setData({
  236. recentBook: recentBook,
  237. showRecentBook: true,
  238. isRecentBookHidden: false
  239. });
  240. // 重置动画
  241. if (this.recentBookAnimator) {
  242. this.recentBookAnimator.translateX(0).step();
  243. this.setData({
  244. recentBookAnimation: this.recentBookAnimator.export()
  245. });
  246. }
  247. } else {
  248. this.setData({
  249. showRecentBook: false
  250. });
  251. }
  252. } catch (error) {
  253. console.error('获取最近阅读失败:', error);
  254. this.setData({
  255. showRecentBook: false
  256. });
  257. }
  258. },
  259. // 跳转到最近阅读的书籍
  260. goToRecentBook() {
  261. if (this.data.recentBook) {
  262. SendEvent('click_bookmall_recently_read', {
  263. "video_id": this.data.recentBook.novelId,
  264. "wx_book_id": this.data.recentBook.wxBookId,
  265. "chapter_no": this.data.recentBook.novelChapterId,
  266. "uuid": app.globalData.uuid
  267. });
  268. goToBookDetail({
  269. bookId: this.data.recentBook.novelId,
  270. wxBookId: this.data.recentBook.wxBookId,
  271. chapterId: this.data.recentBook.novelChapterId
  272. });
  273. }
  274. },
  275. // 加载所有数据
  276. loadAllData() {
  277. wx.showLoading({
  278. title: '加载中...'
  279. });
  280. // 并行请求数据
  281. Promise.all([
  282. this.getBannerList(),
  283. this.getCardNovels()
  284. ]).finally(() => {
  285. wx.hideLoading();
  286. });
  287. },
  288. // 切换性别分类
  289. switchGender: function (e) {
  290. const {
  291. gender
  292. } = e.detail;
  293. // 如果性别没有改变,直接返回
  294. if (this.data.gender === gender) {
  295. return;
  296. }
  297. // 保存性别设置到本地存储
  298. wx.setStorageSync('gender', gender);
  299. this.setData({
  300. gender
  301. });
  302. SendEvent('click_bookmall_classify', {
  303. "gender": gender, "uuid": app.globalData.uuid
  304. });
  305. // 重新加载数据
  306. this.loadAllData();
  307. },
  308. // 跳转到搜索页面
  309. goToSearch: function () {
  310. // SendEvent('click_bookmall_classify', {});
  311. wx.navigateTo({
  312. url: '/pages/search/search',
  313. });
  314. },
  315. // 跳转到书籍详情页
  316. goToBookDetail: function (e) {
  317. const bookId = e.currentTarget.dataset.bookId;
  318. const wxBookId = e.currentTarget.dataset.wxBookId;
  319. const chapterId = e.currentTarget.dataset.chapterId;
  320. console.log('bookId', bookId);
  321. console.log('wxBookId', wxBookId);
  322. console.log('chapterId', chapterId);
  323. goToBookDetail({
  324. bookId,
  325. wxBookId,
  326. chapterId
  327. });
  328. },
  329. // 跳转到功能页面
  330. goToFeature: function (e) {
  331. const feature = e.currentTarget.dataset.feature;
  332. switch (feature) {
  333. case 'recent':
  334. // 修改为跳转到书架页面的阅读历史标签
  335. SendEvent('click_shelf_tab', { 'uuid': app.globalData.uuid })
  336. wx.switchTab({
  337. url: '/pages/bookshelf/bookshelf'
  338. });
  339. break;
  340. case 'user':
  341. // 修改为跳转到我的页面
  342. SendEvent('click_mine_tab', { 'uuid': app.globalData.uuid })
  343. wx.switchTab({
  344. url: '/pages/mine/mine'
  345. });
  346. break;
  347. case 'category':
  348. // 修改为跳转到分类页面
  349. SendEvent('click_classify_tab', { 'uuid': app.globalData.uuid })
  350. wx.switchTab({
  351. url: '/pages/category/category'
  352. });
  353. break;
  354. case 'hot':
  355. SendEvent('click_bookmall_classify', { 'uuid': app.globalData.uuid })
  356. wx.navigateTo({
  357. url: '/pages/book/list?type=hot'
  358. });
  359. break;
  360. case 'recommend':
  361. SendEvent('click_bookmall_classify', { 'uuid': app.globalData.uuid })
  362. wx.navigateTo({
  363. url: '/pages/book/list?type=recommend'
  364. });
  365. break;
  366. default:
  367. break;
  368. }
  369. },
  370. bindViewTap() {
  371. wx.navigateTo({
  372. url: '../logs/logs'
  373. })
  374. },
  375. onChooseAvatar(e) {
  376. const {
  377. avatarUrl
  378. } = e.detail
  379. const {
  380. nickName
  381. } = this.data.userInfo
  382. this.setData({
  383. "userInfo.avatarUrl": avatarUrl,
  384. hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl,
  385. })
  386. },
  387. onInputChange(e) {
  388. const nickName = e.detail.value
  389. const {
  390. avatarUrl
  391. } = this.data.userInfo
  392. this.setData({
  393. "userInfo.nickName": nickName,
  394. hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl,
  395. })
  396. },
  397. getUserProfile(e) {
  398. // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
  399. wx.getUserProfile({
  400. desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
  401. success: (res) => {
  402. console.log(res)
  403. this.setData({
  404. userInfo: res.userInfo,
  405. hasUserInfo: true
  406. })
  407. }
  408. })
  409. },
  410. // 获取banner列表
  411. async getBannerList() {
  412. try {
  413. const channel = this.data.gender === 'male' ? 1 : 2;
  414. const bannerList = await getBannerList(channel);
  415. this.setData({
  416. bannerList
  417. });
  418. return bannerList;
  419. } catch (error) {
  420. console.error('获取banner失败:', error);
  421. wx.showToast({
  422. title: '获取banner失败',
  423. icon: 'none'
  424. });
  425. return [];
  426. }
  427. },
  428. async getCardNovels() {
  429. try {
  430. const channel = this.data.gender === 'male' ? 1 : 2;
  431. const cardNovels = await getCardNovels(channel);
  432. this.setData({
  433. cardNovels
  434. });
  435. // 处理主编推荐数据
  436. if (cardNovels[0]) {
  437. const [firstBook, ...restBooks] = cardNovels[0].novelList;
  438. this.setData({
  439. recommendBooks: firstBook ? [{
  440. id: firstBook.id,
  441. title: firstBook.title,
  442. desc: firstBook.brief,
  443. stats: `近期收藏${firstBook.readingNumber}`,
  444. cover: firstBook.cover,
  445. wxBookId: firstBook.wxBookId,
  446. chapterId: firstBook.chapterId
  447. }] : [],
  448. bookList: restBooks.slice(0, 4).map(novel => ({
  449. id: novel.id,
  450. title: novel.title,
  451. cover: novel.cover,
  452. wxBookId: novel.wxBookId,
  453. chapterId: novel.chapterId
  454. })),
  455. editorTitle: cardNovels[0].name // 设置实际的标题
  456. });
  457. }
  458. // 处理全网热推数据
  459. if (cardNovels[1]) {
  460. this.setData({
  461. hotBooks: cardNovels[1].novelList.map(novel => ({
  462. id: novel.id,
  463. title: novel.title,
  464. desc: novel.brief,
  465. stats: `${novel.readingNumber}人看过`,
  466. cover: novel.cover,
  467. wxBookId: novel.wxBookId,
  468. chapterId: novel.chapterId
  469. })),
  470. hotTitle: cardNovels[1].name // 设置实际的标题
  471. });
  472. }
  473. // 处理强力推荐数据
  474. if (cardNovels[2] && cardNovels[2].novelList.length > 0) {
  475. this.setData({
  476. strongBooks: cardNovels[2].novelList.slice(0, 4).map(novel => ({
  477. id: novel.id,
  478. title: novel.title,
  479. cover: novel.cover,
  480. wxBookId: novel.wxBookId,
  481. chapterId: novel.chapterId
  482. })),
  483. showStrongRecommend: true
  484. });
  485. } else {
  486. // 如果没有第三组数据,隐藏强力推荐模块
  487. this.setData({
  488. strongBooks: [],
  489. showStrongRecommend: false
  490. });
  491. }
  492. return cardNovels;
  493. } catch (error) {
  494. console.error('获取卡片小说失败:', error);
  495. wx.showToast({
  496. title: '获取卡片小说失败',
  497. icon: 'none'
  498. });
  499. return [];
  500. }
  501. },
  502. // 处理banner点击
  503. onBannerTap(e) {
  504. const banner = e.currentTarget.dataset.item;
  505. if (banner.linkUrl) {
  506. SendEvent('banner_click', {
  507. "banner_id": banner.id,
  508. "banner_title": banner.title,
  509. "uuid": app.globalData.uuid
  510. });
  511. wx.navigateTo({
  512. url: banner.linkUrl
  513. });
  514. }
  515. },
  516. })