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,28 @@
import Realm, { ObjectSchema } from 'realm'
import { BookBackTaskStatus, BookBackTaskType } from '../../../enum/bookEnum'
export class BookBackTaskList extends Realm.Object<BookBackTaskList> {
id: string
bookId: string
bookTaskId: string
name: string
type: BookBackTaskType
status: BookBackTaskStatus
createTime: Date
updateTime: Date
static schema: ObjectSchema = {
name: 'BookBackTaskList',
properties: {
id: 'string',
bookId: { type: 'string', indexed: true },
bookTaskId: { type: 'string', indexed: true },
name: 'string',
type: 'string',
status: 'string',
createTime: 'date',
updateTime: 'date'
},
primaryKey: 'id'
}
}
+37
View File
@@ -0,0 +1,37 @@
import Realm, { ObjectSchema } from 'realm'
import { BookType } from '../../../enum/bookEnum'
export class BookModel extends Realm.Object<BookModel> {
id: string
no: number
name: string
bookFolderPath: string
imageFolder: string | null
type: BookType
oldVideoPath: string | null
srtPath: string | null
audioPath: string | null
updateTime: Date
createTime: Date
test: string | null
static schema: ObjectSchema = {
name: 'Book',
properties: {
id: 'string',
no: 'int',
name: 'string',
bookFolderPath: 'string',
type: 'string',
oldVideoPath: 'string?',
srtPath: 'string?',
audioPath: 'string?',
imageFolder: 'string?',
updateTime: 'date',
createTime: 'date',
test: 'string?'
},
// 主键为_id
primaryKey: 'id'
}
}
+43
View File
@@ -0,0 +1,43 @@
import Realm, { ObjectSchema } from 'realm'
import { BookTaskStatus, BookType } from '../../../enum/bookEnum'
export class BookTaskModel extends Realm.Object<BookTaskModel> {
id: string
no: number
bookId: string
name: string
generateVideoPath: string | null
srtPath: string | null
audioPath: string | null
imageFolder: string | null
styleList: Realm.List<string> | null
prefix: string | null
status: BookTaskStatus
errorMsg: string | null
isAuto: boolean // 是否自动
updateTime: Date
createTime: Date
static schema: ObjectSchema = {
name: 'BookTask',
properties: {
id: 'string',
bookId: { type: 'string', indexed: true },
no: 'int',
name: 'string',
generateVideoPath: 'string?',
srtPath: 'string?',
audioPath: 'string?',
imageFolder: 'string?',
styleList: 'string[]',
prefix: 'string?',
status: 'string',
errorMsg: 'string?',
isAuto: 'bool',
updateTime: 'date',
createTime: 'date'
},
// 主键为_id
primaryKey: 'id'
}
}
+163
View File
@@ -0,0 +1,163 @@
import Realm, { ObjectSchema } from 'realm'
import {
BookBackTaskStatus,
BookBackTaskType,
BookTaskStatus,
BookType,
MJAction,
MJCategroy
} from '../../../enum/bookEnum'
export class Subtitle extends Realm.Object<Subtitle> {
startTime: number
endTime: number
srtValue: string
id: string
static schema = {
name: 'Subtitle',
properties: {
startTime: 'int',
endTime: 'int',
srtValue: 'string',
id: 'string'
},
primaryKey: 'id'
}
}
export class MJMessage extends Realm.Object<MJMessage> {
id: string
mjApiUrl: string | null
progress: number
category: MJCategroy
imageClick: string | null // 图片点击(显示的小的)
imageShow: string | null // 图片实际的地址
messageId: string // 消息ID(可以是MJ中的,也可以是API中的)
action: MJAction // 动作(生图,反推之类)
status: string // 状态
message: string | null // 消息
static schema: ObjectSchema = {
name: 'MJMessage',
properties: {
id: 'string',
mjApiUrl: 'string?',
progress: 'int',
category: 'string',
imageClick: 'string?',
imageShow: 'string?',
messageId: 'string',
action: 'string',
status: 'string',
message: 'string?'
},
primaryKey: 'id'
}
}
export class WebuiConfig extends Realm.Object<WebuiConfig> {
sampler_name: string // 采样器名称
negative_prompt: string // 负面提示
batch_size: number // 批次大小
steps: number // 步数
cfg_scale: number // 提示词相关性
denoising_strength: number // 降噪强度
width: number // 宽度
height: number // 高度
seed: number // 种子
init_images: string // 初始图片(垫图的图片地址)
id: string
static schema: ObjectSchema = {
name: 'WebuiConfig',
properties: {
sampler_name: 'string',
negative_prompt: 'string',
batch_size: 'int',
steps: 'int',
cfg_scale: 'int',
denoising_strength: 'int',
width: 'int',
height: 'int',
seed: 'int',
init_images: 'string',
id: 'string'
},
primaryKey: 'id'
}
}
export class SDConfig extends Realm.Object<SDConfig> {
checkpoints: string // 大模型
api: string // api地址
model: string // 生图方式
webuiConfig: WebuiConfig
id: string
static schema: ObjectSchema = {
name: 'SDConfig',
properties: {
checkpoints: 'string',
api: 'string',
model: 'string',
webuiConfig: 'WebuiConfig',
id: 'string'
},
primaryKey: 'id'
}
}
export class BookTaskDetailModel extends Realm.Object<BookTaskDetailModel> {
id: string
no: number
name: string
bookId: string
bookTaskId: string
videoPath: string | null // 视频地址
word: string | null // 文案
oldImage: string | null // 旧图片(用于SD的图生图)
afterGpt: string | null // GPT生成的文案
startTime: number | null // 开始时间
endTime: number | null // 结束时间
timeLimit: string | null // 事件实现(0 -- 3000
subValue: Realm.List<Subtitle> | null // 包含的字幕数据
characterTags: string[] | null // 角色标签
gptPrompt: string | null // GPT提示词
mjMessage: MJMessage | null // MJ消息
outImagePath: string | null // 输出图片地址
subImagePath: string[] | null // 字幕图片地址
prompt: string | null // 提示
adetailer: boolean // 是否开启修脸
sdConifg: SDConfig | null // SD配置
createTime: Date
updateTime: Date
static schema: ObjectSchema = {
name: 'BookTaskDetail',
properties: {
id: 'string',
no: 'int',
name: 'string',
bookId: { type: 'string', indexed: true },
bookTaskId: { type: 'string', indexed: true },
videoPath: 'string?',
word: 'string?',
oldImage: 'string?',
afterGpt: 'string?',
startTime: 'int?',
endTime: 'int?',
timeLimit: 'string?',
subValue: { type: 'list', objectType: 'Subtitle' },
characterTags: { type: 'list', objectType: 'string' },
gptPrompt: 'string?',
mjMessage: 'MJMessage?',
outImagePath: 'string?',
subImagePath: 'string[]',
prompt: 'string?',
adetailer: 'bool',
sdConifg: 'SDConfig?',
createTime: 'date',
updateTime: 'date'
},
// 主键为_id
primaryKey: 'id'
}
}
+27
View File
@@ -0,0 +1,27 @@
import Realm, { ObjectSchema } from 'realm'
import { LoggerStatus, LoggerType } from '../../../enum/softwareEnum'
export class LoggerModel extends Realm.Object<LoggerModel> {
id: string
bookId: string // 小说ID
bookTaskId: string // 小说任务ID
type: LoggerType
status: LoggerStatus
date: Date
content: string
static schema: ObjectSchema = {
name: 'Logger',
properties: {
id: 'string',
bookId: 'string',
bookTaskId: 'string',
type: 'string',
status: 'string',
date: 'date',
content: 'string'
},
// 主键为_id
primaryKey: 'id'
}
}
+136
View File
@@ -0,0 +1,136 @@
import Realm, { ObjectSchema } from 'realm'
import { LoggerStatus, LoggerType } from '../../../enum/softwareEnum'
import { MJImageType, MJRobotType } from '../../../enum/mjEnum'
export class BrowserMJModel extends Realm.Object<BrowserMJModel> {
id: string
serviceId: string
channelId: string
mjBotId: string
nijBotId: string
token: string
userAgent: string
userAgentCustom: boolean
createTime: Date
updateTime: Date
version: string
static schema: ObjectSchema = {
name: 'BrowserMJ',
properties: {
id: 'string',
serviceId: 'string',
channelId: 'string',
mjBotId: 'string?',
nijBotId: 'string?',
token: 'string',
userAgent: 'string',
userAgentCustom: 'bool',
createTime: 'date',
updateTime: 'date',
version: 'string'
},
// 主键为_id
primaryKey: 'id'
}
}
export class RemoteMJModel extends Realm.Object<RemoteMJModel> {
id: string
accountId: string | null
channelId: string
coreSize: number
guildId: string
mjBotChannelId: string
nijiBotChannelId: string
queueSize: number
remark: string
remixAutoSubmit: boolean
timeoutMinutes: number
userAgent: string
userToken: string
createTime: Date
updateTime: Date
version: string
static schema: ObjectSchema = {
name: 'RemoteMJ',
properties: {
id: 'string',
accountId: 'string?',
channelId: 'string',
coreSize: 'int',
guildId: 'string',
mjBotChannelId: 'string',
nijiBotChannelId: 'string',
queueSize: 'int',
remark: 'string',
remixAutoSubmit: 'bool',
timeoutMinutes: 'int',
userAgent: 'string',
userToken: 'string',
createTime: 'date',
updateTime: 'date',
version: 'string'
},
// 主键为_id
primaryKey: 'id'
}
}
export class APIMjModel extends Realm.Object<APIMjModel> {
id: string
mjApiUrl: string
mjSpeed: string // MJ出图的速度模式
apiKey: string
createTime: Date
updateTime: Date
version: string
static schema: ObjectSchema = {
name: 'APIMj',
properties: {
id: 'string',
mjApiUrl: 'string',
mjSpeed: 'string',
apiKey: 'string',
createTime: 'date',
updateTime: 'date',
version: 'string'
},
// 主键为_id
primaryKey: 'id'
}
}
export class MjSettingModel extends Realm.Object<MjSettingModel> {
id: string
type: MJImageType
requestModel: MJImageType
selectRobot: MJRobotType
imageScale: string
imageModel: string
imageSuffix: string
taskCount: number
spaceTime: number
createTime: Date
updateTime: Date
version: string
static schema: ObjectSchema = {
name: 'MjSetting',
properties: {
id: 'string',
type: 'string',
requestModel: 'string',
selectRobot: 'string',
imageScale: 'string',
imageModel: 'string',
imageSuffix: 'string',
taskCount: 'int',
spaceTime: 'int',
createTime: 'date',
updateTime: 'date',
version: 'string'
},
// 主键为_id
primaryKey: 'id'
}
}
+23
View File
@@ -0,0 +1,23 @@
import Realm, { ObjectSchema } from 'realm'
import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum'
export class SoftwareModel extends Realm.Object<SoftwareModel> {
id: string
theme: SoftwareThemeType
reverse_display_show: boolean
reverse_show_book_striped: boolean
reverse_data_table_size: ComponentSize
static schema: ObjectSchema = {
name: 'Software',
properties: {
id: 'string',
theme: 'string',
reverse_display_show: 'bool',
reverse_show_book_striped: 'bool',
reverse_data_table_size: 'string'
},
// 主键为_id
primaryKey: 'id'
}
}
@@ -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
}
}
}
@@ -0,0 +1,80 @@
import Realm, { UpdateMode } from 'realm'
import path from 'path'
import { BaseService } from '../baseService.js'
import { define } from '../../../define.js'
import { SoftwareModel } from '../../model/SoftWare/software.js'
import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum.js'
import { errorMessage, successMessage } from '../../../../main/generalTools.js'
import { BaseSoftWareService } from './softwareBasic.js'
import { isEmpty } from 'lodash'
const { v4: uuidv4 } = require('uuid')
export class LoggerService extends BaseSoftWareService {
static instance: LoggerService | null = null
realm: Realm
private constructor() {
super()
}
/**
* 获取当前实例对象,为空则创建一个新的
* @returns
*/
public static async getInstance() {
if (LoggerService.instance === null) {
LoggerService.instance = new LoggerService()
await super.getInstance()
}
return LoggerService.instance
}
// 添加一条日志信息
async AddLogger(logger) {
try {
await this.open()
// 判断数据是不是存在 bookIdbookTaskIdtypestatuscontent
if (
isEmpty(logger.bookId) ||
isEmpty(logger.bookTaskId) ||
isEmpty(logger.type) ||
isEmpty(logger.status) ||
isEmpty(logger.content)
) {
throw new Error('新增日志信息到数据库失败,数据不完整,缺少必要字段')
}
logger.id = uuidv4()
logger.date = new Date()
this.realm.write(() => {
this.realm.create('Logger', logger)
})
return successMessage(logger, '新增日志信息成功', 'LoggerService_AddLogger')
} catch (error) {
return errorMessage(
'新增日志信息失败,错误信息如下:' + error.toString(),
'LoggerService_AddLogger'
)
}
}
// 删除日志信息 (删除指定日期之前的)
async DeleteLogger(date) {
try {
await this.open()
this.realm.write(() => {
// 删除十五天之前的日志数据
const currentDate = new Date()
currentDate.setDate(currentDate.getDate() - 5)
let logger = this.realm.objects('Logger').filtered('date < $0', currentDate)
this.realm.delete(logger)
})
return successMessage(null, '删除日志信息成功', 'LoggerService_DeleteLogger')
} catch (error) {
return errorMessage(
'删除日志信息失败,错误信息如下:' + error.toString(),
'LoggerService_DeleteLogger'
)
}
}
}
@@ -0,0 +1,611 @@
import Realm, { UpdateMode } from 'realm'
import path from 'path'
import { BaseService } from '../baseService'
import { define } from '../../../define.js'
import { SoftwareModel } from '../../model/SoftWare/software.js'
import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum.js'
import { errorMessage, successMessage } from '../../../../main/generalTools.js'
import { BaseSoftWareService } from './softwareBasic.js'
import { isEmpty, isNumber } from 'lodash'
const { v4: uuidv4 } = require('uuid')
import { version } from '../../../../../package.json'
export class MJSettingService extends BaseSoftWareService {
static instance: MJSettingService | null = null
realm: Realm
private constructor() {
super()
}
/**
* 获取当前实例对象,为空则创建一个新的
* @returns
*/
public static async getInstance() {
if (MJSettingService.instance === null) {
MJSettingService.instance = new MJSettingService()
await super.getInstance()
}
await MJSettingService.instance.open()
return MJSettingService.instance
}
//#region 览器模式的MJ设置
/**
* 查询对应的浏览器的MJ设置
* @param browserQuery 查询条件 Id null 返回全部
*/
GetBrowserMJSetting(browserQuery) {
try {
let browserMjSettings = this.realm.objects('BrowserMJ')
if (browserQuery?.id) {
browserMjSettings = this.realm.objects('BrowserMJ').filtered('id = $0', browserQuery.id)
}
let resBrowserMj = Array.from(browserMjSettings).map((browserMj) => {
return {
...browserMj
}
})
return successMessage(
resBrowserMj,
'获取浏览器配置成功',
'MJSettingService_GetBrowserMJSetting'
)
} catch (error) {
throw error
}
}
/**
* 添加浏览器相关的MJ设置
* @param browserMj 浏览器的MJ设置对象
* @returns
*/
AddBrowserMJSetting(browserMj) {
try {
if (isEmpty(browserMj.serviceId) || isEmpty(browserMj.channelId)) {
throw new Error('服务器ID和频道ID必填')
}
if (isEmpty(browserMj.token) || isEmpty(browserMj.userAgent)) {
throw new Error('用户Agent和token必填')
}
browserMj.id = uuidv4()
browserMj.createTime = new Date()
browserMj.updateTime = new Date()
browserMj.version = version
browserMj.userAgentCustom = false
if (this.realm.isInTransaction) {
this.realm.create('BrowserMJ', browserMj)
} else {
this.realm.write(() => {
this.realm.create('BrowserMJ', browserMj)
})
}
return successMessage(
browserMj,
'新增MJ浏览器模式配置成功',
'MJSettingService_AddBrowserMJSetting'
)
} catch (error) {
throw error
}
}
/**
* 更新浏览器的MJ设置
* @param browserMj
*/
UpdateBrowserMJSetting(browserMj) {
try {
if (isEmpty(browserMj.id)) {
throw new Error('更改浏览器模式配置,ID不能为空')
}
if (
isEmpty(browserMj.serviceId) ||
isEmpty(browserMj.channelId) ||
isEmpty(browserMj.token)
) {
throw new Error('更改浏览器配置,服务器ID,频道ID,Token不能为空')
}
// 判断是不是有数据
let browserMjRes = this.realm.objects('BrowserMJ').filtered('id = $0', browserMj.id)
if (browserMjRes.length <= 0) {
throw new Error('没有找到对应的浏览器配置信息')
}
browserMj.updateTime = new Date()
browserMj.version = version
if (this.realm.isInTransaction) {
this.realm.create('BrowserMJ', browserMj, UpdateMode.Modified)
} else {
this.realm.write(() => {
this.realm.create('BrowserMJ', browserMj, UpdateMode.Modified)
})
}
return successMessage(
browserMj,
'修改浏览器模式配置成功',
'MJSettingService_UpdateBrowserMJSetting'
)
} catch (error) {
throw error
}
}
//#endregion
//#region API 模式的相关配置
/**
* 获取API配置信息
* @param apiQuery 查询条件 Id null 返回全部
* @returns
*/
GetAPIMjSetting(apiQuery) {
try {
let apiMjSettings = this.realm.objects('APIMj')
if (apiQuery?.id) {
apiMjSettings = this.realm.objects('APIMj').filtered('id = $0', apiQuery.id)
}
let resApiMj = Array.from(apiMjSettings).map((apiMj) => {
return {
...apiMj
}
})
return successMessage(resApiMj, '获取API配置成功', 'MJSettingService_GetAPIMjSetting')
} catch (error) {
throw error
}
}
/**
* 添加API模式的配置
* @param apiMj API的配置信息
*/
AddAPIMjSetting(apiMj) {
try {
if (isEmpty(apiMj.mjApiUrl) || isEmpty(apiMj.mjSpeed) || isEmpty(apiMj.apiKey)) {
throw new Error('请求的API URL,对应的API Key,请求模式这些必填')
}
apiMj.id = uuidv4()
apiMj.createTime = new Date()
apiMj.updateTime = new Date()
apiMj.version = version
if (this.realm.isInTransaction) {
this.realm.create('APIMj', apiMj)
} else {
this.realm.write(() => {
this.realm.create('APIMj', apiMj)
})
}
return successMessage(apiMj, '添加API设置成功', 'MJSettingService_AddAPIMjSetting')
} catch (error) {
throw error
}
}
/**
* 修改APIMJ的配置信息
* @param apiSetting
*/
UpdateAPIMJSetting(apiSetting) {
try {
if (apiSetting.id == null) {
throw new Error('修改API配置数据,ID必填')
}
// 判断必填的数据是不是为空
if (
isEmpty(apiSetting.mjApiUrl) ||
isEmpty(apiSetting.mjSpeed) ||
isEmpty(apiSetting.apiKey)
) {
throw new Error('请求的API URL,对应的API Key,请求模式这些必填')
}
// 判断对应的ID是不是存在
let apiSettingRes = this.realm.objects('APIMj').filtered('id = $0', apiSetting.id)
if (apiSettingRes.length <= 0) {
throw new Error('没有找到对应的API配置信息')
}
apiSetting.updateTime = new Date()
apiSetting.version = version
if (this.realm.isInTransaction) {
this.realm.create('APIMj', apiSetting, UpdateMode.Modified)
} else {
this.realm.write(() => {
this.realm.create('APIMj', apiSetting, UpdateMode.Modified)
})
}
return successMessage(apiSetting, '修改API设置成功', 'MJSettingService_UpdateAPIMJSetting')
} catch (error) {
throw error
}
}
//#endregion
//#region 代理模式的相关配置
/**
* 查询代理模式的配置信息
* @param remoteMjQuery 查询条件,idnull-返回全部
*/
GetRemoteMJSettings(remoteMjQuery) {
try {
let remoteMjSettings = this.realm.objects('RemoteMJ')
if (remoteMjQuery?.id) {
remoteMjSettings = this.realm.objects('RemoteMJ').filtered('id = $0', remoteMjQuery.id)
}
let resRemoteMj = Array.from(remoteMjSettings).map((remoteMj) => {
return {
...remoteMj
}
})
return successMessage(
resRemoteMj,
'获取代理模式配置成功',
'MJSettingService_GetRemoteMjSettings'
)
} catch (error) {
throw error
}
}
/**
* 添加代理API配置
* @param remoteMjSetting 代理API的设置对象
* @returns
*/
AddRemoteMjSetting(remoteMjSetting) {
try {
if (
isEmpty(remoteMjSetting.channelId) ||
isEmpty(remoteMjSetting.guildId) ||
isEmpty(remoteMjSetting.userToken)
) {
throw new Error('代理模式的频道ID,服务器ID,用户Token必填')
}
let defaultSetting = {
coreSize: 3,
mjBotChannelId: null,
nijiBotChannelId: null,
queueSize: 5,
remark: global.machineId,
remixAutoSubmit: false,
timeoutMinutes: 6,
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
}
// 覆盖
remoteMjSetting = Object.assign(defaultSetting, remoteMjSetting)
remoteMjSetting.id = uuidv4()
remoteMjSetting.createTime = new Date()
remoteMjSetting.updateTime = new Date()
remoteMjSetting.version = version
remoteMjSetting.remark = global.machineId
// 判断当前this.relam 是不是已经处于一个事务中
if (this.realm.isInTransaction) {
this.realm.create('RemoteMJ', remoteMjSetting)
} else {
this.realm.write(() => {
this.realm.create('RemoteMJ', remoteMjSetting)
})
}
return successMessage(
remoteMjSetting,
'新增代理API配置成功',
'MJSettingService_AddRemoteMjSetting'
)
} catch (error) {
throw error
}
}
/**
* 更新代理模式的配置信息
* @param remoteMjSetting
*/
UpdateRemoteMjSetting(remoteMjSetting) {
try {
if (isEmpty(remoteMjSetting.id)) {
throw new Error('更改代理模式配置,ID不能为空')
}
if (
isEmpty(remoteMjSetting.channelId) ||
isEmpty(remoteMjSetting.guildId) ||
isEmpty(remoteMjSetting.userToken)
) {
throw new Error('代理模式的账号ID,服务ID,频道ID,用户Token不能为空')
}
if (
remoteMjSetting.coreSize == null ||
remoteMjSetting.queueSize == null ||
remoteMjSetting.timeoutMinutes == null
) {
throw new Error('核心数量,队列数量,超时时间不能为空')
}
let remoteMjSettingRes = this.realm
.objects('RemoteMJ')
.filtered('id = $0', remoteMjSetting.id)
if (remoteMjSettingRes.length <= 0) {
throw new Error('没有找到对应的代理模式配置信息')
}
remoteMjSetting.updateTime = new Date()
remoteMjSetting.version = version
remoteMjSetting.remark = global.machineId
// 判断relam是不是在事务中
if (this.realm.isInTransaction) {
this.realm.create('RemoteMJ', remoteMjSetting, UpdateMode.Modified)
} else {
this.realm.write(() => {
this.realm.create('RemoteMJ', remoteMjSetting, UpdateMode.Modified)
})
}
return successMessage(
remoteMjSetting,
'修改代理API配置成功',
'MJSettingService_UpdateRemoteMjSetting'
)
} catch (error) {
throw error
}
}
//#endregion
//#region MJ设置的基础设置
/**
* 获取MJ的基础配置信息
* @param mjSettingQuery 查询的条件 Id null 返回全部
* @returns
*/
GetMjSetting(mjSettingQuery) {
try {
let mjSettings = this.realm.objects('MjSetting')
if (mjSettingQuery?.id) {
mjSettings = this.realm.objects('MjSetting').filtered('id = $0', mjSettingQuery.id)
}
let resMjSetting = Array.from(mjSettings).map((mjSetting) => {
return {
...mjSetting
}
})
return successMessage(resMjSetting, '获取MJ基础设置成功', 'MJSettingService_getMjSetting')
} catch (error) {
throw error
}
}
/**
* 添加MJ的基础配置到数据库
* @param mjSetting 添加的mj基础配置的对象
* @returns
*/
AddMJSetting(mjSetting) {
try {
mjSetting.type = mjSetting.requestModel
// 判断传入的必填数据是不是为空
if (isEmpty(mjSetting.type) || isEmpty(mjSetting.requestModel)) {
throw new Error('MJ设置的类型和请求模型不能为空')
}
if (
isEmpty(mjSetting.imageScale) ||
isEmpty(mjSetting.imageModel) ||
isEmpty(mjSetting.imageSuffix) ||
isEmpty(mjSetting.selectRobot)
) {
throw new Error('MJ设置的图片比例、图片模型、生图后缀、选择机器人不能为空')
}
mjSetting.id = uuidv4()
mjSetting.createTime = new Date()
mjSetting.updateTime = new Date()
mjSetting.version = version
//TODO 还有一些判断条件,后面需要添加,比如选择生图模式,要保存对应的配置数据
if (this.realm.isInTransaction) {
this.realm.create('MjSetting', mjSetting)
} else {
this.realm.write(() => {
this.realm.create('MjSetting', mjSetting)
})
}
// 返回成功信息
return successMessage(mjSetting, '添加MJ设置成功', 'MJSettingService_AddMJSetting')
} catch (error) {
throw error
}
}
/**
* 更新MJ的基础配置信息
* @param mjSetting
*/
UpdateMJSetting(mjSetting) {
try {
// 判断传入的数据中的必填数据是不是为空
if (isEmpty(mjSetting.id)) {
throw new Error('更改MJ基础设置,ID不能为空')
}
if (isEmpty(mjSetting.requestModel)) {
throw new Error('MJ设置的请求模型不能为空')
}
mjSetting.type = mjSetting.requestModel
if (
isEmpty(mjSetting.selectRobot) ||
isEmpty(mjSetting.imageScale) ||
isEmpty(mjSetting.imageModel) ||
isEmpty(mjSetting.imageSuffix)
) {
throw new Error('MJ设置的图片比例、图片模型、生图后缀、选择机器人不能为空')
}
if (mjSetting.taskCount == null || mjSetting.spaceTime == null) {
throw new Error('任务数量和间隔时间不能为空')
}
// 判断指定ID的数据是不是存在
let mjSettingRes = this.realm.objects('MjSetting').filtered('id = $0', mjSetting.id)
if (mjSettingRes.length <= 0) {
throw new Error('没有找到对应的MJ配置信息')
}
mjSetting.updateTime = new Date()
mjSetting.version = version
if (this.realm.isInTransaction) {
this.realm.create('MjSetting', mjSetting, UpdateMode.Modified)
} else {
this.realm.write(() => {
this.realm.create('MjSetting', mjSetting, UpdateMode.Modified)
})
}
// 返回成功信息
return successMessage(mjSetting, '修改MJ配置信息成功', 'MJSettingService_UpdateMJSetting')
} catch (error) {
throw error
}
}
//#endregion
//#region 组合操作,组合返回前端的数据信息
/**
* 获取MJ的所有配置信息,包含所有的子项
*/
GetMJSettingTreeData() {
try {
// 获取MJ的基础配置信息
let mjSettings = this.GetMjSetting(null)
if (mjSettings.data.length <= 0) {
throw new Error('没有找到MJ的配置信息,请先添加')
}
// 获取API的配置信息
let apiSettings = this.GetAPIMjSetting(null)
// 获取代理模式的配置信息
let remoteSettings = this.GetRemoteMJSettings(null)
// 获取浏览器模式的配置信息
let browserSettings = this.GetBrowserMJSetting(null)
let mjSetting = mjSettings.data[0]
mjSetting.apiSetting = apiSettings.data.length > 0 ? apiSettings.data[0] : null
mjSetting.remoteSetting = remoteSettings.data.length > 0 ? remoteSettings.data[0] : null
mjSetting.browserSetting = browserSettings.data.length > 0 ? browserSettings.data[0] : null
return successMessage(
mjSetting,
'获取MJ的所有配置信息成功',
'MJSettingService_GetMJSettingTreeData'
)
} catch (error) {
throw error
}
}
/**
* 组合操作,保存数据
* @param mjSetting
*/
SaveMJSettingTreeData(mjSetting) {
try {
if (mjSetting == null) {
throw new Error('保存的数据不能为空')
}
// 组合添加数据
this.realm.write(() => {
// 先添加RemoteMJ的数据
let remoteSetting = mjSetting.remoteSetting ? mjSetting.remoteSetting : null
if (remoteSetting != null) {
let remoteSettingRes: { code: number; data: any; message: any }
if (isEmpty(remoteSetting.id)) {
// 新增
remoteSettingRes = this.AddRemoteMjSetting(remoteSetting)
} else {
// 修改
remoteSettingRes = this.UpdateRemoteMjSetting(remoteSetting)
}
if (remoteSettingRes && remoteSettingRes.code == 1) {
mjSetting.remoteSetting = remoteSettingRes.data
}
}
// 判断API设置的数据是不是存在
let apiSetting = mjSetting.apiSetting ? mjSetting.apiSetting : null
if (apiSetting != null) {
let apiSettingRes: { code: number; data: any; message: any }
if (isEmpty(apiSetting.id)) {
// 新增
apiSettingRes = this.AddAPIMjSetting(apiSetting)
} else {
// 修改
apiSettingRes = this.UpdateAPIMJSetting(apiSetting)
}
if (apiSettingRes && apiSettingRes.code == 1) {
mjSetting.apiSetting = apiSettingRes.data
}
}
// 判断浏览器模式的数据是不是存在
let browserSetting = mjSetting.browserSetting ? mjSetting.browserSetting : null
if (browserSetting != null) {
let browserSettingRes: { code: number; data: any; message: any }
if (isEmpty(browserSetting.id)) {
// 新增
browserSettingRes = this.AddBrowserMJSetting(browserSetting)
} else {
// 修改
browserSettingRes = this.UpdateBrowserMJSetting(browserSetting)
}
if (browserSettingRes && browserSettingRes.code == 1) {
mjSetting.browserSetting = browserSettingRes.data
}
}
// 添加MJ的基础配置信息
let mjSettingRes: { code: number; data: any; message: any }
if (isEmpty(mjSetting.id)) {
// 新增
mjSettingRes = this.AddMJSetting(mjSetting)
} else {
// 修改
mjSettingRes = this.UpdateMJSetting(mjSetting)
}
if (mjSettingRes && mjSettingRes.code == 1) {
mjSetting = mjSettingRes.data
}
})
return successMessage(mjSetting, '添加信息成功', 'MJSettingService_SaveMJSettingTreeData')
} catch (error) {
throw error
}
}
//#endregion
}
@@ -0,0 +1,133 @@
import Realm from 'realm'
import { BaseService } from '../baseService'
import { define } from '../../../define'
import path from 'path'
import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum'
import { SoftwareModel } from '../../model/SoftWare/software'
import { LoggerModel } from '../../model/SoftWare/logger'
import {
APIMjModel,
BrowserMJModel,
MjSettingModel,
RemoteMJModel
} from '../../model/SoftWare/mjSetting'
import { MJImageType, MJRobotType } from '../../../enum/mjEnum'
const { v4: uuidv4 } = require('uuid')
let dbPath = path.resolve(define.db_path, 'software.realm')
// 版本迁移
const migration = (oldRealm: Realm, newRealm: Realm) => {
const oldBooks = oldRealm.objects('Software')
const newBooks = newRealm.objects('Software')
if (oldRealm.schemaVersion < 1) {
}
// 第二个版本
if (oldRealm.schemaVersion < 2) {
newRealm.write(() => {
const newSoftwares = newRealm.objects('Software')
for (let software of newSoftwares) {
software.theme = SoftwareThemeType.LIGHT // 为新属性设置默认值
}
})
}
// 第三个版本
if (oldRealm.schemaVersion < 3) {
newRealm.write(() => {
const newSoftwares = newRealm.objects('Software')
for (let software of newSoftwares) {
software.reverse_display_show = false
software.reverse_show_book_striped = false
software.reverse_data_table_size = ComponentSize.SMALL
}
})
}
if (oldRealm.schemaVersion < 6) {
newRealm.write(() => {
const newSoftwares = newRealm.objects('MjSetting')
for (let software of newSoftwares) {
software.requestModel = MJImageType.API_MJ
}
})
}
if (oldRealm.schemaVersion < 8) {
newRealm.write(() => {
const newSoftwares = newRealm.objects('MjSetting')
for (let software of newSoftwares) {
software.imageModel = MJRobotType.MJ
}
})
}
if (oldRealm.schemaVersion < 9) {
newRealm.write(() => {
const newSoftwares = newRealm.objects('MjSetting')
for (let software of newSoftwares) {
software.accountId = null
}
})
}
if (oldRealm.schemaVersion < 10) {
newRealm.write(() => {
const newSoftwares = newRealm.objects('MjSetting')
for (let software of newSoftwares) {
software.accountId = null
}
})
}
}
export class BaseSoftWareService extends BaseService {
static instance: BaseSoftWareService | null = null
protected realm: Realm
dbpath: string
protected constructor() {
super()
this.dbpath = dbPath
}
public static async getInstance() {
if (BaseSoftWareService.instance === null) {
BaseSoftWareService.instance = new BaseSoftWareService()
await BaseSoftWareService.instance.open()
}
return BaseSoftWareService.instance
}
/**
* 创建数据库连接,如果已经存在则直接返回
* @param dbPath 数据库文件地址
* @returns
*/
async open() {
try {
if (this.realm != null) return
let config = {
schema: [
SoftwareModel,
LoggerModel,
BrowserMJModel,
RemoteMJModel,
APIMjModel,
MjSettingModel
],
path: dbPath,
schemaVersion: 10, // 当前版本号
migration: migration
}
// 判断当前全局是不是又当前这个
this.realm = await Realm.open(config)
// 判断当前是不是有数据,一条都没有的话添加一条空白数据
if (this.realm.objects('Software').length == 0) {
this.realm.write(() => {
this.realm.create('Software', {
id: uuidv4(),
theme: SoftwareThemeType.LIGHT // 默认是亮色主题
})
})
}
} catch (error) {
console.log(error)
}
}
}
@@ -0,0 +1,78 @@
import Realm, { UpdateMode } from 'realm'
import path from 'path'
import { BaseService } from '../baseService.js'
import { define } from '../../../define.js'
import { SoftwareModel } from '../../model/SoftWare/software.js'
import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum.js'
import { successMessage } from '../../../../main/generalTools.js'
import { BaseSoftWareService } from './softwareBasic.js'
const { v4: uuidv4 } = require('uuid')
export class SoftwareService extends BaseSoftWareService {
static instance: SoftwareService | null = null
realm: Realm
private constructor() {
super()
}
/**
* 获取当前实例对象,为空则创建一个新的
* @returns
*/
public static async getInstance() {
if (SoftwareService.instance === null) {
SoftwareService.instance = new SoftwareService()
await super.getInstance()
}
return SoftwareService.instance
}
// 修改数据库中行中的某个属性数据
async UpdateSoftware(software) {
try {
await this.open()
this.realm.write(() => {
this.realm.create('Software', software, UpdateMode.Modified)
})
// 返回成功信息
return successMessage(null, '修改软件配置信息成功', 'SoftwareService_UpdateSoftware')
} catch (error) {
throw error
}
}
async AddSfotware(software) {
try {
await this.open()
software.id = uuidv4()
this.realm.write(() => {
this.realm.create('Software', software)
})
} catch (error) {
throw error
}
}
/**
* 或软件基础配置信息
*/
async GetSoftwareData() {
try {
await this.open()
let software = this.realm.objects('Software')
return successMessage(
software.toJSON(),
'获取软件配置信息成功',
'SoftwareService_GetSoftwareData'
)
} catch (error) {
global.logger.error(
'SoftwareService_GetSoftwareData',
'获取软件的基础设置失败 ,错误信息如下:' + error.toString()
)
throw error
}
}
}
export default SoftwareService
+36
View File
@@ -0,0 +1,36 @@
// 定义抽象基类
import Realm from 'realm'
export abstract class BaseService {
protected realm: Realm | null = null
// 抽象类的构造函数应该是protected,以防止外部直接实例化
protected constructor() {
// 构造函数逻辑,使用someValue进行初始化
}
// 定义抽象方法,子类必须实现,打开数据库连接
abstract open(dbPath: string): void
// 关闭数据库连接
close(): void {
// 关闭数据库的连接,防止内存溢出
// 实现关闭数据库连接的逻辑
if (this.realm != null) {
console.log('Closing database connection')
this.realm.close()
this.realm = null // 清理引用,确保垃圾回收
}
}
transaction(func: () => unknown): void {
if (this.realm != null) {
// 判断当前的relam是不是在一个事务中
if (this.realm.isInTransaction) {
func()
} else {
this.realm.write(() => {
func()
})
}
}
}
}