310 lines
10 KiB
TypeScript
310 lines
10 KiB
TypeScript
|
|
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 查询条件 id,bookId,name,no,page, 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
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|