6 Commits

14 changed files with 149 additions and 60 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
# 更新日志 # 更新日志
本文档记录了 MoonTV 项目的所有重要更改。 本文档记录了 KatelyaTV 项目的所有重要更改。KatelyaTV 为在「MoonTV」基础上的二创与继承版本,延续上游核心能力并持续修复优化。
## [未发布] ## [未发布]
@@ -11,7 +11,7 @@
- 社交分享功能 - 社交分享功能
- 用户评分系统 - 用户评分系统
## [0.1.0] - 2025-01-XX ## [0.1.0-katelya] - 2025-01-XX
### ✨ 新功能 ### ✨ 新功能
- 🎬 多源聚合搜索系统,集成20+个免费资源站点 - 🎬 多源聚合搜索系统,集成20+个免费资源站点
+9 -9
View File
@@ -1,6 +1,6 @@
# 贡献指南 # 贡献指南
感谢您对 MoonTV 项目的关注!我们欢迎所有形式的贡献,包括但不限于: 感谢您对 KatelyaTV 项目的关注!我们欢迎所有形式的贡献,包括但不限于:
- 🐛 报告 Bug - 🐛 报告 Bug
- 💡 提出新功能建议 - 💡 提出新功能建议
@@ -23,8 +23,8 @@
```bash ```bash
# 在 GitHub 上 Fork 本仓库 # 在 GitHub 上 Fork 本仓库
# 然后克隆到本地 # 然后克隆到本地
git clone https://github.com/YOUR_USERNAME/moontv.git git clone https://github.com/YOUR_USERNAME/katelyatv.git
cd moontv cd katelyatv
``` ```
2. **安装依赖** 2. **安装依赖**
@@ -114,7 +114,7 @@ git commit -m "test: 添加播放记录 API 测试用例"
在提交 Bug 报告之前,请: 在提交 Bug 报告之前,请:
1. 搜索现有的 [Issues](https://github.com/senshinya/moontv/issues) 1. 搜索现有的 Issues(仓库 Issues 页面)
2. 检查是否已有相关报告 2. 检查是否已有相关报告
3. 使用 Bug 报告模板 3. 使用 Bug 报告模板
@@ -153,7 +153,7 @@ git commit -m "test: 添加播放记录 API 测试用例"
在提出功能建议之前,请: 在提出功能建议之前,请:
1. 搜索现有的 [Discussions](https://github.com/senshinya/moontw/discussions) 1. 搜索现有的 Discussions(仓库 Discussions 页面)
2. 检查是否已有相关讨论 2. 检查是否已有相关讨论
3. 使用功能建议模板 3. 使用功能建议模板
@@ -349,11 +349,11 @@ pnpm start
### Docker 测试 ### Docker 测试
```bash ```bash
# 构建 Docker 镜像 # 构建 Docker 镜像(镜像名示例)
docker build -t moontv:test . docker build -t katelyatv:test .
# 运行容器 # 运行容器
docker run -d --name moontv-test -p 3000:3000 --env PASSWORD=test123 moontv:test docker run -d --name katelyatv-test -p 3000:3000 --env PASSWORD=test123 katelyatv:test
``` ```
## 📞 获取帮助 ## 📞 获取帮助
@@ -367,7 +367,7 @@ docker run -d --name moontv-test -p 3000:3000 --env PASSWORD=test123 moontv:test
## 🎉 致谢 ## 🎉 致谢
感谢所有为 MoonTV 项目做出贡献的开发者! 感谢所有为 KatelyaTV 项目做出贡献的开发者!
您的贡献让这个项目变得更好。无论是代码、文档、测试还是反馈,我们都非常感激。 您的贡献让这个项目变得更好。无论是代码、文档、测试还是反馈,我们都非常感激。
+6 -4
View File
@@ -1,10 +1,10 @@
# 📊 MoonTV 项目状态报告 # 📊 KatelyaTV 项目状态报告
## 🎯 项目概述 ## 🎯 项目概述
**MoonTV** 是一个功能完整的影视聚合播放器,基于现代 Web 技术栈构建,支持多平台部署和多种存储后端。 **KatelyaTV** 是一个功能完整的影视聚合播放器,基于现代 Web 技术栈构建,支持多平台部署和多种存储后端。该项目为在原始项目「MoonTV」基础上的二创与继承版本,延续其优秀架构并在此之上进行持续优化与维护。
**当前版本**: v0.1.0 **当前版本**: v0.1.0-katelya
**最后更新**: 2025-01-XX **最后更新**: 2025-01-XX
**项目状态**: 🟢 生产就绪 **项目状态**: 🟢 生产就绪
@@ -193,7 +193,7 @@
## 🎉 总结 ## 🎉 总结
MoonTV 项目目前处于**生产就绪**状态,核心功能完整,技术架构成熟,用户体验优秀。项目具备以下特点: KatelyaTV 项目目前处于**生产就绪**状态,核心功能完整,技术架构成熟,用户体验优秀。项目具备以下特点:
-**功能完整**: 所有核心功能均已实现 -**功能完整**: 所有核心功能均已实现
-**技术先进**: 使用最新的 Web 技术 -**技术先进**: 使用最新的 Web 技术
@@ -203,6 +203,8 @@ MoonTV 项目目前处于**生产就绪**状态,核心功能完整,技术架
项目可以安全地用于生产环境,适合个人用户和中小型团队使用。 项目可以安全地用于生产环境,适合个人用户和中小型团队使用。
> 注:KatelyaTV 基于 MoonTV 二创与继承开发,保留并致谢原作者与社区贡献;如有授权或版权问题,请联系以尽快处理。
--- ---
**最后更新**: 2025-01-XX **最后更新**: 2025-01-XX
+9 -9
View File
@@ -1,6 +1,6 @@
# 🚀 MoonTV 快速开始指南 # 🚀 KatelyaTV 快速开始指南
欢迎使用 MoonTV!本指南将帮助您在几分钟内完成部署和配置。 欢迎使用 KatelyaTV!本指南将帮助您在几分钟内完成部署和配置。
## 📋 前置要求 ## 📋 前置要求
@@ -13,12 +13,12 @@
### 1. 快速启动 ### 1. 快速启动
```bash ```bash
# 拉取最新镜像 # 拉取最新镜像(当前镜像沿用上游命名空间)
docker pull ghcr.io/senshinya/moontv:latest docker pull ghcr.io/senshinya/moontv:latest
# 启动容器 # 启动容器
docker run -d \ docker run -d \
--name moontv \ --name katelyatv \
-p 3000:3000 \ -p 3000:3000 \
--env PASSWORD=your_password \ --env PASSWORD=your_password \
--restart unless-stopped \ --restart unless-stopped \
@@ -33,10 +33,10 @@ docker run -d \
```bash ```bash
# 停止容器 # 停止容器
docker stop moontv docker stop katelyatv
# 删除容器 # 删除容器
docker rm moontv docker rm katelyatv
``` ```
## 🌐 云平台部署 ## 🌐 云平台部署
@@ -224,13 +224,13 @@ NEXT_PUBLIC_STORAGE_TYPE=d1
## 📞 获取帮助 ## 📞 获取帮助
- 📖 [完整文档](README.md) - 📖 [完整文档](README.md)
- 🐛 [问题反馈](https://github.com/senshinya/moontv/issues) - 🐛 问题反馈:在仓库 Issues 页面提交
- 💬 [功能讨论](https://github.com/senshinya/moontv/discussions) - 💬 功能讨论:在 Discussions 页面参与
- 📝 [更新日志](CHANGELOG.md) - 📝 [更新日志](CHANGELOG.md)
## 🎉 开始使用 ## 🎉 开始使用
现在您已经完成了基础配置,可以开始享受 MoonTV 带来的影视体验了! 现在您已经完成了基础配置,可以开始享受 KatelyaTV 带来的影视体验了!
**重要提醒:** **重要提醒:**
- 本项目仅供学习和个人使用 - 本项目仅供学习和个人使用
+32 -18
View File
@@ -1,10 +1,12 @@
# MoonTV # KatelyaTV
<div align="center"> <div align="center">
<img src="public/logo.png" alt="MoonTV Logo" width="120"> <img src="public/logo.png" alt="KatelyaTV Logo" width="120">
</div> </div>
> 🎬 **MoonTV** 是一个开箱即用的、跨平台的影视聚合播放器。它基于 **Next.js 14** + **Tailwind&nbsp;CSS** + **TypeScript** 构建,支持多资源搜索、在线播放、收藏同步、播放记录、本地/云端存储,让你可以随时随地畅享海量免费影视内容。 > 🎬 **KatelyaTV** 是一个开箱即用的、跨平台的影视聚合播放器。它基于 **Next.js 14** + **Tailwind&nbsp;CSS** + **TypeScript** 构建,支持多资源搜索、在线播放、收藏同步、播放记录、本地/云端存储,让你可以随时随地畅享海量免费影视内容。
>
> 本项目是在原始项目「MoonTV」基础上的二创与继承版本,由 Katelya 持续开发与维护。在致敬原作的前提下,继续修复问题、优化体验并扩展功能。
<div align="center"> <div align="center">
@@ -43,6 +45,7 @@
- [技术栈](#技术栈) - [技术栈](#技术栈)
- [核心功能](#核心功能) - [核心功能](#核心功能)
- [项目来源与声明](#项目来源与声明)
- [部署](#部署) - [部署](#部署)
- [Docker Compose 最佳实践](#Docker-Compose-最佳实践) - [Docker Compose 最佳实践](#Docker-Compose-最佳实践)
- [环境变量](#环境变量) - [环境变量](#环境变量)
@@ -69,6 +72,7 @@
## 🎯 核心功能 ## 🎯 核心功能
### 观看历史记录 ### 观看历史记录
- **智能进度记录**:自动记录每个视频的播放进度、观看时长、当前集数 - **智能进度记录**:自动记录每个视频的播放进度、观看时长、当前集数
- **断点续播**:支持从上次观看位置继续播放,无需手动寻找 - **断点续播**:支持从上次观看位置继续播放,无需手动寻找
- **多设备同步**:通过 Redis/D1/Upstash 存储,实现跨设备观看记录同步 - **多设备同步**:通过 Redis/D1/Upstash 存储,实现跨设备观看记录同步
@@ -76,23 +80,32 @@
- **进度条显示**:在视频卡片上显示观看进度百分比 - **进度条显示**:在视频卡片上显示观看进度百分比
### 多源聚合搜索 ### 多源聚合搜索
- **20+ 资源站点**:集成电影天堂、黑木耳、如意资源等热门站点 - **20+ 资源站点**:集成电影天堂、黑木耳、如意资源等热门站点
- **统一搜索接口**:一次搜索返回多个源的结果,提高资源获取成功率 - **统一搜索接口**:一次搜索返回多个源的结果,提高资源获取成功率
- **智能去重**:自动识别重复内容,优化搜索结果展示 - **智能去重**:自动识别重复内容,优化搜索结果展示
- **分类筛选**:支持按电影、电视剧、综艺等类型筛选 - **分类筛选**:支持按电影、电视剧、综艺等类型筛选
### 收藏与同步 ### 收藏与同步
- **个性化收藏**:支持收藏喜欢的影视作品,创建个人片单 - **个性化收藏**:支持收藏喜欢的影视作品,创建个人片单
- **多端同步**:收藏数据云端存储,多设备访问保持一致 - **多端同步**:收藏数据云端存储,多设备访问保持一致
- **观看状态**:收藏夹中显示观看进度和当前集数 - **观看状态**:收藏夹中显示观看进度和当前集数
- **批量管理**:支持批量删除和清空收藏 - **批量管理**:支持批量删除和清空收藏
### PWA 特性 ### PWA 特性
- **离线缓存**:支持离线访问已缓存的内容 - **离线缓存**:支持离线访问已缓存的内容
- **桌面安装**:可安装到桌面,提供原生应用体验 - **桌面安装**:可安装到桌面,提供原生应用体验
- **推送通知**:支持新内容推送和更新提醒 - **推送通知**:支持新内容推送和更新提醒
- **响应式设计**:完美适配各种屏幕尺寸 - **响应式设计**:完美适配各种屏幕尺寸
## 📢 项目来源与声明
- 本项目自「MoonTV」演进而来,为其二创/继承版本,持续维护与改进功能与体验。
- 代码中保留并致谢原有作者与社区贡献者;如有授权或版权问题,请与我们联系以尽快处理。
- KatelyaTV 致力于在原作优秀基础上,提供更易部署、更友好、更稳定的使用体验。
## 🚀 部署 ## 🚀 部署
本项目**支持 Vercel、Docker 和 Cloudflare** 部署。 本项目**支持 Vercel、Docker 和 Cloudflare** 部署。
@@ -167,7 +180,7 @@ docker pull ghcr.io/senshinya/moontv:latest
# 运行容器 # 运行容器
# -d: 后台运行 -p: 映射端口 3000 -> 3000 # -d: 后台运行 -p: 映射端口 3000 -> 3000
docker run -d --name moontv -p 3000:3000 --env PASSWORD=your_password ghcr.io/senshinya/moontv:latest docker run -d --name katelyatv -p 3000:3000 --env PASSWORD=your_password ghcr.io/senshinya/moontv:latest
``` ```
访问 `http://服务器 IP:3000` 即可。(需自行到服务器控制台放通 `3000` 端口) 访问 `http://服务器 IP:3000` 即可。(需自行到服务器控制台放通 `3000` 端口)
@@ -180,9 +193,9 @@ docker run -d --name moontv -p 3000:3000 --env PASSWORD=your_password ghcr.io/se
```yaml ```yaml
services: services:
moontv: katelyatv:
image: ghcr.io/senshinya/moontv:latest image: ghcr.io/senshinya/moontv:latest
container_name: moontv container_name: katelyatv
restart: unless-stopped restart: unless-stopped
ports: ports:
- '3000:3000' - '3000:3000'
@@ -197,9 +210,9 @@ services:
```yaml ```yaml
services: services:
moontv-core: katelyatv-core:
image: ghcr.io/senshinya/moontv:latest image: ghcr.io/senshinya/moontv:latest
container_name: moontv container_name: katelyatv
restart: unless-stopped restart: unless-stopped
ports: ports:
- '3000:3000' - '3000:3000'
@@ -207,26 +220,26 @@ services:
- USERNAME=admin - USERNAME=admin
- PASSWORD=admin_password - PASSWORD=admin_password
- NEXT_PUBLIC_STORAGE_TYPE=redis - NEXT_PUBLIC_STORAGE_TYPE=redis
- REDIS_URL=redis://moontv-redis:6379 - REDIS_URL=redis://katelyatv-redis:6379
- NEXT_PUBLIC_ENABLE_REGISTER=true - NEXT_PUBLIC_ENABLE_REGISTER=true
networks: networks:
- moontv-network - katelyatv-network
depends_on: depends_on:
- moontv-redis - katelyatv-redis
# 如需自定义配置,可挂载文件 # 如需自定义配置,可挂载文件
# volumes: # volumes:
# - ./config.json:/app/config.json:ro # - ./config.json:/app/config.json:ro
moontv-redis: katelyatv-redis:
image: redis image: redis
container_name: moontv-redis container_name: katelyatv-redis
restart: unless-stopped restart: unless-stopped
networks: networks:
- moontv-network - katelyatv-network
# 如需持久化 # 如需持久化
# volumes: # volumes:
# - ./data:/data # - ./data:/data
networks: networks:
moontv-network: katelyatv-network:
driver: bridge driver: bridge
``` ```
@@ -242,7 +255,7 @@ networks:
| --------------------------- | ----------------------------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | --------------------------- | ----------------------------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| USERNAME | redis 部署时的管理员账号 | 任意字符串 | (空) | | USERNAME | redis 部署时的管理员账号 | 任意字符串 | (空) |
| PASSWORD | 默认部署时为唯一访问密码,redis 部署时为管理员密码 | 任意字符串 | (空) | | PASSWORD | 默认部署时为唯一访问密码,redis 部署时为管理员密码 | 任意字符串 | (空) |
| SITE_NAME | 站点名称 | 任意字符串 | MoonTV | | SITE_NAME | 站点名称 | 任意字符串 | KatelyaTV |
| ANNOUNCEMENT | 站点公告 | 任意字符串 | 本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。 | | ANNOUNCEMENT | 站点公告 | 任意字符串 | 本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。 |
| NEXT_PUBLIC_STORAGE_TYPE | 播放记录/收藏的存储方式 | localstorage、redis、d1、upstash | localstorage | | NEXT_PUBLIC_STORAGE_TYPE | 播放记录/收藏的存储方式 | localstorage、redis、d1、upstash | localstorage |
| REDIS_URL | redis 连接 url,若 NEXT_PUBLIC_STORAGE_TYPE 为 redis 则必填 | 连接 url | 空 | | REDIS_URL | redis 连接 url,若 NEXT_PUBLIC_STORAGE_TYPE 为 redis 则必填 | 连接 url | 空 |
@@ -278,7 +291,7 @@ networks:
- `name`:在人机界面中展示的名称。 - `name`:在人机界面中展示的名称。
- `detail`:(可选)部分无法通过 API 获取剧集详情的站点,需要提供网页详情根 URL,用于爬取。 - `detail`:(可选)部分无法通过 API 获取剧集详情的站点,需要提供网页详情根 URL,用于爬取。
MoonTV 支持标准的苹果 CMS V10 API 格式。 KatelyaTV 支持标准的苹果 CMS V10 API 格式。
修改后 **无需重新构建**,服务会在启动时读取一次。 修改后 **无需重新构建**,服务会在启动时读取一次。
@@ -336,12 +349,13 @@ MoonTV 支持标准的苹果 CMS V10 API 格式。
## 📄 License ## 📄 License
[MIT](LICENSE) © 2025 MoonTV & Contributors [MIT](LICENSE) © 2025 KatelyaTV & Contributors
## 🙏 致谢 ## 🙏 致谢
- [ts-nextjs-tailwind-starter](https://github.com/theodorusclarence/ts-nextjs-tailwind-starter) — 项目最初基于该脚手架。 - [ts-nextjs-tailwind-starter](https://github.com/theodorusclarence/ts-nextjs-tailwind-starter) — 项目最初基于该脚手架。
- [LibreTV](https://github.com/LibreSpark/LibreTV) — 由此启发,站在巨人的肩膀上。 - [LibreTV](https://github.com/LibreSpark/LibreTV) — 由此启发,站在巨人的肩膀上。
- MoonTV 原始项目与作者社区 — 感谢原作奠定坚实基础。
- [ArtPlayer](https://github.com/zhw2590582/ArtPlayer) — 提供强大的网页视频播放器。 - [ArtPlayer](https://github.com/zhw2590582/ArtPlayer) — 提供强大的网页视频播放器。
- [HLS.js](https://github.com/video-dev/hls.js) — 实现 HLS 流媒体在浏览器中的播放支持。 - [HLS.js](https://github.com/video-dev/hls.js) — 实现 HLS 流媒体在浏览器中的播放支持。
- 感谢所有提供免费影视接口的站点。 - 感谢所有提供免费影视接口的站点。
+53
View File
@@ -0,0 +1,53 @@
# KatelyaTV v0.1.0-katelya 发布说明
> 本项目在「MoonTV」基础上进行二创与继承,由 Katelya 持续维护。保留并致谢原作与社区贡献,在不改变核心理念的前提下,专注于更易部署、更友好体验与更稳定维护。
## 亮点
- 全面延续上游核心:多源聚合搜索、在线播放、收藏与观看历史、PWA 支持、响应式布局、多用户系统等
- 文档重写与梳理:README、QUICKSTART、PROJECT_STATUS、CONTRIBUTING、CHANGELOG 全面适配 KatelyaTV 品牌
- 部署指引优化:Vercel / Docker / Cloudflare Pages 一站式说明,提供 Compose 最佳实践
- 安全与隐私提醒:新增部署安全提示与法律风险说明
## 变更摘要
- 品牌与文档
- 将项目品牌统一为 KatelyaTV,并明确二创与继承来源
- 更新部署与使用说明,优化快速上手体验
- 调整仓库路径、示例命令与 Docker 镜像示例名称(镜像仍沿用上游命名空间)
- 代码与配置
- 保持与上游 MoonTV 的接口与行为兼容
- 默认站点名改为 `KatelyaTV`(可通过 `SITE_NAME` 环境变量覆盖)
## 安装与升级
- 首次安装(Docker 推荐)
```bash
# 拉取镜像(当前仍沿用上游命名空间)
docker pull ghcr.io/senshinya/moontv:latest
# 启动示例
docker run -d --name katelyatv \
-p 3000:3000 \
--env PASSWORD=your_password \
--restart unless-stopped \
ghcr.io/senshinya/moontv:latest
```
- 或使用 README 中的 Docker Compose 示例
## 兼容性
- 保持与上游 MoonTV v0.1.0 行为一致
- 支持存储后端:localStorage / Redis / Cloudflare D1 / Upstash Redis
- 运行环境:Node.js 18+;容器镜像支持多架构
## 已知问题
- 部分第三方资源站可用性受其自身状态影响
- Android TV 端收藏与网页端暂未完全互通(后续版本优化)
## 后续路线
- 弹幕系统、字幕支持、下载功能、社交分享
- 数据同步与多端互通完善
- 性能与稳定性持续优化
## 鸣谢
- 原始项目 MoonTV 及其作者与社区
- 所有为本项目提供反馈、贡献代码与文档的开发者
— Katelya
+1 -1
View File
@@ -11,7 +11,7 @@ const publicDir = path.join(projectRoot, 'public');
const manifestPath = path.join(publicDir, 'manifest.json'); const manifestPath = path.join(publicDir, 'manifest.json');
// 从环境变量获取站点名称 // 从环境变量获取站点名称
const siteName = process.env.SITE_NAME || 'MoonTV'; const siteName = process.env.SITE_NAME || 'KatelyaTV';
// manifest.json 模板 // manifest.json 模板
const manifestTemplate = { const manifestTemplate = {
Executable → Regular
View File
+1 -1
View File
@@ -66,7 +66,7 @@ const BottomKatelyaLogo = () => {
<div className='text-center'> <div className='text-center'>
<div className='bottom-logo'>KatelyaTV</div> <div className='bottom-logo'>KatelyaTV</div>
<div className='mt-2 text-sm text-gray-500 dark:text-gray-400 opacity-75'> <div className='mt-2 text-sm text-gray-500 dark:text-gray-400 opacity-75'>
Powered by MoonTV Core Powered by KatelyaTV Core
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -1,7 +1,7 @@
import { Metadata } from 'next'; import { Metadata } from 'next';
export const metadata: Metadata = { export const metadata: Metadata = {
title: '安全警告 - MoonTV', title: '安全警告 - KatelyaTV',
description: '站点安全配置警告', description: '站点安全配置警告',
}; };
+4 -4
View File
@@ -151,7 +151,7 @@ async function initConfig() {
} }
adminConfig = { adminConfig = {
SiteConfig: { SiteConfig: {
SiteName: process.env.SITE_NAME || 'MoonTV', SiteName: process.env.SITE_NAME || 'KatelyaTV',
Announcement: Announcement:
process.env.ANNOUNCEMENT || process.env.ANNOUNCEMENT ||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。', '本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
@@ -190,7 +190,7 @@ async function initConfig() {
// 本地存储直接使用文件配置 // 本地存储直接使用文件配置
cachedConfig = { cachedConfig = {
SiteConfig: { SiteConfig: {
SiteName: process.env.SITE_NAME || 'MoonTV', SiteName: process.env.SITE_NAME || 'KatelyaTV',
Announcement: Announcement:
process.env.ANNOUNCEMENT || process.env.ANNOUNCEMENT ||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。', '本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
@@ -230,7 +230,7 @@ export async function getConfig(): Promise<AdminConfig> {
} }
if (adminConfig) { if (adminConfig) {
// 合并一些环境变量配置 // 合并一些环境变量配置
adminConfig.SiteConfig.SiteName = process.env.SITE_NAME || 'MoonTV'; adminConfig.SiteConfig.SiteName = process.env.SITE_NAME || 'KatelyaTV';
adminConfig.SiteConfig.Announcement = adminConfig.SiteConfig.Announcement =
process.env.ANNOUNCEMENT || process.env.ANNOUNCEMENT ||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。'; '本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。';
@@ -337,7 +337,7 @@ export async function resetConfig() {
} }
const adminConfig = { const adminConfig = {
SiteConfig: { SiteConfig: {
SiteName: process.env.SITE_NAME || 'MoonTV', SiteName: process.env.SITE_NAME || 'KatelyaTV',
Announcement: Announcement:
process.env.ANNOUNCEMENT || process.env.ANNOUNCEMENT ||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。', '本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
+20 -7
View File
@@ -55,12 +55,17 @@ interface UserCacheStore {
} }
// ---- 常量 ---- // ---- 常量 ----
const PLAY_RECORDS_KEY = 'moontv_play_records'; // 新的键名(KatelyaTV)与旧键名(MoonTV)保持向后兼容
const FAVORITES_KEY = 'moontv_favorites'; const PLAY_RECORDS_KEY = 'katelyatv_play_records';
const SEARCH_HISTORY_KEY = 'moontv_search_history'; const FAVORITES_KEY = 'katelyatv_favorites';
const SEARCH_HISTORY_KEY = 'katelyatv_search_history';
const LEGACY_PLAY_RECORDS_KEY = 'moontv_play_records';
const LEGACY_FAVORITES_KEY = 'moontv_favorites';
const LEGACY_SEARCH_HISTORY_KEY = 'moontv_search_history';
// 缓存相关常量 // 缓存相关常量
const CACHE_PREFIX = 'moontv_cache_'; const CACHE_PREFIX = 'katelyatv_cache_';
const LEGACY_CACHE_PREFIX = 'moontv_cache_';
const CACHE_VERSION = '1.0.0'; const CACHE_VERSION = '1.0.0';
const CACHE_EXPIRE_TIME = 60 * 60 * 1000; // 一小时缓存过期 const CACHE_EXPIRE_TIME = 60 * 60 * 1000; // 一小时缓存过期
@@ -426,7 +431,9 @@ export async function getAllPlayRecords(): Promise<Record<string, PlayRecord>> {
// localstorage 模式 // localstorage 模式
try { try {
const raw = localStorage.getItem(PLAY_RECORDS_KEY); const primary = localStorage.getItem(PLAY_RECORDS_KEY);
const fallback = localStorage.getItem(LEGACY_PLAY_RECORDS_KEY);
const raw = primary ?? fallback;
if (!raw) return {}; if (!raw) return {};
return JSON.parse(raw) as Record<string, PlayRecord>; return JSON.parse(raw) as Record<string, PlayRecord>;
} catch (err) { } catch (err) {
@@ -614,7 +621,9 @@ export async function getSearchHistory(): Promise<string[]> {
// localStorage 模式 // localStorage 模式
try { try {
const raw = localStorage.getItem(SEARCH_HISTORY_KEY); const primary = localStorage.getItem(SEARCH_HISTORY_KEY);
const fallback = localStorage.getItem(LEGACY_SEARCH_HISTORY_KEY);
const raw = primary ?? fallback;
if (!raw) return []; if (!raw) return [];
const arr = JSON.parse(raw) as string[]; const arr = JSON.parse(raw) as string[];
// 仅返回字符串数组 // 仅返回字符串数组
@@ -835,7 +844,9 @@ export async function getAllFavorites(): Promise<Record<string, Favorite>> {
// localStorage 模式 // localStorage 模式
try { try {
const raw = localStorage.getItem(FAVORITES_KEY); const primary = localStorage.getItem(FAVORITES_KEY);
const fallback = localStorage.getItem(LEGACY_FAVORITES_KEY);
const raw = primary ?? fallback;
if (!raw) return {}; if (!raw) return {};
return JSON.parse(raw) as Record<string, Favorite>; return JSON.parse(raw) as Record<string, Favorite>;
} catch (err) { } catch (err) {
@@ -1053,6 +1064,7 @@ export async function clearAllPlayRecords(): Promise<void> {
// localStorage 模式 // localStorage 模式
if (typeof window === 'undefined') return; if (typeof window === 'undefined') return;
localStorage.removeItem(PLAY_RECORDS_KEY); localStorage.removeItem(PLAY_RECORDS_KEY);
localStorage.removeItem(LEGACY_PLAY_RECORDS_KEY);
window.dispatchEvent( window.dispatchEvent(
new CustomEvent('playRecordsUpdated', { new CustomEvent('playRecordsUpdated', {
detail: {}, detail: {},
@@ -1094,6 +1106,7 @@ export async function clearAllFavorites(): Promise<void> {
// localStorage 模式 // localStorage 模式
if (typeof window === 'undefined') return; if (typeof window === 'undefined') return;
localStorage.removeItem(FAVORITES_KEY); localStorage.removeItem(FAVORITES_KEY);
localStorage.removeItem(LEGACY_FAVORITES_KEY);
window.dispatchEvent( window.dispatchEvent(
new CustomEvent('favoritesUpdated', { new CustomEvent('favoritesUpdated', {
detail: {}, detail: {},
+5 -2
View File
@@ -271,8 +271,9 @@ export class UpstashRedisStorage implements IStorage {
// 单例 Upstash Redis 客户端 // 单例 Upstash Redis 客户端
function getUpstashRedisClient(): Redis { function getUpstashRedisClient(): Redis {
const globalKey = Symbol.for('__MOONTV_UPSTASH_REDIS_CLIENT__'); const legacyKey = Symbol.for('__MOONTV_UPSTASH_REDIS_CLIENT__');
let client: Redis | undefined = (global as any)[globalKey]; const globalKey = Symbol.for('__KATELYATV_UPSTASH_REDIS_CLIENT__');
let client: Redis | undefined = (global as any)[globalKey] || (global as any)[legacyKey];
if (!client) { if (!client) {
const upstashUrl = process.env.UPSTASH_URL; const upstashUrl = process.env.UPSTASH_URL;
@@ -299,6 +300,8 @@ function getUpstashRedisClient(): Redis {
console.log('Upstash Redis client created successfully'); console.log('Upstash Redis client created successfully');
(global as any)[globalKey] = client; (global as any)[globalKey] = client;
// 同步设置旧的全局键,保持向后兼容
(global as any)[legacyKey] = client;
} }
return client; return client;
+6 -2
View File
@@ -11,11 +11,15 @@ export enum UpdateStatus {
FETCH_FAILED = 'fetch_failed', // 获取失败 FETCH_FAILED = 'fetch_failed', // 获取失败
} }
// 远程版本检查URL配置 // 远程版本检查URL配置(支持环境变量覆盖,并保留 MoonTV 上游作为后备)
const ENV_PRIMARY = process.env.NEXT_PUBLIC_VERSION_URL_PRIMARY;
const ENV_BACKUP = process.env.NEXT_PUBLIC_VERSION_URL_BACKUP;
const VERSION_CHECK_URLS = [ const VERSION_CHECK_URLS = [
ENV_PRIMARY,
ENV_BACKUP,
'https://ghfast.top/raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt', 'https://ghfast.top/raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt',
'https://raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt', 'https://raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt',
]; ].filter(Boolean) as string[];
/** /**
* 检查是否有新版本可用 * 检查是否有新版本可用