index.js 15 KB

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