LaiTool/src/main/Service/Book/BooKBasic.ts
2024-08-03 12:46:12 +08:00

283 lines
11 KiB
TypeScript

import { BookType, OperateBookType, TagDefineType } from '../../../define/enum/bookEnum'
import { errorMessage, successMessage } from '../../Public/generalTools'
import { BookService } from '../../../define/db/service/Book/bookService'
import { BookTaskService } from '../../../define/db/service/Book/bookTaskService'
import { BookTaskDetailService } from '../../../define/db/service/Book/bookTaskDetailService'
import { CopyImageType } from '../../../define/enum/bookEnum'
const { v4: uuidv4 } = require('uuid')
import { define } from '../../../define/define'
import path from 'path'
import { CheckFileOrDirExist, CheckFolderExistsOrCreate, CopyFileOrFolder } from '../../../define/Tools/file'
import { Book } from '../../../model/book'
import { GeneralResponse } from '../../../model/generalResponse'
import { cloneDeep, isEmpty } from 'lodash'
export class BookBasic {
constructor() { }
bookTaskService: BookTaskService
bookTaskDetailService: BookTaskDetailService
async InitService() {
if (!this.bookTaskService) {
this.bookTaskService = await BookTaskService.getInstance()
}
if (!this.bookTaskDetailService) {
this.bookTaskDetailService = await BookTaskDetailService.getInstance()
}
}
//#region 小说相关操作
/**
* 新增或者是修小说数据
* @param {*} book 小说信息
* @returns
*/
async AddOrModifyBook(book) {
try {
if (book == null) {
return errorMessage('小说数据为空,无法修改')
}
// 处理一下数据,处理文件地址(删除前缀,转换为默认地址)
// 当前的小说的名字是不是在数据库中以存在
let _bookService = await BookService.getInstance()
let res = await _bookService.AddOrModifyBook(book)
return res
} catch (error) {
return errorMessage(
'修改数据错误,错误信息如下:' + error.message,
'BookBasic_AddOrModifyBook'
)
}
}
// 小说类型返回
GetBookType() {
return successMessage(
[
{
label: 'SD反推',
value: BookType.SD_REVERSE
},
{
label: 'MJ反推',
value: BookType.MJ_REVERSE
},
{
label: '原创',
value: BookType.ORIGINAL
}
],
'获取小说类型成功'
)
}
//#endregion
//#region 小说批次任务相关操作
async OneToFourBookTask(bookTaskId: string) {
try {
console.log(bookTaskId)
await this.InitService();
let copyCount = 100
let bookTask = this.bookTaskService.GetBookTaskDataById(bookTaskId)
if (bookTask == null) {
throw new Error("没有找到对应的数小说任务,请检查数据")
}
// 获取所有的出图中最少的
let bookTaskDetail = this.bookTaskDetailService.GetBookTaskData({
bookTaskId: bookTaskId
}).data as Book.SelectBookTaskDetail[]
if (bookTaskDetail == null || bookTaskDetail.length <= 0) {
throw new Error("没有对应的小说分镜任务,请先添加分镜任务")
}
for (let i = 0; i < bookTaskDetail.length; i++) {
const element = bookTaskDetail[i];
if (isEmpty(element.subImagePath)) {
throw new Error("检测到图片没有出完,请先检查出图")
}
if (element.subImagePath == null || element.subImagePath.length <= 0) {
throw new Error("检测到图片没有出完,请先检查出图")
}
if (element.subImagePath.length < copyCount) {
copyCount = element.subImagePath.length
}
}
if (copyCount <= 0) {
throw new Error("批次设置错误,无法进行一拆四")
}
// 开始复制
let res = await this.CopyNewBookTask(bookTask, bookTaskDetail, copyCount - 1, CopyImageType.ONE)
if (res.code == 0) {
throw new Error(res.message)
}
return successMessage(res.data, "一拆四成功", "BookBasic_OneToFourBookTask")
} catch (error) {
return errorMessage("一拆四失败,失败信息如下:" + error.message, "BookBasic_OneToFourBookTask")
}
}
/**
* 复制一个小说批次任务,创建新的小说批次任务
* @param oldBookTaskId
* @param copyCount 复制的数量
* @param isCopyImage 是否复制图片
*/
async CopyNewBookTask(sourceBookTask: Book.SelectBookTask, sourceBookTaskDetail: Book.SelectBookTaskDetail[], copyCount: number, copyImageType: CopyImageType) {
try {
await this.InitService();
let addBookTask = [] as Book.SelectBookTask[]
let addBookTaskDetail = [] as Book.SelectBookTaskDetail[]
// 先处理文件夹的创建,包括小说任务的和小说任务分镜的
for (let i = 0; i < copyCount; i++) {
let maxNo = this.bookTaskService.realm
.objects('BookTask')
.filtered('bookId = $0', sourceBookTask.bookId)
.max('no')
let no = maxNo == null ? 1 : Number(maxNo) + 1 + i
let name = 'output_0000' + no
let imageFolder = path.join(define.project_path, `${sourceBookTask.bookId}/tmp/${name}`)
await CheckFolderExistsOrCreate(imageFolder)
// 创建对应的文件夹
let addOneBookTask = {
id: uuidv4(),
bookId: sourceBookTask.bookId,
no: no,
name: name,
generateVideoPath: sourceBookTask.generateVideoPath,
srtPath: sourceBookTask.srtPath,
audioPath: sourceBookTask.audioPath,
draftSrtStyle: sourceBookTask.draftSrtStyle,
backgroundMusic: sourceBookTask.backgroundMusic,
friendlyReminder: sourceBookTask.friendlyReminder,
imageFolder: path.relative(define.project_path, imageFolder),
status: sourceBookTask.status,
errorMsg: sourceBookTask.errorMsg,
updateTime: new Date(),
createTime: new Date(),
isAuto: sourceBookTask.isAuto,
imageStyle: sourceBookTask.imageStyle,
autoAnalyzeCharacter: sourceBookTask.autoAnalyzeCharacter,
customizeImageStyle: sourceBookTask.customizeImageStyle,
videoConfig: sourceBookTask.videoConfig,
prefixPrompt: sourceBookTask.prefixPrompt,
suffixPrompt: sourceBookTask.suffixPrompt,
version: sourceBookTask.version,
imageCategory: sourceBookTask.imageCategory,
} as Book.SelectBookTask
addBookTask.push(addOneBookTask)
for (let j = 0; j < sourceBookTaskDetail.length; j++) {
const element = sourceBookTaskDetail[j];
let outImagePath = undefined as string
let subImagePath = [] as string[]
if (copyImageType == CopyImageType.ALL) { // 直接全部复制
outImagePath = element.outImagePath
subImagePath = element.subImagePath
} else if (copyImageType == CopyImageType.ONE) { // 只复制对应的
let oldImage = element.subImagePath[i + 1]
outImagePath = path.join(imageFolder, path.basename(element.outImagePath))
await CopyFileOrFolder(oldImage, outImagePath)
subImagePath = []
}
else if (copyImageType == CopyImageType.NONE) {
outImagePath = undefined
subImagePath = []
} else {
throw new Error("无效的图片复制类型")
}
if (outImagePath) {
// 单独处理一下显示的图片
let imageBaseName = path.basename(element.outImagePath);
let newImageBaseName = path.join(define.project_path, `${sourceBookTask.bookId}/tmp/${name}/${imageBaseName}`)
await CopyFileOrFolder(outImagePath, newImageBaseName)
}
// 处理SD设置
let sdConifg = undefined
if (element.sdConifg) {
let sdConifg = cloneDeep(element.sdConifg)
if (sdConifg.webuiConfig) {
let tempSdConfig = cloneDeep(sdConifg.webuiConfig);
tempSdConfig.id = uuidv4()
sdConifg.webuiConfig = tempSdConfig
}
}
let reverseId = uuidv4()
// 处理反推数据
let reverseMessage = [] as Book.ReversePrompt[]
if (element.reversePrompt && element.reversePrompt.length > 0) {
reverseMessage = cloneDeep(element.reversePrompt)
for (let k = 0; k < reverseMessage.length; k++) {
reverseMessage[k].id = uuidv4()
reverseMessage[k].bookTaskDetailId = reverseId
}
}
let addOneBookTaskDetail = {
id: reverseId,
no: element.no,
name: element.name,
bookId: sourceBookTask.bookId,
bookTaskId: addOneBookTask.id,
videoPath: path.relative(define.project_path, element.videoPath),
word: element.word,
oldImage: path.relative(define.project_path, element.oldImage),
afterGpt: element.afterGpt,
startTime: element.startTime,
endTime: element.endTime,
timeLimit: element.timeLimit,
subValue: element.subValue,
characterTags: element.characterTags && element.characterTags.length > 0 ? cloneDeep(element.characterTags) : [],
gptPrompt: element.gptPrompt,
outImagePath: path.relative(define.project_path, outImagePath),
subImagePath: subImagePath || [],
prompt: element.prompt,
adetailer: element.adetailer,
sdConifg: sdConifg,
createTime: new Date(),
updateTime: new Date(),
audioPath: element.audioPath,
subtitlePosition: element.subtitlePosition,
status: element.status,
reversePrompt: reverseMessage,
imageLock: element.imageLock
} as Book.SelectBookTaskDetail
addBookTaskDetail.push(addOneBookTaskDetail)
}
}
// 数据处理完毕,开始新增数据
// 将所有的复制才做,全部放在一个事务中
this.bookTaskService.transaction(() => {
for (let i = 0; i < addBookTask.length; i++) {
const element = addBookTask[i];
this.bookTaskService.realm.create('BookTask', element)
}
for (let i = 0; i < addBookTaskDetail.length; i++) {
const element = addBookTaskDetail[i];
this.bookTaskDetailService.realm.create('BookTaskDetail', element)
}
})
// 全部创建完成
// 查找到数据,然后全部返回
let returnBookTask = this.bookTaskService.GetBookTaskData({
bookId: sourceBookTask.bookId
}).data as Book.SelectBookTask[]
return successMessage(returnBookTask, "复制小说任务成功", "BookBasic_CopyNewBookTask")
} catch (error) {
console.log(error)
throw error
}
}
//#endregion
}