244 lines
8.3 KiB
TypeScript
244 lines
8.3 KiB
TypeScript
import NeDBManager from '@/lib/database/nedb.js';
|
||
|
||
// 生成结果表数据模型
|
||
export interface IGenerationResult {
|
||
task_id: string; // 关联的任务ID,主键
|
||
task_type: 'image' | 'video'; // 任务类型
|
||
server_id: string; // 处理服务器ID
|
||
|
||
// 生成结果
|
||
status: 'success' | 'failed'; // 最终状态
|
||
original_urls: string[]; // 原始URL数组(即梦返回的地址)
|
||
tos_urls: string[]; // TOS URL数组(上传后的地址)
|
||
|
||
// 处理元数据
|
||
metadata: {
|
||
generation_time?: number; // 生成耗时(毫秒)
|
||
tos_upload_time?: number; // TOS上传耗时(毫秒)
|
||
total_files: number; // 文件总数
|
||
successful_uploads: number; // 成功上传数量
|
||
upload_retry_count?: number; // 上传重试次数
|
||
tos_upload_errors?: string[]; // TOS上传错误信息
|
||
fail_reason?: string; // 失败原因
|
||
};
|
||
|
||
// 时间管理
|
||
created_at: number; // 创建时间戳(秒)
|
||
expires_at: number; // 过期时间戳(用于自动清理,默认24小时后)
|
||
|
||
// 读取状态
|
||
is_read: boolean; // 是否已被读取
|
||
first_read_at?: number; // 首次读取时间戳(秒)
|
||
read_count: number; // 读取次数
|
||
}
|
||
|
||
// NeDB 数据操作类
|
||
export class GenerationResult {
|
||
private static dbName = 'generation_results';
|
||
|
||
// 默认过期时间:24小时(86400秒)
|
||
private static DEFAULT_EXPIRY_SECONDS = 24 * 60 * 60;
|
||
|
||
// 创建结果
|
||
static async create(resultData: Omit<IGenerationResult, '_id'>): Promise<IGenerationResult> {
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const result = {
|
||
...resultData,
|
||
created_at: resultData.created_at || currentTime,
|
||
expires_at: resultData.expires_at || (currentTime + this.DEFAULT_EXPIRY_SECONDS),
|
||
is_read: resultData.is_read || false,
|
||
read_count: resultData.read_count || 0
|
||
};
|
||
|
||
return await NeDBManager.insert(this.dbName, result);
|
||
}
|
||
|
||
// 查找单个结果
|
||
static async findOne(query: any): Promise<IGenerationResult | null> {
|
||
// 自动过滤过期数据
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const filterQuery = {
|
||
...query,
|
||
expires_at: { $gt: currentTime }
|
||
};
|
||
|
||
return await NeDBManager.findOne(this.dbName, filterQuery);
|
||
}
|
||
|
||
// 查找多个结果
|
||
static async find(query: any, sort?: any, limit?: number): Promise<IGenerationResult[]> {
|
||
// 自动过滤过期数据
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const filterQuery = {
|
||
...query,
|
||
expires_at: { $gt: currentTime }
|
||
};
|
||
|
||
return await NeDBManager.find(this.dbName, filterQuery, sort, limit);
|
||
}
|
||
|
||
// 更新结果
|
||
static async updateOne(query: any, update: any, options: any = {}): Promise<number> {
|
||
// 自动过滤过期数据
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const filterQuery = {
|
||
...query,
|
||
expires_at: { $gt: currentTime }
|
||
};
|
||
|
||
return await NeDBManager.update(this.dbName, filterQuery, update, { ...options, multi: false });
|
||
}
|
||
|
||
// 批量更新结果
|
||
static async updateMany(query: any, update: any, options: any = {}): Promise<number> {
|
||
// 自动过滤过期数据
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const filterQuery = {
|
||
...query,
|
||
expires_at: { $gt: currentTime }
|
||
};
|
||
|
||
return await NeDBManager.update(this.dbName, filterQuery, update, { ...options, multi: true });
|
||
}
|
||
|
||
// 删除结果
|
||
static async deleteOne(query: any): Promise<number> {
|
||
return await NeDBManager.remove(this.dbName, query, { multi: false });
|
||
}
|
||
|
||
// 批量删除结果
|
||
static async deleteMany(query: any): Promise<number> {
|
||
return await NeDBManager.remove(this.dbName, query, { multi: true });
|
||
}
|
||
|
||
// 批量插入结果
|
||
static async insertMany(results: Omit<IGenerationResult, '_id'>[]): Promise<IGenerationResult[]> {
|
||
const insertedResults: IGenerationResult[] = [];
|
||
|
||
for (const resultData of results) {
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const result = {
|
||
...resultData,
|
||
created_at: resultData.created_at || currentTime,
|
||
expires_at: resultData.expires_at || (currentTime + this.DEFAULT_EXPIRY_SECONDS),
|
||
is_read: resultData.is_read || false,
|
||
read_count: resultData.read_count || 0
|
||
};
|
||
|
||
const insertedResult = await NeDBManager.insert(this.dbName, result);
|
||
insertedResults.push(insertedResult);
|
||
}
|
||
|
||
return insertedResults;
|
||
}
|
||
|
||
// 计数(排除过期数据)
|
||
static async countDocuments(query: any): Promise<number> {
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const filterQuery = {
|
||
...query,
|
||
expires_at: { $gt: currentTime }
|
||
};
|
||
|
||
return await NeDBManager.count(this.dbName, filterQuery);
|
||
}
|
||
|
||
// 根据任务ID查找结果并更新读取状态
|
||
static async findByTaskIdAndMarkRead(taskId: string): Promise<IGenerationResult | null> {
|
||
const result = await this.findOne({ task_id: taskId });
|
||
|
||
if (result) {
|
||
// 更新读取状态和计数
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
await this.updateOne(
|
||
{ task_id: taskId },
|
||
{
|
||
$set: {
|
||
is_read: true,
|
||
first_read_at: result.first_read_at || currentTime
|
||
},
|
||
$inc: { read_count: 1 }
|
||
}
|
||
);
|
||
|
||
// 返回更新后的结果
|
||
result.is_read = true;
|
||
result.first_read_at = result.first_read_at || currentTime;
|
||
result.read_count = (result.read_count || 0) + 1;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
// 清理过期数据
|
||
static async cleanupExpiredResults(): Promise<number> {
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
|
||
return await this.deleteMany({
|
||
expires_at: { $lte: currentTime }
|
||
});
|
||
}
|
||
|
||
// 获取即将过期的结果(用于预警)
|
||
static async getExpiringResults(warningSeconds: number = 3600): Promise<IGenerationResult[]> {
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
const warningTime = currentTime + warningSeconds;
|
||
|
||
return await this.find({
|
||
expires_at: {
|
||
$gt: currentTime,
|
||
$lte: warningTime
|
||
}
|
||
});
|
||
}
|
||
|
||
// 延长结果过期时间
|
||
static async extendExpiry(taskId: string, additionalSeconds: number): Promise<boolean> {
|
||
const numUpdated = await this.updateOne(
|
||
{ task_id: taskId },
|
||
{
|
||
$inc: { expires_at: additionalSeconds }
|
||
}
|
||
);
|
||
|
||
return numUpdated > 0;
|
||
}
|
||
|
||
// 获取统计信息
|
||
static async getStats(): Promise<{
|
||
total: number;
|
||
unread: number;
|
||
read: number;
|
||
byType: { [key: string]: number };
|
||
byStatus: { [key: string]: number };
|
||
}> {
|
||
const allResults = await this.find({});
|
||
|
||
const stats = {
|
||
total: allResults.length,
|
||
unread: 0,
|
||
read: 0,
|
||
byType: {} as { [key: string]: number },
|
||
byStatus: {} as { [key: string]: number }
|
||
};
|
||
|
||
allResults.forEach(result => {
|
||
// 读取状态统计
|
||
if (!result.is_read) {
|
||
stats.unread++;
|
||
} else {
|
||
stats.read++;
|
||
}
|
||
|
||
// 任务类型统计
|
||
stats.byType[result.task_type] = (stats.byType[result.task_type] || 0) + 1;
|
||
|
||
// 最终状态统计
|
||
stats.byStatus[result.status] = (stats.byStatus[result.status] || 0) + 1;
|
||
});
|
||
|
||
return stats;
|
||
}
|
||
}
|
||
|
||
export default GenerationResult; |