LaiTool V3.1.1.

This commit is contained in:
2024-09-12 14:13:09 +08:00
parent 5dc75f018a
commit 918d06e990
123 changed files with 8028 additions and 756 deletions
+30
View File
@@ -37,3 +37,33 @@ export async function RetryWithBackoff<T>(fn: () => Promise<T>, retries: number
}
throw new Error('所有重试失败'); // 理论上不会到达这里
}
/**
* 并发执行任务(控制同时执行的任务数)
* @param tasks 总的任务列表
* @param concurrentCount 同时执行的数量
* @returns
*/
export async function ExecuteConcurrently(tasks: Array<() => Promise<any>>, concurrentCount: number): Promise<any[]> {
let activeTasks: Array<Promise<any>> = [];
let results: Array<Promise<any>> = [];
while (tasks.length > 0) {
if (activeTasks.length < concurrentCount) {
let task = tasks.shift();
let promise = task().then(result => {
activeTasks = activeTasks.filter(t => t !== promise);
return result;
}).catch(error => {
// 抛出任务,停止所有的任务
tasks.length = 0;
throw error
});
activeTasks.push(promise);
results.push(promise);
} else {
await Promise.race(activeTasks);
}
}
return Promise.all(results);
}
+21
View File
@@ -1,6 +1,9 @@
import fs from 'fs'
import { isEmpty } from 'lodash'
import path from 'path'
import util from 'util'
import { exec } from 'child_process'
const execAsync = util.promisify(exec)
const fspromises = fs.promises
/**
@@ -253,3 +256,21 @@ export async function GetSubdirectories(folderPath: string): Promise<string[]> {
throw new Error(error);
}
}
/**
* 删除目标图片,然后将原图片的exif信息删除,然后将原图片复制到目标图片地址
* @param {*} exiftoolPath exiftool的地址
* @param {*} source 原图片地址
* @param {*} target 目标图片地址
*/
export async function DeleteFileExifData(exiftoolPath: string, source: string, target: string) {
try {
if (await CheckFileOrDirExist(target)) {
await fspromises.unlink(target)
}
let script = `"${exiftoolPath}" -all= -overwrite_original "${source}" -o "${target}"`
const output = await execAsync(script, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' })
} catch (error) {
throw error
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
import path from 'path'
import sharp from 'sharp'
import { CheckFileOrDirExist } from './file'
import { CheckFileOrDirExist, CheckFolderExistsOrCreate } from './file'
import fs from 'fs'
import https from 'https'
@@ -237,7 +237,7 @@ export async function Base64ToFile(base64: string, outFilePath: string): Promise
let base64Data = base64.replace(/^data:image\/\w+;base64,/, '')
let dataBuffer = Buffer.from(base64Data, 'base64')
let out_folder = path.dirname(outFilePath)
await this.tools.checkFolderExistsOrCreate(out_folder)
await CheckFolderExistsOrCreate(out_folder)
await fs.promises.writeFile(outFilePath, dataBuffer)
// await this.tools.writeArrayToFile(dataBuffer, out_file);
} catch (error) {
@@ -15,6 +15,7 @@ export class BookBackTaskList extends Realm.Object<BookBackTaskList> {
updateTime: Date
startTime: number
endTime: number
messageName?: string
static schema: ObjectSchema = {
name: 'BookBackTaskList',
@@ -31,7 +32,8 @@ export class BookBackTaskList extends Realm.Object<BookBackTaskList> {
createTime: 'date',
updateTime: 'date',
startTime: 'int',
endTime: 'int'
endTime: 'int',
messageName: 'string?'
},
primaryKey: 'id'
}
@@ -141,6 +141,7 @@ export class BookTaskDetailModel extends Realm.Object<BookTaskDetailModel> {
timeLimit: string | null // 事件实现(0 -- 3000
subValue: string | null // 包含的字幕数据
characterTags: string[] | null // 角色标签
sceneTags: string[] | null // 场景标签
gptPrompt: string | null // GPT提示词
mjMessage: MJMessage | null // MJ消息
outImagePath: string | null // 输出图片地址
@@ -174,6 +175,7 @@ export class BookTaskDetailModel extends Realm.Object<BookTaskDetailModel> {
subValue: 'string?',
reversePrompt: { type: 'list', objectType: 'ReversePrompt' },
characterTags: { type: 'list', objectType: 'string' },
sceneTags: 'string[]',
gptPrompt: 'string?',
mjMessage: 'MJMessage?',
outImagePath: 'string?',
+36
View File
@@ -0,0 +1,36 @@
import Realm, { ObjectSchema } from 'realm'
export class PresetModel extends Realm.Object<PresetModel> {
id: string
label: string
type: string
showImage?: string
prompt: string
chinesePrompt?: string
imageUrl?: string
srefSw?: number
crefCw?: number
lora?: string
loraWeight?: number
isShow: boolean
children?: string
static schema: ObjectSchema = {
name: 'PresetModel',
properties: {
id: 'string',
label: 'string',
type: 'string',
showImage: 'string?',
imageUrl: 'string?',
prompt: 'string',
chinesePrompt: 'string?',
srefSw: 'int?',
crefCw: 'int?',
lora: 'string?',
loraWeight: 'int?',
isShow: 'bool',
children: 'string?'
},
primaryKey: 'id'
}
}
@@ -140,7 +140,8 @@ export class BookBackTaskListService extends BaseRealmService {
taskType: BookBackTaskType,
executeType = TaskExecuteType.AUTO,
bookTaskId = null,
bookTaskDetailId = null
bookTaskDetailId = null,
responseMessageName: string = null
): GeneralResponse.SuccessItem | GeneralResponse.ErrorItem {
try {
// 通过bookid获取book信息
@@ -181,6 +182,7 @@ export class BookBackTaskListService extends BaseRealmService {
status: BookBackTaskStatus.WAIT,
createTime: new Date(),
updateTime: new Date(),
messageName: responseMessageName,
startTime: 0,
endTime: 0
} as TaskModal.Task
+15 -1
View File
@@ -162,6 +162,20 @@ const migration = (oldRealm: Realm, newRealm: Realm) => {
newBookTask[i].watermarkPosition = '[]'
}
}
if (oldRealm.schemaVersion < 23) {
const oldBookTask = oldRealm.objects('BookTaskDetail')
const newBookTask = newRealm.objects('BookTaskDetail')
for (let i = 0; i < oldBookTask.length; i++) {
newBookTask[i].subImagePath = '[]'
}
}
if (oldRealm.schemaVersion < 24) {
const oldBookTask = oldRealm.objects('BookBackTaskList')
const newBookTask = newRealm.objects('BookBackTaskList')
for (let i = 0; i < oldBookTask.length; i++) {
newBookTask[i].messageName = ''
}
}
}
export class BaseRealmService extends BaseService {
@@ -203,7 +217,7 @@ export class BaseRealmService extends BaseService {
BookTaskDetailModel
],
path: this.dbpath,
schemaVersion: 22,
schemaVersion: 24,
migration: migration
}
this.realm = await Realm.open(config)
@@ -195,6 +195,9 @@ export class BookService extends BaseRealmService {
await CheckFolderExistsOrCreate(bookTaskImageFolder) // 创建默认的任务文件夹
// 修改数据
book.oldVideoPath = path.relative(define.project_path, oldVideoPath)
if (book.type == BookType.ORIGINAL) {
book.oldVideoPath = null
}
let imageCategory = BookImageCategory.MJ
if (book.type == BookType.SD_REVERSE) {
@@ -1,6 +1,6 @@
import Realm from 'realm'
import path from 'path'
import { define } from '../../../define.js'
import { define } from '../../../define'
import { BookTaskModel } from '../../model/Book/bookTask.js'
import { successMessage } from '../../../../main/Public/generalTools'
import { BaseRealmService } from './bookBasic'
@@ -72,6 +72,7 @@ export class BookTaskDetailService extends BaseRealmService {
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 {
@@ -116,7 +117,7 @@ export class BookTaskDetailService extends BaseRealmService {
* 添加一条小说任务对应的详细数据
* @param BookTaskDetail
*/
public AddBookTaskDetail(bookTaskDetail) {
public AddBookTaskDetail(bookTaskDetail: Book.SelectBookTaskDetail) {
try {
// 判断是不是又小说ID
if (isEmpty(bookTaskDetail.bookId) || isEmpty(bookTaskDetail.bookTaskId)) {
@@ -191,7 +192,6 @@ export class BookTaskDetailService extends BaseRealmService {
*/
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)
@@ -1,6 +1,6 @@
import Realm from 'realm'
import path from 'path'
import { define } from '../../../define.js'
import { define } from '../../../define'
import { BookTaskModel } from '../../model/Book/bookTask.js'
import { BookBackTaskStatus, BookImageCategory, BookTaskStatus } from '../../../enum/bookEnum.js'
import { successMessage } from '../../../../main/Public/generalTools'
@@ -0,0 +1,26 @@
import Realm, { UpdateMode } from 'realm'
import path from 'path'
import { errorMessage, successMessage } from '../../../../main/Public/generalTools'
import { BaseSoftWareService } from './softwareBasic.js'
import { isEmpty } from 'lodash'
const { v4: uuidv4 } = require('uuid')
export class ImageStyleService extends BaseSoftWareService {
static instance: ImageStyleService | null = null
realm: Realm
private constructor() {
super()
}
/**
* 获取当前实例对象,为空则创建一个新的
* @returns
*/
public static async getInstance() {
if (ImageStyleService.instance === null) {
ImageStyleService.instance = new ImageStyleService()
await super.getInstance()
}
return ImageStyleService.instance
}
}
@@ -1,7 +1,7 @@
import Realm, { UpdateMode } from 'realm'
import path from 'path'
import { BaseService } from '../baseService'
import { define } from '../../../define.js'
import { define } from '../../../define'
import { SoftwareModel } from '../../model/SoftWare/software'
import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum.js'
import { errorMessage, successMessage } from '../../../../main/Public/generalTools'
@@ -12,6 +12,7 @@ import {
RemoteMJModel
} from '../../model/SoftWare/mjSetting'
import { MJImageType, MJRobotType } from '../../../enum/mjEnum'
import { PresetModel } from '../../model/SoftWare/preset'
const { v4: uuidv4 } = require('uuid')
let dbPath = path.resolve(define.db_path, 'software.realm')
@@ -155,6 +156,9 @@ const migration = (oldRealm: Realm, newRealm: Realm) => {
}
})
}
if (oldRealm.schemaVersion < 22) {
}
}
export class BaseSoftWareService extends BaseService {
@@ -190,10 +194,11 @@ export class BaseSoftWareService extends BaseService {
BrowserMJModel,
RemoteMJModel,
APIMjModel,
MjSettingModel
MjSettingModel,
PresetModel
],
path: dbPath,
schemaVersion: 21, // 当前版本号
schemaVersion: 23, // 当前版本号
migration: migration
}
// 判断当前全局是不是又当前这个
@@ -25,15 +25,25 @@ export class SoftwareService extends BaseSoftWareService {
}
// 修改数据库中行中的某个属性数据
UpdateSoftware(software: SoftwareSettingModel.SoftwareSetting): GeneralResponse.SuccessItem {
try {
UpdateSoftware(software: SoftwareSettingModel.SoftwareSetting) {
if (software.id) {
this.realm.write(() => {
this.realm.create('Software', software, UpdateMode.Modified)
})
// 返回成功信息
return successMessage(null, '修改软件配置信息成功', 'SoftwareService_UpdateSoftware')
} catch (error) {
throw error
} else {
// 没有ID,就修改指定属性
let softwareData = this.realm.objects('Software')
if (softwareData.length <= 0) {
throw new Error('数据库中没有软件配置信息')
}
let _software = softwareData[0]
this.realm.write(() => {
for (let key in software) {
if (software[key] != undefined) {
_software[key] = software[key]
}
}
})
}
}
+75 -4
View File
@@ -1,4 +1,5 @@
export const DEFINE_STRING = {
SHOW_GLOBAL_MESSAGE: "SHOW_GLOBAL_MESSAGE",
SHOW_GLOBAL_MAIN_NOTIFICATION: 'SHOW_GLOBAL_MAIN_NOTIFICATION',
OPEN_DEV_TOOLS_PASSWORD: 'OPEN_DEV_TOOLS_PASSWORD',
OPEN_DEV_TOOLS: 'OPEN_DEV_TOOLS',
@@ -7,7 +8,7 @@ export const DEFINE_STRING = {
GET_DEFINE_CONFIG_JSON_BY_PROPERTY: 'GET_DEFINE_CONFIG_JSON_BY_PROPERTY',
GET_IMAGE_GENERATE_CATEGORY: 'GET_IMAGE_GENERATE_CATEGORY',
SHOW_MAIN_NOTIFICATION: 'SHOW_MAIN_NOTIFICATION',
SHOW_GLOABAL_MESSAGE: 'SHOW_GLOABAL_MESSAGE',
SHOW_MAIN_MESSAGE: "SHOW_MAIN_MESSAGE",
CHECK_MACHINE_ID: 'CHECK_MACHINE_ID',
GET_CUSTOMIZE_GPT_PROMPT: 'GET_CUSTOMIZE_GPT_PROMPT',
GENERATE_GPT_EXAMPLE_OUT: 'GENERATE_GPT_EXAMPLE_OUT',
@@ -149,11 +150,19 @@ export const DEFINE_STRING = {
TRANSLATE_NOW_RETURN: 'TRANSLATE_NOW_RETURN',
GET_TRANSLATE_SETTING: 'GET_TRANSLATE_SETTING',
RESET_TRANSLATE_SETTING: 'RESET_TRANSLATE_SETTING',
SAVE_TRANSLATE_SETTING: 'SAVE_TRANSLATE_SETTING'
SAVE_TRANSLATE_SETTING: 'SAVE_TRANSLATE_SETTING',
/**
* GPT 反推提示词翻译返回数据
*/
GPT_PROMPT_TRANSLATE_RETRUN: "GPT_PROMPT_TRANSLATE_RETRUN"
},
SD: {
LOAD_SD_SERVICE_DATA: 'LOAD_SD_SERVICE_DATA',
TXT2IMG: 'TXT2IMG',
//#region SD生成图片相关
//#endregion
},
MJ: {
SAVE_WORD_SRT: 'SAVE_WORD_SRT',
@@ -206,7 +215,6 @@ export const DEFINE_STRING = {
},
BOOK: {
MAIN_DATA_RETURN: 'MAIN_DATA_RETURN', // 监听任务返回
REPLACE_VIDEO_CURRENT_FRAME: 'REPLACE_VIDEO_CURRENT_FRAME',
GET_BOOK_TYPE: 'GET_BOOK_TYPE',
ADD_OR_MODIFY_BOOK: 'ADD_OR_MODIFY_BOOK',
@@ -243,6 +251,41 @@ export const DEFINE_STRING = {
REMOVE_GENERATE_IMAGE: 'REMOVE_GENERATE_IMAGE',
ADD_NEW_BOOK_TASK: "ADD_NEW_BOOK_TASK",
REPLACE_BOOK_DATA: "REPLACE_BOOK_DATA",
SAVE_COPYWRITING: 'SAVE_COPYWRITING',
//#region 原创推理提示词
ORIGINAL_GPT_PROMPT: "ORIGINAL_GPT_PROMPT",
ORIGINAL_GPT_PROMPT_RETURN: "ORIGINAL_GPT_PROMPT_RETURN",
//#endregion
//#region 生图返回相关
/**
* MJ生图返回信息
*/
MJ_IMAGE_GENERATE_RETURN: 'MJ_IMAGE_GENERATE_RETURN',
/**
* SD生图返回信息
*/
SD_IMAGE_GENERATE_RETURN: 'SD_IMAGE_GENERATE_RETURN',
/**
* D3 出图返回信息
*/
D3_IMAGE_GENERATE_RETURN: 'D3_IMAGE_GENERATE_RETURN',
/**
* flux forge 生图返回信息
*/
FLUX_FORGE_IMAGE_GENERATE_RETURN: "FLUX_FORGE_IMAGE_GENERATE_RETURN",
/**
* flux api 生图返回信息
*/
FLUX_API_IMAGE_GENERATE_RETURN: "FLUX_API_IMAGE_GENERATE_RETURN",
//#endregion
COMPUTE_STORYBOARD: 'COMPUTE_STORYBOARD',
@@ -290,6 +333,19 @@ export const DEFINE_STRING = {
GET_PROMPT_SORT_DATA: 'GET_PROMPT_SORT_DATA',
OPEN_PROMPT_FILE_TXT: 'OPEN_PROMPT_FILE_TXT'
},
/**
* IPC事件传递,预设相关
*/
PRESET: {
/**
* 获取任务的预设(只获取 label 和 id)
*/
GET_CHARACTER_PRESET: 'GET_CHARACTER_PRESET',
/**
* 获取场景的预设(只获取 label 和 id)
*/
GET_SCENE_PRESET: "GET_SCENE_PRESET"
},
TTS: {
GET_TTS_CONFIG: 'GET_TTS_CONFIG',
GENERATE_AUDIO: 'GENERATE_AUDIO',
@@ -309,6 +365,21 @@ export const DEFINE_STRING = {
DB: {
UPDATE_BOOK_TASK_DATA: "UPDATE_BOOK_TASK_DATA",
UPDATE_BOOK_TASK_DETAIL_DATA: "UPDATE_BOOK_TASK_DETAIL_DATA",
UPDATE_BOOK_DATA: "UPDATE_BOOK_DATA"
UPDATE_BOOK_DATA: "UPDATE_BOOK_DATA",
UPDATE_SOFTWARE_SETTING: "UPDATE_SOFTWARE_SETTING"
},
/**
* 后台任务相关
*/
TASK: {
/**
* 添加单个后台任务
*/
ADD_BOOK_BACK_TASK: "ADD_BOOK_BACK_TASK",
/**
* 添加多个后台任务
*/
ADD_MULTI_BOOK_BACK_TASK: 'ADD_MULTI_BOOK_BACK_TASK'
}
}
+21 -1
View File
@@ -1,6 +1,8 @@
export enum BookType {
// 原创
ORIGINAL = 'original',
// 区分老版本的原创
NEW_ORIGINAL = 'new_original',
// 反推
SD_REVERSE = 'sd_reverse',
// MJ 反推
@@ -14,7 +16,11 @@ export enum BookImageCategory {
// SD
SD = 'sd',
// D3
D3 = 'd3'
D3 = 'd3',
// FLUX API
FLUX_API = 'flux-api',
// FLUX FORGE
FLUX_FORGE = 'flux-forge'
}
export enum AddBookTaskCopyData {
@@ -67,6 +73,10 @@ export enum BookBackTaskType {
MJ_IMAGE = 'mj_image',
// SD 生成图片
SD_IMAGE = 'sd_image',
// flux forge 生成图片
FLUX_FORGE_IMAGE = 'flux_forge_image',
// flux api 生成图片
FLUX_API_IMAGE = 'flux_api_image',
// D3 生成图片
D3_IMAGE = 'd3_image',
// 高清
@@ -256,3 +266,13 @@ export enum BookRepalceDataType {
// 提示词
PROMPT = 'prompt',
}
/**
* 小说选择标签的方式类型,可以是下拉和标签
*/
export enum BookTagSelectType {
// 下拉
DROP = 'drop',
// 标签
TAG = 'tag'
}
+26
View File
@@ -0,0 +1,26 @@
/**
* Flux 调用API时候的 生图模型
*/
export enum FLxuAPIImageType {
FLUX = "flux",
FLUX_PRO = "flux-pro",
FLUX_DEV = "flux-dev",
FLUX_SCHNELL = "flux-schnell",
FLUX_PRO_MAX = "flux-pro-max"
}
export enum PresetType {
// 角色
CHARACTER = 'character',
// 本地风格
LOCAL_STYLE = 'localStyle',
// 自定义风格
CUSTOM_STYLE = 'customStyle',
// laitool预设风格
LAITOOL_STYLE = 'laitoolStyle',
}
+10 -1
View File
@@ -9,7 +9,16 @@ export enum MJImageType {
BROWSER_MJ = 'browser_mj',
// API模式
API_MJ = 'api_mj'
API_MJ = 'api_mj',
// 本地 SD
LOCAL_SD = 'local_sd',
// flux-api
FLUX_API = 'flux-api',
// flxu-forge
FLUX_FORGE = 'flux-forge'
}
export enum MJRobotType {
+16
View File
@@ -0,0 +1,16 @@
/**
* 标签库预设的图片样式类型
*/
export enum PresetType {
// 角色
CHARACTER = 'character',
// 本地风格
LOCAL_STYLE = 'localStyle',
// 自定义风格
CUSTOM_STYLE = 'customStyle',
// laitool预设风格
LAITOOL_STYLE = 'laitoolStyle',
}
+260 -230
View File
@@ -1,245 +1,275 @@
import { Tools } from "../../main/tools";
import { define } from "../define";
import path from "path";
import { DEFINE_STRING } from "../define_string";
import { get, has } from "lodash";
let tools = new Tools();
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
import { Tools } from '../../main/tools'
import { define } from '../define'
import path from 'path'
import { DEFINE_STRING } from '../define_string'
import { get, has } from 'lodash'
let tools = new Tools()
const { v4: uuidv4 } = require('uuid') // 引入UUID库来生成唯一标识符
export const ImageSetting = {
/**
* 获取自动保存图片的方式
* @returns
*/
async GetAutoSaveImageClassifyOptions() {
return {
code: 1,
data: [{
label: "不分类",
value: "one"
},
// {
// label: "按模型",
// value: "model"
// },
{
label: "按风格",
value: "style"
},
{
label: "风格+模型",
value: "theme"
}]
/**
* 获取自动保存图片的方式
* @returns
*/
async GetAutoSaveImageClassifyOptions() {
return {
code: 1,
data: [
{
label: '不分类',
value: 'one'
},
// {
// label: "按模型",
// value: "model"
// },
{
label: '按风格',
value: 'style'
},
{
label: '风格+模型',
value: 'theme'
}
},
]
}
},
/**
* 获取自动保存图片的方式(sd,mj,d3 等)
*/
async GetImageGenerateCategory() {
return {
code: 1,
data: [{
label: "SD",
value: "sd"
/**
* 获取自动保存图片的方式(sd,mj,d3 等)
*/
async GetImageGenerateCategory() {
return {
code: 1,
data: [
{
label: 'SD',
value: 'sd'
},
{
label: 'MJ',
value: 'mj'
},
{
label: 'D3',
value: 'd3'
},
{
label: 'Flux-Forge',
value: 'flux-forge'
},
{
label: 'Flux-API',
value: 'flux-api'
}
]
}
},
/**
* 保存自动保存图片的设置
*/
async SaveImageAutoSaveSetting(value) {
try {
value = JSON.parse(value)
await tools.writeJsonFilePropertyValue(define.img_base, 'auto_save_image', value)
return {
code: 1
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
},
/**
* 保存自动保存图片的设置
*/
async GetImageAutoSaveSetting() {
try {
let res = await tools.getJsonFilePropertyValue(define.img_base, 'auto_save_image', {}, false)
return {
code: 1,
data: res
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
},
/**
* 保存图片到指定文件夹,只是将任务添加到队列中
*/
async SaveImageToOtherFolder(output = [], value) {
try {
let show = false
if (value) {
value = JSON.parse(value)
show = false
} else {
let auto_save_image = await tools.getJsonFilePropertyValue(
define.img_base,
'auto_save_image',
{},
false
)
value = {
save_match_count: auto_save_image.save_match_count,
save_folder: auto_save_image.main_save_folder
}
if (!auto_save_image.auto_save) {
return {
code: 1
}
}
}
let batch = DEFINE_STRING.QUEUE_BATCH.IMAGE_SAVE_TO_OTHER_FOLDER
// 获取当前的所有的output文件夹
if (output.length == 0) {
output = await tools.getSubFolderList(
path.join(global.config.project_path, 'tmp/bak/'),
'start',
'output_crop_'
)
}
for (let i = 0; i < output.length; i++) {
const element = path.join(global.config.project_path, 'tmp/bak/' + output[i])
// 获取指定的文件夹里面的文件
let png_files = await tools.getFilesWithExtensions(element, '.png')
console.log(png_files)
// 判断当前的png_files中的数据是不是大于value.save_match_count,大于的话,删除数组里面的数据
if (value.save_match_count && png_files.length > value.save_match_count) {
// 删除数组
png_files.splice(value.save_match_count)
}
for (let j = 0; j < png_files.length; j++) {
const item = png_files[j]
global.fileQueue.enqueue(
async () => {
// 复制文件到指定的文件夹
let dst = path.join(
value.save_folder,
`${Date.now().toString()}_${uuidv4().split('-')[0]}.png`
)
await tools.copyFileOrDirectory(item, dst)
},
{
label: "MJ",
value: "mj"
},
{
label: "D3",
value: "d3"
}]
`${batch}_${item}`,
batch
)
}
},
/**
* 保存自动保存图片的设置
*/
async SaveImageAutoSaveSetting(value) {
try {
value = JSON.parse(value);
await tools.writeJsonFilePropertyValue(define.img_base, "auto_save_image", value);
return {
code: 1,
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
},
/**
* 保存自动保存图片的设置
*/
async GetImageAutoSaveSetting() {
try {
let res = await tools.getJsonFilePropertyValue(define.img_base, "auto_save_image", {}, false);
return {
code: 1,
data: res
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
},
/**
* 保存图片到指定文件夹,只是将任务添加到队列中
*/
async SaveImageToOtherFolder(output = [], value) {
try {
let show = false;
if (value) {
value = JSON.parse(value);
show = false;
} else {
let auto_save_image = await tools.getJsonFilePropertyValue(define.img_base, "auto_save_image", {}, false);
value = {
save_match_count: auto_save_image.save_match_count,
save_folder: auto_save_image.main_save_folder
}
if (!auto_save_image.auto_save) {
return {
code: 1
}
}
}
let batch = DEFINE_STRING.QUEUE_BATCH.IMAGE_SAVE_TO_OTHER_FOLDER;
// 获取当前的所有的output文件夹
if (output.length == 0) {
output = await tools.getSubFolderList(path.join(global.config.project_path, "tmp/bak/"), "start", "output_crop_");
}
for (let i = 0; i < output.length; i++) {
const element = path.join(global.config.project_path, 'tmp/bak/' + output[i]);
// 获取指定的文件夹里面的文件
let png_files = await tools.getFilesWithExtensions(element, ".png");
console.log(png_files);
// 判断当前的png_files中的数据是不是大于value.save_match_count,大于的话,删除数组里面的数据
if (value.save_match_count && png_files.length > value.save_match_count) {
// 删除数组
png_files.splice(value.save_match_count);
}
for (let j = 0; j < png_files.length; j++) {
const item = png_files[j];
global.fileQueue.enqueue(async () => {
// 复制文件到指定的文件夹
let dst = path.join(value.save_folder, `${Date.now().toString()}_${uuidv4().split('-')[0]}.png`);
await tools.copyFileOrDirectory(item, dst);
}, `${batch}_${item}`, batch)
}
}
global.fileQueue.setBatchCompletionCallback(batch, (failedTasks) => {
if (failedTasks.length > 0) {
let message = `
}
global.fileQueue.setBatchCompletionCallback(batch, (failedTasks) => {
if (failedTasks.length > 0) {
let message = `
转存任务都已完成。
但是以下任务执行失败:
`
failedTasks.forEach(({ taskId, error }) => {
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
});
failedTasks.forEach(({ taskId, error }) => {
message += `${taskId}-, \n 错误信息: ${error}` + '\n'
})
global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 0,
message: message
})
} else {
if (show) {
global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 1,
message: "所有图片转存完成"
})
}
}
global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 0,
message: message
})
} else {
if (show) {
global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 1,
message: '所有图片转存完成'
})
return {
code: 1
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
},
})
/**
* 获取指定的配置文件里面指定的属性的数据
* @param {*} value 执行方法必要的信息
* 0 define中的指定属性(指定的配置文件)
* 1 要获取的什么属性信息 propertyproperty 为null,赶回当前配置文件的所有数据
* 2 是不是要校验属性不存在
* 3 属性没有找到的默认值
* @returns
*/
async GetDefineConfigJsonByProperty(value) {
try {
value = JSON.parse(value);
let defin_property = value[0];
let property = value[1];
let need_check = value[2];
let default_data = value[3];
// 判断define中的属性是不是存在
let hasProperty = has(define, defin_property);
if (!hasProperty) {
throw new Error(`${defin_property} 属性不存在。`);
}
let data = await tools.getJsonFilePropertyValue(define[defin_property], property, default_data, need_check);
return {
code: 1,
data: data
}
} catch (error) {
return {
code: 0,
message: "获取配置信息失败,错误信息入下 : " + error.message.toString()
}
}
},
/**
* 保存指定的配置文件里面指定的属性的数据
* @param {*} value
* 0 define中的指定属性(指定的配置文件)
* 1 要获取的什么属性信息 propertyproperty 为null,赶回当前配置文件的所有数据
* 2 要写入的值
* 3 是不是要校验属性不存在
*/
async SaveDefineConfigJsonByProperty(value) {
try {
value = JSON.parse(value);
let defin_property = value[0];
let property = value[1];
let data = value[2];
let need_check = value[3] ? value[3] : false;
// 判断define中的属性是不是存在
let hasProperty = has(define, defin_property);
if (!hasProperty) {
throw new Error(`${defin_property} 属性不存在。`);
}
await tools.writeJsonFilePropertyValue(define[defin_property], property, data, need_check);
return {
code: 1,
message: "保存指定的配置成功"
}
} catch (error) {
return {
code: 0,
message: "保存配置信息失败,错误信息入下 : " + error.message.toString()
}
}
return {
code: 1
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
},
}
/**
* 获取指定的配置文件里面指定的属性的数据
* @param {*} value 执行方法必要的信息
* 0 define中的指定属性(指定的配置文件)
* 1 要获取的什么属性信息 propertyproperty 为null,赶回当前配置文件的所有数据
* 2 是不是要校验属性不存在
* 3 属性没有找到的默认值
* @returns
*/
async GetDefineConfigJsonByProperty(value) {
try {
value = JSON.parse(value)
let defin_property = value[0]
let property = value[1]
let need_check = value[2]
let default_data = value[3]
// 判断define中的属性是不是存在
let hasProperty = has(define, defin_property)
if (!hasProperty) {
throw new Error(`${defin_property} 属性不存在。`)
}
let data = await tools.getJsonFilePropertyValue(
define[defin_property],
property,
default_data,
need_check
)
return {
code: 1,
data: data
}
} catch (error) {
return {
code: 0,
message: '获取配置信息失败,错误信息入下 : ' + error.message.toString()
}
}
},
/**
* 保存指定的配置文件里面指定的属性的数据
* @param {*} value
* 0 define中的指定属性(指定的配置文件)
* 1 要获取的什么属性信息 propertyproperty 为null,赶回当前配置文件的所有数据
* 2 要写入的值
* 3 是不是要校验属性不存在
*/
async SaveDefineConfigJsonByProperty(value) {
try {
value = JSON.parse(value)
let defin_property = value[0]
let property = value[1]
let data = value[2]
let need_check = value[3] ? value[3] : false
// 判断define中的属性是不是存在
let hasProperty = has(define, defin_property)
if (!hasProperty) {
throw new Error(`${defin_property} 属性不存在。`)
}
await tools.writeJsonFilePropertyValue(define[defin_property], property, data, need_check)
return {
code: 1,
message: '保存指定的配置成功'
}
} catch (error) {
return {
code: 0,
message: '保存配置信息失败,错误信息入下 : ' + error.message.toString()
}
}
}
}