V 2.2.10 新增MJ的代理模式

This commit is contained in:
2024-06-24 13:11:19 +08:00
parent 79a1929e79
commit bac97bc41c
102 changed files with 6374 additions and 1172 deletions
@@ -0,0 +1,141 @@
import Realm from 'realm'
import path from 'path'
import { BaseService } from '../baseService.js'
import { define } from '../../../define.js'
import { BookTaskModel } from '../../model/Book/bookTask.js'
import { BookTaskStatus } from '../../../enum/bookEnum.js'
import { errorMessage, successMessage } from '../../../../main/generalTools.js'
import { BaseRealmService } from './bookBasic'
import { isEmpty } from 'lodash'
const { v4: uuidv4 } = require('uuid')
export class BookBackTaskListService extends BaseRealmService {
static instance: BookBackTaskListService | null = null
realm: Realm
private constructor() {
super()
}
/**
* 获取当前实例对象,为空则创建一个新的
* @returns
*/
public static async getInstance() {
if (BookBackTaskListService.instance === null) {
BookBackTaskListService.instance = new BookBackTaskListService()
await super.getInstance()
}
return BookBackTaskListService.instance
}
/**
* 新增一个小说相关的后台任务队列
* @param bookBackTask 要添加的小说数据
*/
async AddBookBackTaskList(bookBackTask) {
try {
// 判断数据是不是存在
if (
isEmpty(bookBackTask.bookId) ||
isEmpty(bookBackTask.bookTaskId) ||
isEmpty(bookBackTask.name) ||
isEmpty(bookBackTask.type)
) {
throw new Error('新增后台队列任务到数据库失败,数据不完整,缺少必要字段')
}
// 开始新建
bookBackTask.id = uuidv4()
bookBackTask.createTime = new Date()
bookBackTask.updateTime = new Date()
bookBackTask.status = BookTaskStatus.WAIT
this.realm.write(() => {
this.realm.create('BookBackTaskList', bookBackTask)
})
return successMessage(
bookBackTask,
'新增后台队列任务到数据库成功',
'BookBackTaskList_AddBookBackTaskList'
)
} catch (error) {
return errorMessage(
'新增后台队列任务到数据库失败,错误信息入校' + error.toString(),
'BookBackTaskList_AddBookBackTaskList'
)
}
}
/**
* 修改一个小说相关的后台任务队列中的详细信息(对于后台的队列任务只能修改状态)
* @param bookBackTask 修改的数据
*/
async ModifyBookBackTaskList(bookBackTask) {
try {
// 判断数据是不是存在
if (isEmpty(bookBackTask.id) || isEmpty(bookBackTask.status)) {
throw new Error('修改后台队列任务失败,数据不完整,缺少必要字段')
}
// 开始修改
this.realm.write(() => {
// 获取指定ID的队列任务
let _bookBackTask = this.realm.objectForPrimaryKey('BookBackTaskList', bookBackTask.id)
// 判断数据是不是存在
if (_bookBackTask == null) {
throw new Error('修改后台队列任务失败,数据不存在')
}
// 修改数据
_bookBackTask.status = bookBackTask.status
})
return successMessage(
bookBackTask,
'修改后台队列任务成功',
'BookBackTaskList_ModifyBookBackTaskList'
)
} catch (error) {
return errorMessage(
'修改后台队列任务失败,错误信息如下:' + error.toString(),
'BookBackTaskList_ModifyBookBackTaskList'
)
}
}
/**
* 删除满足条件的数据,包含 id、bookId、bookTaskId
* @param bookBackTask 删除的数据
*/
async DeleteBookBackTaskListBy(bookBackTask) {
try {
this.realm.write(() => {
// 构建查询条件
let query = [] as string[]
if (bookBackTask.id) {
query.push(`id = ${bookBackTask.id}`)
}
if (bookBackTask.bookId) {
query.push(`bookId = ${bookBackTask.bookId}`)
}
if (bookBackTask.bookTaskId) {
query.push(`bookTaskId = ${bookBackTask.bookTaskId}`)
}
const queryString = query.join(' && ')
// 获取指定的数据
if (queryString) {
const tasksToDelete = this.realm.objects('BookBackTaskList').filtered(queryString)
this.realm.delete(tasksToDelete)
} else {
throw new Error('删除后台队列任务失败,没有筛选条件')
}
return successMessage(
bookBackTask,
'删除后台队列任务成功',
'BookBackTaskList_DeleteBookBackTaskListBy'
)
})
} catch (error) {
return errorMessage(
'删除后台队列任务失败,错误信息如下:' + error.toString(),
'BookBackTaskList_DeleteBookBackTaskListBy'
)
}
}
}
+83
View File
@@ -0,0 +1,83 @@
import Realm from 'realm'
import { BookModel } from '../../model/Book/book'
import { BookTaskModel } from '../../model/Book/bookTask'
import { BaseService } from '../baseService'
import { define } from '../../../define'
import path from 'path'
import {
BookTaskDetailModel,
MJMessage,
SDConfig,
Subtitle,
WebuiConfig
} from '../../model/Book/bookTaskDetail'
import { BookBackTaskList } from '../../model/Book/BookBackTaskListModel'
let dbPath = path.resolve(define.db_path, 'book.realm')
// 版本迁移
const migration = (oldRealm: Realm, newRealm: Realm) => {
if (oldRealm.schemaVersion < 1) {
const oldBooks = oldRealm.objects('Book')
const newBooks = newRealm.objects('Book')
for (let i = 0; i < oldBooks.length; i++) {
newBooks[i].test = 'defaultValue' // 为新属性设置默认值
}
}
if (oldRealm.schemaVersion < 2) {
const oldBookTask = oldRealm.objects('BookTask')
const newBookTask = newRealm.objects('BookTask')
for (let i = 0; i < oldBookTask.length; i++) {
newBookTask[i].isAuto = false // 为新属性设置默认值
}
}
}
export class BaseRealmService extends BaseService {
static instance: BaseRealmService | null = null
protected realm: Realm | null = null
dbpath: string
protected constructor() {
super()
this.dbpath = dbPath
}
public static async getInstance() {
if (BaseRealmService.instance === null) {
BaseRealmService.instance = new BaseRealmService()
await BaseRealmService.instance.open()
}
return BaseRealmService.instance
}
/**
* 创建数据库连接,如果已经存在则直接返回
* @returns
*/
async open() {
try {
if (this.realm != null) return
// 判断当前全局是不是又当前这个
const config = {
schema: [
BookModel,
Subtitle,
MJMessage,
BookBackTaskList,
SDConfig,
WebuiConfig,
BookTaskModel,
BookTaskDetailModel
],
path: this.dbpath,
schemaVersion: 2,
migration: migration
}
this.realm = await Realm.open(config)
} catch (error) {
throw error
}
}
}
+214
View File
@@ -0,0 +1,214 @@
import Realm, { UpdateMode } from 'realm'
import { BookModel } from '../../model/Book/book.js'
import path from 'path'
import { BaseService } from '../baseService.js'
import { define } from '../../../define.js'
import { BookTaskStatus, BookType } from '../../../enum/bookEnum.js'
import { successMessage } from '../../../../main/generalTools.js'
import { CheckFolderExistsOrCreate, CopyFileOrFolder } from '../../../Tools/file.js'
const { v4: uuidv4 } = require('uuid')
import { BookTaskService } from './bookTaskService'
import { BaseRealmService } from './bookBasic.js'
import { isEmpty } from 'lodash'
class BooKService extends BaseRealmService {
static instance: BooKService | null = null
realm: Realm
private constructor() {
super()
}
/**
* 获取当前实例对象,为空则创建一个新的
* @returns
*/
public static async getInstance() {
if (BooKService.instance === null) {
BooKService.instance = new BooKService()
await super.getInstance()
}
return BooKService.instance
}
/**
* 获取小说信息,通过参数查询
* @returns
*/
async GetBookData(bookQuery) {
try {
await this.open()
// 获取所有的小说数据,并进行时间降序排序
let books = this.realm.objects<BookModel>('Book')
let book_length = books.length
// 开始开始筛选
if (bookQuery.bookId) {
// 查询对应的小说ID的数据
books = books.filtered('id = $0', bookQuery.bookId)
}
books = books.sorted('updateTime', true)
// 判断是不是有page和pageSize,有的话对查询返回的信息做分页
if (bookQuery.page && bookQuery.pageSize) {
books = books.slice(
(bookQuery.page - 1) * bookQuery.pageSize,
bookQuery.page * bookQuery.pageSize
) as unknown as Realm.Results<BookModel>
}
if (books.length <= 0) {
return successMessage(
{
res_book: [],
book_length: 0
},
'没有数据',
'ReverseBook_GetBookData'
)
}
// 将realm对象数组转换为普通对象数组
let res_book = Array.from(books).map((book) => {
// 这里可以直接操作普通对象
let bookObj = {
...book,
bookFolderPath: path.resolve(
define.project_path,
book.bookFolderPath.replace(/\\/g, '/')
),
oldVideoPath: book.oldVideoPath
? path.resolve(define.project_path, book.oldVideoPath.replace(/\\/g, '/'))
: '',
imageFolder: book.imageFolder
? path.resolve(define.project_path, book.imageFolder.replace(/\\/g, '/'))
: ''
}
return bookObj
})
return successMessage(
{
res_book,
book_length
},
'获取成功',
'ReverseBook_GetBookData'
)
} catch (error) {
throw error
}
}
/**
* 新增或者是修小说数据
* @param {*} book 小说信息
* @returns
*/
async AddOrModifyBook(book) {
try {
await this.open()
if (book == null) {
throw new Error('小说数据为空,无法修改')
}
// 当小说的类型是反推的时候,必须传入视频
if (book.type == BookType.MJ_REVERSE || book.type == BookType.SD_REVERSE) {
// 判断视频是否存在
if (book.oldVideoPath == null || book.oldVideoPath == '') {
throw new Error('反推必须传入视频')
}
}
if (book.id == null) {
// 新增
// 判断指定的名字在数据库中是否存在
let books = this.realm.objects('Book').filtered('name = $0', book.name)
if (books.length > 0) {
throw new Error(`小说名字 ${book.name} 已经存在,请更换小说名字`)
}
console.log(this)
// 新增数据
book.id = uuidv4()
book.createTime = new Date()
book.updateTime = new Date()
// 检查传入的视频文件是不是存在
// 获取当前最大的no
let maxNo = this.realm.objects('Book').max('no')
book.no = maxNo == null ? 1 : Number(maxNo) + 1
// 拼接项目文件夹
book.bookFolderPath = book.id
book.imageFolder = `${book.id}/tmp`
let bookFolderPath = path.resolve(define.project_path, book.id)
let imageFolder = path.resolve(define.project_path, `${book.id}/tmp`)
let oldVideoPath = path.resolve(define.project_path, `${book.id}/data/${book.id}.mp4`)
// 将视频拷贝一个到项目文件下面
if (book.oldVideoPath) {
await CopyFileOrFolder(book.oldVideoPath, oldVideoPath)
}
// 创建对应的文件夹
await CheckFolderExistsOrCreate(bookFolderPath)
await CheckFolderExistsOrCreate(imageFolder)
// 修改数据
book.oldVideoPath = path.relative(define.project_path, oldVideoPath)
this.realm.write(() => {
this.realm.create('Book', book)
let bookTaskImageFolder = path.resolve(imageFolder, 'output_00001')
// 添加一个任务
let bookTask = {
id: uuidv4(),
bookId: book.id,
no: 1,
name: 'output_00001',
generateVideoPath: null,
srtPath: null,
audioPath: null,
imageFolder: path.relative(define.project_path, bookTaskImageFolder), // 获取文件输出对于项目的相对路径
styleList: [],
prefix: null,
status: BookTaskStatus.WAIT,
errorMsg: null,
isAuto: false,
updateTime: new Date(),
createTime: new Date()
}
// 添加任务
this.realm.create('BookTask', bookTask)
})
// 保存成功,返回数据,但是要做处理
book.bookFolderPath = bookFolderPath
book.imageFolder = imageFolder
book.oldVideoPath = oldVideoPath
return successMessage(book, '新增成功', 'BookBasic_AddOrModifyBook')
} else {
// 修改
// 判断指定的名字在数据库中是否存在(不算自己)
let books = this.realm
.objects('Book')
.filtered('name = $0 AND id != $1', book.name, book.id)
if (books.length > 0) {
throw new Error(`小说名字 ${book.name} 已经存在,请更换小说名字`)
}
// 两个文件夹地址不能改,删除两个属性
delete book.bookFolderPath
delete book.imageFolder
// 修改数据
book.updateTime = new Date()
this.realm.write(() => {
this.realm.create('Book', book, UpdateMode.Modified)
})
// 保存成功,返回数据,但是要做处理
return successMessage(null, '修改成功', 'BookBasic_AddOrModifyBook')
}
} catch (error) {
throw error
}
}
}
export default BooKService
@@ -0,0 +1,47 @@
import Realm from 'realm'
import path from 'path'
import { BaseService } from '../baseService.js'
import { define } from '../../../define.js'
import { BookTaskModel } from '../../model/Book/bookTask.js'
import { BookTaskStatus } from '../../../enum/bookEnum.js'
import { successMessage } from '../../../../main/generalTools.js'
import { BaseRealmService } from './bookBasic'
const { v4: uuidv4 } = require('uuid')
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()
}
return BookTaskDetailService.instance
}
/**
* 添加一条小说人物对应的详细数据
* @param BookTaskDetail
*/
public async AddBookTaskDetail(BookTaskDetail) {
try {
// 判断是不是又小说的ID
} catch (error) {
throw error
}
}
}
@@ -0,0 +1,139 @@
import Realm from 'realm'
import path from 'path'
import { BaseService } from '../baseService.js'
import { define } from '../../../define.js'
import { BookTaskModel } from '../../model/Book/bookTask.js'
import { BookTaskStatus } from '../../../enum/bookEnum.js'
import { successMessage } from '../../../../main/generalTools.js'
import { BaseRealmService } from './bookBasic'
import { isEmpty } from 'lodash'
import { JoinPath } from '../../../Tools/file.js'
const { v4: uuidv4 } = require('uuid')
let dbPath = path.resolve(define.db_path, 'book.realm')
export class BookTaskService extends BaseRealmService {
static instance: BookTaskService | null = null
realm: Realm
private constructor() {
super()
}
/**
* 获取当前实例对象,为空则创建一个新的
* @returns
*/
public static async getInstance() {
if (BookTaskService.instance === null) {
BookTaskService.instance = new BookTaskService()
await super.getInstance()
}
return BookTaskService.instance
}
/**
* 查询满足条件的小说子任务信息
* @param bookTaskCondition 查询条件 idbookIdnamenopage, pageSize
*/
async GetBookTaskData(bookTaskCondition) {
try {
await this.open()
// 获取所有的小说数据,并进行时间降序排序
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>
}
// 做一下数据转换
// 将realm对象数组转换为普通对象数组
let res_bookTasks = Array.from(bookTasks).map((bookTask) => {
// 这里可以直接操作普通对象
let bookObj = {
...bookTask,
styleList: bookTask.styleList ? Array.from(bookTask.styleList) : [],
generateVideoPath: JoinPath(define.project_path, bookTask.generateVideoPath),
srtPath: JoinPath(define.project_path, bookTask.srtPath),
audioPath: JoinPath(define.project_path, bookTask.audioPath),
imageFolder: JoinPath(define.project_path, bookTask.imageFolder)
}
return bookObj
})
return successMessage(
{
bookTasks: res_bookTasks,
total: bookTask_length
},
'查询小说任务成功',
'BookTaskService_GetBookTaskData'
)
} catch (error) {
throw error
}
}
// 添加一条数据
async AddOrModifyBookTask(bookTask) {
try {
await this.open()
if (bookTask == null) {
throw new Error('添加的小说任务不能为空')
}
if (bookTask.id == null) {
// 新增
if (bookTask.bookId == '' || bookTask.bookId == null) {
throw new Error('小说ID不能为空')
}
bookTask.id = uuidv4()
// 获取当前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)
})
return successMessage(bookTask, '新增小说任务成功', 'BookTaskService_AddOrModifyBookTask')
} else {
// 修改
}
} catch (error) {
throw error
}
}
}