Browse Source

feat 视频合集

erekook 11 tháng trước cách đây
mục cha
commit
5befa705c8

+ 179 - 108
api/api.js

@@ -1,183 +1,214 @@
 // 接口文档:https://hyperion-novel-qa-app.mokamrp.com/swagger-ui/#/
-import { requestAll, requestLogin, post, postWithCommonParams, uploadTrackLog } from '../utils/request'
-export const userLogin = (data) => requestLogin(data)
+import {
+  requestAll,
+  requestLogin,
+  post,
+  postWithCommonParams,
+  uploadTrackLog,
+} from "../utils/request";
+export const userLogin = (data) => requestLogin(data);
+import { https, apple } from "../config/config.js";
 
 // 获取token
 const getToken = () => {
-    return wx.getStorageSync('accessToken') || ''
-}
+  return wx.getStorageSync("accessToken") || "";
+};
 
 // 添加token到header
 const addTokenToHeader = () => {
-    return {
-        token: getToken()
-    }
-}
+  return {
+    token: getToken(),
+  };
+};
 
 export const getBannerList = (channel) => {
-    return requestAll('/novel/banner', {channel}, 'GET', addTokenToHeader())
-}
+  return requestAll("/novel/banner", { channel }, "GET", addTokenToHeader());
+};
 
 export const getChapterList = (channel) => {
-  return requestAll('/novel/chapter/list', {channel}, 'GET', addTokenToHeader())
-}
+  return requestAll(
+    "/novel/chapter/list",
+    { channel },
+    "GET",
+    addTokenToHeader(),
+  );
+};
 
 // /novel/cardNovels
 export const getCardNovels = (channel) => {
-    return requestAll('/novel/cardNovels', {channel}, 'GET', addTokenToHeader())
-}
+  return requestAll(
+    "/novel/cardNovels",
+    { channel },
+    "GET",
+    addTokenToHeader(),
+  );
+};
 
 // /novel/cardNovelsMore
 export const getCardNovelsMore = (id) => {
-    if (!id) {
-        return Promise.reject(new Error('缺少必要参数: id'));
-    }
-    return requestAll('/novel/cardNovelsMore', {id}, 'GET', addTokenToHeader())
-}
+  if (!id) {
+    return Promise.reject(new Error("缺少必要参数: id"));
+  }
+  return requestAll("/novel/cardNovelsMore", { id }, "GET", addTokenToHeader());
+};
 
 // /category/list
 export const getCategoryList = (category) => {
-    if (!category) {
-        return Promise.reject(new Error('缺少必要参数: category'));
-    }
-    return requestAll('/category/list', {category}, 'GET', addTokenToHeader())
-}
+  if (!category) {
+    return Promise.reject(new Error("缺少必要参数: category"));
+  }
+  return requestAll("/category/list", { category }, "GET", addTokenToHeader());
+};
 
 // /novel/detail
 export const getNovelDetail = (id) => {
-    if (!id) {
-        return Promise.reject(new Error('缺少必要参数: id'));
-    }
-    return requestAll('/novel/detail', {id}, 'GET', addTokenToHeader())
-}
+  if (!id) {
+    return Promise.reject(new Error("缺少必要参数: id"));
+  }
+  return requestAll("/novel/detail", { id }, "GET", addTokenToHeader());
+};
 
 // /novel/search
-export const getNovelSearch = ({
-                                   keyword,
-                                   page = 1,
-                                   size = 10,
-                                   category
-                               }) => {
-    // 创建基本参数对象
-    const params = {keyword, page, size};
-
-    // 如果category有值,才添加到参数中
-    if (category) {
-        params.category = category;
-    }
+export const getNovelSearch = ({ keyword, page = 1, size = 10, category }) => {
+  // 创建基本参数对象
+  const params = { keyword, page, size };
 
-    return requestAll('/novel/search', params, 'GET', addTokenToHeader());
-}
+  // 如果category有值,才添加到参数中
+  if (category) {
+    params.category = category;
+  }
+
+  return requestAll("/novel/search", params, "GET", addTokenToHeader());
+};
 
 // /user/bookshelf 获取书架列表
 export const getBookshelfList = () => {
-    return requestAll('/user/bookshelf', {}, 'GET', addTokenToHeader())
-}
+  return requestAll("/user/bookshelf", {}, "GET", addTokenToHeader());
+};
 
 // /user/bookshelf 添加书架
 export const addBookshelf = (data) => {
-    return requestAll('/user/bookshelf', data, 'POST', addTokenToHeader())
-}
+  return requestAll("/user/bookshelf", data, "POST", addTokenToHeader());
+};
 
 // /user/bookshelf 移除用户书架
 export const removeBookshelf = (data) => {
-    return requestAll('/user/bookshelf', data, 'DELETE', addTokenToHeader())
-}
+  return requestAll("/user/bookshelf", data, "DELETE", addTokenToHeader());
+};
 
 // /user/chapter/unlock-status 获取章节解锁状态
 export const getChapterUnlockStatus = (data) => {
-    return requestAll('/user/chapter/unlock-status-val', data, 'GET', addTokenToHeader())
-}
+  return requestAll(
+    "/user/chapter/unlock-status-val",
+    data,
+    "GET",
+    addTokenToHeader(),
+  );
+};
 
 // /user/browsing-history 新增用户阅读历史
 export const addBrowsingHistory = (data) => {
-    return requestAll('/user/browsing-history', data, 'POST', addTokenToHeader())
-}
+  return requestAll("/user/browsing-history", data, "POST", addTokenToHeader());
+};
 
 // /user/chapter/unlock 解锁章节
 export const unlockChapter = (data) => {
-  return requestAll('/user/chapter/unlock', data, 'POST', addTokenToHeader())
-}
+  return requestAll("/user/chapter/unlock", data, "POST", addTokenToHeader());
+};
 
 // 获取阅读记录
 export const getBrowsingHistory = () => {
-    return requestAll('/user/browsing-history', {}, 'GET', addTokenToHeader())
-}
+  return requestAll("/user/browsing-history", {}, "GET", addTokenToHeader());
+};
 
 // 获取短剧列表
 export function getVideoList(params = {}) {
-    const {page = 1, size = 10, tag_id = 2245, filter_id = "", next_id = "",gh_id = ""} = params;
-
-    const requestData = {
-        tag_id: tag_id,
-        filter_id: filter_id,
-        next_id: next_id,
-        count: size,
-        uuid: getApp().globalData.uuid, // 固定值,实际应用中可能需要动态生成
-        gh_id: gh_id // 固定值
-    };
-
-    return postWithCommonParams("https://applet.xiaoduer.cn/cashvideoapi/cashvideo/getvideolist", requestData)
-        .then(data => {
-
-            return data;
-            // 处理返回数据的格式转换,确保与页面期望的数据结构一致
-            if (data) {
-                return data.map(video => ({
-                    id: video.id,
-                    title: video.title,
-                    cover: video.cover_image,
-                    playCount: video.views || '0'
-                }));
-            }
-            return [];
-        });
+  const {
+    page = 1,
+    size = 10,
+    tag_id = 2245,
+    filter_id = "",
+    next_id = "",
+    gh_id = "",
+  } = params;
+
+  const requestData = {
+    tag_id: tag_id,
+    filter_id: filter_id,
+    next_id: next_id,
+    count: size,
+    uuid: getApp().globalData.uuid, // 固定值,实际应用中可能需要动态生成
+    gh_id: gh_id, // 固定值
+  };
+
+  return postWithCommonParams(
+    `${https.goHttps}/cashvideoapi/cashvideo/getvideolist`,
+    requestData,
+  ).then((data) => {
+    return data;
+    // 处理返回数据的格式转换,确保与页面期望的数据结构一致
+    if (data) {
+      return data.map((video) => ({
+        id: video.id,
+        title: video.title,
+        cover: video.cover_image,
+        playCount: video.views || "0",
+      }));
+    }
+    return [];
+  });
 }
 
 // 获取视频详情
 export function getVideoDetail(params = {}) {
-    if (!params.id) {
-        return Promise.reject(new Error('缺少必要参数: id'));
-    }
-
-    return postWithCommonParams('https://applet.xiaoduer.cn/cashvideoapi/cashvideo/getvideoinfo', params);
+  if (!params.id) {
+    return Promise.reject(new Error("缺少必要参数: id"));
+  }
+
+  return postWithCommonParams(
+    `${https.goHttps}/cashvideoapi/cashvideo/getvideoinfo`,
+    params,
+  );
 }
 
 // 获取真实视频播放地址
 export function getRealVideoUrl(id, tagId) {
-    if (!id || !tagId) {
-        return Promise.reject(new Error('缺少必要参数: id 或 tagId'));
-    }
+  if (!id || !tagId) {
+    return Promise.reject(new Error("缺少必要参数: id 或 tagId"));
+  }
 
-    const url = `https://applet.xiaoduer.cn/coral/cashvideo/getOasVideoUrl?id=${id}&tagId=${tagId}`;
-    return postWithCommonParams(url, {}, 'GET');
+  const url = `${https.goHttps}/coral/cashvideo/getOasVideoUrl?id=${id}&tagId=${tagId}`;
+  return postWithCommonParams(url, {}, "GET");
 }
 
 // 获取相关视频列表
 export function getRelatedVideos(params = {}) {
-    const {tag_id = 2250, count = 10, filter_id = "", gh_id = ""} = params;
-
-    const requestData = {
-        tag_id,
-        count,
-        filter_id,
-        uuid: getApp().globalData.uuid,
-        gh_id: gh_id
-    };
-
-    return post("https://applet.xiaoduer.cn/cashvideoapi/cashvideo/getrandvideolistpro", requestData);
+  const { tag_id = 2250, count = 10, filter_id = "", gh_id = "" } = params;
+
+  const requestData = {
+    tag_id,
+    count,
+    filter_id,
+    uuid: getApp().globalData.uuid,
+    gh_id: gh_id,
+  };
+
+  return post(
+    `${https.goHttps}/cashvideoapi/cashvideo/getrandvideolistpro`,
+    requestData,
+  );
 }
 
 /**
  * 获取 uuid
  */
 export function getUuid(body) {
-    return postWithCommonParams('https://applet.xiaoduer.cn/api/user/getuuid', body)
+  return postWithCommonParams(`${https.goHttps}/api/user/getuuid`, body);
 }
 
 // https://applet.xiaoduer.cn/coral/template/config
 export function getTemplateConfig(body) {
-    return postWithCommonParams('https://applet.xiaoduer.cn/coral/template/config', body)
+  return postWithCommonParams(`${https.goHttps}/coral/template/config`, body);
 }
 
 // 导出postWithCommonParams
@@ -186,4 +217,44 @@ export { postWithCommonParams };
 /**
  * 打点
  */
-export const recordLog = (body) => uploadTrackLog('/track', body)
+export const recordLog = (body) => uploadTrackLog("/track", body);
+
+// 获取合集视频
+export function getCollectDetail(collectionId) {
+  const requestData = {
+    collectionId,
+    uuid: getApp().globalData.uuid, // 固定值,实际应用中可能需要动态生成
+    gh_id: apple.ghid, // 固定值
+  };
+
+  return postWithCommonParams(
+    `${https.goHttps}/materialvideoapi/materialvideo/getCollectionVideoList`,
+    requestData,
+  ).then((data) => {
+    return data;
+  });
+}
+
+// 获取真实视频播放地址
+export function getCollectRealVideoUrl(url) {
+  return postWithCommonParams(url, {}, "GET");
+}
+
+// 获取推荐合集列表
+export function getRecCollectList(params) {
+  const { tagIdList, count, id } = params;
+  const requestData = {
+    id,
+    tagIdList,
+    count,
+    uuid: getApp().globalData.uuid, // 固定值,实际应用中可能需要动态生成
+    gh_id: apple.ghid, // 固定值
+  };
+
+  return postWithCommonParams(
+    `${https.goHttps}/materialvideoapi/materialvideo/getRandomCollectionList`,
+    requestData,
+  ).then((data) => {
+    return data;
+  });
+}

+ 314 - 304
app.js

@@ -1,336 +1,346 @@
-import {
-    SendEvent,
-} from '/utils/util.js'
+import { SendEvent } from "/utils/util.js";
 
-import {
-    unlockChapter
-} from '/api/api.js'
+import { unlockChapter } from "/api/api.js";
 
 // app.js
 // 引入阅读器插件
-const novelPlugin = requirePlugin('novel-plugin')
+const novelPlugin = requirePlugin("novel-plugin");
 
