LaiTool_PRO/src/define/db/service/book/bookTaskService.ts

310 lines
10 KiB
TypeScript
Raw Normal View History

2025-08-19 14:33:59 +08:00
import Realm from 'realm'
import { RealmBaseService } from '../base/realmBase'
import { Book } from '@/define/model/book/book'
import { BookTaskModel } from '../../model/bookTask'
import { getProjectPath } from '@/main/service/option/optionCommonService'
import { ImageCategory } from '@/define/data/imageData'
import { JoinPath } from '@/define/Tools/file'
import { BookTaskStatus } from '@/define/enum/bookEnum'
export class BookTaskService extends RealmBaseService {
static instance: BookTaskService | null = null
declare realm: Realm
private constructor() {
super()
}
/**
*
* @returns
*/
public static async getInstance() {
if (BookTaskService.instance === null) {
BookTaskService.instance = new BookTaskService()
await super.getInstance()
}
await BookTaskService.instance.open()
return BookTaskService.instance
}
/**
*
* @param bookTaskCondition idbookIdnamenopage, pageSize
*/
async GetBookTaskDataByCondition(
bookTaskCondition: Book.QueryBookTaskCondition
): Promise<Book.QueryBookTaskConditionResponse> {
try {
// 获取所有的小说数据,并进行时间降序排序
let bookTasks = this.realm.objects<BookTaskModel>('BookTask')
// 开始开始筛选
if (bookTaskCondition.id) {
// 查询对应的小说ID的数据
bookTasks = bookTasks.filtered('id = $0', bookTaskCondition.id)
}
if (bookTaskCondition.bookId) {
// 查询对应的小说ID的数据
bookTasks = bookTasks.filtered('bookId = $0', bookTaskCondition.bookId)
}
if (bookTaskCondition.name) {
// 查询对应的小说ID的数据
bookTasks = bookTasks.filtered('name = $0', bookTaskCondition.name)
}
if (bookTaskCondition.no) {
// 查询对应的小说ID的数据
bookTasks = bookTasks.filtered('no = $0', bookTaskCondition.no)
}
let bookTask_length = bookTasks.length
// bookTasks = bookTasks.sorted('updateTime', true)
// 判断是不是有page和pageSize有的话对查询返回的信息做分页
if (bookTaskCondition.page && bookTaskCondition.pageSize) {
bookTasks = bookTasks.slice(
(bookTaskCondition.page - 1) * bookTaskCondition.pageSize,
bookTaskCondition.page * bookTaskCondition.pageSize
) as unknown as Realm.Results<BookTaskModel>
}
let projectPath: string = await getProjectPath()
// 做一下数据转换
// 将realm对象数组转换为普通对象数组
// 将realm对象数组转换为普通对象数组并处理异步操作
let res_bookTasks = Array.from(bookTasks).map((bookTask) => {
// 直接操作普通对象
return {
...bookTask,
imageStyle: bookTask.imageStyle ? Array.from(bookTask.imageStyle) : [],
customizeImageStyle: bookTask.customizeImageStyle
? Array.from(bookTask.customizeImageStyle)
: [],
generateVideoPath: JoinPath(projectPath, bookTask.generateVideoPath),
srtPath: JoinPath(projectPath, bookTask.srtPath),
audioPath: JoinPath(projectPath, bookTask.audioPath),
imageFolder: JoinPath(projectPath, bookTask.imageFolder),
cacheImageList: bookTask.cacheImageList
? Array.from(bookTask.cacheImageList).map((item) => JoinPath(projectPath, item))
: [],
imageCategory: bookTask.imageCategory ? bookTask.imageCategory : ImageCategory.Midjourney // 默认使用MJ出图
} as Book.SelectBookTask
})
return {
bookTasks: JSON.parse(JSON.stringify(res_bookTasks)),
bookTaskLength: bookTask_length
} as Book.QueryBookTaskConditionResponse
} catch (error) {
throw error
}
}
/**
* ID获取小说批次任务的数据
* @param bookTaskId
*/
async GetBookTaskDataById(bookTaskId: string): Promise<Book.SelectBookTask> {
try {
if (bookTaskId == null) {
throw new Error('小说任务ID不能为空')
}
let bookTasks = await this.GetBookTaskDataByCondition({ id: bookTaskId })
if (bookTasks.bookTasks.length <= 0) {
throw new Error('未找到对应的小说任务')
} else {
return bookTasks.bookTasks[0]
}
} catch (error) {
throw error
}
}
/**
*
* @param bookTaskId Id
* @param status
*/
ModifyBookTaskStatus(bookTaskId: string, status: BookTaskStatus, errorMsg?: string): void {
try {
this.transaction(() => {
// 修改对应小说批次任务的状态
let bookTask = this.realm.objectForPrimaryKey('BookTask', bookTaskId)
if (bookTask == null) {
throw new Error('未找到对应的小说任务')
}
bookTask.status = status
bookTask.updateTime = new Date()
if (errorMsg != null) {
bookTask.errorMsg = errorMsg
}
})
} catch (error) {
throw error
}
}
/**
*
* @param bookTaskId ID
* @param data
*/
async ModifyBookTaskDataById(
bookTaskId: string,
data: Book.SelectBookTask
): Promise<Book.SelectBookTask> {
try {
this.transaction(() => {
let updateData = this.realm.objectForPrimaryKey('BookTask', bookTaskId)
if (updateData == null) {
throw new Error('未找到对应的小说任务详细信息')
}
// 开始修改
for (let key in data) {
updateData[key] = data[key]
}
})
let res = await this.GetBookTaskDataById(bookTaskId)
return res
} catch (error) {
throw error
}
}
// 添加一条数据
async AddBookTask(bookTask: Book.SelectBookTask): Promise<Book.SelectBookTask> {
try {
// 新增
if (bookTask.bookId == '' || bookTask.bookId == null) {
throw new Error('小说ID不能为空')
}
bookTask.id = crypto.randomUUID()
// 获取当前bookID对应的最大的no
let maxNo = this.realm.objects('BookTask').filtered('bookId = $0', bookTask.bookId).max('no')
bookTask.no = maxNo == null ? 1 : Number(maxNo) + 1
bookTask.name = 'output_0000' + bookTask.no
bookTask.status = BookTaskStatus.WAIT
bookTask.updateTime = new Date()
bookTask.createTime = new Date()
this.realm.write(() => {
this.realm.create('BookTask', bookTask)
})
// 处理完毕,返回结果
let res = await this.GetBookTaskDataById(bookTask.id)
return res
} catch (error) {
throw error
}
}
/**
*
* @param bookId ID
*/
async GetMaxBookTaskNo(bookId: string): Promise<number> {
let maxNo = this.realm.objects('BookTask').filtered('bookId = $0', bookId).max('no')
let no = maxNo == null ? 1 : Number(maxNo) + 1
return no
}
/**
*
* @param bookTaskId ID
*/
async ResetBookTaskDataById(
bookTaskId: string,
resetBase: boolean = true
): Promise<Book.SelectBookTask> {
try {
// 开始重置数据,先重置小说批次数据,在重置其他
this.transaction(() => {
this.ResetBookTaskDataInfo(bookTaskId, resetBase)
})
let res = await this.GetBookTaskDataById(bookTaskId)
return res
} catch (error) {
throw error
}
}
/**
*
* @param bookTaskId ID
*/
DeleteBookTaskDataById(bookTaskId: string): void {
try {
this.transaction(() => {
// 先调用清除数据的方法
this.ResetBookTaskDataInfo(bookTaskId)
// 删除批次数据
let bookTask = this.realm.objectForPrimaryKey('BookTask', bookTaskId)
if (bookTask == null) {
throw new Error('未找到对应的小说任务,无法执行删除操作')
}
this.realm.delete(bookTask)
})
} catch (error) {
throw error
}
}
/** 重置小说批次任务数据 */
private ResetBookTaskDataInfo(bookTaskId: string, resetBase: boolean = true) {
try {
let modifyBookTask = this.realm.objectForPrimaryKey('BookTask', bookTaskId)
if (modifyBookTask == null) {
throw new Error('未找到对应的小说批次任务,无法执行重置操作')
}
let book = this.realm.objectForPrimaryKey('Book', modifyBookTask.bookId)
if (book == null) {
throw new Error('未找到对应的小说,无法执行重置操作')
}
if (resetBase) {
// 基础数据的重置
modifyBookTask.errorMsg = ''
modifyBookTask.updateTime = new Date()
modifyBookTask.imageStyle = []
modifyBookTask.autoAnalyzeCharacter = undefined
modifyBookTask.customizeImageStyle = []
modifyBookTask.videoConfig = undefined
modifyBookTask.prefixPrompt = undefined
modifyBookTask.suffixPrompt = undefined
modifyBookTask.subImageFolder = []
modifyBookTask.srtPath = book.srtPath ?? undefined
modifyBookTask.audioPath = book.audioPath ?? undefined
}
// 继承小说的srt和配音文件
modifyBookTask.imageCategory = ImageCategory.Midjourney // 默认使用MJ出图
modifyBookTask.status = BookTaskStatus.WAIT
// 开始删除 分镜信息
let bookTaskDetails = this.realm
.objects('BookTaskDetail')
.filtered('bookTaskId = $0', bookTaskId)
// 开始删除数据
for (const bookTaskDetail of bookTaskDetails) {
// 删除MJMessage
if (bookTaskDetail.mjMessage) {
this.realm.delete(bookTaskDetail.mjMessage)
}
if (bookTaskDetail.reversePrompt) {
;(bookTaskDetail.reversePrompt as any[]).forEach((item) => {
this.realm.delete(item)
})
}
if (bookTaskDetail.sdConifg) {
this.realm.delete(bookTaskDetail.sdConifg)
}
this.realm.delete(bookTaskDetail)
}
} catch (error) {
throw error
}
}
}