1. (聚合推文)修复原创默认出图方式设置默认值 2. (聚合推文)优化出图显示 3. (聚合推文)添加图片上传功能,包括主图和选图区域 4. (聚合推文)新增图片缓存区,上传缓存图片(主图和选图区的图片),可以直接在当前小说所有的批次中的分镜中调用(下载到主图和选图区) 5. (聚合推文)添加一键修脸开关 6. (聚合推文)原创添加一键锁定 7. (聚合推文)新增小说批次任务显示当前所属小说 8. (聚合推文)小说批次任务状态显示优化 9. (聚合推文)优化后台任务状态显示 10. (聚合推文)原创,反推 一键生图 修复
321 lines
11 KiB
TypeScript
321 lines
11 KiB
TypeScript
import Realm from 'realm'
|
||
import path from 'path'
|
||
import { define } from '../../../define'
|
||
import { BookTaskModel } from '../../model/Book/bookTask.js'
|
||
import { successMessage } from '../../../../main/Public/generalTools'
|
||
import { BaseRealmService } from './bookBasic'
|
||
import { cloneDeep, isEmpty } from 'lodash'
|
||
import { JoinPath } from '../../../Tools/file'
|
||
import { BookTaskDetailModel, ReversePrompt } from '../../model/Book/bookTaskDetail.js'
|
||
const { v4: uuidv4 } = require('uuid')
|
||
import { Book } from "../../../../model/book/book"
|
||
import { GeneralResponse } from '../../../../model/generalResponse.js'
|
||
|
||
let dbPath = path.resolve(define.db_path, 'book.realm')
|
||
|
||
// 版本迁移
|
||
const migration = (oldRealm: Realm, newRealm: Realm) => { }
|
||
|
||
export class BookTaskDetailService extends BaseRealmService {
|
||
static instance: BookTaskDetailService | null = null
|
||
realm: Realm
|
||
|
||
private constructor() {
|
||
super()
|
||
}
|
||
|
||
/**
|
||
* 获取当前实例对象,为空则创建一个新的
|
||
* @returns
|
||
*/
|
||
public static async getInstance() {
|
||
if (BookTaskDetailService.instance === null) {
|
||
BookTaskDetailService.instance = new BookTaskDetailService()
|
||
await super.getInstance()
|
||
}
|
||
await BookTaskDetailService.instance.open()
|
||
return BookTaskDetailService.instance
|
||
}
|
||
|
||
/**
|
||
* 更具条件查询执行的小说的分镜信息
|
||
* @param condition 查询的条件,id,name,bookId,bookTaskId
|
||
*/
|
||
GetBookTaskData(condition: Book.QueryBookTaskDetailCondition) {
|
||
try {
|
||
if (condition == null) {
|
||
throw new Error('查询小说分镜信息,查询条件不能为空')
|
||
}
|
||
let tasksToDelete = this.realm.objects<BookTaskDetailModel>('BookTaskDetail')
|
||
if (condition.id) {
|
||
tasksToDelete = tasksToDelete.filtered('id==$0', condition.id)
|
||
}
|
||
if (condition.bookId) {
|
||
tasksToDelete = tasksToDelete.filtered('bookId==$0', condition.bookId)
|
||
}
|
||
if (condition.bookTaskId) {
|
||
tasksToDelete = tasksToDelete.filtered('bookTaskId==$0', condition.bookTaskId)
|
||
}
|
||
if (condition.name) {
|
||
tasksToDelete = tasksToDelete.filtered('name==$0', condition.name)
|
||
}
|
||
|
||
|
||
let resData = Array.from(tasksToDelete).map((item) => {
|
||
let resObj = {
|
||
...item,
|
||
videoPath: JoinPath(define.project_path, item.videoPath),
|
||
audioPath: JoinPath(define.project_path, item.audioPath),
|
||
oldImage: JoinPath(define.project_path, item.oldImage),
|
||
outImagePath: JoinPath(define.project_path, item.outImagePath),
|
||
subImagePath: (item.subImagePath as string[])?.map((subImage) => {
|
||
return JoinPath(define.project_path, subImage)
|
||
}),
|
||
characterTags: item.characterTags ? item.characterTags.map((tag) => tag) : null,
|
||
sceneTags: item.sceneTags ? item.sceneTags.map((tag) => tag) : null,
|
||
subValue: isEmpty(item.subValue) ? null : JSON.parse(item.subValue),
|
||
reversePrompt: item.reversePrompt.map((reversePrompt) => {
|
||
return {
|
||
...reversePrompt
|
||
}
|
||
}),
|
||
mjMessage: item.mjMessage ? item.mjMessage.toJSON() : null,
|
||
}
|
||
return cloneDeep(resObj)
|
||
})
|
||
return successMessage(
|
||
resData,
|
||
'获取小说的分镜信息成功',
|
||
'BookTaskDetailService_GetBookTaskData'
|
||
)
|
||
} catch (error) {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通过ID获取指定的小说任务分镜详细数据
|
||
* @param bookTaskDetailId
|
||
*/
|
||
public GetBookTaskDetailDataById(bookTaskDetailId: string): Book.SelectBookTaskDetail {
|
||
try {
|
||
if (bookTaskDetailId == null) {
|
||
throw new Error('获取小说任务详细信息失败,缺少ID')
|
||
}
|
||
let bookTaskDetails = this.GetBookTaskData({ id: bookTaskDetailId })
|
||
if (bookTaskDetails.data.length <= 0) {
|
||
return null;
|
||
} else {
|
||
return bookTaskDetails.data[0]
|
||
}
|
||
} catch (error) {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 添加一条小说任务对应的详细数据
|
||
* @param BookTaskDetail
|
||
*/
|
||
public AddBookTaskDetail(bookTaskDetail: Book.SelectBookTaskDetail) {
|
||
try {
|
||
// 判断是不是又小说ID
|
||
if (isEmpty(bookTaskDetail.bookId) || isEmpty(bookTaskDetail.bookTaskId)) {
|
||
throw new Error(
|
||
'新增小说任务详细信息到数据库失败,数据不完整,缺少小说ID或者小说批次任务ID'
|
||
)
|
||
}
|
||
|
||
// 开始初始化数据(获取指定的bookId和bookTaskId)中最大的no
|
||
let bookTaskDetails = this.realm
|
||
.objects<BookTaskModel>('BookTaskDetail')
|
||
.filtered(
|
||
'bookId == $0 AND bookTaskId == $1',
|
||
bookTaskDetail.bookId,
|
||
bookTaskDetail.bookTaskId
|
||
)
|
||
|
||
let maxNo = bookTaskDetails.max('no')
|
||
bookTaskDetail.no = maxNo ? Number(maxNo) + 1 : 1
|
||
let name = bookTaskDetail.no.toString().padStart(5, '0')
|
||
|
||
bookTaskDetail.name = name
|
||
bookTaskDetail.id = uuidv4()
|
||
bookTaskDetail.imageLock = false
|
||
bookTaskDetail.createTime = new Date()
|
||
bookTaskDetail.updateTime = new Date()
|
||
|
||
if (!bookTaskDetail.hasOwnProperty('adetailer')) {
|
||
bookTaskDetail.adetailer = false; // 设置默认值
|
||
}
|
||
// 开始添加
|
||
this.transaction(() => {
|
||
this.realm.create('BookTaskDetail', bookTaskDetail)
|
||
})
|
||
//创建成功,返回
|
||
return successMessage(
|
||
bookTaskDetail,
|
||
'新增小说任务详细信息成功',
|
||
'BookTaskDetailService_AddBookTaskDetail'
|
||
)
|
||
} catch (error) {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新指定ID的指定数据
|
||
* @param bookTaskDetailId
|
||
* @param updateData
|
||
*/
|
||
UpdateBookTaskDetail(bookTaskDetailId: string, updateData: Book.SelectBookTaskDetail): Book.SelectBookTaskDetail {
|
||
try {
|
||
this.transaction(() => {
|
||
let bookTaskDetail = this.realm.objectForPrimaryKey('BookTaskDetail', bookTaskDetailId)
|
||
if (bookTaskDetail == null) {
|
||
throw new Error('未找到对应的小说任务详细信息')
|
||
}
|
||
// 开始修改
|
||
for (let key in updateData) {
|
||
bookTaskDetail[key] = updateData[key]
|
||
}
|
||
bookTaskDetail.updateTime = new Date()
|
||
})
|
||
let res = this.GetBookTaskDetailDataById(bookTaskDetailId)
|
||
return res;
|
||
} catch (error) {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新指定ID的反推提示词数据
|
||
* @param bookTaskDetailId
|
||
* @param mjMessage
|
||
*/
|
||
UpdateBookTaskDetailMjMessage(bookTaskDetailId: string, mjMessage: Book.MJMessage): void {
|
||
try {
|
||
this.transaction(() => {
|
||
let mjMessageRes = this.realm.objectForPrimaryKey('MJMessage', bookTaskDetailId)
|
||
let bookTaskDetail = this.realm.objectForPrimaryKey('BookTaskDetail', bookTaskDetailId)
|
||
if (bookTaskDetail.mjMessage == null) {
|
||
// 新增
|
||
mjMessage.id = bookTaskDetailId
|
||
bookTaskDetail.mjMessage = mjMessage
|
||
} else {
|
||
for (const key in mjMessage) {
|
||
mjMessageRes[key] = mjMessage[key]
|
||
}
|
||
}
|
||
})
|
||
} catch (error) {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新指定ID的反推提示词数据
|
||
* @param bookTaskDetailId 分镜数据的ID
|
||
* @param reversePromptId 反推出来的提示词ID
|
||
* @param updateData 要更新的数据
|
||
*/
|
||
UpdateBookTaskDetailReversePrompt(bookTaskDetailId: string, reversePromptId: string, reversePrompt: Book.ReversePrompt): GeneralResponse.SuccessItem {
|
||
try {
|
||
this.transaction(() => {
|
||
let bookTaskDetails = this.realm.objects<ReversePrompt>("ReversePrompt");
|
||
bookTaskDetails = bookTaskDetails.filtered("id = $0 && bookTaskDetailId = $1", reversePromptId, bookTaskDetailId);
|
||
|
||
if (bookTaskDetails.length <= 0) {
|
||
throw new Error("未找到执行的翻译数据,无法写回")
|
||
}
|
||
let bookTaskDetail = bookTaskDetails[0];
|
||
// 直接写入
|
||
for (const key in reversePrompt) {
|
||
bookTaskDetail[key] = reversePrompt[key]
|
||
}
|
||
})
|
||
return successMessage(null, `${reversePromptId} 更新完成`, "BookTaskDetailService_UpdateBookTaskDetailReversePrompt")
|
||
} catch (error) {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除满足条件的对象吗,必传小说ID和小说任务ID
|
||
* @param condition bookId,bookTaskId,name,id
|
||
*/
|
||
DeleteBookTaskDetail(condition: Book.DeleteBookTaskDetailCondition) {
|
||
try {
|
||
if (isEmpty(condition.id) && isEmpty(condition.bookTaskId) && isEmpty(condition.bookId)) {
|
||
throw new Error('删除小说分镜信息失败,没有必要参数')
|
||
}
|
||
let tasksToDelete = this.realm.objects<BookTaskDetailModel>('BookTaskDetail')
|
||
if (condition.id) {
|
||
tasksToDelete = tasksToDelete.filtered('id==$0', condition.id)
|
||
}
|
||
if (condition.bookId) {
|
||
tasksToDelete = tasksToDelete.filtered('bookId==$0', condition.bookId)
|
||
}
|
||
if (condition.bookTaskId) {
|
||
tasksToDelete = tasksToDelete.filtered('bookTaskId==$0', condition.bookTaskId)
|
||
}
|
||
if (condition.name) {
|
||
tasksToDelete = tasksToDelete.filtered('name==$0', condition.name)
|
||
}
|
||
|
||
this.transaction(() => {
|
||
this.realm.delete(tasksToDelete)
|
||
})
|
||
return successMessage(
|
||
null,
|
||
'删除指定的分镜任务成功',
|
||
'BookTaskDetailService_DeleteBookTaskDetail'
|
||
)
|
||
} catch (error) {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除指定ID的小说任务详细数据中的所有的反推提示词数据
|
||
* @param bookTaskDetailId 小说分镜的ID
|
||
*/
|
||
DeleteBookTaskDetailReversePromptById(bookTaskDetailId: string): void {
|
||
this.transaction(() => {
|
||
let bookTaskDetails = this.realm.objects<BookTaskDetailModel>('BookTaskDetail').filtered('id = $0', bookTaskDetailId);
|
||
if (bookTaskDetails.length <= 0) {
|
||
throw new Error('删除小说任务详细信息的反推提示词失败,未找到对应的分镜信息')
|
||
}
|
||
let bookTaskDetail = bookTaskDetails[0];
|
||
|
||
bookTaskDetail.gptPrompt = undefined;
|
||
// 删除所有的反推提示词
|
||
if (bookTaskDetail.reversePrompt) {
|
||
bookTaskDetail.reversePrompt.forEach(item => {
|
||
this.realm.delete(item)
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 删除MJ中生成图片的所有的信息,包括 outImagePath subImagePath mjMessage (mjMessage是另一张表,要单独生成)
|
||
* @param bookTaskDetailId
|
||
*/
|
||
DeleteBoookTaskDetailGenerateImage(bookTaskDetailId: string): void {
|
||
this.transaction(() => {
|
||
let bookTaskDetail = this.realm.objectForPrimaryKey<BookTaskDetailModel>('BookTaskDetail', bookTaskDetailId)
|
||
if (bookTaskDetail == null) {
|
||
throw new Error("没有找到要删除的分镜信息")
|
||
}
|
||
if (bookTaskDetail.mjMessage) {
|
||
this.realm.delete(bookTaskDetail.mjMessage)
|
||
}
|
||
bookTaskDetail.mjMessage = undefined
|
||
bookTaskDetail.outImagePath = undefined;
|
||
bookTaskDetail.subImagePath = []
|
||
})
|
||
|
||
}
|
||
}
|