-import { userLogin, getChapterUnlockStatus, getNovelDetail, addBrowsingHistory } from './api/api'
-import { apple } from './config/config'
+import {
+  userLogin,
+  getChapterUnlockStatus,
+  getNovelDetail,
+  addBrowsingHistory,
+} from "./api/api";
+import { apple } from "./config/config";
 
 App({
-    onLaunch(options) {
-        console.log('场景值:', options, options.scene);
-        this.globalData.from = options.query.from || ''
-        novelPlugin.setLoggerConfig({
-            info: false,
-            debug: false,
-            log: false,
-            warn: false,
-            error: true,
-        })
-
-        // 监听进入插件页事件
-        novelPlugin.onPageLoad(onNovelPluginLoad)
-
-        // 展示本地存储能力
-        // const logs = wx.getStorageSync('logs') || []
-        // logs.unshift(Date.now())
-        // wx.setStorageSync('logs', logs);
-        wx.setStorageSync('scene', options.scene)// 储存场景值
-    },
-
-    onShow: function (opt) {
-        console.log('onShow-小程序进入前台', opt)
-        SendEvent('customAppletsShowEvent', {}, this)
-    },
-
-    // 登录方法
-    login(promotionid) {
-        return new Promise((resolve, reject) => {
-
-            // 检查登录状态
-            if (this.checkLoginStatus()) {
-                resolve();
-                return;
-            }
-
-            wx.login({
-                success: res => {
-                    userLogin({
-                        "appid": apple.appid,
-                        "channel": 1,
-                        "srcType": "0",
-                        "srcAppId": "",
-                        "srcId": "",
-                        "cusId": "",
-                        "inviter": "",
-                        "promotionId": promotionid,
-                        "inviterPromotionId": "",
-                        "system": "pc",
-                        "type": "inner",
-                        "inner": 1,
-                        code: res.code,
-                    }).then(res => {
-                        console.log(res);
-                        wx.setStorageSync('accessToken', res.accessToken);
-                        this.globalData.isLogin = true;
-                        this.globalData.userCode = res.userCode;
-                        this.globalData.openId = res.openId;
-                        this.globalData.unionId = res.unionId;
-                        console.log('登录成功', this.globalData)
-                        SendEvent('login', {
-                            "userCode": res.userCode,
-                            "openId": res.openId,
-                            "unionId": res.unionId
-                        })
-                        resolve(res);
-                    }).catch(err => {
-                        this.globalData.isLogin = false;
-                        reject(err);
-                    })
-                },
-                fail: err => {
-                    this.globalData.isLogin = false;
-                    reject(err);
-                }
+  onLaunch(options) {
+    console.log("场景值:", options, options.scene);
+    this.globalData.from = options.query.from || "";
+    novelPlugin.setLoggerConfig({
+      info: false,
+      debug: false,
+      log: false,
+      warn: false,
+      error: true,
+    });
+
+    // 监听进入插件页事件
+    novelPlugin.onPageLoad(onNovelPluginLoad);
+
+    // 展示本地存储能力
+    // const logs = wx.getStorageSync('logs') || []
+    // logs.unshift(Date.now())
+    // wx.setStorageSync('logs', logs);
+    wx.setStorageSync("scene", options.scene); // 储存场景值
+  },
+
+  onShow: function (opt) {
+    console.log("onShow-小程序进入前台", opt);
+    SendEvent("customAppletsShowEvent", {}, this);
+  },
+
+  // 登录方法
+  login(promotionid) {
+    return new Promise((resolve, reject) => {
+      // 检查登录状态
+      if (this.checkLoginStatus()) {
+        resolve();
+        return;
+      }
+
+      wx.login({
+        success: (res) => {
+          userLogin({
+            appid: apple.appid,
+            channel: 1,
+            srcType: "0",
+            srcAppId: "",
+            srcId: "",
+            cusId: "",
+            inviter: "",
+            promotionId: promotionid,
+            inviterPromotionId: "",
+            system: "pc",
+            type: "inner",
+            inner: 1,
+            code: res.code,
+          })
+            .then((res) => {
+              console.log(res);
+              wx.setStorageSync("accessToken", res.accessToken);
+              this.globalData.isLogin = true;
+              this.globalData.userCode = res.userCode;
+              this.globalData.openId = res.openId;
+              this.globalData.unionId = res.unionId;
+              console.log("登录成功", this.globalData);
+              SendEvent("login", {
+                userCode: res.userCode,
+                openId: res.openId,
+                unionId: res.unionId,
+              });
+              resolve(res);
             })
-        })
-    },
-
-    // 自动登录
-    async autoLogin(promotionid) {
-        try {
-            // 检查是否已经登录
-            const token = wx.getStorageSync('accessToken');
-            if (token) {
-                // 已经登录
-                console.log('已经登录')
-                return;
-            }
-            // 未登录,执行登录
-            const res = this.login(promotionid);
-        } catch (error) {
-            console.error('登录失败:', error);
-        }
-    },
-
-    // 检查登录状态
-    checkLoginStatus() {
-        const token = wx.getStorageSync('accessToken');
-        return !!token && this.globalData.isLogin;
-    },
-
-    globalData: {
-        userInfo: null,
-        isLogin: false,
-        novelManager: {},
-        uuid: '',
-        isShowDialog: false,
-        novelManagerId: 0,
-        novelId: '',
-        chapterIndex: 0,
-        unlockChapterNum: 1,
-        bookmarkAdNum: 3,
-        openId: '',
-        unionId: '',
-        isEnterVideoDetail: false,  // 是否进入过视频详情页
-        ads_config: {}, // 广告策略配置
-        userCode: '',
-        from: '',
-        videoAd: null
+            .catch((err) => {
+              this.globalData.isLogin = false;
+              reject(err);
+            });
+        },
+        fail: (err) => {
+          this.globalData.isLogin = false;
+          reject(err);
+        },
+      });
+    });
+  },
+
+  // 自动登录
+  async autoLogin(promotionid) {
+    try {
+      // 检查是否已经登录
+      const token = wx.getStorageSync("accessToken");
+      if (token) {
+        // 已经登录
+        console.log("已经登录");
+        return;
+      }
+      // 未登录,执行登录
+      const res = this.login(promotionid);
+    } catch (error) {
+      console.error("登录失败:", error);
     }
-})
+  },
+
+  // 检查登录状态
+  checkLoginStatus() {
+    const token = wx.getStorageSync("accessToken");
+    return !!token && this.globalData.isLogin;
+  },
+
+  globalData: {
+    userInfo: null,
+    isLogin: false,
+    novelManager: {},
+    uuid: "fuck",
+    isShowDialog: false,
+    novelManagerId: 0,
+    novelId: "",
+    chapterIndex: 0,
+    unlockChapterNum: 1,
+    bookmarkAdNum: 3,
+    openId: "",
+    unionId: "",
+    isEnterVideoDetail: false, // 是否进入过视频详情页
+    ads_config: {}, // 广告策略配置
+    userCode: "",
+    from: "",
+    videoAd: null,
+  },
+});
 
 // 插件初始化回调
 async function onNovelPluginLoad(data) {
-    // data.id - 阅读器实例 id,每个插件页对应一个阅读器实例
-    const novelManager = novelPlugin.getNovelManager(data.id)
-    getApp().globalData.novelManagerId = data.id
-    getApp().globalData.novelManager = novelManager
-    rewardVideoLoad()
-
-    // novelManager.setFullScreenComponentStatus({
-    //     show: true,
-    // });
-
-    let pluginInfo = novelManager.getPluginInfo();
-    let innerBookId = pluginInfo.query?.innerBookId;
-    let unlockStatus = await getChapterUnlockStatus({
-        novelId: innerBookId
+  // data.id - 阅读器实例 id,每个插件页对应一个阅读器实例
+  const novelManager = novelPlugin.getNovelManager(data.id);
+  getApp().globalData.novelManagerId = data.id;
+  getApp().globalData.novelManager = novelManager;
+  rewardVideoLoad();
+
+  // novelManager.setFullScreenComponentStatus({
+  //     show: true,
+  // });
+
+  let pluginInfo = novelManager.getPluginInfo();
+  let innerBookId = pluginInfo.query?.innerBookId;
+  let unlockStatus = await getChapterUnlockStatus({
+    novelId: innerBookId,
+  });
+
+  let bookDetail = await getNovelDetail(innerBookId);
+  getApp().globalData.novelId = bookDetail.id;
+  console.log("bookDetail", bookDetail);
+
+  if (unlockStatus && Array.isArray(unlockStatus.status)) {
+    const contents = unlockStatus.status.map((lockState, index) => {
+      return {
+        index: index,
+        status: lockState,
+      };
     });
 
-    let bookDetail = await getNovelDetail(innerBookId);
-    getApp().globalData.novelId = bookDetail.id
-    console.log("bookDetail", bookDetail);
+    novelManager.setContents({
+      contents: contents,
+    });
+    novelManager.setChargeWay({
+      globalConfig: {
+        mode: 5,
+        buttonText: "解锁",
+        showButton: true,
+        tip: "看完广告之后可继续阅读",
+      },
+    });
 
-    if (unlockStatus && Array.isArray(unlockStatus.status)) {
-        const contents = unlockStatus.status.map((lockState, index) => {
-            return {
-                index: index,
-                status: lockState,
-            };
-        });
+    novelManager.onCountdownDoneUnlock((res) => {
+      console.log("novelManager倒计时结束");
+      rewardVideoPlayFn();
+    });
+    novelManager.onUserClickCustomUnlock((res) => {
+      console.log("novelManager 点击解锁");
+      rewardVideoPlayFn();
+    });
 
-        novelManager.setContents({
-            contents: contents,
+    let chapterConfigs = [];
+    for (let index = 0; index < bookDetail.latestChapterNo; index++) {
+      if ((index + 1) % getApp().globalData.bookmarkAdNum === 0) {
+        chapterConfigs.push({
+          chapterIndex: index,
+          blocks: [
+            {
+              type: 3,
+              unitId: apple.ads.bookmarkAdId,
+            },
+          ],
         });
-        novelManager.setChargeWay({
-            globalConfig: {
-                mode: 5,
-                buttonText: '解锁',
-                showButton: true,
-                tip: '看完广告之后可继续阅读',
-            }
-        })
-
-        novelManager.onCountdownDoneUnlock(res => {
-            console.log('novelManager倒计时结束')
-            rewardVideoPlayFn()
-        })
-        novelManager.onUserClickCustomUnlock(res => {
-            console.log('novelManager 点击解锁')
-            rewardVideoPlayFn()
-        })
-
-        let chapterConfigs = []
-        for (let index = 0; index < bookDetail.latestChapterNo; index++) {
-            if ((index + 1) % getApp().globalData.bookmarkAdNum === 0) {
-                chapterConfigs.push({
-                    chapterIndex: index,
-                    blocks: [
-                        {
-                            type: 3,
-                            unitId: apple.ads.bookmarkAdId
-                        }
-                    ]
-                })
-            }
-        }
-
-        novelManager.setAdBlock({
-            chapterConfigs: chapterConfigs
-        })
+      }
     }
 
-    function startRead(res) {
-        console.log('开始阅读', res);
-        updateBrowsingHistory(res);
-    }
+    novelManager.setAdBlock({
+      chapterConfigs: chapterConfigs,
+    });
+  }
+
+  function startRead(res) {
+    console.log("开始阅读", res);
+    updateBrowsingHistory(res);
+  }
+
+  function updateBrowsingHistory(res) {
+    let params = {
+      novelAuthor: bookDetail.author,
+      novelCover: bookDetail.cover,
+      novelId: bookDetail.id,
+      novelTitle: bookDetail.title,
+      status: bookDetail.status,
+    };
+    addBrowsingHistory(params);
+  }
+
+  // 监听用户行为事件
+  novelManager.onUserTriggerEvent((res) => {
+    const { event_id } = res;
+    console.log("用户行为:", event_id, res);
+
+    // 根据不同的事件类型处理
+    switch (event_id) {
+      case "start_read": // 开始阅读
+        console.log("开始阅读章节:", res.chapter_id);
+        SendEvent("start_read", {
+          page: "开始阅读",
+        });
+        getApp().globalData.chapterIndex = res.chapter_index;
+        console.log(
+          "开始阅读跳转",
+          pluginInfo.query?.shared_video_id,
+          pluginInfo.query?.tag_id,
+        );
+        if (pluginInfo.query?.shared_video_id && pluginInfo.query?.tag_id)
+          setTimeout(() => {
+            novelManager.redirectTo({
+              url: `/pages/video/detail?id=${pluginInfo.query?.shared_video_id}&tag_id=${pluginInfo.query?.tag_id}`,
+            });
+          }, 200);
+        break;
+
+      case "click_startread": // 点击开始阅读
+        SendEvent("click_startread", {
+          page: "点击开始阅读",
+        });
+        getApp().globalData.chapterIndex = res.chapter_index;
+        startRead(res);
+        break;
 
-    function updateBrowsingHistory(res) {
-        let params = {
-            novelAuthor: bookDetail.author,
-            novelCover: bookDetail.cover,
-            novelId: bookDetail.id,
-            novelTitle: bookDetail.title,
-            status: bookDetail.status
-        }
-        addBrowsingHistory(params);
-    }
+      case "leave_readpage": // 离开阅读页
+        SendEvent("leave_readpage", {
+          page: "离开阅读页",
+        });
+        console.log("阅读时长:", res.read_time);
+        break;
 
-    // 监听用户行为事件
-    novelManager.onUserTriggerEvent(res => {
-        const {
-            event_id
-        } = res;
-        console.log('用户行为:', event_id, res);
-
-        // 根据不同的事件类型处理
-        switch (event_id) {
-            case 'start_read': // 开始阅读
-                console.log('开始阅读章节:', res.chapter_id);
-                SendEvent('start_read', {
-                    page: '开始阅读'
-                })
-                getApp().globalData.chapterIndex = res.chapter_index
-                console.log('开始阅读跳转', pluginInfo.query?.shared_video_id, pluginInfo.query?.tag_id)
-                if (pluginInfo.query?.shared_video_id && pluginInfo.query?.tag_id)
-                    setTimeout(() => {
-                        novelManager.redirectTo({
-                            url: `/pages/video/detail?id=${pluginInfo.query?.shared_video_id}&tag_id=${pluginInfo.query?.tag_id}`,
-                        });
-                    }, 200)
-                break;
-
-            case 'click_startread': // 点击开始阅读
-                SendEvent('click_startread', {
-                    page: '点击开始阅读'
-                })
-                getApp().globalData.chapterIndex = res.chapter_index
-                startRead(res);
-                break;
-
-            case 'leave_readpage': // 离开阅读页
-                SendEvent('leave_readpage', {
-                    page: '离开阅读页'
-                })
-                console.log('阅读时长:', res.read_time);
-                break;
-
-            case 'change_chapter': // 切换章节
-                SendEvent('change_chapter', {
-                    page: '切换到章节'
-                })
-                getApp().globalData.chapterIndex = res.chapter_index
-                console.log('切换到章节:', res.chapter_id);
-                break;
-
-            case 'get_chapter': // 获取章节数据
-                SendEvent('get_chapter', {
-                    page: '获取章节数据'
-                })
-                console.log("get_chapter", res);
-                console.log('章节状态:', res.pay_status);
-                break;
-
-            default:
-                break;
-        }
-    })
+      case "change_chapter": // 切换章节
+        SendEvent("change_chapter", {
+          page: "切换到章节",
+        });
+        getApp().globalData.chapterIndex = res.chapter_index;
+        console.log("切换到章节:", res.chapter_id);
+        break;
+
+      case "get_chapter": // 获取章节数据
+        SendEvent("get_chapter", {
+          page: "获取章节数据",
+        });
+        console.log("get_chapter", res);
+        console.log("章节状态:", res.pay_status);
+        break;
+
+      default:
+        break;
+    }
+  });
 }
 
 // 激励视频加载
 function rewardVideoLoad() {
-    if (getApp().globalData.videoAd === null && wx.createRewardedVideoAd) {
-        getApp().globalData.videoAd = wx.createRewardedVideoAd({
-            adUnitId: apple.ads.rewardAdId
-        })
-        getApp().globalData.videoAd.onLoad(() => {
-            console.log('激励加载成功')
-        })
-        getApp().globalData.videoAd.onError((err) => {
-            console.log('激励失败', err)
-        })
-
-        getApp().globalData.videoAd.onClose((res) => {
-            const novelManager = novelPlugin.getNovelManager(getApp().globalData.novelManagerId)
-            if (res && res.isEnded) {
-                let params = {
-                    chapterNo: getApp().globalData.chapterIndex,
-                    novelId: getApp().globalData.novelId,
-                    type: 1
-                }
-                unlockChapter(params).then(res => {
-                    console.log(res)
-                    novelManager.paymentCompleted({
-                        chapterIndex: getApp().globalData.chapterIndex
-                    })
-                    console.log('章节解锁成功', getApp().globalData.chapterIndex)
-                })
-            } else {
-                novelManager.closeChargeDialog()
-                console.log('关闭解锁组件')
-            }
-        })
-    }
+  if (getApp().globalData.videoAd === null && wx.createRewardedVideoAd) {
+    getApp().globalData.videoAd = wx.createRewardedVideoAd({
+      adUnitId: apple.ads.rewardAdId,
+    });
+    getApp().globalData.videoAd.onLoad(() => {
+      console.log("激励加载成功");
+    });
+    getApp().globalData.videoAd.onError((err) => {
+      console.log("激励失败", err);
+    });
+
+    getApp().globalData.videoAd.onClose((res) => {
+      const novelManager = novelPlugin.getNovelManager(
+        getApp().globalData.novelManagerId,
+      );
+      if (res && res.isEnded) {
+        let params = {
+          chapterNo: getApp().globalData.chapterIndex,
+          novelId: getApp().globalData.novelId,
+          type: 1,
+        };
+        unlockChapter(params).then((res) => {
+          console.log(res);
+          novelManager.paymentCompleted({
+            chapterIndex: getApp().globalData.chapterIndex,
+          });
+          console.log("章节解锁成功", getApp().globalData.chapterIndex);
+        });
+      } else {
+        novelManager.closeChargeDialog();
+        console.log("关闭解锁组件");
+      }
+    });
+  }
 }
 
 // 激励视频展示
 function rewardVideoPlayFn() {
-    wx.showLoading({
-        title: '解锁视频中',
+  wx.showLoading({
+    title: "解锁视频中",
+  });
+  getApp()
+    .globalData.videoAd.show()
+    .then(() => {
+      console.log("激励视频播放成功");
     })
-    getApp().globalData.videoAd.show().then(() => {
-        console.log('激励视频播放成功')
-    }).catch((err) => {
-        console.log('激励视频播放失败', err)
-    }).then(() => {
-        wx.hideLoading()
+    .catch((err) => {
+      console.log("激励视频播放失败", err);
     })
+    .then(() => {
+      wx.hideLoading();
+    });
 }

+ 4 - 2
app.json

@@ -9,7 +9,8 @@
     "pages/book/list",
     "pages/search/search",
     "pages/video/video",
-    "pages/video/detail"
+    "pages/video/detail",
+    "pages/collect-video/video"
   ],
   "window": {
     "navigationStyle": "custom",
@@ -67,4 +68,5 @@
   "componentFramework": "glass-easel",
   "sitemapLocation": "sitemap.json",
   "lazyCodeLoading": "requiredComponents"
-}
+}
+

BIN
assets/images/playing.png


BIN
assets/images/tv.png


+ 549 - 495
config/config.js

@@ -1,505 +1,559 @@
 const appInfoObj = {
-    wxa7a33088566e1292: {
-        appid: "wxa7a33088566e1292",
-        ghid: "gh_4e55f615d5dc",
-        appName: "视读空间",
-        ads: {
-            insertAdId: "adunit-37ee342a8fc046b7",
-            rewardAdId: "adunit-7df7b95b78f624f8",
-            bookmarkAdId: "adunit-343af082b8c8ea18",
-            templateAdId: "adunit-80f6ec7a264f968b",
-        },
-    },
-    wxa13166979d7011c4: {
-        appid: "wxa13166979d7011c4",
-        ghid: "gh_dd2c1a9b59d8",
-        appName: "稻香悦读视界",
-        ads: {
-            insertAdId: "adunit-6f652c983c83b94a",
-            rewardAdId: "adunit-62327e73abec00ec",
-            bookmarkAdId: "adunit-4abed888086e614e",
-            templateAdId: "adunit-649273f8a7428d0c",
-        },
-    },
-    wx8a8aae7f462df482: {
-        appid: "wx8a8aae7f462df482",
-        ghid: "gh_1098838a2d7e",
-        appName: "稻香悠享阅界",
-        ads: {
-            insertAdId: "adunit-099862d68eb0c19e",
-            rewardAdId: "adunit-7ff33188ea39abf1",
-            bookmarkAdId: "adunit-ce71b57d87227b6c",
-            templateAdId: "adunit-0d3db2f0131d82d3",
-        },
-    },
-    wx1344c35820ac688e: {
-        appid: "wx1344c35820ac688e",
-        ghid: "gh_e6ca97959a69",
-        appName: "稻香悠享视界",
-        ads: {
-            insertAdId: "adunit-cd80b2eb24606ae1",
-            rewardAdId: "adunit-9556014e024c3193",
-            bookmarkAdId: "adunit-0da094052a6d4149",
-            templateAdId: "adunit-4850c8e6d5c25efc",
-        },
-    },
-    wx8bd40e8ce9deb2b6: {
-        appid: "wx8bd40e8ce9deb2b6",
-        ghid: "gh_c40c32e29788",
-        appName: "稻香悦读空间",
-        ads: {
-            insertAdId: "adunit-845614eb5c48a349",
-            rewardAdId: "adunit-ace5375fafb06dde",
-            bookmarkAdId: "adunit-38b29a959923f2ab",
-            templateAdId: "adunit-29715e8ff52accc0",
-        },
-    },
-    wx9e90adce31181f7f: {
-        appid: "wx9e90adce31181f7f",
-        ghid: "gh_8a8044f49d85",
-        appName: "稻香视读空间",
-        ads: {
-            insertAdId: "adunit-37c9e33d8a286c1c",
-            rewardAdId: "adunit-22c7928ec266c640",
-            bookmarkAdId: "adunit-e88afcea1a5e259f",
-            templateAdId: "adunit-19d6379df05c8482",
-        },
-    },
-    wxdabfa5e02785fe9b: {
-        appid: "wxdabfa5e02785fe9b",
-        ghid: "gh_cb3eb04d904c",
-        appName: "稻阅视觉",
-        ads: {
-            insertAdId: "adunit-2be3e81517d06870",
-            rewardAdId: "adunit-f227f9580844948a",
-            bookmarkAdId: "adunit-76e2c4d9e0dd6cfa",
-            templateAdId: "adunit-2150b3c315deb165",
-        },
-    },
-    wx37dab28af5492d98: {
-        appid: "wx37dab28af5492d98",
-        ghid: "gh_c153bd1f3877",
-        appName: "蓝晶甄读空间",
-        ads: {
-            insertAdId: "adunit-8a2a50d93002887f",
-            rewardAdId: "adunit-465e6429a9886f64",
-            bookmarkAdId: "adunit-5e97262afcfa6bc4",
-            templateAdId: "adunit-c7f449e43a19593a",
-        },
-    },
-    wx04b705205757217b: {
-        appid: "wx04b705205757217b",
-        ghid: "gh_0f1c04dc3790",
-        appName: "蓝晶享看空间",
-        ads: {},
-    },
-    wxc4e78d0425e83571: {
-        appid: "wxc4e78d0425e83571",
-        ghid: "gh_e0fd18c3f79f",
-        appName: "蓝晶悦享视界",
-        ads: {},
-    },
-    wx9d93825db1c7dcbe: {
-        appid: "wx9d93825db1c7dcbe",
-        ghid: "gh_1042b9599e05",
-        appName: "蓝晶看这视界",
-        ads: {
-            insertAdId: "adunit-e034d1512362cc26",
-            rewardAdId: "adunit-39bffc44f27f8d46",
-            bookmarkAdId: "adunit-3097633e13d9d2c7",
-            templateAdId: "adunit-7ac384f29d306c14",
-        },
-    },
-    wx3fe2e6c200ec7133: {
-        appid: "wx3fe2e6c200ec7133",
-        ghid: "gh_298cbd19ddcb",
-        appName: "蓝晶畅看视界",
-        ads: {
-            insertAdId: "adunit-a9b7bc395d3fd3f6",
-            rewardAdId: "adunit-d05aadf553c7e1be",
-            bookmarkAdId: "adunit-2dfb09a147900542",
-            templateAdId: "adunit-d79320739b2741d3",
-        },
-    },
-    wx3800bb2ed4a326c5: {
-        appid: "wx3800bb2ed4a326c5",
-        ghid: "gh_7e70db53a149",
-        appName: "蓝晶享看视界",
-        ads: {
-            insertAdId: "adunit-b84544f2078afaea",
-            rewardAdId: "adunit-e46d123c61e26dc3",
-            bookmarkAdId: "adunit-adc28f71b145520a",
-            templateAdId: "adunit-6b81fb8f0e662aa8",
-        },
-    },
-    // ------------------------2025-04-11 新增
-    wxa721f4474e3d548a: {
-        appid: "wxa721f4474e3d548a",
-        ghid: "gh_63df1cb1521b",
-        appName: "蓝晶创映空间",
-        ads: {
-            insertAdId: "adunit-68b3d5c56e04e960",
-            rewardAdId: "adunit-21a681a835b2c8b3",
-            bookmarkAdId: "adunit-b02b93b1ec5f4c58",
-            templateAdId: "adunit-84aaf08a02103ec2",
-        },
-    },
-    wxc5e6b24889027032: {
-        appid: "wxc5e6b24889027032",
-        ghid: "gh_87e9da72ca79",
-        appName: "蓝晶云瞰视界",
-        ads: {
-            insertAdId: "adunit-4b6c744ac34086e7",
-            rewardAdId: "adunit-b4dac0748889527e",
-            bookmarkAdId: "adunit-724d975f3bf271d6",
-            templateAdId: "adunit-6419d9748ccf8d08",
-        },
-    },
-    wxef68681d5044ca05: {
-        appid: "wxef68681d5044ca05", // 小说类目没过
-        ghid: "gh_1a76c4ef014a",
-        appName: "蓝晶帧享视界",
-        ads: {
-            insertAdId: "adunit-e253e1de485f4921",
-            rewardAdId: "adunit-9918e9c1a74ddfe5",
-            bookmarkAdId: "adunit-7414ced26816ab2f",
-            templateAdId: "adunit-97c63bae25dbe549",
-        },
-    },
-    wx706acdc696d025ad: {
-        appid: "wx706acdc696d025ad",
-        ghid: "gh_e9351f804e32",
-        appName: "蓝晶视界漫游",
-        ads: {
-            insertAdId: "adunit-60aa9f77aa212dee",
-            rewardAdId: "adunit-ee1380631c491575",
-            bookmarkAdId: "adunit-1d61149bc2a69e8d",
-            templateAdId: "adunit-52415537ff6eb87e",
-        },
-    },
-    wx8288d587b717897e: {
-        appid: "wx8288d587b717897e",
-        ghid: "gh_7d5b65ac29ee",
-        appName: "蓝晶瞰影工坊",
-        ads: {
-            insertAdId: "adunit-897cd1bac6818154",
-            rewardAdId: "adunit-c686fbe741463800",
-            bookmarkAdId: "adunit-9e9e06a14d110a81",
-            templateAdId: "adunit-c59fe75d4b496cd9",
-        },
-    },
-    wx54a8d0e7b33c48c8: {
-        appid: "wx54a8d0e7b33c48c8", // 小说类目没过
-        ghid: "gh_cbbd0f0b8865",
-        appName: "蓝晶帧探视界",
-        ads: {
-            insertAdId: "adunit-83b5b14d08f7da00",
-            rewardAdId: "adunit-cb9ddb2b7b42c17f",
-            bookmarkAdId: "adunit-8fb3cee5580d91cc",
-            templateAdId: "adunit-1ffde1b5de20cf4f",
-        },
-    },
-    wx0138dee6d680c705: {
-        appid: "wx0138dee6d680c705",
-        ghid: "gh_f82668af04f8",
-        appName: "蓝晶视海遨游",
-        ads: {
-            insertAdId: "adunit-e87983ad642e7cf9",
-            rewardAdId: "adunit-d719bf4ba6d98eb4",
-            bookmarkAdId: "adunit-e93e248eb00a5877",
-            templateAdId: "adunit-84b0358ab4f5f540",
-        },
-    },
-    wx4420e2d55b0ede27: {
-        appid: "wx4420e2d55b0ede27",
-        ghid: "gh_16815103d58f",
-        appName: "蓝晶影创空间",
-        ads: {
-            insertAdId: "adunit-c7b0d21d8de6928a",
-            rewardAdId: "adunit-d88c33e7e38116d2",
-            bookmarkAdId: "adunit-798a05dbad0f6eeb",
-            templateAdId: "adunit-f17b64f6898d6c57",
-        },
-    },
-    wx1eb74c589da1731f: {
-        appid: "wx1eb74c589da1731f",
-        ghid: "gh_e8ccd3f2b283",
-        appName: "蓝晶视界奇遇",
-        ads: {
-            insertAdId: "adunit-1cd2be68dcac5cca",
-            rewardAdId: "adunit-691ad12b3e1db48b",
-            bookmarkAdId: "adunit-61e1e71ba4130ea6",
-            templateAdId: "adunit-ad17239cb71da086",
-        },
-    },
-    // -------------------------2025-04-15 新增
-    wx9641ddf3bfce4fe7: {
-        appid: "wx9641ddf3bfce4fe7",
-        ghid: "gh_64bd22957a0b",
-        appName: "蓝晶视界工场",
-        ads: {},
-    },
-    wxf2dd3343ad28ec14: {
-        appid: "wxf2dd3343ad28ec14",
-        ghid: "gh_d0e730b0b751",
-        appName: "蓝晶帧溯视界",
-        ads: {},
-    },
-    wxfd680c7b25e81a0f: {
-        appid: "wxfd680c7b25e81a0f",
-        ghid: "gh_4eb2c76973fb",
-        appName: "蓝晶视链星云",
-        ads: {},
-    },
-    wx246f273102a99f45: {
-        appid: "wx246f273102a99f45",
-        ghid: "gh_9da98ef130ee",
-        appName: "蓝晶映界魔盒",
-        ads: {},
-    },
-    wxee36470b004439ea: {
-        appid: "wxee36470b004439ea",
-        ghid: "gh_fcda1c86f2d5",
-        appName: "蓝晶像素工场",
-        ads: {},
-    },
-    wx6dacc3c0d8cb4b9f: {
-        appid: "wx6dacc3c0d8cb4b9f",
-        ghid: "gh_77c67c3bbe01",
-        appName: "蓝晶帧域奇点",
-        ads: {
-            insertAdId: "adunit-cc27495210286bbb",
-            rewardAdId: "adunit-31600fa1ffff6ed7",
-            bookmarkAdId: "adunit-8cba3bbf7421f8c9",
-            templateAdId: "adunit-ebedec0bf2de9567",
-        },
-    },
-    wx39a47cc77988c431: {
-        appid: "wx39a47cc77988c431",
-        ghid: "gh_7744bebfa666",
-        appName: "蓝晶流影矩阵",
-        ads: {
-            insertAdId: "adunit-162bfa5b0607bf70",
-            rewardAdId: "adunit-4d681b61a9524179",
-            bookmarkAdId: "adunit-7b7d271e015b80e7",
-            templateAdId: "adunit-a3b1238500930b83",
-        },
-    },
-    wx91a45e115ece8a3e: {
-        appid: "wx91a45e115ece8a3e",
-        ghid: "gh_ec4e9f908f9f",
-        appName: "蓝晶帧跃视廊",
-        ads: {
-            insertAdId: "adunit-4825c8c1648b4058",
-            rewardAdId: "adunit-7f60a732a67c05c1",
-            bookmarkAdId: "adunit-6ae9423dc680f053",
-            templateAdId: "adunit-350617cea0f90fc3",
-        },
-    },
-    wx6e80e54b9ce8a47d: {
-        appid: "wx6e80e54b9ce8a47d",
-        ghid: "gh_1bacd9d64b74",
-        appName: "蓝晶视创云端",
-        ads: {},
-    },
-    wx6b11ce533c3aca92: {
-        appid: "wx6b11ce533c3aca92",
-        ghid: "gh_6f31b8bf1d53",
-        appName: "蓝晶光迹映画",
-        ads: {
-            insertAdId: "adunit-15276e04608095fc",
-            rewardAdId: "adunit-6fe168a7dd2eaadc",
-            bookmarkAdId: "adunit-8812127668d07aa2",
-            templateAdId: "adunit-87de056e4170a4c1",
-        },
-    },
-    wx5d607cf4fa663c72: {
-        appid: "wx5d607cf4fa663c72",
-        ghid: "gh_37d4da670892",
-        appName: "蓝晶光映视看",
-        ads: {
-            insertAdId: "adunit-4de4c80bc90c9221",
-            rewardAdId: "adunit-90022d0fa596af34",
-            bookmarkAdId: "adunit-aa6b3952f83a0a77",
-            templateAdId: "adunit-8337678adccb5bc6",
-        },
-    },
-    wxa9fb660c0d4bd708: {
-        appid: "wxa9fb660c0d4bd708",
-        ghid: "gh_2967a8bee850",
-        appName: "蓝晶光影漫游",
-        ads: {},
-    },
-    wxbece4f28b6b71271: {
-        appid: "wxbece4f28b6b71271",
-        ghid: "gh_a1ab49f66596",
-        appName: "蓝晶视能引擎",
-        ads: {
-            insertAdId: "adunit-2320f5752b792e1a",
-            rewardAdId: "adunit-da3f6d50065110b8",
-            bookmarkAdId: "adunit-230da9c9674853c6",
-            templateAdId: "adunit-8c77ec239912ff08",
-        },
-    },
-    wxf91f09a57b8aa3ae: {
-        appid: "wxf91f09a57b8aa3ae",
-        ghid: "gh_4b248a5a37a0",
-        appName: "蓝晶帧溯星海",
-        ads: {
-            insertAdId: "adunit-d7202e1676297bec",
-            rewardAdId: "adunit-13310c06b167d192",
-            bookmarkAdId: "adunit-b709500d5e4f798e",
-            templateAdId: "adunit-f31053cebe9b6779",
-        },
-    },
-    wxdd1bde4de9f6a6a0: {
-        appid: "wxdd1bde4de9f6a6a0",
-        ghid: "gh_028e0784579d",
-        appName: "蓝晶帧界星空",
-        ads: {
-            insertAdId: "adunit-5077cf6f1e8f92a7",
-            rewardAdId: "adunit-4d94f2cf076eb4c2",
-            bookmarkAdId: "adunit-8a319ef3795bd800",
-            templateAdId: "adunit-344650623385d050",
-        },
-    },
-    wxcdfd21a368ed2ced: {
-        appid: "wxcdfd21a368ed2ced",
-        ghid: "gh_e144db7dd445",
-        appName: "蓝晶视界星链",
-        ads: {},
-    },
-    wxbf40c735c0d263a5: {
-        appid: "wxbf40c735c0d263a5",
-        ghid: "gh_5203fc3a1f80",
-        appName: "蓝晶影创视野",
-        ads: {
-            insertAdId: "adunit-35128a8198535637",
-            rewardAdId: "adunit-31fcc8515e7ea865",
-            bookmarkAdId: "adunit-1b5bd8389f76239d",
-            templateAdId: "adunit-2f5df77a0dfe5153",
-        },
-    },
-    wxf0248772f67666ee: {
-        appid: "wxf0248772f67666ee",
-        ghid: "gh_e43f5a747e67",
-        appName: "蓝晶映画视界",
-        ads: {},
-    },
-    wx3f464072571c1fd3: {
-        appid: "wx3f464072571c1fd3",
-        ghid: "gh_f4b45b2b82af",
-        appName: "蓝晶影音视看",
-        ads: {
-            insertAdId: "adunit-d700b1959d308def",
-            rewardAdId: "adunit-aed9cf18e2b32be6",
-            bookmarkAdId: "adunit-5034fd21f47c3c06",
-            templateAdId: "adunit-c1493205859ee2d2",
-        },
-    },
-    // -------------------------2025-04-22 新增
-    wxdf7e08f21084c8e2: {
-        appid: "wxdf7e08f21084c8e2",
-        ghid: "gh_5030bf66aef0",
-        appName: "蓝晶影迹视界",
-        ads: {},
-    },
-    wx092045bdfe26a5ee: {
-        appid: "wx092045bdfe26a5ee",
-        ghid: "gh_f68920763a81",
-        appName: "蓝晶映见星云",
-        ads: {
-            insertAdId: "adunit-6625b1f0896a394f",
-            rewardAdId: "adunit-15db2a87322ef917",
-            bookmarkAdId: "adunit-6203c9e333bbeae5",
-            templateAdId: "adunit-252a5a156dd3a298",
-        },
-    },
-    wx6c4bb5ef1e6c1e70: {
-        appid: "wx6c4bb5ef1e6c1e70",
-        ghid: "gh_b6e8f03fc727",
-        appName: "蓝晶映画视野",
-        ads: {
-            insertAdId: "adunit-f5ae3d618ee14477",
-            rewardAdId: "adunit-abf25e90d698285c",
-            bookmarkAdId: "adunit-6e2c127031bb88f2",
-            templateAdId: "adunit-94ac9867830f3296",
-        },
-    },
-    wx60db1bff60cd771c: {
-        appid: "wx60db1bff60cd771c",
-        ghid: "gh_01f93f7f5035",
-        appName: "蓝晶光影视野",
-        ads: {
-            insertAdId: "adunit-9f07220c0aaffa26",
-            rewardAdId: "adunit-d94991b8abf13dc7",
-            bookmarkAdId: "adunit-45c3a29471d987c3",
-            templateAdId: "adunit-22fb35825020838a",
-        },
-    },
-    wx5a9dda0604c2ea67: {
-        appid: "wx5a9dda0604c2ea67",
-        ghid: "gh_a186898d8dcc",
-        appName: "蓝晶视语工场",
-        ads: {},
-    },
-    wxdecb83db79aa5bc0: {
-        appid: "wxdecb83db79aa5bc0",
-        ghid: "gh_ac31f1281a2e",
-        appName: "蓝晶视觉魔方",
-        ads: {},
-    },
-    wx616a7e327bd9574a: {
-        appid: "wx616a7e327bd9574a",
-        ghid: "gh_06dab34906a2",
-        appName: "蓝晶影构空间",
-        ads: {},
-    },
-    wxdcf60b8e89ff6fa0: {
-        appid: "wxdcf60b8e89ff6fa0",
-        ghid: "gh_0c04415d1aec",
-        appName: "蓝晶视能象限",
-        ads: {},
-    },
-    wx54c216ec4ad011fd: {
-        appid: "wx54c216ec4ad011fd",
-        ghid: "gh_27b2a85570df",
-        appName: "蓝晶映动视廊",
-        ads: {},
-    },
-    wxd40b677f35319eea: {
-        appid: "wxd40b677f35319eea",
-        ghid: "gh_303939d4a258",
-        appName: "蓝晶云映视界",
-        ads: {},
-    },
+  wxa7a33088566e1292: {
+    appid: "wxa7a33088566e1292",
+    ghid: "gh_4e55f615d5dc",
+    appName: "视读空间",
+    ads: {
+      insertAdId: "adunit-37ee342a8fc046b7",
+      rewardAdId: "adunit-7df7b95b78f624f8",
+      bookmarkAdId: "adunit-343af082b8c8ea18",
+      templateAdId: "adunit-80f6ec7a264f968b",
+    },
+  },
+  wxa13166979d7011c4: {
+    appid: "wxa13166979d7011c4",
+    ghid: "gh_dd2c1a9b59d8",
+    appName: "稻香悦读视界",
+    ads: {
+      insertAdId: "adunit-6f652c983c83b94a",
+      rewardAdId: "adunit-62327e73abec00ec",
+      bookmarkAdId: "adunit-4abed888086e614e",
+      templateAdId: "adunit-649273f8a7428d0c",
+    },
+  },
+  wx8a8aae7f462df482: {
+    appid: "wx8a8aae7f462df482",
+    ghid: "gh_1098838a2d7e",
+    appName: "稻香悠享阅界",
+    ads: {
+      insertAdId: "adunit-099862d68eb0c19e",
+      rewardAdId: "adunit-7ff33188ea39abf1",
+      bookmarkAdId: "adunit-ce71b57d87227b6c",
+      templateAdId: "adunit-0d3db2f0131d82d3",
+    },
+  },
+  wx1344c35820ac688e: {
+    appid: "wx1344c35820ac688e",
+    ghid: "gh_e6ca97959a69",
+    appName: "稻香悠享视界",
+    ads: {
+      insertAdId: "adunit-cd80b2eb24606ae1",
+      rewardAdId: "adunit-9556014e024c3193",
+      bookmarkAdId: "adunit-0da094052a6d4149",
+      templateAdId: "adunit-4850c8e6d5c25efc",
+    },
+  },
+  wx8bd40e8ce9deb2b6: {
+    appid: "wx8bd40e8ce9deb2b6",
+    ghid: "gh_c40c32e29788",
+    appName: "稻香悦读空间",
+    ads: {
+      insertAdId: "adunit-845614eb5c48a349",
+      rewardAdId: "adunit-ace5375fafb06dde",
+      bookmarkAdId: "adunit-38b29a959923f2ab",
+      templateAdId: "adunit-29715e8ff52accc0",
+    },
+  },
+  wx9e90adce31181f7f: {
+    appid: "wx9e90adce31181f7f",
+    ghid: "gh_8a8044f49d85",
+    appName: "稻香视读空间",
+    ads: {
+      insertAdId: "adunit-37c9e33d8a286c1c",
+      rewardAdId: "adunit-22c7928ec266c640",
+      bookmarkAdId: "adunit-e88afcea1a5e259f",
+      templateAdId: "adunit-19d6379df05c8482",
+    },
+  },
+  wxdabfa5e02785fe9b: {
+    appid: "wxdabfa5e02785fe9b",
+    ghid: "gh_cb3eb04d904c",
+    appName: "稻阅视觉",
+    ads: {
+      insertAdId: "adunit-2be3e81517d06870",
+      rewardAdId: "adunit-f227f9580844948a",
+      bookmarkAdId: "adunit-76e2c4d9e0dd6cfa",
+      templateAdId: "adunit-2150b3c315deb165",
+    },
+  },
+  wx37dab28af5492d98: {
+    appid: "wx37dab28af5492d98",
+    ghid: "gh_c153bd1f3877",
+    appName: "蓝晶甄读空间",
+    ads: {
+      insertAdId: "adunit-8a2a50d93002887f",
+      rewardAdId: "adunit-465e6429a9886f64",
+      bookmarkAdId: "adunit-5e97262afcfa6bc4",
+      templateAdId: "adunit-c7f449e43a19593a",
+    },
+  },
+  wx04b705205757217b: {
+    appid: "wx04b705205757217b",
+    ghid: "gh_0f1c04dc3790",
+    appName: "蓝晶享看空间",
+    ads: {},
+  },
+  wxc4e78d0425e83571: {
+    appid: "wxc4e78d0425e83571",
+    ghid: "gh_e0fd18c3f79f",
+    appName: "蓝晶悦享视界",
+    ads: {},
+  },
+  wx9d93825db1c7dcbe: {
+    appid: "wx9d93825db1c7dcbe",
+    ghid: "gh_1042b9599e05",
+    appName: "蓝晶看这视界",
+    ads: {
+      insertAdId: "adunit-e034d1512362cc26",
+      rewardAdId: "adunit-39bffc44f27f8d46",
+      bookmarkAdId: "adunit-3097633e13d9d2c7",
+      templateAdId: "adunit-7ac384f29d306c14",
+    },
+  },
+  wx3fe2e6c200ec7133: {
+    appid: "wx3fe2e6c200ec7133",
+    ghid: "gh_298cbd19ddcb",
+    appName: "蓝晶畅看视界",
+    ads: {
+      insertAdId: "adunit-a9b7bc395d3fd3f6",
+      rewardAdId: "adunit-d05aadf553c7e1be",
+      bookmarkAdId: "adunit-2dfb09a147900542",
+      templateAdId: "adunit-d79320739b2741d3",
+    },
+  },
+  wx3800bb2ed4a326c5: {
+    appid: "wx3800bb2ed4a326c5",
+    ghid: "gh_7e70db53a149",
+    appName: "蓝晶享看视界",
+    ads: {
+      insertAdId: "adunit-b84544f2078afaea",
+      rewardAdId: "adunit-e46d123c61e26dc3",
+      bookmarkAdId: "adunit-adc28f71b145520a",
+      templateAdId: "adunit-6b81fb8f0e662aa8",
+    },
+  },
+  // ------------------------2025-04-11 新增
+  wxa721f4474e3d548a: {
+    appid: "wxa721f4474e3d548a",
+    ghid: "gh_63df1cb1521b",
+    appName: "蓝晶创映空间",
+    ads: {
+      insertAdId: "adunit-68b3d5c56e04e960",
+      rewardAdId: "adunit-21a681a835b2c8b3",
+      bookmarkAdId: "adunit-b02b93b1ec5f4c58",
+      templateAdId: "adunit-84aaf08a02103ec2",
+    },
+  },
+  wxc5e6b24889027032: {
+    appid: "wxc5e6b24889027032",
+    ghid: "gh_87e9da72ca79",
+    appName: "蓝晶云瞰视界",
+    ads: {
+      insertAdId: "adunit-4b6c744ac34086e7",
+      rewardAdId: "adunit-b4dac0748889527e",
+      bookmarkAdId: "adunit-724d975f3bf271d6",
+      templateAdId: "adunit-6419d9748ccf8d08",
+    },
+  },
+  wxef68681d5044ca05: {
+    appid: "wxef68681d5044ca05", // 小说类目没过
+    ghid: "gh_1a76c4ef014a",
+    appName: "蓝晶帧享视界",
+    ads: {
+      insertAdId: "adunit-e253e1de485f4921",
+      rewardAdId: "adunit-9918e9c1a74ddfe5",
+      bookmarkAdId: "adunit-7414ced26816ab2f",
+      templateAdId: "adunit-97c63bae25dbe549",
+    },
+  },
+  wx706acdc696d025ad: {
+    appid: "wx706acdc696d025ad",
+    ghid: "gh_e9351f804e32",
+    appName: "蓝晶视界漫游",
+    ads: {
+      insertAdId: "adunit-60aa9f77aa212dee",
+      rewardAdId: "adunit-ee1380631c491575",
+      bookmarkAdId: "adunit-1d61149bc2a69e8d",
+      templateAdId: "adunit-52415537ff6eb87e",
+    },
+  },
+  wx8288d587b717897e: {
+    appid: "wx8288d587b717897e",
+    ghid: "gh_7d5b65ac29ee",
+    appName: "蓝晶瞰影工坊",
+    ads: {
+      insertAdId: "adunit-897cd1bac6818154",
+      rewardAdId: "adunit-c686fbe741463800",
+      bookmarkAdId: "adunit-9e9e06a14d110a81",
+      templateAdId: "adunit-c59fe75d4b496cd9",
+    },
+  },
+  wx54a8d0e7b33c48c8: {
+    appid: "wx54a8d0e7b33c48c8", // 小说类目没过
+    ghid: "gh_cbbd0f0b8865",
+    appName: "蓝晶帧探视界",
+    ads: {
+      insertAdId: "adunit-83b5b14d08f7da00",
+      rewardAdId: "adunit-cb9ddb2b7b42c17f",
+      bookmarkAdId: "adunit-8fb3cee5580d91cc",
+      templateAdId: "adunit-1ffde1b5de20cf4f",
+    },
+  },
+  wx0138dee6d680c705: {
+    appid: "wx0138dee6d680c705",
+    ghid: "gh_f82668af04f8",
+    appName: "蓝晶视海遨游",
+    ads: {
+      insertAdId: "adunit-e87983ad642e7cf9",
+      rewardAdId: "adunit-d719bf4ba6d98eb4",
+      bookmarkAdId: "adunit-e93e248eb00a5877",
+      templateAdId: "adunit-84b0358ab4f5f540",
+    },
+  },
+  wx4420e2d55b0ede27: {
+    appid: "wx4420e2d55b0ede27",
+    ghid: "gh_16815103d58f",
+    appName: "蓝晶影创空间",
+    ads: {
+      insertAdId: "adunit-c7b0d21d8de6928a",
+      rewardAdId: "adunit-d88c33e7e38116d2",
+      bookmarkAdId: "adunit-798a05dbad0f6eeb",
+      templateAdId: "adunit-f17b64f6898d6c57",
+    },
+  },
+  wx1eb74c589da1731f: {
+    appid: "wx1eb74c589da1731f",
+    ghid: "gh_e8ccd3f2b283",
+    appName: "蓝晶视界奇遇",
+    ads: {
+      insertAdId: "adunit-1cd2be68dcac5cca",
+      rewardAdId: "adunit-691ad12b3e1db48b",
+      bookmarkAdId: "adunit-61e1e71ba4130ea6",
+      templateAdId: "adunit-ad17239cb71da086",
+    },
+  },
+  // -------------------------2025-04-15 新增
+  wx9641ddf3bfce4fe7: {
+    appid: "wx9641ddf3bfce4fe7",
+    ghid: "gh_64bd22957a0b",
+    appName: "蓝晶视界工场",
+    ads: {},
+  },
+  wxf2dd3343ad28ec14: {
+    appid: "wxf2dd3343ad28ec14",
+    ghid: "gh_d0e730b0b751",
+    appName: "蓝晶帧溯视界",
+    ads: {},
+  },
+  wxfd680c7b25e81a0f: {
+    appid: "wxfd680c7b25e81a0f",
+    ghid: "gh_4eb2c76973fb",
+    appName: "蓝晶视链星云",
+    ads: {},
+  },
+  wx246f273102a99f45: {
+    appid: "wx246f273102a99f45",
+    ghid: "gh_9da98ef130ee",
+    appName: "蓝晶映界魔盒",
+    ads: {},
+  },
+  wxee36470b004439ea: {
+    appid: "wxee36470b004439ea",
+    ghid: "gh_fcda1c86f2d5",
+    appName: "蓝晶像素工场",
+    ads: {},
+  },
+  wx6dacc3c0d8cb4b9f: {
+    appid: "wx6dacc3c0d8cb4b9f",
+    ghid: "gh_77c67c3bbe01",
+    appName: "蓝晶帧域奇点",
+    ads: {
+      insertAdId: "adunit-cc27495210286bbb",
+      rewardAdId: "adunit-31600fa1ffff6ed7",
+      bookmarkAdId: "adunit-8cba3bbf7421f8c9",
+      templateAdId: "adunit-ebedec0bf2de9567",
+    },
+  },
+  wx39a47cc77988c431: {
+    appid: "wx39a47cc77988c431",
+    ghid: "gh_7744bebfa666",
+    appName: "蓝晶流影矩阵",
+    ads: {
+      insertAdId: "adunit-162bfa5b0607bf70",
+      rewardAdId: "adunit-4d681b61a9524179",
+      bookmarkAdId: "adunit-7b7d271e015b80e7",
+      templateAdId: "adunit-a3b1238500930b83",
+    },
+  },
+  wx91a45e115ece8a3e: {
+    appid: "wx91a45e115ece8a3e",
+    ghid: "gh_ec4e9f908f9f",
+    appName: "蓝晶帧跃视廊",
+    ads: {
+      insertAdId: "adunit-4825c8c1648b4058",
+      rewardAdId: "adunit-7f60a732a67c05c1",
+      bookmarkAdId: "adunit-6ae9423dc680f053",
+      templateAdId: "adunit-350617cea0f90fc3",
+    },
+  },
+  wx6e80e54b9ce8a47d: {
+    appid: "wx6e80e54b9ce8a47d",
+    ghid: "gh_1bacd9d64b74",
+    appName: "蓝晶视创云端",
+    ads: {},
+  },
+  wx6b11ce533c3aca92: {
+    appid: "wx6b11ce533c3aca92",
+    ghid: "gh_6f31b8bf1d53",
+    appName: "蓝晶光迹映画",
+    ads: {
+      insertAdId: "adunit-15276e04608095fc",
+      rewardAdId: "adunit-6fe168a7dd2eaadc",
+      bookmarkAdId: "adunit-8812127668d07aa2",
+      templateAdId: "adunit-87de056e4170a4c1",
+    },
+  },
+  wx5d607cf4fa663c72: {
+    appid: "wx5d607cf4fa663c72",
+    ghid: "gh_37d4da670892",
+    appName: "蓝晶光映视看",
+    ads: {
+      insertAdId: "adunit-4de4c80bc90c9221",
+      rewardAdId: "adunit-90022d0fa596af34",
+      bookmarkAdId: "adunit-aa6b3952f83a0a77",
+      templateAdId: "adunit-8337678adccb5bc6",
+    },
+  },
+  wxa9fb660c0d4bd708: {
+    appid: "wxa9fb660c0d4bd708",
+    ghid: "gh_2967a8bee850",
+    appName: "蓝晶光影漫游",
+    ads: {},
+  },
+  wxbece4f28b6b71271: {
+    appid: "wxbece4f28b6b71271",
+    ghid: "gh_a1ab49f66596",
+    appName: "蓝晶视能引擎",
+    ads: {
+      insertAdId: "adunit-2320f5752b792e1a",
+      rewardAdId: "adunit-da3f6d50065110b8",
+      bookmarkAdId: "adunit-230da9c9674853c6",
+      templateAdId: "adunit-8c77ec239912ff08",
+    },
+  },
+  wxf91f09a57b8aa3ae: {
+    appid: "wxf91f09a57b8aa3ae",
+    ghid: "gh_4b248a5a37a0",
+    appName: "蓝晶帧溯星海",
+    ads: {
+      insertAdId: "adunit-d7202e1676297bec",
+      rewardAdId: "adunit-13310c06b167d192",
+      bookmarkAdId: "adunit-b709500d5e4f798e",
+      templateAdId: "adunit-f31053cebe9b6779",
+    },
+  },
+  wxdd1bde4de9f6a6a0: {
+    appid: "wxdd1bde4de9f6a6a0",
+    ghid: "gh_028e0784579d",
+    appName: "蓝晶帧界星空",
+    ads: {
+      insertAdId: "adunit-5077cf6f1e8f92a7",
+      rewardAdId: "adunit-4d94f2cf076eb4c2",
+      bookmarkAdId: "adunit-8a319ef3795bd800",
+      templateAdId: "adunit-344650623385d050",
+    },
+  },
+  wxcdfd21a368ed2ced: {
+    appid: "wxcdfd21a368ed2ced",
+    ghid: "gh_e144db7dd445",
+    appName: "蓝晶视界星链",
+    ads: {},
+  },
+  wxbf40c735c0d263a5: {
+    appid: "wxbf40c735c0d263a5",
+    ghid: "gh_5203fc3a1f80",
+    appName: "蓝晶影创视野",
+    ads: {
+      insertAdId: "adunit-35128a8198535637",
+      rewardAdId: "adunit-31fcc8515e7ea865",
+      bookmarkAdId: "adunit-1b5bd8389f76239d",
+      templateAdId: "adunit-2f5df77a0dfe5153",
+    },
+  },
+  wxf0248772f67666ee: {
+    appid: "wxf0248772f67666ee",
+    ghid: "gh_e43f5a747e67",
+    appName: "蓝晶映画视界",
+    ads: {},
+  },
+  wx3f464072571c1fd3: {
+    appid: "wx3f464072571c1fd3",
+    ghid: "gh_f4b45b2b82af",
+    appName: "蓝晶影音视看",
+    ads: {
+      insertAdId: "adunit-d700b1959d308def",
+      rewardAdId: "adunit-aed9cf18e2b32be6",
+      bookmarkAdId: "adunit-5034fd21f47c3c06",
+      templateAdId: "adunit-c1493205859ee2d2",
+    },
+  },
+  // -------------------------2025-04-22 新增
+  wxdf7e08f21084c8e2: {
+    appid: "wxdf7e08f21084c8e2",
+    ghid: "gh_5030bf66aef0",
+    appName: "蓝晶影迹视界",
+    ads: {},
+  },
+  wx092045bdfe26a5ee: {
+    appid: "wx092045bdfe26a5ee",
+    ghid: "gh_f68920763a81",
+    appName: "蓝晶映见星云",
+    ads: {
+      insertAdId: "adunit-6625b1f0896a394f",
+      rewardAdId: "adunit-15db2a87322ef917",
+      bookmarkAdId: "adunit-6203c9e333bbeae5",
+      templateAdId: "adunit-252a5a156dd3a298",
+    },
+  },
+  wx6c4bb5ef1e6c1e70: {
+    appid: "wx6c4bb5ef1e6c1e70",
+    ghid: "gh_b6e8f03fc727",
+    appName: "蓝晶映画视野",
+    ads: {
+      insertAdId: "adunit-f5ae3d618ee14477",
+      rewardAdId: "adunit-abf25e90d698285c",
+      bookmarkAdId: "adunit-6e2c127031bb88f2",
+      templateAdId: "adunit-94ac9867830f3296",
+    },
+  },
+  wx60db1bff60cd771c: {
+    appid: "wx60db1bff60cd771c",
+    ghid: "gh_01f93f7f5035",
+    appName: "蓝晶光影视野",
+    ads: {
+      insertAdId: "adunit-9f07220c0aaffa26",
+      rewardAdId: "adunit-d94991b8abf13dc7",
+      bookmarkAdId: "adunit-45c3a29471d987c3",
+      templateAdId: "adunit-22fb35825020838a",
+    },
+  },
+  wx5a9dda0604c2ea67: {
+    appid: "wx5a9dda0604c2ea67",
+    ghid: "gh_a186898d8dcc",
+    appName: "蓝晶视语工场",
+    ads: {},
+  },
+  wxdecb83db79aa5bc0: {
+    appid: "wxdecb83db79aa5bc0",
+    ghid: "gh_ac31f1281a2e",
+    appName: "蓝晶视觉魔方",
+    ads: {},
+  },
+  wx616a7e327bd9574a: {
+    appid: "wx616a7e327bd9574a",
+    ghid: "gh_06dab34906a2",
+    appName: "蓝晶影构空间",
+    ads: {},
+  },
+  wxdcf60b8e89ff6fa0: {
+    appid: "wxdcf60b8e89ff6fa0",
+    ghid: "gh_0c04415d1aec",
+    appName: "蓝晶视能象限",
+    ads: {},
+  },
+  wx54c216ec4ad011fd: {
+    appid: "wx54c216ec4ad011fd",
+    ghid: "gh_27b2a85570df",
+    appName: "蓝晶映动视廊",
+    ads: {},
+  },
+  wxd40b677f35319eea: {
+    appid: "wxd40b677f35319eea",
+    ghid: "gh_303939d4a258",
+    appName: "蓝晶云映视界",
+    ads: {},
+  },
 };
 
 // @config 确定使用的小程序appid
-const current_appid = "wx706acdc696d025ad";
+const current_appid = "wxa7a33088566e1292";
 export const apple = {
-    ...appInfoObj[current_appid],
-    appKey: "49TBR8Z1rA7PyqD30FV0v48AU",
-    bookList: [
-      {"bookId":10622,"wxBookId":"A1HfxT8JKd2JZVaNWv2wdUSzzt","chapterId":"A1Hcfv5eeHmEiXSLaUZDjcEU9e"},
-      {"bookId":9103,"wxBookId":"A1cueQWFr6kGvoEA2p1WXnn31S","chapterId":"A1cvAuHjAHmfBT6NzbBUQSoZg4"},
-      {"bookId":9548,"wxBookId":"A1aXCxrnU64jSoTwofX4cGY1X6","chapterId":"A1aXjTj4SwRjSo9nJ6TSd8pt3J"},
-      {"bookId":9549,"wxBookId":"A1aXCbKJz2R6j6DPC2mqAPdP3E","chapterId":"A1aXCbNXNfrwnNcYxSjDbKFvn4"},
-      {"bookId":9731,"wxBookId":"A1Y6apumQqSqZcEt2SnLra9UQ8","chapterId":"A1Y6apwPA9G1oRhMD6owTd2MZ2"},
-      {"bookId":9801,"wxBookId":"A1Y3reSnEdvAHkUmU1hFeFY5nY","chapterId":"A1Y3rmPBr8HSNDEy2HgBSnKJjJ"},
-      {"bookId":9986,"wxBookId":"A1TGRnK36ZfT3KmMoaAWY3cCNt","chapterId":"A1TGRnLdNabQhFEoRUE1ovUPLC"},
-      {"bookId":10078,"wxBookId":"A1Qt15VnJZE7T2FbfGH8SzEjng","chapterId":"A1Qt15ag7jg5iw3JbQ472bfCm6"},
-      {"bookId":10622,"wxBookId":"A1aXCxrnU64jSoTwofX4cGY1X6","chapterId":"A1HfxT9tbdxGDR3p8p6SuMKBxC"},
-      {"bookId":9867,"wxBookId":"A1VesxhvPvFaffxQauVc9pTSun","chapterId":"A1VesxmBMpk4FGpsb9Peuo7Czt"},
-      {"bookId":10664,"wxBookId":"A1L3J3wnFgexyHNTKFWVEzCiM6","chapterId":"A1L3J414KZJrVJjBzZP6zqrzat"},
-      {"bookId":10745,"wxBookId":"A1L2D5CPFHZW6Gzr9VdypmijDJ","chapterId":"A1L2D5FcjuAm5ytHayZwFaMo6p"},
-      {"bookId":10746,"wxBookId":"A1L2CaaQKERs4BNTxDYhF1L8PA","chapterId":"A1L2CafH2SiRPffuDHM6pjk5Ct"}
-    ]
+  ...appInfoObj[current_appid],
+  appKey: "49TBR8Z1rA7PyqD30FV0v48AU",
+  bookList: [
+    {
+      bookId: 10622,
+      wxBookId: "A1HfxT8JKd2JZVaNWv2wdUSzzt",
+      chapterId: "A1Hcfv5eeHmEiXSLaUZDjcEU9e",
+    },
+    {
+      bookId: 9103,
+      wxBookId: "A1cueQWFr6kGvoEA2p1WXnn31S",
+      chapterId: "A1cvAuHjAHmfBT6NzbBUQSoZg4",
+    },
+    {
+      bookId: 9548,
+      wxBookId: "A1aXCxrnU64jSoTwofX4cGY1X6",
+      chapterId: "A1aXjTj4SwRjSo9nJ6TSd8pt3J",
+    },
+    {
+      bookId: 9549,
+      wxBookId: "A1aXCbKJz2R6j6DPC2mqAPdP3E",
+      chapterId: "A1aXCbNXNfrwnNcYxSjDbKFvn4",
+    },
+    {
+      bookId: 9731,
+      wxBookId: "A1Y6apumQqSqZcEt2SnLra9UQ8",
+      chapterId: "A1Y6apwPA9G1oRhMD6owTd2MZ2",
+    },
+    {
+      bookId: 9801,
+      wxBookId: "A1Y3reSnEdvAHkUmU1hFeFY5nY",
+      chapterId: "A1Y3rmPBr8HSNDEy2HgBSnKJjJ",
+    },
+    {
+      bookId: 9986,
+      wxBookId: "A1TGRnK36ZfT3KmMoaAWY3cCNt",
+      chapterId: "A1TGRnLdNabQhFEoRUE1ovUPLC",
+    },
+    {
+      bookId: 10078,
+      wxBookId: "A1Qt15VnJZE7T2FbfGH8SzEjng",
+      chapterId: "A1Qt15ag7jg5iw3JbQ472bfCm6",
+    },
+    {
+      bookId: 10622,
+      wxBookId: "A1aXCxrnU64jSoTwofX4cGY1X6",
+      chapterId: "A1HfxT9tbdxGDR3p8p6SuMKBxC",
+    },
+    {
+      bookId: 9867,
+      wxBookId: "A1VesxhvPvFaffxQauVc9pTSun",
+      chapterId: "A1VesxmBMpk4FGpsb9Peuo7Czt",
+    },
+    {
+      bookId: 10664,
+      wxBookId: "A1L3J3wnFgexyHNTKFWVEzCiM6",
+      chapterId: "A1L3J414KZJrVJjBzZP6zqrzat",
+    },
+    {
+      bookId: 10745,
+      wxBookId: "A1L2D5CPFHZW6Gzr9VdypmijDJ",
+      chapterId: "A1L2D5FcjuAm5ytHayZwFaMo6p",
+    },
+    {
+      bookId: 10746,
+      wxBookId: "A1L2CaaQKERs4BNTxDYhF1L8PA",
+      chapterId: "A1L2CafH2SiRPffuDHM6pjk5Ct",
+    },
+  ],
 };
 
 // 线上域名信息
 export const https = {
-    dev_apiHttps: "https://hyperion-novel-qa-app.mokamrp.com",
-    test_apiHttps: "https://hyperion-novel-qa-app.mokamrp.com",
-    apiHttps: "https://hyperion-novel-qa-app.mokamrp.com",
+  dev_apiHttps: "https://hyperion-novel-qa-app.mokamrp.com",
+  test_apiHttps: "https://hyperion-novel-qa-app.mokamrp.com",
+  apiHttps: "https://hyperion-novel-qa-app.mokamrp.com",
+  goHttps: "https://applet.xiaoduer.cn",
+  // goHttps: "http://172.16.18.51:8080",
 };

+ 530 - 0
pages/collect-video/video.js

@@ -0,0 +1,530 @@
+// pages/collect-video/video.js
+import {
+  getCollectDetail,
+  getTemplateConfig,
+  getUuid,
+  getCollectRealVideoUrl,
+  getRecCollectList,
+} from "../../api/api";
+import { rnd, goToVideoDetail, SendEvent } from "../../utils/util";
+import { apple } from "../../config/config";
+
+const app = getApp();
+let interstitialAd = null;
+
+Page({
+  data: {
+    loading: false,
+    hasMore: true,
+    // 状态栏高度
+    statusBarHeight: 20,
+    navHeight: 64, // 导航栏高度 = 状态栏 + 44
+    navStyle: "",
+    listStyle: "",
+    ads: null,
+    globalConfig: null,
+
+    hasLoadAdConfig: false,
+    templateAdId: "",
+    adErrorField: {
+      videoError: false,
+      bannerError: false,
+      templateError: false,
+    },
+
+    collectId: "",
+    eps: [], // 合集视频列表
+    playingEp: 0, // 正在播放集
+    videoDetail: null,
+
+    isPlaying: false,
+    videoStatus: 1,
+    duration: 0, // 视频总时长
+    currentTime: 0, // 当前播放时间
+  },
+
+  onLoad(options) {
+    console.log("打开视频合集页面--------------------------");
+    // wx.setStorageSync("jump", parseInt(options.jump)); // 是否跳转阅读器
+    this.autoLogin(options.promotionid);
+    if (!app.globalData.uuid) {
+      this.getUUID().then((uuid) => {
+        // getApp().globalData.uuid = uuid
+        console.log("登录成功");
+      });
+    }
+
+    this.handleEntrace(options);
+    this.setData({
+      collectId: options.collectId,
+      templateAdId: apple.ads.templateAdId,
+      hasLoadAdConfig: true,
+    });
+
+    getTemplateConfig({
+      box_type: 73,
+      uuid: app.globalData.uuid,
+    }).then((res) => {
+      this.setData({
+        globalConfig: res.globalConfig,
+      });
+      this.interstitalLoad();
+      this.rewardVideoLoad();
+      // 获取合集视频详情
+      this.getCollectVideoDetail();
+      this.loadVideoList();
+    });
+
+    // 获取状态栏高度
+    this.getSystemInfo();
+    // this.handleEntrace(options);
+  },
+
+  // 自动登录
+  async autoLogin(promotionid) {
+    try {
+      await getApp().login(promotionid);
+    } catch (error) {
+      console.error("登录失败:", error);
+    }
+  },
+
+  onShow() {},
+
+  handleEntrace(options) {
+    // console.log("点击入口按钮");
+    // if (!options || Object.keys(options).length === 0) {
+    //   return;
+    // }
+    // console.log("入口:", options);
+    // try {
+    // } catch (e) {
+    //   console.log("处理不同场景进入小程序出错", error);
+    // }
+  },
+
+  // 获取视频合集详情
+  getCollectVideoDetail() {
+    // 显示加载中提示
+    wx.showLoading({
+      title: "加载中...",
+      mask: true,
+    });
+    getCollectDetail(this.data.collectId)
+      .then((res) => {
+        if (res && res.video.length > 0) {
+          res.video
+            .sort((a, b) => a.sort < b.sort)
+            .map((e, i) => {
+              // -------- 锁定判断 --------
+              if (this.isCollectNeedLock()) {
+                // set lock status
+                if (i + 1 >= res.lockStart) {
+                  e.lock = true;
+                } else {
+                  e.lock = false;
+                }
+              } else {
+                e.lock = false;
+              }
+              return e;
+            });
+          this.setData({
+            eps: res.video,
+            playingEp: 0,
+            videoDetail: res.video[0],
+          });
+          // 默认播放第一集
+          this.getVideoPlayUrl();
+        }
+      })
+      .catch((err) => {
+        console.error(err);
+      })
+      .then(() => {
+        wx.hideLoading();
+      });
+  },
+
+  // 判断合集是否需要锁定
+  isCollectNeedLock() {
+    // 获取当前日期(格式:YYYY-MM-DD)
+    const today = new Date().toISOString().split("T")[0];
+
+    // 从 localStorage 获取数据
+    const hadRewardNum = parseInt(
+      wx.getStorageSync("had_reward_num") || "0",
+      10,
+    );
+    const unlockCollectIds = JSON.parse(
+      wx.getStorageSync("unlock_collect_ids") || "[]",
+    );
+    const lastCheckDate = wx.getStorageSync("last_check_date");
+
+    if (this.data.globalConfig.isShowReward === 1) {
+      // 检查是否需要重置(新的一天)
+      if (lastCheckDate !== today) {
+        // 重置解锁数据
+        wx.setStorageSync("had_reward_num", "0");
+        wx.setStorageSync("unlock_collect_ids", "[]");
+        wx.setStorageSync("last_check_date", today);
+        return true; // 新的一天,当前视频未解锁
+      }
+
+      // 判断解锁状态
+      // 1. 如果当天广告观看次数 >= 3,所有视频解锁
+      if (hadRewardNum >= 3) {
+        return false;
+      }
+
+      // 2. 如果视频ID在已解锁列表中,当前视频解锁
+      console.log(JSON.parse(wx.getStorageSync("unlock_collect_ids") || "[]"));
+      if (unlockCollectIds.includes(this.data.collectId)) {
+        return false;
+      }
+      return true;
+    } else {
+      return false;
+    }
+  },
+
+  async getVideoPlayUrl() {
+    try {
+      const res = await getCollectRealVideoUrl(this.data.videoDetail.url);
+      this.setData({
+        "videoDetail.playUrl": res.url_info[0].url,
+      });
+    } catch (error) {}
+  },
+
+  // 点击集
+  clickEp(e) {
+    const { ep, idx } = e.currentTarget.dataset;
+    if (idx === this.data.playingEp) return;
+    this.setData({
+      playingEp: idx,
+      videoDetail: ep,
+    });
+    if (!this.data.videoDetail.lock) {
+      this.getVideoPlayUrl();
+    }
+  },
+
+  clickUnlock() {
+    this.rewardVideoPlayFn();
+  },
+  /**
+   * 获取uuid
+   */
+  getUUID() {
+    return new Promise((resolve, reject) => {
+      wx.login({
+        success: (res) => {
+          console.log("wxlogin:", res);
+          let body = {
+            code: res.code,
+            source_type: 1,
+            source_id: "",
+          };
+          getUuid(body)
+            .then(async (uuidres) => {
+              console.log("登录成功:", uuidres);
+              app.globalData.uuid = uuidres.uuid;
+              app.globalData.openId = uuidres.open_id;
+              console.log("登录后的openid:", uuidres.open_id);
+              console.log("登录成功:", app.globalData);
+              SendEvent("login_shanhu", { uuid: uuidres.uuid });
+              resolve(res.uuid);
+            })
+            .catch((err) => {
+              reject(err);
+            });
+        },
+      });
+    });
+  },
+
+  // 获取系统信息
+  getSystemInfo() {
+    const systemInfo = wx.getSystemInfoSync();
+    const statusBarHeight = systemInfo.statusBarHeight;
+    const navHeight = statusBarHeight + 44;
+
+    this.setData({
+      statusBarHeight: statusBarHeight,
+      navHeight: navHeight,
+      navStyle: `height:${navHeight}px`,
+      listStyle: `top:${navHeight}px`,
+    });
+  },
+
+  // 加载视频列表
+  async loadVideoList() {
+    this.setData({
+      loading: true,
+    });
+
+    try {
+      const params = {
+        tagIdList: this.data.globalConfig.tagIds.join(","),
+        count: this.data.globalConfig.recommendListNum,
+        id: Number(this.data.collectId),
+      };
+      const res = await getRecCollectList(params);
+      res.forEach((e) => {
+        e.adType = "video";
+        e.views = rnd(1, 10);
+      });
+      this.setData({
+        videoList: res,
+        loading: false,
+        hasMore: false,
+      });
+    } catch (error) {
+      console.error("加载视频列表失败:", error);
+    }
+  },
+
+  // 视频播放事件
+  onVideoPlay() {
+    this.setData({
+      isPlaying: true,
+      videoStatus: 1,
+    });
+
+    // 可以添加播放埋点
+  },
+
+  // 视频暂停事件
+  onVideoPause() {
+    this.setData({
+      isPlaying: false,
+      videoStatus: 2,
+    });
+  },
+
+  // 视频播放结束事件
+  onVideoEnd() {
+    this.setData({
+      isPlaying: false,
+      videoStatus: 0,
+    });
+
+    // 切换下一集
+    const nextEp = this.data.playingEp + 1;
+    if (nextEp <= this.data.eps.length - 1) {
+      this.setData({
+        playingEp: nextEp,
+        videoDetail: this.data.eps[nextEp],
+      });
+      if (!this.data.videoDetail.lock) {
+        this.getVideoPlayUrl();
+      }
+    }
+  },
+
+  // 视频时间更新事件
+  onVideoUpdate(e) {
+    const { currentTime, duration } = e.detail;
+    this.setData({
+      currentTime,
+      duration,
+    });
+  },
+
+  // 视频元数据加载完成
+  onVideoLoaded(e) {
+    console.log("视频元数据加载完成", e.detail);
+  },
+
+  /* ------------------ 广告相关 ----------------- */
+  /**
+   * 标记广告位置
+   * @param {} arr
+   * @returns
+   */
+  formatVideoAdList(arr) {
+    // 原生广告间隔,激励广告间隔
+    let templateGap = 0,
+      rewardGap = 0;
+    console.log(this.data.globalConfig);
+    if (this.data.globalConfig.isHomeTemplateAd === 1) {
+      templateGap = this.data.globalConfig.homeTemplateAdInterval;
+    } else {
+      templateGap = 0;
+    }
+    if (this.data.globalConfig.isHomeRewardAd) {
+      rewardGap = this.data.globalConfig.homeRewardAdInterval;
+    } else {
+      rewardGap = 0;
+    }
+    console.log(
+      "原生间隔templateGap",
+      templateGap,
+      "激励间隔rewardGap",
+      rewardGap,
+    );
+
+    // 第二个固定是原生广告
+    let result = [
+      arr.shift(),
+      {
+        adType: "templateAd",
+      },
+    ];
+    // 辅助计算间隔变量
+    let markIndex = 0;
+    let templateAdFlag = true;
+    let rewardAdFlag = true;
+
+    do {
+      markIndex += 1;
+      if (templateGap > 0) {
+        if (templateAdFlag && markIndex - 1 === templateGap) {
+          markIndex = 0;
+          result.push({
+            adType: "templateAd",
+          });
+          templateAdFlag = false;
+          rewardAdFlag = true;
+          continue;
+        }
+      } else {
+        rewardAdFlag = true;
+      }
+      if (rewardGap > 0) {
+        if (rewardAdFlag && markIndex - 1 === rewardGap) {
+          markIndex = 0;
+          templateAdFlag = true;
+          rewardAdFlag = false;
+          let rewardItem = arr.shift();
+          rewardItem.lock = true;
+          result.push(rewardItem);
+          console.log("标记激励项:", rewardItem);
+          continue;
+        }
+      } else {
+        templateAdFlag = true;
+      }
+
+      result.push(arr.shift());
+    } while (arr.length > 0);
+
+    return result;
+  },
+
+  // 点击合集
+  clickCollect(e) {
+    const { id, info, index } = e.currentTarget.dataset;
+    this.setData({
+      collectId: id,
+    });
+    console.log(id, info, index, "合集详情");
+    this.getCollectVideoDetail();
+  },
+
+  // 分享给朋友
+  onShareAppMessage(e) {},
+
+  // 跳转视频详情
+  goToVideoDetail(videoId, tagId) {
+    // 使用公共的goToVideoDetail函数
+    goToVideoDetail({
+      videoId: videoId,
+      tagId: tagId,
+    });
+  },
+
+  // 激励视频加载
+  rewardVideoLoad() {
+    if (this.data.globalConfig.isShowReward !== 1) return;
+    if (wx.createRewardedVideoAd) {
+      let adId = apple.ads.rewardAdId;
+      this.videoAd = wx.createRewardedVideoAd({
+        adUnitId: adId,
+      });
+
+      this.videoAd.onLoad(() => {
+        console.log("首页激励加载成功");
+      });
+      this.videoAd.onError((err) => {
+        console.log("首页激励失败", err);
+      });
+      this.videoAd.onClose((res) => {
+        // 用户点击了【关闭广告】按钮
+        if (res && res.isEnded) {
+          // 发放奖励
+          const hadRewardNum = parseInt(
+            wx.getStorageSync("had_reward_num") || "0",
+            10,
+          );
+          const unlockCollectIds = JSON.parse(
+            wx.getStorageSync("unlock_collect_ids") || "[]",
+          );
+          wx.setStorageSync("had_reward_num", hadRewardNum + 1);
+          wx.setStorageSync(
+            "unlock_collect_ids",
+            JSON.stringify([...unlockCollectIds, this.data.collectId]),
+          );
+          // 解锁当前合集,播放视频
+          this.data.eps = this.data.eps.map((e) => {
+            e.lock = false;
+            return e;
+          });
+          this.setData({
+            "videoDetail.lock": false,
+            eps: this.data.eps,
+          });
+          this.getVideoPlayUrl();
+        }
+      });
+    }
+  },
+
+  // 激励视频展示
+  rewardVideoPlayFn() {
+    if (this.data.globalConfig.isShowReward !== 1) return;
+    wx.showLoading({
+      title: "解锁视频中",
+    });
+    this.videoAd
+      .show()
+      .then(() => {
+        console.log("激励视频播放成功");
+      })
+      .catch((err) => {
+        console.log("激励视频播放失败", err);
+      })
+      .then(() => {
+        wx.hideLoading();
+      });
+  },
+
+  // 插屏广告加载
+  interstitalLoad() {
+    if (this.data.globalConfig.isShowInsert !== 1) return;
+    let adId = apple.ads.insertAdId;
+    interstitialAd = wx.createInterstitialAd({
+      adUnitId: adId,
+    });
+    interstitialAd.onLoad(() => {
+      console.log("合集视频页插屏广告onLoad");
+    });
+    interstitialAd.onError((err) => {
+      console.log("合集视频页插屏广告onError", err);
+    });
+    interstitialAd.onClose(() => {
+      console.log("合集视频页插屏广告onClose");
+    });
+  },
+
+  // 插屏广告展示
+  interstitalPlayFn() {
+    if (this.data.globalConfig.isShowInsert !== 1) return;
+    if (interstitialAd) {
+      interstitialAd.show().catch((err) => {
+        console.error("合集视频页插屏显示错误", err);
+      });
+    }
+  },
+});

+ 6 - 0
pages/collect-video/video.json

@@ -0,0 +1,6 @@
+{
+  "enablePullDownRefresh": true,
+  "backgroundTextStyle": "dark",
+  "usingComponents": {}
+}
+

+ 115 - 0
pages/collect-video/video.wxml

@@ -0,0 +1,115 @@
+<!--pages/video/video.wxml-->
+<view class="collect-video-container">
+  <view class="video-main">
+    <block wx:if="{{eps && eps.length > 0}}">
+      <video autoplay="{{true}}" src="{{videoDetail.playUrl}}" direction="{{0}}" poster="{{videoDetail.cover_image}}"
+        bindplay="onVideoPlay" bindpause="onVideoPause" bindended="onVideoEnd" class="my-video" id="my-video"
+        style="height: 100%" bindtimeupdate="onVideoUpdate" bindseekcomplete="onVideoSeek"
+        bindloadedmetadata="onVideoLoaded" x5-video-player-type="h5" x5-video-player-fullscreen="true" x5-video-orientation="portrait">
+        <view wx:if="{{isShowComplainBtn}}" class="complaint-btn" catchtap="handleComplain">投诉</view>
+        <!-- 激励使用设置的首帧图 -->
+        <!-- <image wx:if="{{videoDetail.coverUrl && !videoDetail.lock}}" class="poster" src="{{videoDetail.coverUrl}}"> -->
+        <!-- </image> -->
+        <view catchtap="handleClickRewardMask" class="reward-mask" wx:if="{{videoDetail.lock}}">
+          <view class="reward-btn" catchtap="clickUnlock">
+            <image class="icon-lock" src="/assets/images/lock.png"></image>
+            <text>看完广告解锁本合集所有内容</text>
+          </view>
+          <view class="reward-tip">今日看满3个广告可解锁本小程序所有内容</view>
+        </view>
+      </video>
+    </block>
+    
+    <!-- 加载中提示 -->
+    <view wx:if="{{(isLoading || !videoDetail.playUrl) && !videoDetail.lock}}" class="loading-container">
+      <view class="loading-spinner"></view>
+      <view class="loading-text">{{isLoading ? '加载中...' : '获取视频中...'}}</view>
+    </view>
+  </view>
+  <view class="video-info">
+    <view class="video-title">{{videoDetail.videoTitle}}</view>
+    <view class="video-desc">
+      <text class="xuanji">选集</text>
+      <text class="total-ep">共{{eps.length}}集</text>
+      <text class="ep-tip">锁定集在观看广告后可解锁</text>
+    </view>
+    <scroll-view scroll-x class="video-eps-scroll">
+      <view class="video-eps">
+        <view wx:for="{{eps}}" class="ep-item" data-ep="{{item}}" data-idx="{{index}}" bindtap="clickEp">
+        <view class="ep-item-title">
+            <image wx:if="{{playingEp === index && !item.lock}}" class="icon" src="/assets/images/playing.png"></image>
+            <image wx:if="{{item.lock}}" class="icon" src="/assets/images/lock.png"></image>
+            <text style="color: {{playingEp === index ? '#CA4D7A':'#ffffff'}}">第{{index + 1}}集</text>
+          </view>
+          <image class="ep-item-cover" src="{{item.coverUrl}}"></image>
+      </view>
+      </view>
+    </scroll-view>
+  </view>
+  <view class="title">猜你喜欢</view>
+  <!-- 视频列表 -->
+  <scroll-view
+    scroll-y
+    class="list-container"
+    enhanced="{{ true }}"
+    show-scrollbar="{{ false }}"
+    bounces="{{ true }}"
+    fast-deceleration="{{ true }}"
+  >
+    <view class="list">
+      <block wx:for="{{ videoList }}" wx:key="id" wx:for-index="idx">
+        <!-- 视频广告 -->
+        <!-- <view wx:if="{{item.adType === 'videoAd' && hasLoadAdConfig}}" class="ad-custom-card"> -->
+        <!--   <ad unit-id="{{templateAdId}}" ad-type="video" style="height: 100%;margin-bottom: 20rpx;"></ad> -->
+        <!-- </view> -->
+        <view wx:if="{{ item.adType === 'video' }}">
+          <!-- 视频卡片 -->
+          <view class="video-item" bindtap="clickCollect" data-info="{{ item }}" data-id="{{ item.id }}" data-index="{{idx}}">
+            <view class="video-cover-container">
+              <image
+                class="video-cover"
+                src="{{ item.coverUrl }}"
+                mode="aspectFill"
+              />
+            </view>
+            <view class="video-item-right">
+              <view class="video-title">{{ item.title }}</view>
+              <view class="video-play-count">
+                <image class="icon" src="/assets/images/tv.png"></image>
+                <text>{{ item.views }}w+人观看</text>
+              </view>
+            </view>
+          </view>
+        </view>
+         <!-- 卡片原生广告 -->
+         <!-- <view wx:if="{{item.adType === 'templateAd' && hasLoadAdConfig }}" class="ad-custom-card-1"> -->
+         <!--    <ad-custom unit-id="{{templateAdId}}" style="height: 100%;margin-bottom: 20rpx;"></ad-custom> -->
+         <!--  </view> -->
+      </block>
+    </view>
+
+    <!-- 加载状态 -->
+    <view class="loading-status">
+      <!-- loading 提示 -->
+      <view class="loading" wx:if="{{ loading }}">
+        <view class="loading-spinner"></view>
+        <text>加载中...</text>
+      </view>
+
+      <!-- 没有更多 -->
+      <view
+        class="finished"
+        wx:if="{{ !loading && videoList.length > 0 && !hasMore }}"
+      >
+        <text>没有更多视频了</text>
+      </view>
+
+      <!-- 空状态 -->
+      <view class="empty" wx:if="{{ !loading && videoList.length === 0 }}">
+        <image class="empty-icon" src="/assets/images/empty.png"></image>
+        <text>暂无视频内容</text>
+      </view>
+    </view>
+  </scroll-view>
+
+</view>

+ 285 - 0
pages/collect-video/video.wxss

@@ -0,0 +1,285 @@
+/* pages/collect-video/video/video.wxss */
+.collect-video-container {
+  height: 100vh;
+  background-color: #f8f8f8;
+  position: relative;
+}
+
+.video-main {
+  position: relative;
+  width: 100%;
+  height: 500rpx;
+}
+
+.my-video {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+
+.reward-mask {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  background-color: #333;
+}
+
+.reward-btn {
+  background-color: #1b8edb;
+  width: 460rpx;
+  height: 80rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #ffffff;
+  font-size: 26rpx;
+  border-radius: 8rpx;
+  margin-bottom: 20rpx;
+}
+
+.reward-btn .icon-lock {
+  width: 40rpx;
+  height: 40rpx;
+  margin-right: 10rpx;
+}
+
+.reward-tip {
+  color: #ffffff;
+  font-size: 24rpx;
+  padding-top: 20rpx;
+}
+
+/* 加载中样式 */
+.loading-container {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  background-color: #000;
+}
+
+.loading-spinner {
+  width: 80rpx;
+  height: 80rpx;
+  border: 6rpx solid rgba(255, 255, 255, 0.1);
+  border-left-color: #fff;
+  border-radius: 50%;
+  animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+  to {
+    transform: rotate(360deg);
+  }
+}
+
+.loading-text {
+  margin-top: 20rpx;
+  font-size: 28rpx;
+  color: rgba(255, 255, 255, 0.7);
+}
+
+.video-info {
+  padding: 30rpx;
+}
+
+.video-info .video-title {
+  width: 100%;
+  font-size: 34rpx;
+  font-family:
+    PingFang SC,
+    PingFang SC-Bold;
+  letter-spacing: 2rpx;
+  font-weight: bold;
+  overflow: hidden;
+  white-space: wrap;
+}
+
+.video-desc {
+  margin-top: 30rpx;
+  margin-bottom: 30rpx;
+}
+
+.video-desc .xuanji {
+  color: #666;
+  font-size: 30rpx;
+  margin-right: 20rpx;
+}
+
+.video-desc .total-ep {
+  color: #999;
+  font-size: 30rpx;
+  margin-right: 20rpx;
+}
+
+.video-desc .ep-tip {
+  color: #bbb;
+  font-size: 30rpx;
+}
+
+.video-eps-scroll {
+  width: 100%;
+}
+
+.video-eps {
+  display: flex;
+  flex-wrap: nowrap;
+}
+
+.ep-item {
+  flex-shrink: 0;
+  width: 200rpx;
+  height: 140rpx;
+  border-radius: 8rpx;
+  position: relative;
+  margin-right: 15rpx;
+}
+
+.ep-item .ep-item-title {
+  width: 200rpx;
+  height: 50rpx;
+  position: absolute;
+  top: 0;
+  left: 0;
+  color: #fff;
+  background-color: rgba(0, 0, 0, 0.7);
+  border-top-left-radius: 8rpx;
+  border-top-right-radius: 8rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 26rpx;
+}
+
+.ep-item .ep-item-title .icon {
+  width: 30rpx;
+  height: 30rpx;
+  margin-right: 15rpx;
+}
+
+.ep-item .ep-item-cover {
+  width: 100%;
+  height: 100%;
+  border-radius: 8rpx;
+}
+
+.title {
+  padding-left: 30rpx;
+  font-size: 34rpx;
+  color: #111;
+}
+
+/* 列表容器 */
+.list-container {
+  height: calc(100vh - 500rpx);
+  background-color: #f8f8f8;
+}
+
+.list {
+  padding: 30rpx;
+  box-sizing: border-box;
+}
+
+/* 视频卡片样式 */
+.video-item {
+  position: relative;
+  margin-bottom: 20rpx;
+  display: flex;
+}
+
+.video-cover-container {
+  width: 240rpx;
+  height: 160rpx;
+  padding-right: 20rpx;
+}
+
+.video-cover-container .video-cover {
+  width: 100%;
+  height: 100%;
+  border-radius: 8rpx;
+}
+
+.video-item-right {
+  flex: 1;
+}
+
+.video-item-right .video-title {
+  font-size: 34rpx;
+  color: #333;
+}
+.video-item-right .video-play-count .icon {
+  width: 30rpx;
+  height: 30rpx;
+  margin-right: 20rpx;
+}
+
+.video-item-right .video-play-count {
+  font-size: 28rpx;
+  color: #bfbfbf;
+  display: flex;
+  align-items: center;
+  margin-top: 20rpx;
+}
+
+/* 加载状态样式 */
+.loading-status {
+  padding: 30rpx 0;
+  text-align: center;
+  font-size: 28rpx;
+  color: #999;
+}
+
+.loading {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: 100rpx;
+}
+
+.loading-spinner {
+  width: 40rpx;
+  height: 40rpx;
+  border: 4rpx solid #f3f3f3;
+  border-top: 4rpx solid #07c160;
+  border-radius: 50%;
+  animation: spin 1s linear infinite;
+  margin-bottom: 10rpx;
+}
+
+.finished {
+  height: 80rpx;
+  line-height: 80rpx;
+  color: #999;
+}
+
+.empty {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 100rpx 0;
+}
+
+.empty-icon {
+  width: 200rpx;
+  height: 200rpx;
+  margin-bottom: 20rpx;
+}
+
+@keyframes spin {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}

+ 13 - 2
project.private.config.json

@@ -24,11 +24,22 @@
     "miniprogram": {
       "list": [
         {
+          "name": "合集视频",
+          "pathName": "pages/collect-video/video",
+          "query": "collectId=1",
+          "scene": null,
+          "launchMode": "default",
+          "partialCompile": {
+            "enabled": true,
+            "pages": []
+          }
+        },
+        {
           "name": "测试",
           "pathName": "pages/video/video",
           "query": "shared_video_id=413559&tag_id=2072&share_count=1&type=tuiguang",
-          "scene": 1008,
-          "launchMode": "default"
+          "launchMode": "default",
+          "scene": 1008
         },
         {
           "name": "非1007,1008场景进入播放",

+ 61 - 57
utils/request.js

@@ -1,18 +1,18 @@
 // 预发布地址
-import { apple } from '../config/config';
+import { apple } from "../config/config";
 
-let httpTrackLog = 'https://hyperion-track-app.mokamrp.com';
-let httpServiceURL = '';
+let httpTrackLog = "https://hyperion-track-app.mokamrp.com";
+let httpServiceURL = "";
 let version = __wxConfig.envVersion;
-import { https } from '../config/config';
+import { https } from "../config/config";
 switch (version) {
-  case 'develop':
+  case "develop":
     httpServiceURL = https.dev_apiHttps;
     break;
-  case 'trial':
+  case "trial":
     httpServiceURL = https.test_apiHttps;
     break;
-  case 'release': //正式版
+  case "release": //正式版
     httpServiceURL = https.apiHttps;
     break;
   default: //未知,默认调用正式版
@@ -29,7 +29,7 @@ let pendingRequests = [];
 const executePendingRequests = () => {
   const requests = [...pendingRequests];
   pendingRequests = [];
-  return Promise.all(requests.map(req => req()));
+  return Promise.all(requests.map((req) => req()));
 };
 
 // 普通POST请求
@@ -38,8 +38,8 @@ export const post = (url, body = {}) => {
     wx.request({
       url: url,
       data: body,
-      method: 'POST',
-      dataType: 'json',
+      method: "POST",
+      dataType: "json",
       success: (res) => {
         if (res.statusCode == 200 && res.data.code == 200) {
           resolve(res.data.data);
@@ -48,7 +48,7 @@ export const post = (url, body = {}) => {
         }
       },
       fail: (res) => {
-        console.log(url, 'error--------', res);
+        console.log(url, "error--------", res);
         reject(res);
       },
     });
@@ -60,7 +60,7 @@ export const get = (url) => {
   return new Promise((resolve, reject) => {
     wx.request({
       url: url,
-      method: 'GET',
+      method: "GET",
       success: (res) => {
         if (res.statusCode == 200) {
           resolve(res.data);
@@ -86,40 +86,40 @@ export function uploadTrackLog(url, body) {
 }
 
 export const requestLogin = (data) => {
-  console.log('开始登录请求,参数:', data);
+  console.log("开始登录请求,参数:", data);
   return new Promise((resolve, reject) => {
     // 检查是否已经有token
-    const existingToken = wx.getStorageSync('accessToken');
+    const existingToken = wx.getStorageSync("accessToken");
     if (existingToken) {
-      console.log('已存在token,跳过登录');
+      console.log("已存在token,跳过登录");
       return resolve({ accessToken: existingToken });
     }
 
     wx.request({
-      url: httpServiceURL + '/user/loginWx',
+      url: httpServiceURL + "/user/loginWx",
       data: data,
-      method: 'POST',
-      dataType: 'json',
+      method: "POST",
+      dataType: "json",
       header: {},
       success: function (res) {
         if (res.data.code == 200) {
-          console.log('登录成功,保存token');
-          wx.setStorageSync('accessToken', res.data.data.accessToken);
+          console.log("登录成功,保存token");
+          wx.setStorageSync("accessToken", res.data.data.accessToken);
           resolve(res.data.data);
         } else {
-          console.log('登录失败,错误信息:', res.data);
+          console.log("登录失败,错误信息:", res.data);
           wx.showToast({
-            title: res.data.msg || res.data.error || '登录失败...',
-            icon: 'none',
+            title: res.data.msg || res.data.error || "登录失败...",
+            icon: "none",
           });
           reject(res.data);
         }
       },
       fail: function (res) {
-        console.log('登录请求失败:', res);
+        console.log("登录请求失败:", res);
         wx.showToast({
-          title: '登录失败...',
-          icon: 'none',
+          title: "登录失败...",
+          icon: "none",
         });
         reject(res);
       },
@@ -127,11 +127,16 @@ export const requestLogin = (data) => {
   });
 };
 
-export const requestAll = (requestUrl, body, method = 'POST', customHeaders = {}) => {
+export const requestAll = (
+  requestUrl,
+  body,
+  method = "POST",
+  customHeaders = {},
+) => {
   let url = httpServiceURL + requestUrl;
-  if (method === 'GET') {
+  if (method === "GET") {
     if (body) {
-      url += '?';
+      url += "?";
       for (const k in body) {
         url += `&${k}=${body[k]}`;
       }
@@ -141,36 +146,34 @@ export const requestAll = (requestUrl, body, method = 'POST', customHeaders = {}
   // 封装请求函数
   const doRequest = () => {
     return new Promise((resolve, reject) => {
-      const token = wx.getStorageSync('accessToken') || '';
+      const token = wx.getStorageSync("accessToken") || "";
 
       wx.request({
         url: url,
         data: body,
         method: method,
-        dataType: 'json',
+        dataType: "json",
         header: {
-          token
+          token,
         },
         success: function (res) {
           if (res.data.code == 200) {
-            if (typeof res.data.data === 'number') {
+            if (typeof res.data.data === "number") {
               resolve(res.data.data);
             } else {
               resolve(res.data.data || []);
             }
-          }
-          else if (res.data.code == 20001) {
-            console.error('令牌过期', url);
-            reject({ code: 20001, msg: '令牌过期' });
-          }
-          else {
+          } else if (res.data.code == 20001) {
+            console.error("令牌过期", url);
+            reject({ code: 20001, msg: "令牌过期" });
+          } else {
             reject(res.data);
           }
         },
         fail: function (res) {
           wx.showToast({
-            title: '网络出错,请重试...',
-            icon: 'none',
+            title: "网络出错,请重试...",
+            icon: "none",
           });
           reject(res);
         },
@@ -179,7 +182,7 @@ export const requestAll = (requestUrl, body, method = 'POST', customHeaders = {}
   };
 
   // 执行请求,如果token过期则重新登录后重试
-  return doRequest().catch(async error => {
+  return doRequest().catch(async (error) => {
     if (error.code == 20001) {
       // 如果已经在登录中,将请求添加到队列
       if (isLoggingIn) {
@@ -194,7 +197,7 @@ export const requestAll = (requestUrl, body, method = 'POST', customHeaders = {}
       try {
         // 使用单例登录Promise
         if (!loginPromise) {
-          wx.removeStorageSync('accessToken');
+          wx.removeStorageSync("accessToken");
           loginPromise = getApp().login();
         }
         await loginPromise;
@@ -205,7 +208,7 @@ export const requestAll = (requestUrl, body, method = 'POST', customHeaders = {}
 
         // 执行所有请求
         if (pendingRequests.length > 0) {
-          console.log(wx.getStorageSync('accessToken'))
+          console.log(wx.getStorageSync("accessToken"));
           pendingRequests.push(() => doRequest());
           return executePendingRequests();
         }
@@ -215,7 +218,7 @@ export const requestAll = (requestUrl, body, method = 'POST', customHeaders = {}
         isLoggingIn = false;
         loginPromise = null;
         pendingRequests = [];
-        console.error('重新登录失败:', loginError);
+        console.error("重新登录失败:", loginError);
         throw loginError;
       }
     }
@@ -226,25 +229,26 @@ export const requestAll = (requestUrl, body, method = 'POST', customHeaders = {}
 /**
  * 添加公共参数
  */
-export function postWithCommonParams(url, body, method = 'POST') {
-  const app = getApp()
+export function postWithCommonParams(url, body, method = "POST") {
+  const app = getApp();
   if (!body) {
-    body = {}
+    body = {};
   }
   if (app.globalData.uuid) {
-    body.uuid = app.globalData.uuid
+    body.uuid = app.globalData.uuid;
   } else {
-    body.uuid = 'fuck'
+    body.uuid = "fuck";
   }
-  body.gh_id = apple.ghid
+  body.gh_id = apple.ghid;
 
   // 判断是否为完整URL
-  const isFullUrl = url.startsWith('http://') || url.startsWith('https://')
-  const fullUrl = isFullUrl ? url : https.apiHttps + url
+  const isFullUrl = url.startsWith("http://") || url.startsWith("https://");
+  const fullUrl = isFullUrl ? url : https.apiHttps + url;
 
-  if (method === 'POST') {
-    return post(fullUrl, body)
+  if (method === "POST") {
+    return post(fullUrl, body);
   } else {
-    return get(fullUrl)
+    return get(fullUrl);
   }
-}
+}
+