增加待看名单功能

This commit is contained in:
2025-09-06 10:03:00 +08:00
parent 9b2527379a
commit 8258d7c63b
9 changed files with 2151 additions and 3 deletions
+275
View File
@@ -0,0 +1,275 @@
const fs = require('fs').promises
const path = require('path')
const { defaultLogger } = require('../utils/logger');
// 创建logger实例
const logger = defaultLogger.child('WatchlistManager');
/**
* 待看名单管理器
* 负责管理用户的待看名单数据
*/
class WatchlistManager {
constructor() {
// 检测是否在pkg打包环境中运行
const isPkg = process.pkg !== undefined;
if (isPkg) {
// 在打包环境中,使用可执行文件所在目录
this.configDir = path.join(process.cwd(), 'data', 'watchlist.json')
} else {
// 在开发环境中,使用相对路径
this.configDir = path.join(__dirname, 'watchlist.json')
}
// 确保配置目录存在
this.ensureConfigDir()
this.defaultData = {
items: [],
lastUpdated: new Date().toISOString()
}
}
/**
* 确保配置目录存在
*/
ensureConfigDir() {
try {
const configDirPath = path.dirname(this.configDir)
if (!require('fs').existsSync(configDirPath)) {
require('fs').mkdirSync(configDirPath, { recursive: true })
logger.info('待看名单目录创建成功:', configDirPath)
}
} catch (error) {
logger.error('创建待看名单目录失败:', error)
}
}
/**
* 初始化待看名单文件
* 如果文件不存在,则创建默认数据
*/
async initialize() {
try {
// 检查文件是否存在
await fs.access(this.configDir)
logger.info('待看名单文件已存在')
} catch (error) {
// 文件不存在,创建默认文件
logger.info('创建默认待看名单文件...')
await this.createDefaultData()
}
}
/**
* 创建默认数据文件
*/
async createDefaultData() {
try {
// 确保配置目录存在
const configDirPath = path.dirname(this.configDir)
await fs.mkdir(configDirPath, { recursive: true })
// 检查目录是否创建成功
try {
await fs.access(configDirPath)
logger.info('待看名单目录确认存在:', configDirPath)
} catch (accessError) {
logger.error('待看名单目录访问失败:', accessError)
throw new Error(`无法访问配置目录: ${configDirPath}`)
}
// 写入默认数据
const dataContent = JSON.stringify(this.defaultData, null, 2)
await fs.writeFile(this.configDir, dataContent, 'utf8')
// 验证文件是否写入成功
try {
await fs.access(this.configDir)
logger.info('默认待看名单文件创建成功:', this.configDir)
} catch (verifyError) {
logger.error('待看名单文件验证失败:', verifyError)
throw new Error('待看名单文件创建后无法访问')
}
} catch (error) {
logger.error('创建默认待看名单文件失败:', error)
throw error
}
}
/**
* 读取待看名单数据
*/
async readData() {
try {
// 首先检查文件是否存在
const exists = await this.dataExists()
if (!exists) {
logger.info('待看名单文件不存在,创建默认数据...')
await this.createDefaultData()
}
const dataContent = await fs.readFile(this.configDir, 'utf8')
const data = JSON.parse(dataContent)
// 合并默认数据,确保所有必要的字段都存在
return { ...this.defaultData, ...data }
} catch (error) {
logger.error('读取待看名单文件失败:', error)
logger.info('使用默认数据...')
// 如果读取失败,尝试创建默认数据
try {
await this.createDefaultData()
return { ...this.defaultData }
} catch (createError) {
logger.error('创建默认数据也失败:', createError)
// 最后返回内存中的默认数据
return { ...this.defaultData }
}
}
}
/**
* 保存待看名单数据
*/
async saveData(data) {
try {
// 添加更新时间
const dataToSave = {
...data,
lastUpdated: new Date().toISOString()
}
await fs.writeFile(
this.configDir,
JSON.stringify(dataToSave, null, 2),
'utf8'
)
logger.info('待看名单文件保存成功')
return true
} catch (error) {
logger.error('保存待看名单文件失败:', error)
throw error
}
}
/**
* 添加待看项目
*/
async addItem(item) {
try {
const data = await this.readData()
// 检查是否已存在相同的URL
const existingIndex = data.items.findIndex(existingItem => existingItem.url === item.url)
if (existingIndex !== -1) {
// 如果存在,更新现有项目
data.items[existingIndex] = {
...data.items[existingIndex],
...item,
updatedAt: new Date().toISOString()
}
} else {
// 添加新项目
const newItem = {
id: Date.now().toString(),
...item,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
}
data.items.push(newItem)
}
await this.saveData(data)
return data.items
} catch (error) {
logger.error('添加待看项目失败:', error)
throw error
}
}
/**
* 删除待看项目
*/
async removeItem(id) {
try {
const data = await this.readData()
const initialLength = data.items.length
data.items = data.items.filter(item => item.id !== id)
if (data.items.length === initialLength) {
throw new Error('待看项目不存在')
}
await this.saveData(data)
return data.items
} catch (error) {
logger.error('删除待看项目失败:', error)
throw error
}
}
/**
* 更新待看项目
*/
async updateItem(id, updates) {
try {
const data = await this.readData()
const itemIndex = data.items.findIndex(item => item.id === id)
if (itemIndex === -1) {
throw new Error('待看项目不存在')
}
data.items[itemIndex] = {
...data.items[itemIndex],
...updates,
updatedAt: new Date().toISOString()
}
await this.saveData(data)
return data.items[itemIndex]
} catch (error) {
logger.error('更新待看项目失败:', error)
throw error
}
}
/**
* 获取所有待看项目
*/
async getAllItems() {
try {
const data = await this.readData()
return data.items
} catch (error) {
logger.error('获取待看项目失败:', error)
throw error
}
}
/**
* 获取配置文件路径
*/
getConfigPath() {
return this.configDir
}
/**
* 检查配置文件是否存在
*/
async dataExists() {
try {
await fs.access(this.configDir)
return true
} catch (error) {
return false
}
}
}
module.exports = WatchlistManager
+348
View File
@@ -0,0 +1,348 @@
{
"items": [
{
"id": "1757123368005",
"url": "http://localhost:3001/artist/72143697",
"title": "作者 72143697",
"createdAt": "2025-09-06T01:49:28.005Z",
"updatedAt": "2025-09-06T01:49:28.005Z"
},
{
"id": "1757123801822",
"url": "http://localhost:3001/artist/103047332",
"title": "作者管理",
"createdAt": "2025-09-06T01:56:41.822Z",
"updatedAt": "2025-09-06T01:56:41.822Z"
},
{
"id": "1757124092574",
"url": "http://localhost:3001/artist/113088709",
"title": "作者 113088709",
"createdAt": "2025-09-06T02:01:32.574Z",
"updatedAt": "2025-09-06T02:01:32.574Z"
},
{
"id": "1757124092579",
"url": "http://localhost:3001/artist/116491647",
"title": "作者 116491647",
"createdAt": "2025-09-06T02:01:32.579Z",
"updatedAt": "2025-09-06T02:01:32.579Z"
},
{
"id": "1757124092583",
"url": "http://localhost:3001/artist/20002274",
"title": "作者 20002274",
"createdAt": "2025-09-06T02:01:32.583Z",
"updatedAt": "2025-09-06T02:01:32.583Z"
},
{
"id": "1757124092586",
"url": "http://localhost:3001/artist/102068964",
"title": "作者 102068964",
"createdAt": "2025-09-06T02:01:32.586Z",
"updatedAt": "2025-09-06T02:01:32.586Z"
},
{
"id": "1757124092589",
"url": "http://localhost:3001/artist/57881733",
"title": "作者 57881733",
"createdAt": "2025-09-06T02:01:32.589Z",
"updatedAt": "2025-09-06T02:01:32.589Z"
},
{
"id": "1757124092595",
"url": "http://localhost:3001/artist/106498479",
"title": "作者 106498479",
"createdAt": "2025-09-06T02:01:32.595Z",
"updatedAt": "2025-09-06T02:01:32.595Z"
},
{
"id": "1757124092598",
"url": "http://localhost:3001/artist/87347255?page=21",
"title": "作者 87347255 - 第21页",
"createdAt": "2025-09-06T02:01:32.598Z",
"updatedAt": "2025-09-06T02:01:32.598Z"
},
{
"id": "1757124092601",
"url": "http://localhost:3001/artist/112391670",
"title": "作者 112391670",
"createdAt": "2025-09-06T02:01:32.601Z",
"updatedAt": "2025-09-06T02:01:32.601Z"
},
{
"id": "1757124092605",
"url": "http://localhost:3001/artist/97349140",
"title": "作者 97349140",
"createdAt": "2025-09-06T02:01:32.605Z",
"updatedAt": "2025-09-06T02:01:32.605Z"
},
{
"id": "1757124092608",
"url": "http://localhost:3001/artist/32222272",
"title": "作者 32222272",
"createdAt": "2025-09-06T02:01:32.608Z",
"updatedAt": "2025-09-06T02:01:32.608Z"
},
{
"id": "1757124092612",
"url": "http://localhost:3001/artist/16315304",
"title": "作者 16315304",
"createdAt": "2025-09-06T02:01:32.612Z",
"updatedAt": "2025-09-06T02:01:32.612Z"
},
{
"id": "1757124092615",
"url": "http://localhost:3001/artist/20420220",
"title": "作者 20420220",
"createdAt": "2025-09-06T02:01:32.615Z",
"updatedAt": "2025-09-06T02:01:32.615Z"
},
{
"id": "1757124092619",
"url": "http://localhost:3001/artist/95485582",
"title": "作者 95485582",
"createdAt": "2025-09-06T02:01:32.619Z",
"updatedAt": "2025-09-06T02:01:32.619Z"
},
{
"id": "1757124092622",
"url": "http://localhost:3001/artwork/99046180",
"title": "作品 99046180",
"createdAt": "2025-09-06T02:01:32.622Z",
"updatedAt": "2025-09-06T02:01:32.622Z"
},
{
"id": "1757124092625",
"url": "http://localhost:3001/artist/92969522",
"title": "作者 92969522",
"createdAt": "2025-09-06T02:01:32.625Z",
"updatedAt": "2025-09-06T02:01:32.625Z"
},
{
"id": "1757124092629",
"url": "http://localhost:3001/artist/35790899",
"title": "作者 35790899",
"createdAt": "2025-09-06T02:01:32.629Z",
"updatedAt": "2025-09-06T02:01:32.629Z"
},
{
"id": "1757124092632",
"url": "http://localhost:3001/artist/115689478?page=11",
"title": "作者 115689478 - 第11页",
"createdAt": "2025-09-06T02:01:32.632Z",
"updatedAt": "2025-09-06T02:01:32.632Z"
},
{
"id": "1757124092635",
"url": "http://localhost:3001/artist/54082094",
"title": "作者 54082094",
"createdAt": "2025-09-06T02:01:32.635Z",
"updatedAt": "2025-09-06T02:01:32.635Z"
},
{
"id": "1757124092639",
"url": "http://localhost:3001/artist/113605557",
"title": "作者 113605557",
"createdAt": "2025-09-06T02:01:32.639Z",
"updatedAt": "2025-09-06T02:01:32.639Z"
},
{
"id": "1757124092642",
"url": "http://localhost:3001/artist/12288015",
"title": "作者 12288015",
"createdAt": "2025-09-06T02:01:32.642Z",
"updatedAt": "2025-09-06T02:01:32.642Z"
},
{
"id": "1757124092646",
"url": "http://localhost:3001/artist/107444384",
"title": "作者 107444384",
"createdAt": "2025-09-06T02:01:32.646Z",
"updatedAt": "2025-09-06T02:01:32.646Z"
},
{
"id": "1757124092649",
"url": "http://localhost:3001/artist/98929998",
"title": "作者 98929998",
"createdAt": "2025-09-06T02:01:32.649Z",
"updatedAt": "2025-09-06T02:01:32.649Z"
},
{
"id": "1757124092653",
"url": "http://localhost:3001/artist/35227306",
"title": "作者 35227306",
"createdAt": "2025-09-06T02:01:32.653Z",
"updatedAt": "2025-09-06T02:01:32.653Z"
},
{
"id": "1757124092656",
"url": "http://localhost:3001/artist/55914620",
"title": "作者 55914620",
"createdAt": "2025-09-06T02:01:32.656Z",
"updatedAt": "2025-09-06T02:01:32.656Z"
},
{
"id": "1757124092662",
"url": "http://localhost:3001/artist/112826987",
"title": "作者 112826987",
"createdAt": "2025-09-06T02:01:32.662Z",
"updatedAt": "2025-09-06T02:01:32.662Z"
},
{
"id": "1757124092665",
"url": "http://localhost:3001/artist/117505514",
"title": "作者 117505514",
"createdAt": "2025-09-06T02:01:32.665Z",
"updatedAt": "2025-09-06T02:01:32.665Z"
},
{
"id": "1757124092669",
"url": "http://localhost:3001/artist/116034471?page=11",
"title": "作者 116034471 - 第11页",
"createdAt": "2025-09-06T02:01:32.669Z",
"updatedAt": "2025-09-06T02:01:32.669Z"
},
{
"id": "1757124092672",
"url": "http://localhost:3001/artist/116826562",
"title": "作者 116826562",
"createdAt": "2025-09-06T02:01:32.672Z",
"updatedAt": "2025-09-06T02:01:32.672Z"
},
{
"id": "1757124092675",
"url": "http://localhost:3001/artist/119419938",
"title": "作者 119419938",
"createdAt": "2025-09-06T02:01:32.675Z",
"updatedAt": "2025-09-06T02:01:32.675Z"
},
{
"id": "1757124092679",
"url": "http://localhost:3001/artist/105818043",
"title": "作者 105818043",
"createdAt": "2025-09-06T02:01:32.679Z",
"updatedAt": "2025-09-06T02:01:32.679Z"
},
{
"id": "1757124092683",
"url": "http://localhost:3001/artist/3328617",
"title": "作者 3328617",
"createdAt": "2025-09-06T02:01:32.683Z",
"updatedAt": "2025-09-06T02:01:32.683Z"
},
{
"id": "1757124092686",
"url": "http://localhost:3001/artist/114508563",
"title": "作者 114508563",
"createdAt": "2025-09-06T02:01:32.686Z",
"updatedAt": "2025-09-06T02:01:32.686Z"
},
{
"id": "1757124092689",
"url": "http://localhost:3001/artist/48447420",
"title": "作者 48447420",
"createdAt": "2025-09-06T02:01:32.689Z",
"updatedAt": "2025-09-06T02:01:32.689Z"
},
{
"id": "1757124092696",
"url": "http://localhost:3001/artist/18898196",
"title": "作者 18898196",
"createdAt": "2025-09-06T02:01:32.696Z",
"updatedAt": "2025-09-06T02:01:32.696Z"
},
{
"id": "1757124092699",
"url": "http://localhost:3001/artist/24503943",
"title": "作者 24503943",
"createdAt": "2025-09-06T02:01:32.699Z",
"updatedAt": "2025-09-06T02:01:32.699Z"
},
{
"id": "1757124092703",
"url": "http://localhost:3001/artist/83735825",
"title": "作者 83735825",
"createdAt": "2025-09-06T02:01:32.703Z",
"updatedAt": "2025-09-06T02:01:32.703Z"
},
{
"id": "1757124092706",
"url": "http://localhost:3001/artist/109989392",
"title": "作者 109989392",
"createdAt": "2025-09-06T02:01:32.706Z",
"updatedAt": "2025-09-06T02:01:32.706Z"
},
{
"id": "1757124092712",
"url": "http://localhost:3001/artist/119068816",
"title": "作者 119068816",
"createdAt": "2025-09-06T02:01:32.712Z",
"updatedAt": "2025-09-06T02:01:32.712Z"
},
{
"id": "1757124092718",
"url": "http://localhost:3001/artist/8934406",
"title": "作者 8934406",
"createdAt": "2025-09-06T02:01:32.718Z",
"updatedAt": "2025-09-06T02:01:32.718Z"
},
{
"id": "1757124092725",
"url": "http://localhost:3001/artist/118710458",
"title": "作者 118710458",
"createdAt": "2025-09-06T02:01:32.725Z",
"updatedAt": "2025-09-06T02:01:32.725Z"
},
{
"id": "1757124092733",
"url": "http://localhost:3001/artist/111705416",
"title": "作者 111705416",
"createdAt": "2025-09-06T02:01:32.733Z",
"updatedAt": "2025-09-06T02:01:32.733Z"
},
{
"id": "1757124092737",
"url": "http://localhost:3001/artist/114537113",
"title": "作者 114537113",
"createdAt": "2025-09-06T02:01:32.737Z",
"updatedAt": "2025-09-06T02:01:32.737Z"
},
{
"id": "1757124092741",
"url": "http://localhost:3001/artist/117665623",
"title": "作者 117665623",
"createdAt": "2025-09-06T02:01:32.741Z",
"updatedAt": "2025-09-06T02:01:32.741Z"
},
{
"id": "1757124092745",
"url": "http://localhost:3001/artist/17745716",
"title": "作者 17745716",
"createdAt": "2025-09-06T02:01:32.745Z",
"updatedAt": "2025-09-06T02:01:32.745Z"
},
{
"id": "1757124092749",
"url": "http://localhost:3001/artist/113801960",
"title": "作者 113801960",
"createdAt": "2025-09-06T02:01:32.749Z",
"updatedAt": "2025-09-06T02:01:32.749Z"
},
{
"id": "1757124092752",
"url": "http://localhost:3001/artist/116034471",
"title": "作者 116034471",
"createdAt": "2025-09-06T02:01:32.752Z",
"updatedAt": "2025-09-06T02:01:32.752Z"
},
{
"id": "1757124092756",
"url": "http://localhost:3001/artist/117814316",
"title": "作者 117814316",
"createdAt": "2025-09-06T02:01:32.756Z",
"updatedAt": "2025-09-06T02:01:32.756Z"
}
],
"lastUpdated": "2025-09-06T02:01:32.756Z"
}