import Realm from 'realm' import path from 'path' import { define } from '../../../define.js' 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" 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('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, 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) { try { // 判断是不是又小说ID if (isEmpty(bookTaskDetail.bookId) || isEmpty(bookTaskDetail.bookTaskId)) { throw new Error( '新增小说任务详细信息到数据库失败,数据不完整,缺少小说ID或者小说批次任务ID' ) } // 开始初始化数据(获取指定的bookId和bookTaskId)中最大的no let bookTaskDetails = this.realm .objects('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() bookTaskDetail.adetailer = false // 先写死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 { console.log('UpdateBookTaskDetailMjMessage', bookTaskDetailId, mjMessage) 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"); 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) { try { if (isEmpty(condition.id) && isEmpty(condition.bookTaskId) && isEmpty(condition.bookId)) { throw new Error('删除小说分镜信息失败,没有必要参数') } let tasksToDelete = this.realm.objects('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('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('BookTaskDetail', bookTaskDetailId) if (bookTaskDetail == null) { throw new Error("没有找到要删除的分镜信息") } if (bookTaskDetail.mjMessage) { this.realm.delete(bookTaskDetail.mjMessage) } bookTaskDetail.mjMessage = undefined bookTaskDetail.outImagePath = undefined; bookTaskDetail.subImagePath = [] }) } }