This commit is contained in:
2025-07-19 12:46:27 +08:00
parent 12e1da5681
commit c1d6fe181d
47 changed files with 3570 additions and 24 deletions
@@ -0,0 +1,22 @@
import { BookImageTextToVideoInfo } from "./bookImageTextToVideoInfo";
export class BookImageTextToVideoIndex {
bookImageTextToVideoInfo: BookImageTextToVideoInfo;
constructor() {
this.bookImageTextToVideoInfo = new BookImageTextToVideoInfo();
}
//#region Info
/** 获取用于视频生成的小说信息列表 根据查询条件返回小说数据,如果指定了bookTaskId,则返回对应小说的单个任务数据 否则返回所有启用了视频生成功能的小说及其任务数据 */
GetVideoBookInfoList = async (condition: BookVideo.BookVideoInfoListQuertCondition) => await this.bookImageTextToVideoInfo.GetVideoBookInfoList(condition)
GetBookImageAndVideoProgress = async (bookId?: string, bookTaskId?: string) => await this.bookImageTextToVideoInfo.GetBookImageAndVideoProgress(bookId, bookTaskId);
//#endregion
}
@@ -0,0 +1,257 @@
import { errorMessage, successMessage } from "@/main/Public/generalTools";
import { BookBasicHandle } from "../bookBasicHandle";
import { isEmpty } from "lodash";
import { CheckFileOrDirExist } from "@/define/Tools/file";
import { Book } from "@/model/book/book";
// 定义进度数据的类型
export interface ProgressData {
imageProgress: number;
videoProgress: number;
totalCount: number;
imageRate: number;
videoRate: number;
}
// 定义嵌套的 Record 类型
export type BookProgressRecord = Record<string, Record<string, ProgressData>>;
export class BookImageTextToVideoInfo extends BookBasicHandle {
constructor() {
super();
}
//#region GetVideoBookInfoList
/**
* 获取用于视频生成的小说信息列表
* 根据查询条件返回小说数据,如果指定了bookTaskId,则返回对应小说的单个任务数据
* 否则返回所有启用了视频生成功能的小说及其任务数据
* @param condition 查询条件,包含可选的bookTaskId等参数
* @returns 处理结果,成功时返回小说数据,失败时返回错误信息
*/
GetVideoBookInfoList = async (condition: BookVideo.BookVideoInfoListQuertCondition) => {
try {
await this.InitBookBasicHandle();
// 获取小说的所有的数据
let bookRes = this.bookService.GetBookData(condition);
if (bookRes.code !== 1) {
return errorMessage('获取小说数据失败,错误信息:' + bookRes.message, 'BookImageTextToVideoInfo_GetVideoBookInfoList');
}
let bookList = bookRes.data.res_book ?? [];
if (bookList.length <= 0) {
return errorMessage('没有找到对应的小说数据,请先添加小说', 'BookImageTextToVideoInfo_GetVideoBookInfoList');
}
// 有指定的小说批次任务的ID情况下 只返回当前的小说数据
if (condition.bookTaskId) {
let bookTask = this.bookTaskService.GetBookTaskDataById(condition.bookTaskId);
if (bookTask == null) {
return errorMessage('没有找到对应的小说批次数据,请先添加小说批次', 'BookImageTextToVideoInfo_GetVideoBookInfoList');
}
// 再上面的小说数据里面获取数据 然后直接返回就行
let bookInfo = bookList.find(book => book.id === bookTask.bookId);
if (!bookInfo) {
return errorMessage('没有找到对应的小说数据,请先添加小说', 'BookImageTextToVideoInfo_GetVideoBookInfoList');
}
bookInfo.bookTasks = [bookTask];
// 返回
return successMessage(bookInfo, '获取小说批次任务数据成功', 'BookImageTextToVideoInfo_GetVideoBookInfoList');
}
// 没有那个数据 将所有的数据进行处理
let res = [];
for (let i = 0; i < bookList.length; i++) {
const element = bookList[i];
// 获取小说批次任务数据
let bookTaskRes = this.bookTaskService.GetBookTaskData({ bookId: element.id });
if (bookTaskRes.code != 1) {
continue;
}
if (bookTaskRes.data.bookTasks.length > 0) {
// 检查所有的 bookTasks 里面是不是开启了图转视频功能
let videoBookTasks = bookTaskRes.data.bookTasks.filter(task => task.openVideoGenerate);
if (videoBookTasks.length <= 0) {
continue;
} else {
element.bookTasks = videoBookTasks;
res.push(element);
}
}
}
return successMessage(
res,
'获取小说批次任务数据成功',
'BookImageTextToVideoInfo_GetVideoBookInfoList'
);
} catch (error) {
return errorMessage(
'初始化BookBasicHandle失败,错误信息如下:' + error.toString(),
'BookImageTextToVideoInfo_GetVideoBookInfoList'
);
}
}
//#endregion
//#region GetBookImageAndVideoProgress
/**
* 获取小说图片和视频生成的进度信息
* 根据提供的参数查询指定小说或小说任务的图片和视频生成进度
* @param bookId 可选,小说ID,如果提供则只返回该小说的进度数据
* @param bookTaskId 可选,小说任务ID,如果提供则只返回该任务的进度数据
* @returns 返回包含进度信息的对象,成功时返回进度数据,失败时返回错误信息
*/
GetBookImageAndVideoProgress = async (bookId?: string, bookTaskId?: string) => {
try {
await this.InitBookBasicHandle();
let bookIds: Record<string, string[]> = {};
// 开始处理获取对应的小说ID和关联数据
if (!isEmpty(bookId)) {
let bookInfo = this.bookService.GetBookDataById(bookId);
if (bookInfo == null) {
return errorMessage('没有找到对应的小说数据,请先添加小说', 'BookImageTextToVideoInfo_GetBookImageAndVideoProgress');
}
bookIds[bookInfo.id] = [];
} else {
// 获取所有的小说数据
let bookRes = this.bookService.GetBookData({});
if (bookRes.code !== 1) {
return errorMessage('获取小说数据失败,错误信息:' + bookRes.message, 'BookImageTextToVideoInfo_GetBookImageAndVideoProgress');
}
let bookList = bookRes.data.res_book ?? [];
if (bookList.length <= 0) {
return errorMessage('没有找到对应的小说数据,请先添加小说', 'BookImageTextToVideoInfo_GetBookImageAndVideoProgress');
}
// 将所有的小说ID添加到bookIds里面
for (let i = 0; i < bookList.length; i++) {
const element = bookList[i];
bookIds[element.id] = [];
}
}
// 判断小说任务ID是不是存在 存在的话判断小说任务的ID是不是再bookIds里面 在的话更新bookIds中指定的ID的值数据
if (!isEmpty(bookTaskId)) {
let bookTaskInfo = this.bookTaskService.GetBookTaskDataById(bookTaskId);
if (bookTaskInfo == null) {
return errorMessage('没有找到对应的小说批次数据,请先添加小说批次', 'BookImageTextToVideoInfo_GetBookImageAndVideoProgress');
}
// 判断当前的bookid 是不是再 bookIds里面
if (bookTaskInfo.bookId && bookIds[bookTaskInfo.bookId]) {
bookIds[bookTaskInfo.bookId] = [bookTaskInfo.id];
} else {
return errorMessage('当前的小说批次任务ID不属于指定的小说ID', 'BookImageTextToVideoInfo_GetBookImageAndVideoProgress');
}
} else {
// 遍历 bookIds 获取所有的小说批次任务ID
for (const bookId of Object.keys(bookIds)) {
// 获取小说批次任务数据
let bookTaskRes = this.bookTaskService.GetBookTaskData({ bookId: bookId });
if (bookTaskRes.code !== 1) {
continue;
}
if (bookTaskRes.data.bookTasks.length > 0) {
// 检查所有的 bookTasks 里面是不是开启了图转视频功能
let ids = bookTaskRes.data.bookTasks.map(task => task.id);
bookIds[bookId] = ids;
}
}
}
// 遍历 bookIds 将值数据为空或者长度为0的都删除
Object.keys(bookIds).forEach(bookId => {
if (isEmpty(bookIds[bookId]) || bookIds[bookId].length <= 0) {
delete bookIds[bookId];
}
});
// 检查最终结果
if (Object.keys(bookIds).length === 0) {
return successMessage({}, '没有找到对应的小说数据或者小说批次任务数据', 'BookImageTextToVideoInfo_GetBookImageAndVideoProgress');
}
// 这边开始处理数据
let resData = await this.ProgressHandle(bookIds);
return successMessage(
resData,
'获取小说图片和视频生成进度成功',
'BookImageTextToVideoInfo_GetBookImageAndVideoProgress'
);
} catch (error) {
return errorMessage(
'获取小说图片和视频生成进度失败,错误信息如下:' + error.toString(),
'BookImageTextToVideoInfo_GetBookImageAndVideoProgress'
);
}
}
/**
* 处理进度数据
* 遍历小说ID和批次任务ID,计算每个任务的图片和视频生成进度
* @param bookIds 小说ID和对应小说任务ID的映射关系,格式为 {bookId: [taskId1, taskId2, ...]}
* @returns 返回每本书每个任务的进度数据,包含图片进度、视频进度、总数量和完成率
*/
private ProgressHandle = async (bookIds: Record<string, string[]>) => {
// 这边开始处理数据
let resData: BookProgressRecord = {};
// 遍历 bookIds 获取所有的小说批次任务数据
for (const bookId of Object.keys(bookIds)) {
let bookTaskIds = bookIds[bookId];
if (!bookTaskIds && bookTaskIds.length <= 0) {
continue;
}
resData[bookId] = {};
// 获取小说批次任务数据
for (let i = 0; i < bookTaskIds.length; i++) {
const element = bookTaskIds[i];
let bookTaskDetails = this.bookTaskDetailService.GetBookTaskData({ bookTaskId: element, bookId: bookId });
if (bookTaskDetails.code !== 1) {
continue;
}
// 遍历 bookTaskDetails 获取每个小说批次任务的进度数据
let imageProgress = 0;
let videoProgress = 0;
for (let j = 0; j < bookTaskDetails.data.length; j++) {
const bookTaskDetail = bookTaskDetails.data[j] as Book.SelectBookTaskDetail;
// 检查图片信息
if (!isEmpty(bookTaskDetail.outImagePath) && await CheckFileOrDirExist(bookTaskDetail.outImagePath)) {
imageProgress += 1;
}
// 检查视频信息
if (!isEmpty(bookTaskDetail.videoPath) && await CheckFileOrDirExist(bookTaskDetail.videoPath)) {
videoProgress += 1;
}
}
// 开始添加数据
resData[bookId][element] = {
imageProgress: imageProgress,
videoProgress: videoProgress,
totalCount: bookTaskDetails.data.length,
imageRate: bookTaskDetails.data.length > 0 ? (imageProgress / bookTaskDetails.data.length) * 100 : 0,
videoRate: bookTaskDetails.data.length > 0 ? (videoProgress / bookTaskDetails.data.length) * 100 : 0
}
}
}
return resData;
}
//#endregion
}