V 3.2.1 2024.11.9
1. (聚合推文)修复原创默认出图方式设置默认值 2. (聚合推文)优化出图显示 3. (聚合推文)添加图片上传功能,包括主图和选图区域 4. (聚合推文)新增图片缓存区,上传缓存图片(主图和选图区的图片),可以直接在当前小说所有的批次中的分镜中调用(下载到主图和选图区) 5. (聚合推文)添加一键修脸开关 6. (聚合推文)原创添加一键锁定 7. (聚合推文)新增小说批次任务显示当前所属小说 8. (聚合推文)小说批次任务状态显示优化 9. (聚合推文)优化后台任务状态显示 10. (聚合推文)原创,反推 一键生图 修复
This commit is contained in:
parent
51deef0c09
commit
6fa58e4d94
13
package-lock.json
generated
13
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "laitool",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "laitool",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.1",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@alicloud/alimt20181012": "^1.2.0",
|
||||
@ -30,7 +30,7 @@
|
||||
"lodash": "^4.17.21",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"music-metadata": "^7.14.0",
|
||||
"node-edge-tts": "^1.2.3",
|
||||
"node-edge-tts": "^1.2.4",
|
||||
"node-machine-id": "^1.1.12",
|
||||
"npm": "^10.7.0",
|
||||
"pinia": "^2.1.7",
|
||||
@ -6274,9 +6274,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/node-edge-tts": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/node-edge-tts/-/node-edge-tts-1.2.3.tgz",
|
||||
"integrity": "sha512-ug2osAv7qihpbcuuhWWrnDbqDZ0q7AcIHtRumQ/PJaXV6QR2sI/1bBlUWLNk0tTF6Y6CWCYuBoHYYBQztRterg==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmmirror.com/node-edge-tts/-/node-edge-tts-1.2.4.tgz",
|
||||
"integrity": "sha512-6IvNVJz+pFmgMuGGAew0MlhfexgakXGH11pXZtqfMR/l+afhK0XxxUIEOf3MEJQ8vhR3jeXEECOSW9w4LjX7Fw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"ws": "^8.13.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "laitool",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.1",
|
||||
"description": "An AI tool for image processing, video processing, and other functions.",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "laitool.cn",
|
||||
@ -38,7 +38,7 @@
|
||||
"lodash": "^4.17.21",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"music-metadata": "^7.14.0",
|
||||
"node-edge-tts": "^1.2.3",
|
||||
"node-edge-tts": "^1.2.4",
|
||||
"node-machine-id": "^1.1.12",
|
||||
"npm": "^10.7.0",
|
||||
"pinia": "^2.1.7",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 1011 KiB |
Binary file not shown.
Binary file not shown.
@ -11,9 +11,9 @@ const fspromises = fs.promises
|
||||
* @param {*} path 文件或目录的路径
|
||||
* @returns true表示存在,false表示不存在
|
||||
*/
|
||||
export async function CheckFileOrDirExist(path) {
|
||||
export async function CheckFileOrDirExist(filePath) {
|
||||
try {
|
||||
await fspromises.access(path)
|
||||
await fspromises.access(filePath)
|
||||
return true // 文件或目录存在
|
||||
} catch (error) {
|
||||
return false // 文件或目录不存在
|
||||
|
||||
@ -49,7 +49,8 @@ export class BookTaskModel extends Realm.Object<BookTaskModel> {
|
||||
backgroundMusic: string | null // 背景音乐ID
|
||||
friendlyReminder: string | null // 友情提示
|
||||
imageFolder: string | null
|
||||
imageStyle: string[] | null // 软件内置的样式
|
||||
imageStyle: string | null // 软件内置的样式
|
||||
cacheImageList: string[] | null // 缓存的图片列表
|
||||
autoAnalyzeCharacter: string | null // 自动分析角色设置
|
||||
customizeImageStyle: string[] | null // 自定义的样式
|
||||
videoConfig: string | null // 合成视频设置
|
||||
@ -80,6 +81,7 @@ export class BookTaskModel extends Realm.Object<BookTaskModel> {
|
||||
friendlyReminder: 'string?',
|
||||
imageFolder: 'string?',
|
||||
subImageFolder: "string?[]",
|
||||
cacheImageList: 'string?[]',
|
||||
imageStyle: 'string?[]',
|
||||
autoAnalyzeCharacter: 'string?',
|
||||
customizeImageStyle: 'string?[]',
|
||||
|
||||
@ -9,7 +9,7 @@ import { BaseRealmService } from './bookBasic'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { OtherData } from '../../../enum/softwareEnum.js'
|
||||
import { BookBackTaskList } from '../../model/Book/BookBackTaskListModel.js'
|
||||
import { Book } from '../../../../model/book.js'
|
||||
import { Book } from '../../../../model/book/book.js'
|
||||
import { GeneralResponse } from '../../../../model/generalResponse.js'
|
||||
const { v4: uuidv4 } = require('uuid')
|
||||
|
||||
|
||||
@ -197,6 +197,13 @@ const migration = (oldRealm: Realm, newRealm: Realm) => {
|
||||
newBookTask[i].draftDepend = ''
|
||||
}
|
||||
}
|
||||
if (oldRealm.schemaVersion < 29) {
|
||||
const oldBookTask = oldRealm.objects('BookTask')
|
||||
const newBookTask = newRealm.objects('BookTask')
|
||||
for (let i = 0; i < oldBookTask.length; i++) {
|
||||
newBookTask[i].cacheImageList = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class BaseRealmService extends BaseService {
|
||||
@ -238,7 +245,7 @@ export class BaseRealmService extends BaseService {
|
||||
BookTaskDetailModel
|
||||
],
|
||||
path: this.dbpath,
|
||||
schemaVersion: 27,
|
||||
schemaVersion: 29,
|
||||
migration: migration
|
||||
}
|
||||
this.realm = await Realm.open(config)
|
||||
|
||||
@ -10,7 +10,7 @@ import { BaseRealmService } from './bookBasic.js'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { FfmpegOptions } from '../../../../main/Service/ffmpegOptions.js'
|
||||
import { version } from '../../../../../package.json'
|
||||
import { Book } from '../../../../model/book.js'
|
||||
import { Book } from '../../../../model/book/book.js'
|
||||
import { GeneralResponse } from '../../../../model/generalResponse.js'
|
||||
|
||||
export class BookService extends BaseRealmService {
|
||||
@ -205,7 +205,7 @@ export class BookService extends BaseRealmService {
|
||||
} else if (book.type == BookType.MJ_REVERSE) {
|
||||
imageCategory = BookImageCategory.MJ
|
||||
} else if (book.type == BookType.ORIGINAL) {
|
||||
imageCategory = global.config.defaultImageMode
|
||||
imageCategory = global.config.defaultImageMode ?? BookImageCategory.MJ
|
||||
} else {
|
||||
throw new Error('未知的小说类型')
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ 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 { Book } from "../../../../model/book/book"
|
||||
import { GeneralResponse } from '../../../../model/generalResponse.js'
|
||||
|
||||
let dbPath = path.resolve(define.db_path, 'book.realm')
|
||||
|
||||
@ -8,7 +8,7 @@ import { BaseRealmService } from './bookBasic'
|
||||
import { JoinPath } from '../../../Tools/file'
|
||||
import { BookBackTaskList } from '../../model/Book/BookBackTaskListModel.js'
|
||||
const { v4: uuidv4 } = require('uuid')
|
||||
import { Book } from '../../../../model/book'
|
||||
import { Book } from '../../../../model/book/book'
|
||||
import { TagDefine } from '../../../tagDefine.js'
|
||||
import { ImageStyleDefine } from "../../../../define/iamgeStyleDefine"
|
||||
import { cloneDeep } from 'lodash'
|
||||
@ -89,6 +89,7 @@ export class BookTaskService extends BaseRealmService {
|
||||
srtPath: JoinPath(define.project_path, bookTask.srtPath),
|
||||
audioPath: JoinPath(define.project_path, bookTask.audioPath),
|
||||
imageFolder: JoinPath(define.project_path, bookTask.imageFolder),
|
||||
cacheImageList: bookTask.cacheImageList ? Array.from(bookTask.cacheImageList).map(item => JoinPath(define.project_path, item)) : [],
|
||||
imageCategory: bookTask.imageCategory ? bookTask.imageCategory : BookImageCategory.MJ, // 默认使用MJ出图
|
||||
} as Book.SelectBookTask;
|
||||
})
|
||||
|
||||
@ -150,7 +150,9 @@ define['hkServerUrl'] = 'https://laitool.net/'
|
||||
define['bakServerUrl'] = 'https://laitool.net/'
|
||||
define['API'] = 'f85d39ed5a40fd09966f13f12b6cf0f0'
|
||||
|
||||
define['lms'] =
|
||||
process.env.NODE_ENV == 'development' ? 'https://localhost:44362' : 'https://lms.laitool.cn'
|
||||
// define['lms'] =
|
||||
// process.env.NODE_ENV == 'development' ? 'https://localhost:44362' : 'https://lms.laitool.cn'
|
||||
|
||||
define['lms'] = 'https://lms.laitool.cn'
|
||||
|
||||
export { define }
|
||||
|
||||
@ -107,6 +107,18 @@ const BOOK = {
|
||||
/** 添加一键生图后台任务 */
|
||||
GENERATE_ALL_TASK_IMAGE: "GENERATE_ALL_TASK_IMAGE",
|
||||
|
||||
/** 上传图片到小说中,并修改小说信息 */
|
||||
UPLOAD_IMAGE_TO_BOOK_AND_UPDATE_MESSAGE: "UPLOAD_IMAGE_TO_BOOK_AND_UPDATE_MESSAGE",
|
||||
|
||||
/** 上传图片到缓存 */
|
||||
UPLOAD_IMAGE_TO_CACHE: "UPLOAD_IMAGE_TO_CACHE",
|
||||
|
||||
/** 获取当前小说中的所有的批次中的缓存图片 */
|
||||
GET_ALL_BOOK_TASK_IMAGE_CACHE: "GET_ALL_BOOK_TASK_IMAGE_CACHE",
|
||||
|
||||
/** 保存缓存区的屠图片到小说主图或者是选图区 */
|
||||
SAVE_CACHE_IMAGE_TO_DATA: "SAVE_CACHE_IMAGE_TO_DATA",
|
||||
|
||||
//#endregion
|
||||
|
||||
COMPUTE_STORYBOARD: 'COMPUTE_STORYBOARD',
|
||||
|
||||
@ -10,5 +10,11 @@ export const SYSTEM = {
|
||||
/** 检查机器码状态 */
|
||||
CHECK_MACHINE_STATUS: "CHECK_MACHINE_STATUS",
|
||||
/** 获取软件版本信息,更新信息,首页内容,公告等 */
|
||||
GET_REMOTE_SYSTEM_INFORMATION: 'GET_REMOTE_SYSTEM_INFORMATION'
|
||||
GET_REMOTE_SYSTEM_INFORMATION: 'GET_REMOTE_SYSTEM_INFORMATION',
|
||||
|
||||
/** 选择单个指定文件后缀的文件 */
|
||||
SELECT_SINGLE_FILE: "SELECT_SINGLE_FILE",
|
||||
|
||||
/** 选择多个指定文件后缀的文件 */
|
||||
SELECT_MULTIPLE_FILE: "SELECT_MULTIPLE_FILE",
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
import { TaskModal } from "@/model/task";
|
||||
|
||||
export enum BookType {
|
||||
// 原创
|
||||
ORIGINAL = 'original',
|
||||
@ -333,70 +335,194 @@ export function GetBookBackTaskTypeLabel(key: string) {
|
||||
* @param key
|
||||
* @returns
|
||||
*/
|
||||
export function GetBookTaskDetailStatusLabel(key: string) {
|
||||
export function GetBookTaskDetailStatusLabel(key: string): TaskModal.TaskStatus {
|
||||
switch (key) {
|
||||
case BookTaskStatus.WAIT:
|
||||
return '等待';
|
||||
return {
|
||||
status: BookTaskStatus.WAIT,
|
||||
label: '等待',
|
||||
type: 'warning'
|
||||
};
|
||||
case BookTaskStatus.STORYBOARD:
|
||||
return '分镜计算中';
|
||||
return {
|
||||
status: BookTaskStatus.STORYBOARD,
|
||||
label: '分镜计算中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.STORYBOARD_FAIL:
|
||||
return '分镜计算失败';
|
||||
return {
|
||||
status: BookTaskStatus.STORYBOARD_FAIL,
|
||||
label: '分镜计算失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.STORYBOARD_DONE:
|
||||
return '分镜计算完成';
|
||||
return {
|
||||
status: BookTaskStatus.STORYBOARD_DONE,
|
||||
label: '分镜计算完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.SPLIT:
|
||||
return '分割视频中';
|
||||
return {
|
||||
status: BookTaskStatus.SPLIT,
|
||||
label: '分割视频中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.SPLIT_FAIL:
|
||||
return '分割视频失败';
|
||||
return {
|
||||
status: BookTaskStatus.SPLIT_FAIL,
|
||||
label: '分割视频失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.SPLIT_DONE:
|
||||
return '分割视频完成';
|
||||
return {
|
||||
status: BookTaskStatus.SPLIT_DONE,
|
||||
label: '分割视频完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.AUDIO:
|
||||
return '提取音频中';
|
||||
return {
|
||||
status: BookTaskStatus.AUDIO,
|
||||
label: '提取音频中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.AUDIO_FAIL:
|
||||
return '提取音频失败';
|
||||
return {
|
||||
status: BookTaskStatus.AUDIO_FAIL,
|
||||
label: '提取音频失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.AUDIO_DONE:
|
||||
return '提取音频完成';
|
||||
return {
|
||||
status: BookTaskStatus.AUDIO_DONE,
|
||||
label: '提取音频完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.RECOGNIZE:
|
||||
return '识别字幕中';
|
||||
return {
|
||||
status: BookTaskStatus.RECOGNIZE,
|
||||
label: '识别字幕中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.RECOGNIZE_FAIL:
|
||||
return '识别字幕失败';
|
||||
return {
|
||||
status: BookTaskStatus.RECOGNIZE_FAIL,
|
||||
label: '识别字幕失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.RECOGNIZE_DONE:
|
||||
return '识别字幕完成';
|
||||
return {
|
||||
status: BookTaskStatus.RECOGNIZE_DONE,
|
||||
label: '识别字幕完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.FRAME:
|
||||
return '抽帧中';
|
||||
return {
|
||||
status: BookTaskStatus.FRAME,
|
||||
label: '抽帧中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.FRAME_FAIL:
|
||||
return '抽帧失败';
|
||||
return {
|
||||
status: BookTaskStatus.FRAME_FAIL,
|
||||
label: '抽帧失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.FRAME_DONE:
|
||||
return '抽帧完成';
|
||||
return {
|
||||
status: BookTaskStatus.FRAME_DONE,
|
||||
label: '抽帧完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.REVERSE:
|
||||
return '反推中';
|
||||
return {
|
||||
status: BookTaskStatus.REVERSE,
|
||||
label: '反推中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.REVERSE_FAIL:
|
||||
return '反推失败';
|
||||
return {
|
||||
status: BookTaskStatus.REVERSE_FAIL,
|
||||
label: '反推失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.REVERSE_DONE:
|
||||
return '反推完成';
|
||||
return {
|
||||
status: BookTaskStatus.REVERSE_DONE,
|
||||
label: '反推完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.IMAGE:
|
||||
return '生成图片中';
|
||||
return {
|
||||
status: BookTaskStatus.IMAGE,
|
||||
label: '生成图片中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.IMAGE_FAIL:
|
||||
return '生成图片失败';
|
||||
return {
|
||||
status: BookTaskStatus.IMAGE_FAIL,
|
||||
label: '生成图片失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.IMAGE_DONE:
|
||||
return '生成图片完成';
|
||||
return {
|
||||
status: BookTaskStatus.IMAGE_DONE,
|
||||
label: '生成图片完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.HD:
|
||||
return '高清中';
|
||||
return {
|
||||
status: BookTaskStatus.HD,
|
||||
label: '高清中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.HD_FAIL:
|
||||
return '高清失败';
|
||||
return {
|
||||
status: BookTaskStatus.HD_FAIL,
|
||||
label: '高清失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.HD_DONE:
|
||||
return '高清完成';
|
||||
return {
|
||||
status: BookTaskStatus.HD_DONE,
|
||||
label: '高清完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.COMPOSING:
|
||||
return '合成视频中';
|
||||
return {
|
||||
status: BookTaskStatus.COMPOSING,
|
||||
label: '合成视频中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookTaskStatus.COMPOSING_FAIL:
|
||||
return '合成视频失败';
|
||||
return {
|
||||
status: BookTaskStatus.COMPOSING_FAIL,
|
||||
label: '合成视频失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookTaskStatus.COMPOSING_DONE:
|
||||
return '合成视频完成';
|
||||
return {
|
||||
status: BookTaskStatus.COMPOSING_DONE,
|
||||
label: '合成视频完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.DRAFT_DONE:
|
||||
return '添加草稿完成';
|
||||
return {
|
||||
status: BookTaskStatus.DRAFT_DONE,
|
||||
label: '添加草稿完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookTaskStatus.DRAFT_FAIL:
|
||||
return '添加草稿失败';
|
||||
return {
|
||||
status: BookTaskStatus.DRAFT_FAIL,
|
||||
label: '添加草稿失败',
|
||||
type: 'error'
|
||||
};
|
||||
default:
|
||||
return key;
|
||||
return {
|
||||
status: "UNKNOWN",
|
||||
label: "UNKNOWN",
|
||||
type: 'warning'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,21 +531,50 @@ export function GetBookTaskDetailStatusLabel(key: string) {
|
||||
* @param key
|
||||
* @returns
|
||||
*/
|
||||
export function GetBookBackTaskStatusLabel(key: string) {
|
||||
export function GetBookBackTaskStatusLabel(key: string): TaskModal.TaskStatus {
|
||||
|
||||
switch (key) {
|
||||
case BookBackTaskStatus.WAIT:
|
||||
return '等待';
|
||||
return {
|
||||
status: BookBackTaskStatus.WAIT,
|
||||
label: '等待',
|
||||
type: 'warning'
|
||||
};
|
||||
case BookBackTaskStatus.RUNNING:
|
||||
return '运行中';
|
||||
return {
|
||||
status: BookBackTaskStatus.RUNNING,
|
||||
label: '运行中',
|
||||
type: 'info'
|
||||
};
|
||||
case BookBackTaskStatus.PAUSE:
|
||||
return '暂停';
|
||||
return {
|
||||
status: BookBackTaskStatus.PAUSE,
|
||||
label: '暂停',
|
||||
type: 'warning'
|
||||
};
|
||||
case BookBackTaskStatus.DONE:
|
||||
return '完成';
|
||||
return {
|
||||
status: BookBackTaskStatus.DONE,
|
||||
label: '完成',
|
||||
type: 'success'
|
||||
};
|
||||
case BookBackTaskStatus.FAIL:
|
||||
return '失败';
|
||||
return {
|
||||
status: BookBackTaskStatus.FAIL,
|
||||
label: '失败',
|
||||
type: 'error'
|
||||
};
|
||||
case BookBackTaskStatus.RECONNECT:
|
||||
return '重连';
|
||||
return {
|
||||
status: BookBackTaskStatus.RECONNECT,
|
||||
label: '重连',
|
||||
type: 'warning'
|
||||
};
|
||||
default:
|
||||
return key;
|
||||
return {
|
||||
status: "UNKNOWN",
|
||||
label: "UNKNOWN",
|
||||
type: 'warning'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,6 +280,23 @@ export function BookIpc() {
|
||||
async (event, ids: string[], operateBookType: OperateBookType) => await bookImage.GenerateAllTaskImage(ids, operateBookType)
|
||||
)
|
||||
|
||||
/**上传图片到小说中,并修改小说信息 */
|
||||
ipcMain.handle(
|
||||
DEFINE_STRING.BOOK.UPLOAD_IMAGE_TO_BOOK_AND_UPDATE_MESSAGE,
|
||||
async (event, bookTaskDetailId: string, imageFile: string | string[], option: string) => await bookImage.UpLoadImageToBookAndUpdateMessage(bookTaskDetailId, imageFile, option)
|
||||
)
|
||||
|
||||
/** 上传图片到缓存 */
|
||||
ipcMain.handle(DEFINE_STRING.BOOK.UPLOAD_IMAGE_TO_CACHE,
|
||||
async (event, bookTaskId: string, imageFile: string | string[]) => await bookImage.UpLoadImageToCache(bookTaskId, imageFile)
|
||||
)
|
||||
|
||||
/** 获取当前小说中的所有的批次中的缓存图片 */
|
||||
ipcMain.handle(DEFINE_STRING.BOOK.GET_ALL_BOOK_TASK_IMAGE_CACHE, async (event, bookTaskId: string) => await bookImage.GetAllBookTaskImageCache(bookTaskId))
|
||||
|
||||
/** 保存缓存区的屠图片到小说主图或者是选图区 */
|
||||
ipcMain.handle(DEFINE_STRING.BOOK.SAVE_CACHE_IMAGE_TO_DATA, async (event, bookTaskDetailId: string, imageFile: string | string[], option: string) => await bookImage.SaveCacheImageToData(bookTaskDetailId, imageFile, option))
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ipcMain } from 'electron'
|
||||
import { DEFINE_STRING } from '../../define/define_string'
|
||||
import { errorMessage, successMessage } from '../Public/generalTools'
|
||||
import { Book } from '../../model/book'
|
||||
import { Book } from '../../model/book/book'
|
||||
import { BookTaskService } from '../../define/db/service/Book/bookTaskService'
|
||||
import { BookTaskDetailService } from '../../define/db/service/Book/bookTaskDetailService'
|
||||
import { BookService } from '../../define/db/service/Book/bookService'
|
||||
|
||||
@ -28,5 +28,11 @@ function SystemIpc() {
|
||||
ipcMain.handle(DEFINE_STRING.SYSTEM.CHECK_MACHINE_STATUS, async (event, value: string) => await systemInfo.CheckMachineStatus(value))
|
||||
/** 获取软件版本信息,更新信息,首页内容,公告等 */
|
||||
ipcMain.handle(DEFINE_STRING.SYSTEM.GET_REMOTE_SYSTEM_INFORMATION, async (event) => await systemInfo.GetRemoteSystemInformation())
|
||||
|
||||
/** 选择单个指定文件后缀的文件 */
|
||||
ipcMain.handle(DEFINE_STRING.SYSTEM.SELECT_SINGLE_FILE, async (event, value: string[]) => await electronInterface.SelectSingleFile(value))
|
||||
|
||||
/** 选择多个指定文件后缀的文件 */
|
||||
ipcMain.handle(DEFINE_STRING.SYSTEM.SELECT_MULTIPLE_FILE, async (event, value: string[]) => await electronInterface.SelectMultipleFile(value))
|
||||
}
|
||||
export { SystemIpc }
|
||||
|
||||
@ -7,7 +7,7 @@ import { GeneralResponse } from '../../../model/generalResponse'
|
||||
import { BookServiceBasic } from '../ServiceBasic/bookServiceBasic'
|
||||
import { BookTask } from './bookTask'
|
||||
import fs from 'fs'
|
||||
import { Book } from '../../../model/book'
|
||||
import { Book } from '../../../model/book/book'
|
||||
|
||||
export class BookBasic {
|
||||
bookServiceBasic: BookServiceBasic
|
||||
|
||||
@ -9,7 +9,7 @@ import path from 'path'
|
||||
import { BasicReverse } from './basicReverse'
|
||||
import { BookTaskDetailService } from '../../../define/db/service/Book/bookTaskDetailService'
|
||||
import { LogScheduler } from "../task/logScheduler"
|
||||
import { Book } from '../../../model/book'
|
||||
import { Book } from '../../../model/book/book'
|
||||
import { LoggerStatus, OtherData, ResponseMessageType } from '../../../define/enum/softwareEnum'
|
||||
import { GeneralResponse } from '../../../model/generalResponse'
|
||||
import { Subtitle } from '../Subtitle/subtitle'
|
||||
|
||||
@ -21,7 +21,7 @@ import {
|
||||
BookType,
|
||||
TaskExecuteType
|
||||
} from '../../../define/enum/bookEnum'
|
||||
import { Book } from '../../../model/book'
|
||||
import { Book } from '../../../model/book/book'
|
||||
import { GeneralResponse } from '../../../model/generalResponse'
|
||||
|
||||
const fspromises = fs.promises
|
||||
|
||||
@ -6,7 +6,7 @@ import path from 'path';
|
||||
import { FfmpegOptions } from "../ffmpegOptions";
|
||||
import { CheckFileOrDirExist, CopyFileOrFolder, DeleteFolderAllFile } from "../../../define/Tools/file";
|
||||
import fs from 'fs';
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { LogScheduler } from '../task/logScheduler';
|
||||
import { BookBasic } from "./BooKBasic";
|
||||
import { LoggerStatus, OtherData } from "../../../define/enum/softwareEnum";
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { isEmpty } from "lodash";
|
||||
import { BookRepalceDataType } from "../../../define/enum/bookEnum";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { GeneralResponse } from "../../../model/generalResponse";
|
||||
import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { BookBackTaskType, BookImageCategory, BookType, MJAction, OperateBookType, TaskExecuteType } from "../../../define/enum/bookEnum";
|
||||
import { GeneralResponse } from "../../../model/generalResponse";
|
||||
import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import path from 'path'
|
||||
import { Tools } from "../../../main/tools"
|
||||
import { ImageSplit } from "../../../define/Tools/image";
|
||||
@ -263,7 +263,7 @@ export class BookImage {
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region 将指定的批次任务,添加里面的所有的分镜到出图任务中
|
||||
/**
|
||||
* 将指定的批次任务,添加里面的所有的分镜到出图任务中
|
||||
* @param ids 批次任务ID
|
||||
@ -344,6 +344,9 @@ export class BookImage {
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 生成所有的图片,这个方法主要是分流,根据批次生成的方式,添加对应的数据
|
||||
/**
|
||||
* 生成所有的图片,这个方法主要是分流,根据批次生成的方式,添加对应的数据
|
||||
* @param bookTaskId
|
||||
@ -369,6 +372,8 @@ export class BookImage {
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 对图片进行锁定或者是解锁操作
|
||||
/**
|
||||
* 对图片进行锁定或者是解锁操作
|
||||
@ -583,4 +588,208 @@ export class BookImage {
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region 上传图片到小说中,并修改小说信息
|
||||
|
||||
/**
|
||||
* 上传并修改一个
|
||||
* @param bookTaskDetailId
|
||||
* @param imageFile
|
||||
* @param option
|
||||
*/
|
||||
private async UploadOne(bookTaskDetailId: string, imageFile: string, option: string): Promise<string> {
|
||||
console.log('开始上传图片', bookTaskDetailId, imageFile, option)
|
||||
if (!await CheckFileOrDirExist(path.resolve(imageFile))) {
|
||||
throw new Error(`图片文件 ${imageFile} 不存在,请检查`)
|
||||
}
|
||||
// 修改数据库数据
|
||||
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(bookTaskDetailId);
|
||||
// 将图片复制到对应的文件夹中
|
||||
// 生成一个0-10的随机数
|
||||
let random = Math.floor(Math.random() * 10);
|
||||
let newImagePath = path.join(define.project_path, `${bookTaskDetail.bookId}/data/Upload/${bookTaskDetail.name}_${Date.now()}_${random}.png`);
|
||||
await CheckFolderExistsOrCreate(path.dirname(newImagePath));
|
||||
await CopyFileOrFolder(imageFile, newImagePath);
|
||||
if (option == "outImagePath") {
|
||||
let outImagePath = bookTaskDetail.outImagePath;
|
||||
let bookTask = await this.bookServiceBasic.GetBookTaskDataById(bookTaskDetail.bookTaskId);
|
||||
if (isEmpty(bookTaskDetail.outImagePath)) {
|
||||
outImagePath = path.join(define.project_path, `${bookTaskDetail.bookId}/tmp/${bookTask.name}/${bookTaskDetail.name}.png`);
|
||||
}
|
||||
await CheckFolderExistsOrCreate(path.dirname(outImagePath));
|
||||
await CopyFileOrFolder(newImagePath, outImagePath);
|
||||
await this.bookServiceBasic.UpdateBookTaskDetail(bookTaskDetailId, {
|
||||
outImagePath: path.relative(define.project_path, outImagePath)
|
||||
})
|
||||
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(bookTaskDetailId, {
|
||||
progress: 100,
|
||||
status: 'success',
|
||||
category: MJImageType.IMPORT,
|
||||
messageId: '',
|
||||
action: MJAction.IMAGINE,
|
||||
})
|
||||
return outImagePath + '?t=' + new Date().getTime()
|
||||
} else if (option == "subImagePath") {
|
||||
// 修改数据库数据
|
||||
let subImagePath = bookTaskDetail.subImagePath ?? [];
|
||||
subImagePath.push(newImagePath);
|
||||
await this.bookServiceBasic.UpdateBookTaskDetail(bookTaskDetailId, {
|
||||
subImagePath: subImagePath.map((item) => path.relative(define.project_path, item))
|
||||
})
|
||||
return newImagePath + '?t=' + new Date().getTime()
|
||||
} else {
|
||||
throw new Error("无效的操作类型,请检查")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片到小说中,并修改小说信息
|
||||
* @param bookTaskDetailId 小说分镜ID
|
||||
* @param imageFile 图片文件地址
|
||||
* @param option 操作类型 "outImagePath" | "subImagePath"
|
||||
*/
|
||||
public async UpLoadImageToBookAndUpdateMessage(bookTaskDetailId: string, imageFile: string | string[], option: string): Promise<GeneralResponse.SuccessItem | GeneralResponse.ErrorItem> {
|
||||
try {
|
||||
if (option == "outImagePath") {
|
||||
let res = await this.UploadOne(bookTaskDetailId, imageFile as string, option)
|
||||
return successMessage(res, '上传图片,并修改小说信息成功', 'BookImage_UpLoadImageToBookAndUpdateMessage')
|
||||
} else if (option == "subImagePath") {
|
||||
let subImage = [] as string[]
|
||||
for (let i = 0; i < (imageFile as string[]).length; i++) {
|
||||
let res = await this.UploadOne(bookTaskDetailId, imageFile[i], option);
|
||||
subImage.push(res);
|
||||
}
|
||||
return successMessage(subImage as string[], '上传图片,并修改小说信息成功', 'BookImage_UpLoadImageToBookAndUpdateMessage')
|
||||
} else {
|
||||
throw new Error("无效的操作类型,请检查")
|
||||
}
|
||||
} catch (error) {
|
||||
return errorMessage('上传图片到小说中,并修改小说信息失败,错误信息如下:' + error.message, 'BookImage_UpLoadImageToBookAndUpdateMessage')
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region 上传图片到缓存区
|
||||
|
||||
/**
|
||||
* 上传单个图片到缓存区
|
||||
* @param bookTaskId 小说任务ID
|
||||
* @param imageFile 图片文件地址
|
||||
*/
|
||||
async UpLoadOneImageToCache(bookTaskId: string, imageFile: string): Promise<void> {
|
||||
let bookTask = await this.bookServiceBasic.GetBookTaskDataById(bookTaskId);
|
||||
let cacheImagePath = path.join(define.project_path, `${bookTask.bookId}/data/Cache/${Date.now()}_${Math.floor(Math.random() * 10)}.png`);
|
||||
imageFile = imageFile.split("?t=")[0];
|
||||
imageFile = imageFile.split("?time=")[0];
|
||||
if (imageFile.startsWith("file:/")) {
|
||||
imageFile = imageFile.replace("file:///", "");
|
||||
imageFile = imageFile.replace("file://", "");
|
||||
imageFile = imageFile.replace("file:/", "");
|
||||
}
|
||||
if (!await CheckFileOrDirExist(imageFile)) {
|
||||
throw new Error(`图片文件 ${imageFile} 不存在,请检查`)
|
||||
}
|
||||
await CheckFolderExistsOrCreate(path.dirname(cacheImagePath));
|
||||
await CopyFileOrFolder(imageFile, cacheImagePath);
|
||||
// 修改缓存区数据
|
||||
let cacheImageList = bookTask.cacheImageList ?? [];
|
||||
cacheImageList.push(cacheImagePath);
|
||||
await this.bookServiceBasic.UpdetedBookTaskData(bookTaskId, {
|
||||
cacheImageList: cacheImageList.map((item) => path.relative(define.project_path, item))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片到缓存区
|
||||
* @param bookTaskId
|
||||
* @param imageFile
|
||||
*/
|
||||
public async UpLoadImageToCache(bookTaskId: string, imageFile: string | string[]) {
|
||||
try {
|
||||
// 判断是不是一个数组
|
||||
if (imageFile instanceof Array) {
|
||||
for (let i = 0; i < imageFile.length; i++) {
|
||||
let image = imageFile[i];
|
||||
await this.UpLoadOneImageToCache(bookTaskId, image)
|
||||
}
|
||||
} else if (typeof imageFile === 'string') {
|
||||
await this.UpLoadOneImageToCache(bookTaskId, imageFile)
|
||||
} else {
|
||||
throw new Error('未知的数据类型,请检查')
|
||||
}
|
||||
return successMessage(null, '上传图片到缓存中成功', 'BookImage_UpLoadImageToCache')
|
||||
} catch (error) {
|
||||
return errorMessage('上传图片到缓存中失败,错误信息如下:' + error.message, 'BookImage_UpLoadImageToCache')
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 获取当前小说中的所有的批次中的缓存图片
|
||||
|
||||
/**
|
||||
* 获取当前小说中的所有的批次中的缓存图片
|
||||
* @param bookTaskId 小说任务ID
|
||||
* @returns
|
||||
*/
|
||||
public async GetAllBookTaskImageCache(bookTaskId: string) {
|
||||
try {
|
||||
if (isEmpty(bookTaskId)) {
|
||||
throw new Error('没有找到对应的批次任务,请检查')
|
||||
}
|
||||
|
||||
let bookTask = await this.bookServiceBasic.GetBookTaskDataById(bookTaskId);
|
||||
|
||||
let bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
||||
bookId: bookTask.bookId
|
||||
})).bookTasks;
|
||||
|
||||
if (bookTasks.length <= 0) {
|
||||
throw new Error('没有找到对应的批次任务,请检查')
|
||||
}
|
||||
let result = [] as BookTask.BookTaskImageCacheImageList[]
|
||||
for (let i = 0; i < bookTasks.length; i++) {
|
||||
const element = bookTasks[i];
|
||||
let cacheImageList = element.cacheImageList ?? [];
|
||||
if (cacheImageList.length > 0) {
|
||||
// 检查图片文件是不是存在,不存在移除
|
||||
let cacheImageListTemp = [] as string[]
|
||||
for (let i = 0; i < cacheImageList.length; i++) {
|
||||
const element = cacheImageList[i];
|
||||
if (await CheckFileOrDirExist(element)) {
|
||||
cacheImageListTemp.push(element)
|
||||
}
|
||||
}
|
||||
result.push({
|
||||
bookTaskName: element.name,
|
||||
bookId: element.bookId,
|
||||
bookTaskId: element.id,
|
||||
imagePaths: cacheImageListTemp
|
||||
})
|
||||
}
|
||||
}
|
||||
return successMessage(result, '获取当前小说中的所有的批次中的缓存图片成功', 'BookImage_GetAllBookTaskImageCache')
|
||||
|
||||
} catch (error) {
|
||||
return errorMessage('获取当前小说中的所有的批次中的缓存图片失败,错误信息如下:' + error.message, 'BookImage_GetAllBookTaskImageCache')
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region 保存缓存区的屠图片到小说主图或者是选图区
|
||||
|
||||
/**
|
||||
* 保存缓存区的屠图片到小说主图或者是选图区
|
||||
* @param bookTaskDetailId 小说分镜ID
|
||||
* @param imageFile 图片文件地址
|
||||
* @param option 操作 "outImagePath" (imageFile为字符串) | "subImagePath(imageFile为字符串数组)"
|
||||
* @returns
|
||||
*/
|
||||
async SaveCacheImageToData(bookTaskDetailId: string, imageFile: string | string[], option: string) {
|
||||
return await this.UpLoadImageToBookAndUpdateMessage(bookTaskDetailId, imageFile, option)
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { isEmpty } from "lodash";
|
||||
import { BookType, OperateBookType } from "../../../define/enum/bookEnum";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { GeneralResponse } from "../../../model/generalResponse";
|
||||
import { errorMessage, SendReturnMessage, successMessage } from "../../Public/generalTools";
|
||||
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { CheckFileOrDirExist, CheckFolderExistsOrCreate, CopyFileOrFolder, DeleteFolderAllFile } from "../../../define/Tools/file";
|
||||
import { AddBookTaskCopyData, BookImageCategory, BookTaskStatus, BookType, CopyImageType, OperateBookType } from "../../../define/enum/bookEnum";
|
||||
import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import path from 'path'
|
||||
import { add, cloneDeep, isEmpty } from "lodash";
|
||||
import { define } from '../../../define/define'
|
||||
@ -122,7 +122,7 @@ export class BookTask {
|
||||
async CopyBookTaskBaseData(bookTask: Book.SelectBookTask, addNewBookTask: Book.AddBookTask, no: number): Promise<Book.SelectBookTask> {
|
||||
let name = 'output_' + no.toString().padStart(5, '0');
|
||||
let imageFolder = path.join(define.project_path, `${bookTask.bookId}/tmp/${name}`);
|
||||
let imageCategory = global.config.defaultImageMode;
|
||||
let imageCategory = global.config.defaultImageMode ?? BookImageCategory.MJ;
|
||||
let book = await this.bookServiceBasic.GetBookDataById(bookTask.bookId)
|
||||
if (!isEmpty(bookTask.imageCategory)) {
|
||||
imageCategory = bookTask.imageCategory;
|
||||
@ -132,7 +132,7 @@ export class BookTask {
|
||||
} else if (book.type == BookType.SD_REVERSE) {
|
||||
imageCategory = BookImageCategory.SD
|
||||
} else if (book.type == BookType.ORIGINAL) {
|
||||
imageCategory = global.config.defaultImageMode
|
||||
imageCategory = global.config.defaultImageMode ?? BookImageCategory.MJ
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, OperateBookType, TaskExecuteType } from "../../../define/enum/bookEnum";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import { GeneralResponse } from "../../../model/generalResponse";
|
||||
import { Setting } from '../../../main/setting/setting'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { TagDefineType } from "../../../define/enum/bookEnum";
|
||||
import { ImageStyleDefine } from "../../../define/iamgeStyleDefine";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { GeneralResponse } from "../../../model/generalResponse";
|
||||
import { TagCustomize } from "../../Original/TagCustomize";
|
||||
import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||
|
||||
@ -2,7 +2,7 @@ import { isEmpty } from "lodash";
|
||||
import { gptDefine } from "../../../define/gptDefine";
|
||||
import axios from "axios";
|
||||
import { RetryWithBackoff } from "../../../define/Tools/common";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
|
||||
/**
|
||||
* 一些GPT相关的服务都在这边
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { isEmpty } from "lodash";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { checkStringValueAddPrefix, checkStringValueAddSuffix, errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import { CheckFolderExistsOrCreate, CopyFileOrFolder, JoinPath } from "../../../define/Tools/file";
|
||||
import { define } from "../../../define/define"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { GeneralResponse } from "../../../model/generalResponse";
|
||||
import { checkStringValueAddSuffix, errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import { define } from '../../../define/define'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { BookBackTaskStatus, BookBackTaskType, TaskExecuteType } from "../../../define/enum/bookEnum";
|
||||
import { BookBackTaskListService } from "../../../define/db/service/Book/bookBackTaskListService";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { TaskModal } from "@/model/task";
|
||||
import { cloneDeep, isEmpty } from "lodash";
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BookService } from "../../../define/db/service/Book/bookService";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
|
||||
export class BookBasic {
|
||||
bookService: BookService
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { DEFINE_STRING } from "../../../define/define_string";
|
||||
import { GeneralResponse } from "../../../model/generalResponse";
|
||||
import { BookService } from "../../../define/db/service/Book/bookService";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, TaskExecuteType } from "../../../define/enum/bookEnum";
|
||||
import BookBackTaskServiceBasic from "./bookBackTaskServiceBasic";
|
||||
import { BookBasic } from "./bookBasic";
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { BookTaskDetailService } from "../../../define/db/service/Book/bookTaskDetailService";
|
||||
import { BookTaskStatus } from "../../../define/enum/bookEnum";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { BookTaskService } from "../../../define/db/service/Book/bookTaskService";
|
||||
|
||||
export default class BookTaskDetailServiceBasic {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BookTaskService } from "../../../define/db/service/Book/bookTaskService";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { BookService } from "../../../define/db/service/Book/bookService";
|
||||
|
||||
export default class BookTaskServiceBasic {
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
GetFilesWithExtensions
|
||||
} from '../../../define/Tools/file'
|
||||
import { shell } from 'electron'
|
||||
import { Book } from '../../../model/book'
|
||||
import { Book } from '../../../model/book/book'
|
||||
import fs from 'fs'
|
||||
import { GeneralResponse } from '../../../model/generalResponse'
|
||||
import { BookServiceBasic } from '../ServiceBasic/bookServiceBasic'
|
||||
|
||||
@ -13,7 +13,7 @@ import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
|
||||
import { Subtitle } from "./subtitle";
|
||||
import { LogScheduler } from "../task/logScheduler";
|
||||
import { BookTaskStatus, BookType, OperateBookType } from "../../../define/enum/bookEnum";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { TimeStringToMilliseconds } from "../../../define/Tools/time";
|
||||
|
||||
export class SubtitleService {
|
||||
|
||||
@ -4,7 +4,7 @@ import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import { Translate } from "./Translate";
|
||||
import { DEFINE_STRING } from "../../../define/define_string"
|
||||
import { TranslateAPIType, TranslateType } from "../../../define/enum/translate";
|
||||
import { Book } from "../../../model/book";
|
||||
import { Book } from "../../../model/book/book";
|
||||
import { ResponseMessageType } from "../../../define/enum/softwareEnum";
|
||||
import { isEmpty } from "lodash";
|
||||
import { ValidateJson } from "../../../define/Tools/validate";
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { shell } from "electron";
|
||||
import { dialog, shell } from "electron";
|
||||
import { CheckFileOrDirExist } from "../../../define/Tools/file";
|
||||
import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||
import path from 'path';
|
||||
import { GeneralResponse } from "@/model/generalResponse";
|
||||
|
||||
|
||||
/** 打开指定的文件夹的方法 */
|
||||
@ -29,6 +30,7 @@ export default class ElectronInterface {
|
||||
}
|
||||
await shell.openPath(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开对应的文件夹
|
||||
* @param params
|
||||
@ -57,4 +59,47 @@ export default class ElectronInterface {
|
||||
return errorMessage('打开文件夹错误,错误信息如下:' + error.message, 'SystemIpc_OPEN_FOLDER')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 选择单个指定文件后缀的文件
|
||||
* @param value 后缀列表
|
||||
*/
|
||||
public async SelectSingleFile(value: string[]): Promise<GeneralResponse.SuccessItem | GeneralResponse.ErrorItem> {
|
||||
try {
|
||||
let { filePaths } = await dialog.showOpenDialog({
|
||||
properties: ['openFile'],
|
||||
filters: [{ name: 'fileName', extensions: value }]
|
||||
})
|
||||
if (filePaths.length === 0) {
|
||||
throw new Error('没有选择的文件');
|
||||
}
|
||||
return successMessage(filePaths[0], '选择文件成功', 'SystemIpc_SelectSingleFile')
|
||||
} catch (error) {
|
||||
return errorMessage('选择文件错误,错误信息如下:' + error.message, 'SystemIpc_SelectSingleFile');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择多个指定文件后缀的文件
|
||||
* @param value 文件后缀列表
|
||||
* @returns
|
||||
*/
|
||||
public async SelectMultipleFile(value: string[]): Promise<GeneralResponse.SuccessItem | GeneralResponse.ErrorItem> {
|
||||
try {
|
||||
const { filePaths } = await dialog.showOpenDialog({
|
||||
properties: ['openFile', 'multiSelections'],
|
||||
filters: [{ name: 'fileName', extensions: value }]
|
||||
});
|
||||
|
||||
if (filePaths.length === 0) {
|
||||
throw new Error('没有选择的文件');
|
||||
}
|
||||
|
||||
return successMessage(filePaths, '选择文件成功', 'SystemIpc_SelectMultipleFile');
|
||||
} catch (error) {
|
||||
console.error('选择文件错误:', error); // 记录错误日志
|
||||
return errorMessage('选择文件错误,错误信息如下:' + error.message, 'SystemIpc_SelectMultipleFile');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,10 +140,10 @@ export default class SystemInfo {
|
||||
throw new Error(res.data.message)
|
||||
}
|
||||
|
||||
global.endTime = res.data.endTime
|
||||
global.permissions = res.data.permissions
|
||||
global.endTime = res.data.data.deactivationTime
|
||||
global.permissions = res.data.data.permissions
|
||||
global.CheckMachineId = true
|
||||
return successMessage(res.data, '获取机器码状态成功')
|
||||
return successMessage(res.data.data, '获取机器码状态成功')
|
||||
} catch (error) {
|
||||
return errorMessage('获取机器码状态错误,错误信息如下:' + error.message, 'SystemIpc_CHECK_MACHINE_STATUS')
|
||||
}
|
||||
|
||||
@ -203,7 +203,8 @@ export class TTS {
|
||||
saveSubtitles: true,
|
||||
pitch: `${edgeTTS.pitch}%`,
|
||||
rate: `${edgeTTS.rate}%`,
|
||||
volume: `${edgeTTS.volumn}%`
|
||||
volume: `${edgeTTS.volumn}%`,
|
||||
timeout : 10000
|
||||
})
|
||||
let ttsRes = await tts.ttsPromise(text, mp3Path)
|
||||
console.log(ttsRes)
|
||||
|
||||
@ -22,7 +22,7 @@ import { BookService } from '../../define/db/service/Book/bookService';
|
||||
import { OperateBookType } from '../../define/enum/bookEnum';
|
||||
import { GeneralResponse } from '../../model/generalResponse';
|
||||
import { BookTaskDetailService } from '../../define/db/service/Book/bookTaskDetailService';
|
||||
import { Book } from '../../model/book';
|
||||
import { Book } from '../../model/book/book';
|
||||
import { DEFINE_STRING } from '../../define/define_string';
|
||||
import { BookTaskService } from '../../define/db/service/Book/bookTaskService';
|
||||
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, BookType, TaskExecuteType, BookRepalceDataType, BookImageCategory } from "../define/enum/bookEnum"
|
||||
import { MJAction } from "../define/enum/bookEnum"
|
||||
import { MJImageType } from "../define/enum/mjEnum"
|
||||
import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, BookType, TaskExecuteType, BookRepalceDataType, BookImageCategory } from "../../define/enum/bookEnum"
|
||||
import { MJAction } from "../../define/enum/bookEnum"
|
||||
import { MJImageType } from "../../define/enum/mjEnum"
|
||||
|
||||
declare namespace Book {
|
||||
|
||||
type SelectBook = {
|
||||
id?: string,
|
||||
no?: number,
|
||||
@ -61,6 +60,7 @@ declare namespace Book {
|
||||
friendlyReminder?: string | null // 友情提示
|
||||
imageFolder?: string,
|
||||
customizeImageStyle?: string[],
|
||||
cacheImageList?: string[],
|
||||
prefixPrompt?: string,
|
||||
suffixPrompt?: string,
|
||||
styleList?: BookStyle[] | DefineBookStyle[] // 样式列表,
|
||||
8
src/model/book/bookTask.d.ts
vendored
Normal file
8
src/model/book/bookTask.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
declare namespace BookTask {
|
||||
type BookTaskImageCacheImageList = {
|
||||
bookTaskName: string;
|
||||
bookTaskId: string;
|
||||
bookId: string;
|
||||
imagePaths: string[];
|
||||
}
|
||||
}
|
||||
10
src/model/task.d.ts
vendored
10
src/model/task.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { BookBackTaskStatus, BookBackTaskType, TaskExecuteType } from "@/define/enum/bookEnum"
|
||||
import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, TaskExecuteType } from "@/define/enum/bookEnum"
|
||||
|
||||
declare namespace TaskModal {
|
||||
interface Task {
|
||||
@ -45,4 +45,12 @@ declare namespace TaskModal {
|
||||
count: number,
|
||||
data: BackTaskCollection[]
|
||||
}
|
||||
|
||||
type TaskStatus = {
|
||||
status: BookBackTaskStatus | "UNKNOWN" | BookTaskStatus;
|
||||
label: string;
|
||||
type?: string;
|
||||
color?: string;
|
||||
} & ({ type: string } | { color: string })
|
||||
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { DEFINE_STRING } from '../define/define_string'
|
||||
import { Book } from '../model/book'
|
||||
import { Book } from '../model/book/book'
|
||||
import { SubtitleModel } from '../model/subtitle'
|
||||
import { BookType, OperateBookType } from '../define/enum/bookEnum'
|
||||
|
||||
@ -182,6 +182,16 @@ const book = {
|
||||
/** 添加一键生图后台任务 */
|
||||
GenerateAllTaskImage: async (ids: string[], operateBookType: OperateBookType) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.GENERATE_ALL_TASK_IMAGE, ids, operateBookType),
|
||||
|
||||
/** 上传图片到小说中,并修改小说信息 */
|
||||
UpLoadImageToBookAndUpdateMessage: async (bookTaskDetailId: string, imageFile: string | string[], option: string) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.UPLOAD_IMAGE_TO_BOOK_AND_UPDATE_MESSAGE, bookTaskDetailId, imageFile, option),
|
||||
|
||||
/** 上传图片到缓存 */
|
||||
UpLoadImageToCache: async (bookTaskId: string, imageFile: string | string[]) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.UPLOAD_IMAGE_TO_CACHE, bookTaskId, imageFile),
|
||||
/** 获取当前小说中的所有的批次中的缓存图片 */
|
||||
GetAllBookTaskImageCache: async (bookTaskId: string) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.GET_ALL_BOOK_TASK_IMAGE_CACHE, bookTaskId),
|
||||
/** 保存缓存区的屠图片到小说主图或者是选图区 */
|
||||
SaveCacheImageToData: async (bookTaskDetailId: string, imageFile: string | string[], option: string) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.SAVE_CACHE_IMAGE_TO_DATA, bookTaskDetailId, imageFile, option),
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 一键反推的单个任务
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { DEFINE_STRING } from '../define/define_string'
|
||||
import { Book } from '../model/book'
|
||||
import { Book } from '../model/book/book'
|
||||
|
||||
const db = {
|
||||
//#region 小说相关的修改
|
||||
|
||||
@ -14,7 +14,13 @@ const system = {
|
||||
/** 检查机器码状态 */
|
||||
CheckMachineStatus: (value: string) => ipcRenderer.invoke(DEFINE_STRING.SYSTEM.CHECK_MACHINE_STATUS, value),
|
||||
/** 获取软件版本信息,更新信息,首页内容,公告等 */
|
||||
GetRemoteSystemInformation : () => ipcRenderer.invoke(DEFINE_STRING.SYSTEM.GET_REMOTE_SYSTEM_INFORMATION)
|
||||
GetRemoteSystemInformation: () => ipcRenderer.invoke(DEFINE_STRING.SYSTEM.GET_REMOTE_SYSTEM_INFORMATION),
|
||||
|
||||
/** 选择单个指定文件后缀的文件 */
|
||||
SelectSingleFile: (value: string[]) => ipcRenderer.invoke(DEFINE_STRING.SYSTEM.SELECT_SINGLE_FILE, value),
|
||||
|
||||
/** 选择多个指定文件后缀的文件 */
|
||||
SelectMultipleFile: (value: string[]) => ipcRenderer.invoke(DEFINE_STRING.SYSTEM.SELECT_MULTIPLE_FILE, value),
|
||||
|
||||
}
|
||||
export { system }
|
||||
|
||||
@ -6,11 +6,13 @@
|
||||
:theme="softwareStore.globalSetting.theme == 'dark' ? darkTheme : null"
|
||||
>
|
||||
<n-message-provider>
|
||||
<n-modal-provider>
|
||||
<n-dialog-provider>
|
||||
<n-notification-provider>
|
||||
<RouterView></RouterView>
|
||||
</n-notification-provider>
|
||||
</n-dialog-provider>
|
||||
</n-modal-provider>
|
||||
</n-message-provider>
|
||||
</n-config-provider>
|
||||
</n-spin>
|
||||
@ -24,6 +26,7 @@ import {
|
||||
NMessageProvider,
|
||||
NDialogProvider,
|
||||
NConfigProvider,
|
||||
NModalProvider,
|
||||
darkTheme,
|
||||
NNotificationProvider,
|
||||
NSpin
|
||||
@ -38,13 +41,13 @@ export default defineComponent({
|
||||
NDialogProvider,
|
||||
NMessageProvider,
|
||||
NNotificationProvider,
|
||||
NModalProvider,
|
||||
NSpin
|
||||
},
|
||||
setup() {
|
||||
let softwareStore = useSoftwareStore()
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
softwareStore.SoftColor = SoftColor
|
||||
window.api.getSettingDafultData(async (value) => {
|
||||
await window.darkMode.toggle(value.theme)
|
||||
@ -80,8 +83,8 @@ export default defineComponent({
|
||||
|
||||
/* Customize the scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 2px;
|
||||
height: 4px;
|
||||
width: 4px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
|
||||
@ -103,6 +103,7 @@ import {
|
||||
NFormItem,
|
||||
NInput,
|
||||
NButton,
|
||||
NTag,
|
||||
NGrid,
|
||||
NGridItem,
|
||||
NSelect
|
||||
@ -144,7 +145,10 @@ let columns = [
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
minWidth: 100
|
||||
minWidth: 100,
|
||||
render: (row) => {
|
||||
return renderStatus(row)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '失败原因',
|
||||
@ -156,6 +160,14 @@ let columns = [
|
||||
}
|
||||
]
|
||||
|
||||
function renderStatus(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{ bordered: false, type: GetBookBackTaskStatusLabel(row.status).type },
|
||||
{ default: GetBookBackTaskStatusLabel(row.status).label }
|
||||
)
|
||||
}
|
||||
|
||||
async function ResetQuery() {
|
||||
softwareStore.ResetBackTaskQueryData()
|
||||
await query(1, pagination.value.pageSize)
|
||||
@ -237,7 +249,7 @@ let GeBookBackTaskStatus = () => {
|
||||
let options = []
|
||||
for (const key in BookBackTaskStatus) {
|
||||
options.push({
|
||||
label: GetBookBackTaskStatusLabel(BookBackTaskStatus[key]),
|
||||
label: GetBookBackTaskStatusLabel(BookBackTaskStatus[key]).label,
|
||||
value: BookBackTaskStatus[key]
|
||||
})
|
||||
}
|
||||
|
||||
@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<n-spin :show="show">
|
||||
<n-collapse
|
||||
id="l-collapse"
|
||||
v-model:expanded-names="defaultExpandedNames"
|
||||
@item-header-click="handleItemHeaderClick"
|
||||
>
|
||||
<n-collapse-item
|
||||
v-for="(item, index) in data"
|
||||
:title="item.bookTaskName"
|
||||
:name="item.bookTaskId"
|
||||
:key="item.bookTaskId"
|
||||
>
|
||||
<n-image-group>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
min-width: 50px;
|
||||
overflow: auto;
|
||||
"
|
||||
>
|
||||
<div
|
||||
v-for="(image, index) in item.imagePaths"
|
||||
:key="image.id"
|
||||
:id="image.id"
|
||||
class="image-container"
|
||||
@click="SelectImage(image, index)"
|
||||
>
|
||||
<n-image
|
||||
:width="150"
|
||||
style="margin: 5px"
|
||||
:src="image.imagePath"
|
||||
alt="图片描述"
|
||||
preview-disabled
|
||||
lazy
|
||||
>
|
||||
</n-image>
|
||||
</div>
|
||||
</div>
|
||||
</n-image-group>
|
||||
</n-collapse-item>
|
||||
</n-collapse>
|
||||
<div style="margin-top: 15px; display: flex; justify-content: flex-end">
|
||||
<n-button type="info" @click="SaveImageToData">选择完成</n-button>
|
||||
</div>
|
||||
<template #description> 加载数据中 </template>
|
||||
</n-spin>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { NImageGroup, NImage, NSpin, NButton, useMessage, NCollapse, NCollapseItem } from 'naive-ui'
|
||||
import { useReverseManageStore } from '@/stores/reverseManage'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { MJImageType } from '@/define/enum/mjEnum'
|
||||
import { MJAction } from '@/define/enum/bookEnum'
|
||||
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let props = defineProps({
|
||||
type: undefined,
|
||||
bookTaskDetailId: undefined,
|
||||
bookTaskId: undefined
|
||||
})
|
||||
|
||||
let message = useMessage()
|
||||
let data = ref([])
|
||||
let show = ref(true)
|
||||
let defaultExpandedNames = ref([])
|
||||
|
||||
let selectImageIds = ref([])
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
// 加载所有的小说批次的数据
|
||||
let res = await window.book.GetAllBookTaskImageCache(props.bookTaskId)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
console.log('GetAllBookTaskImageCache', res.data)
|
||||
// 将指定ID的数据放在最前面
|
||||
const specifiedId = reverseManageStore.selectBookTask.id // 替换为你的指定ID
|
||||
res.data.sort((a, b) =>
|
||||
a.bookTaskId === specifiedId ? -1 : b.bookTaskId === specifiedId ? 1 : 0
|
||||
)
|
||||
res.data.forEach((item) => {
|
||||
let images = []
|
||||
for (let i = 0; i < item.imagePaths.length; i++) {
|
||||
const element = item.imagePaths[i]
|
||||
images.push({
|
||||
id: uuidv4(),
|
||||
imagePath: element
|
||||
})
|
||||
}
|
||||
data.value.push({
|
||||
...item,
|
||||
imagePaths: images
|
||||
})
|
||||
})
|
||||
|
||||
defaultExpandedNames.value = res.data.map((item) => {
|
||||
if (item.bookTaskId == specifiedId) {
|
||||
return item.bookTaskId
|
||||
}
|
||||
})
|
||||
message.success('加载数据成功')
|
||||
|
||||
let lCollapse = document.getElementById('l-collapse')
|
||||
if (lCollapse) {
|
||||
lCollapse.style.height = window.innerHeight - 150 + 'px'
|
||||
lCollapse.style.overflow = 'auto'
|
||||
}
|
||||
} catch (error) {
|
||||
message.error(error.message)
|
||||
} finally {
|
||||
show.value = false
|
||||
}
|
||||
})
|
||||
|
||||
async function handleItemHeaderClick({ name, expanded }) {
|
||||
setTimeout(() => {
|
||||
if (expanded) {
|
||||
// 判断里面的数据是不是被选择,选择的话添加效果
|
||||
let bookTasks = data.value.filter((item) => item.bookTaskId == name)
|
||||
for (let i = 0; i < bookTasks.length; i++) {
|
||||
const element = bookTasks[i]
|
||||
for (let i = 0; i < element.imagePaths.length; i++) {
|
||||
const image = element.imagePaths[i]
|
||||
if (selectImageIds.value.some((x) => x.id == image.id)) {
|
||||
let el = document.getElementById(image.id)
|
||||
if (el) {
|
||||
el.classList.add('selected')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0)
|
||||
}
|
||||
|
||||
async function SelectImage(image, index) {
|
||||
if (props.type == 'outImagePath') {
|
||||
// 选择单个图片
|
||||
let tempSelectImageIds = selectImageIds.value
|
||||
selectImageIds.value = []
|
||||
for (let i = 0; i < tempSelectImageIds.length; i++) {
|
||||
const element = tempSelectImageIds[i]
|
||||
let el = document.getElementById(element.id)
|
||||
if (el) {
|
||||
el.classList.remove('selected')
|
||||
}
|
||||
}
|
||||
selectImageIds.value.push(image)
|
||||
for (let i = 0; i < selectImageIds.value.length; i++) {
|
||||
const element = selectImageIds.value[i]
|
||||
let el = document.getElementById(element.id)
|
||||
if (el) {
|
||||
el.classList.add('selected')
|
||||
}
|
||||
}
|
||||
} else if (props.type == 'subImagePath') {
|
||||
// 选择多个图片
|
||||
// 判断当前点击的这个是不是被选中没有被选中就选中,选中的话,就取消选中给
|
||||
let findIndex = selectImageIds.value.findIndex((x) => x.id == image.id)
|
||||
if (findIndex == -1) {
|
||||
selectImageIds.value.push(image)
|
||||
for (let i = 0; i < selectImageIds.value.length; i++) {
|
||||
const element = selectImageIds.value[i]
|
||||
let el = document.getElementById(element.id)
|
||||
if (el) {
|
||||
el.classList.add('selected')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 取消选中
|
||||
// 删除选中的图片
|
||||
selectImageIds.value.splice(findIndex, 1)
|
||||
let el = document.getElementById(image.id)
|
||||
if (el) {
|
||||
el.classList.remove('selected')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function RemoveImageSelect() {
|
||||
for (let i = 0; i < selectImageIds.value.length; i++) {
|
||||
const element = selectImageIds.value[i]
|
||||
let el = document.getElementById(element.id)
|
||||
if (el) {
|
||||
el.classList.remove('selected')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function SaveImageToData() {
|
||||
// 开始保存
|
||||
if (selectImageIds.value.length <= 0) {
|
||||
message.error('请选择图片')
|
||||
return
|
||||
}
|
||||
let selectImagePaths = selectImageIds.value.map((x) => x.imagePath)
|
||||
if (selectImagePaths.length <= 0) {
|
||||
message.error('请选择图片')
|
||||
return
|
||||
}
|
||||
if (props.type == 'outImagePath') {
|
||||
// 主图
|
||||
// 找到图片地址
|
||||
let res = await window.book.SaveCacheImageToData(
|
||||
props.bookTaskDetailId,
|
||||
selectImagePaths[0],
|
||||
props.type
|
||||
)
|
||||
console.log('SaveCacheImageToData', res)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
|
||||
// 保存成功
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(x) => x.id == props.bookTaskDetailId
|
||||
)
|
||||
if (findIndex != -1) {
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].outImagePath = res.data
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].mjMessage = {
|
||||
progress: 100,
|
||||
status: 'success',
|
||||
category: MJImageType.IMPORT,
|
||||
messageId: '',
|
||||
action: MJAction.IMAGINE
|
||||
}
|
||||
}
|
||||
RemoveImageSelect()
|
||||
selectImageIds.value = []
|
||||
message.success(res.message)
|
||||
} else if (props.type == 'subImagePath') {
|
||||
let res = await window.book.SaveCacheImageToData(
|
||||
props.bookTaskDetailId,
|
||||
selectImagePaths,
|
||||
props.type
|
||||
)
|
||||
console.log('SaveCacheImageToData', res)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
// 做一些修改数据的操作
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == props.bookTaskDetailId
|
||||
)
|
||||
if (findIndex != -1) {
|
||||
let subImagePath = reverseManageStore.selectBookTaskDetail[findIndex].subImagePath
|
||||
subImagePath.push(...res.data)
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].subImagePath = subImagePath.map(
|
||||
(item) => item.split('?t=')[0] + `?t=${new Date().getTime()}`
|
||||
)
|
||||
}
|
||||
RemoveImageSelect()
|
||||
selectImageIds.value = []
|
||||
message.success(res.message)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image-container {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
margin: 5px 5px;
|
||||
transition:
|
||||
transform 0.3s,
|
||||
box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.image-container.selected {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
border: 2px solid #1890ff;
|
||||
}
|
||||
|
||||
.image-container::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.image-container.selected::after {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-image-group>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
min-width: 50px;
|
||||
overflow: auto;
|
||||
"
|
||||
>
|
||||
<div
|
||||
v-for="(image, index) in data"
|
||||
:key="image.id"
|
||||
:id="image.id"
|
||||
class="image-container"
|
||||
:class="{ selected: image.selected }"
|
||||
@click="SelectImage(image, index)"
|
||||
>
|
||||
<n-image
|
||||
:width="150"
|
||||
style="margin: 5px"
|
||||
:src="image.imagePath"
|
||||
alt="图片描述"
|
||||
preview-disabled
|
||||
lazy
|
||||
>
|
||||
</n-image>
|
||||
</div>
|
||||
</div>
|
||||
</n-image-group>
|
||||
<div>
|
||||
<n-button type="info" @click="UpdateImageToCache">选择完成</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { NImage, NImageGroup, NButton, useMessage } from 'naive-ui'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { useReverseManageStore } from '@/stores/reverseManage'
|
||||
|
||||
let props = defineProps({
|
||||
imageList: undefined
|
||||
})
|
||||
let data = ref([])
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
|
||||
onMounted(() => {
|
||||
for (let i = 0; i < props.imageList.length; i++) {
|
||||
const element = props.imageList[i]
|
||||
data.value.push({
|
||||
id: uuidv4(),
|
||||
imagePath: element,
|
||||
selected: false
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
async function SelectImage(image, index) {
|
||||
data.value[index].selected = !data.value[index].selected
|
||||
}
|
||||
|
||||
async function UpdateImageToCache() {
|
||||
let tempData = data.value.filter((item) => item.selected)
|
||||
if (tempData.length <= 0) {
|
||||
message.error('请选择图片')
|
||||
return
|
||||
}
|
||||
let images = tempData.map((item) => item.imagePath)
|
||||
let res = await window.book.UpLoadImageToCache(reverseManageStore.selectBookTask.id, images)
|
||||
if (res.code == 1) {
|
||||
// 将当前选中的全部删除
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
const element = data.value[i]
|
||||
if (element.selected) {
|
||||
element.selected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
window.api.showGlobalMessage(res)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image-container {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
margin: 5px 5px;
|
||||
transition:
|
||||
transform 0.3s,
|
||||
box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.image-container.selected {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
border: 2px solid #1890ff;
|
||||
}
|
||||
|
||||
.image-container::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.image-container.selected::after {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center">
|
||||
<span>参数</span>
|
||||
<n-dropdown
|
||||
trigger="hover"
|
||||
:options="options"
|
||||
@select="handleSelect"
|
||||
:render-option="renderOption"
|
||||
>
|
||||
<n-button text :style="style">
|
||||
<n-icon> <MenuOpenRound /> </n-icon
|
||||
></n-button>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { NDropdown, NButton, NIcon, useMessage } from 'naive-ui'
|
||||
import MenuOpenRound from '@/renderer/src/components/Icon/MenuOpenRound.vue'
|
||||
import { useReverseManageStore } from '@/stores/reverseManage'
|
||||
import { BookImageCategory } from '@/define/enum/bookEnum'
|
||||
import { useSoftwareStore } from '@/stores/software'
|
||||
import { TimeDelay } from '@/define/Tools/time'
|
||||
|
||||
let props = defineProps({
|
||||
style: undefined
|
||||
})
|
||||
let style = ref(props.style)
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
|
||||
let options = [
|
||||
{ label: '启用修脸', key: 'openFaceRepair' },
|
||||
{ label: '关闭修脸', key: 'closeFaceRepair' }
|
||||
]
|
||||
|
||||
async function ModifyFaceRepair(key) {
|
||||
//adetailer
|
||||
let adetailer = true
|
||||
if (key == 'openFaceRepair') {
|
||||
adetailer = true
|
||||
} else if (key == 'closeFaceRepair') {
|
||||
adetailer = false
|
||||
} else {
|
||||
message.error('ModifyFaceRepair' + '_' + '未知操作')
|
||||
}
|
||||
// 开始修改
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
const element = reverseManageStore.selectBookTaskDetail[i]
|
||||
let res = await window.db.UpdateBookTaskDetailData(element.id, {
|
||||
adetailer: adetailer
|
||||
})
|
||||
if (res.code == 1) {
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == element.id
|
||||
)
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].adetailer = adetailer
|
||||
} else {
|
||||
throw new Error(`修改${element.name}失败`)
|
||||
}
|
||||
}
|
||||
await TimeDelay(1000)
|
||||
}
|
||||
|
||||
async function handleSelect(key) {
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在修改所有的修脸参数'
|
||||
try {
|
||||
switch (key) {
|
||||
case 'openFaceRepair':
|
||||
await ModifyFaceRepair(key)
|
||||
break
|
||||
case 'closeFaceRepair':
|
||||
await ModifyFaceRepair(key)
|
||||
break
|
||||
default:
|
||||
message.error('未知操作')
|
||||
break
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('操作失败,' + error.message)
|
||||
} finally {
|
||||
softwareStore.spin.spinning = false
|
||||
}
|
||||
}
|
||||
|
||||
function renderOption({ node, option }) {
|
||||
if (option.key === 'openFaceRepair' || option.key === 'closeFaceRepair') {
|
||||
if (
|
||||
reverseManageStore.selectBookTask.imageCategory == BookImageCategory.SD ||
|
||||
reverseManageStore.selectBookTask.imageCategory == BookImageCategory.FLUX_FORGE
|
||||
) {
|
||||
return node
|
||||
}
|
||||
} else {
|
||||
return node
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -50,7 +50,21 @@
|
||||
@drop="imageDragDrop"
|
||||
@dragover="imageDragOver"
|
||||
>
|
||||
<div style="display: flex; align-items: center; position: relative">
|
||||
<div
|
||||
style="display: flex; align-items: center; position: relative"
|
||||
@contextmenu="handleContextMenu"
|
||||
>
|
||||
<n-button
|
||||
text
|
||||
:type="data.imageLock ? 'error' : 'primary'"
|
||||
style="font-size: 32px; position: absolute; left: 0px; top: 0px"
|
||||
@click="ModifyLock"
|
||||
>
|
||||
<n-icon>
|
||||
<LockClosed v-if="data.imageLock" />
|
||||
<LockOpen v-else />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
<n-image
|
||||
class="g-image-class generate-image-show"
|
||||
:src="data.outImagePath ? data.outImagePath : softwareStore.globalSetting.space_image"
|
||||
@ -59,33 +73,69 @@
|
||||
:height="120"
|
||||
lazy
|
||||
/>
|
||||
<n-button
|
||||
text
|
||||
:type="data.imageLock ? 'error' : 'primary'"
|
||||
style="font-size: 24px; position: absolute; left: -12px; top: -5px"
|
||||
@click="ModifyLock"
|
||||
>
|
||||
<n-icon>
|
||||
<LockClosed v-if="data.imageLock" />
|
||||
<LockOpen v-else />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
<n-button
|
||||
text
|
||||
type="info"
|
||||
style="font-size: 24px; position: absolute; left: 8px; top: -5px"
|
||||
@click="DownloadImage"
|
||||
v-if="reverseManageStore.selectBookTask.imageCategory == 'mj'"
|
||||
>
|
||||
<n-icon>
|
||||
<Download />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
<n-dropdown
|
||||
:options="mainImageOptions"
|
||||
placement="bottom-start"
|
||||
trigger="manual"
|
||||
:x="x"
|
||||
:y="y"
|
||||
:show="showDropdown"
|
||||
:on-clickoutside="onClickoutside"
|
||||
@select="handleSelect"
|
||||
>
|
||||
</n-dropdown>
|
||||
<div>
|
||||
<n-divider vertical style="height: 100%" />
|
||||
</div>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="display: flex">
|
||||
<div style="width: 24px">
|
||||
<n-tooltip>
|
||||
<template #trigger>
|
||||
<n-button
|
||||
style="font-size: 24px"
|
||||
text
|
||||
color="#ee7959"
|
||||
@click="UpLoadImageToSelecImageRegion"
|
||||
>
|
||||
<n-icon>
|
||||
<UploadRound />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</template>
|
||||
上传本地图片到选图区
|
||||
</n-tooltip>
|
||||
<n-tooltip>
|
||||
<template #trigger>
|
||||
<n-button
|
||||
style="font-size: 24px"
|
||||
text
|
||||
color="#e5a84b"
|
||||
@click="UpLoadImageRegionToCache"
|
||||
>
|
||||
<n-icon>
|
||||
<OpenInBrowserRound />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</template>
|
||||
上传选图区图片到缓存区
|
||||
</n-tooltip>
|
||||
<n-tooltip>
|
||||
<template #trigger>
|
||||
<n-button
|
||||
style="font-size: 24px"
|
||||
text
|
||||
color="#45465e"
|
||||
@click="DownloadCacheImageToSelecImageRegion"
|
||||
>
|
||||
<n-icon>
|
||||
<DownloadRound />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</template>
|
||||
从缓存区下载图片到选图区
|
||||
</n-tooltip>
|
||||
</div>
|
||||
<n-image-group>
|
||||
<div
|
||||
style="
|
||||
@ -100,7 +150,7 @@
|
||||
subImage="true"
|
||||
class="g-image-class"
|
||||
draggable="true"
|
||||
:width="56"
|
||||
:width="55"
|
||||
style="margin: 1px"
|
||||
v-for="(image, index) in data.subImagePath"
|
||||
:key="image.id"
|
||||
@ -113,11 +163,21 @@
|
||||
</n-image-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<n-drawer v-model:show="showDrawer" :width="drawerWidth" placement="left">
|
||||
<n-drawer-content :title="drawerTitle">
|
||||
<BookTaskImageCache
|
||||
:type="drawertype"
|
||||
:bookTaskDetailId="data.id"
|
||||
:bookTaskId="reverseManageStore.selectBookTask.id"
|
||||
/>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, toRaw, watch } from 'vue'
|
||||
import { ref, onMounted, nextTick, watch, h } from 'vue'
|
||||
import {
|
||||
NImage,
|
||||
useDialog,
|
||||
@ -127,14 +187,25 @@ import {
|
||||
NButton,
|
||||
NPopover,
|
||||
NTag,
|
||||
useMessage
|
||||
NDropdown,
|
||||
NDrawer,
|
||||
NTooltip,
|
||||
NDrawerContent,
|
||||
useMessage,
|
||||
useModal
|
||||
} from 'naive-ui'
|
||||
import { LockClosed, LockOpen, Download } from '@vicons/ionicons5'
|
||||
import { LockClosed, LockOpen, Download, FolderOpen } from '@vicons/ionicons5'
|
||||
import UploadRound from '@/renderer/src/components/Icon/UploadRound.vue'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useImageStore } from '../../../../../stores/image'
|
||||
import { BookImageCategory, OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
import { isEmpty } from 'lodash'
|
||||
import OpenInBrowserRound from '@/renderer/src/components/Icon/OpenInBrowserRound.vue'
|
||||
import BookTaskImageCache from '@/renderer/src/components/Book/Components/Image/BookTaskImageCache.vue'
|
||||
import DownloadRound from '@/renderer/src/components/Icon/DownloadRound.vue'
|
||||
import SelectRegionImage from '@/renderer/src/components/Book/Components/Image/SelectRegionImage.vue'
|
||||
import { isEmpty, reverse } from 'lodash'
|
||||
import { MJAction, MJImageType } from '@/define/enum/mjEnum'
|
||||
let props = defineProps({
|
||||
initData: undefined,
|
||||
index: undefined
|
||||
@ -142,6 +213,7 @@ let props = defineProps({
|
||||
let imageStore = useImageStore()
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let modal = useModal()
|
||||
let data = ref(props.initData)
|
||||
let images = ref(props.initData.subImagePath)
|
||||
let outImagePath = ref(props.initData.outImagePath)
|
||||
@ -149,6 +221,12 @@ let width = ref(null)
|
||||
let dragTarget = null
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let showDropdown = ref(false)
|
||||
let showDrawer = ref(false)
|
||||
let drawertype = ref('outImagePath')
|
||||
let drawerTitle = ref(
|
||||
`选择缓存区文件__主图__${reverseManageStore.selectBookTask.name}__${props.initData.name}`
|
||||
)
|
||||
|
||||
// 监听 props.initData.subImagePath 修改
|
||||
watch(
|
||||
@ -165,7 +243,7 @@ watch(
|
||||
() => props.initData.outImagePath,
|
||||
(value) => {
|
||||
if (value) {
|
||||
outImagePath.value = value + `?t=${new Date().getTime()}`
|
||||
outImagePath.value = value.split('?t=')[0] + `?t=${new Date().getTime()}`
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -250,7 +328,6 @@ async function imageDragOver(e) {
|
||||
}
|
||||
|
||||
async function ModifyLock() {
|
||||
|
||||
if (!data.value.imageLock) {
|
||||
// 锁定之前,判断是不是有
|
||||
if (!outImagePath.value) {
|
||||
@ -335,4 +412,237 @@ async function DownloadImage() {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 上传图片信息到小说出图中 */
|
||||
async function UpLoadImageToBookAndUpdateMessage() {
|
||||
dialog.warning({
|
||||
title: '上传图片提示',
|
||||
content:
|
||||
'注意:上传的图片(png)到主图,并且会覆盖原有的图片,不可恢复,上传到图片只能是裁剪过的,该操作不会自动裁剪上传,是否继续?',
|
||||
positiveText: '继续',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
// 弹窗选择图片
|
||||
let imageFiles = await window.system.SelectSingleFile(['png'])
|
||||
if (imageFiles.code == 0) {
|
||||
message.error(imageFiles.message)
|
||||
return
|
||||
}
|
||||
let res = await window.book.UpLoadImageToBookAndUpdateMessage(
|
||||
data.value.id,
|
||||
imageFiles.data,
|
||||
'outImagePath'
|
||||
)
|
||||
if (res.code == 1) {
|
||||
// 做一些修改数据的操作
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == data.value.id
|
||||
)
|
||||
if (findIndex != -1) {
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].outImagePath = res.data
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].mjMessage = {
|
||||
progress: 100,
|
||||
status: 'success',
|
||||
category: MJImageType.IMPORT,
|
||||
messageId: '',
|
||||
action: MJAction.IMAGINE
|
||||
}
|
||||
}
|
||||
}
|
||||
window.api.showGlobalMessage(res)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 大小当前小说批次的出图文件夹 */
|
||||
async function OpenBookTaskDetailImageFolder() {
|
||||
let imageFolder = reverseManageStore.selectBookTask.imageFolder
|
||||
let res = await window.system.OpenFolder({
|
||||
folderPath: imageFolder,
|
||||
baseProject: false
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
message.success('打开文件夹成功')
|
||||
}
|
||||
}
|
||||
|
||||
/** 将图片上传到选图区域 */
|
||||
async function UpLoadImageToSelecImageRegion() {
|
||||
let da = dialog.warning({
|
||||
title: '上传图片提示',
|
||||
content:
|
||||
'注意:将选中的图片(png)上传到选图区域,回叠加到后面,上传到图片只能是裁剪过的,该操作不会自动裁剪上传,是否继续?',
|
||||
positiveText: '继续',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
// 弹窗选择图片
|
||||
let imageFiles = await window.system.SelectMultipleFile(['png'])
|
||||
if (imageFiles.code == 0) {
|
||||
message.error(imageFiles.message)
|
||||
return
|
||||
}
|
||||
let res = await window.book.UpLoadImageToBookAndUpdateMessage(
|
||||
data.value.id,
|
||||
imageFiles.data,
|
||||
'subImagePath'
|
||||
)
|
||||
if (res.code == 1) {
|
||||
// 做一些修改数据的操作
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == data.value.id
|
||||
)
|
||||
debugger
|
||||
if (findIndex != -1) {
|
||||
let subImagePath = reverseManageStore.selectBookTaskDetail[findIndex].subImagePath
|
||||
subImagePath.push(...res.data)
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].subImagePath = subImagePath.map(
|
||||
(item) => item.split('?t=')[0] + `?t=${new Date().getTime()}`
|
||||
)
|
||||
}
|
||||
}
|
||||
window.api.showGlobalMessage(res)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function UpLoadImageRegionToCache() {
|
||||
if (data.value.subImagePath.length <= 0) {
|
||||
message.error('没有选图区图片,不能上传到缓存区')
|
||||
return
|
||||
}
|
||||
dialog.create({
|
||||
title: '上传图片到缓存区',
|
||||
showIcon: false,
|
||||
style: 'width: 800px',
|
||||
content: () =>
|
||||
h(SelectRegionImage, {
|
||||
imageList: data.value.subImagePath
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function DownloadCacheImageToSelecImageRegion() {
|
||||
drawertype.value = 'subImagePath'
|
||||
drawerTitle.value = `选择缓存区文件__选图区__${reverseManageStore.selectBookTask.name}__${data.value.name}`
|
||||
showDrawer.value = true
|
||||
}
|
||||
|
||||
function renderIcon(icon) {
|
||||
return () => {
|
||||
return h(
|
||||
NIcon,
|
||||
{
|
||||
size: 18
|
||||
},
|
||||
{
|
||||
default: () => h(icon)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
let mainImageOptions = []
|
||||
function GetMainImageOptions() {
|
||||
let t = [
|
||||
{
|
||||
label: data.value.imageLock ? '解锁' : '锁定',
|
||||
key: 'lock',
|
||||
icon: data.value.imageLock ? renderIcon(LockClosed) : renderIcon(LockOpen)
|
||||
},
|
||||
{
|
||||
label: '下载图片',
|
||||
key: 'download',
|
||||
icon: renderIcon(Download)
|
||||
},
|
||||
{
|
||||
label: '上传图片到小说',
|
||||
key: 'upload',
|
||||
icon: renderIcon(UploadRound)
|
||||
},
|
||||
{
|
||||
label: '上传图片到缓存区',
|
||||
key: 'uploadToCache',
|
||||
icon: renderIcon(OpenInBrowserRound)
|
||||
},
|
||||
{
|
||||
label: '从缓存区下载',
|
||||
key: 'downloadFromCache',
|
||||
icon: renderIcon(DownloadRound)
|
||||
},
|
||||
{
|
||||
label: '打开文件夹',
|
||||
key: 'open',
|
||||
icon: renderIcon(FolderOpen)
|
||||
}
|
||||
]
|
||||
if (reverseManageStore.selectBookTask.imageCategory != BookImageCategory.MJ) {
|
||||
return t.filter((item) => item.key != 'download')
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
let x = ref(0)
|
||||
let y = ref(0)
|
||||
function handleContextMenu(e) {
|
||||
e.preventDefault()
|
||||
showDropdown.value = false
|
||||
nextTick().then(() => {
|
||||
mainImageOptions = GetMainImageOptions()
|
||||
showDropdown.value = true
|
||||
x.value = e.clientX
|
||||
y.value = e.clientY
|
||||
})
|
||||
}
|
||||
|
||||
function onClickoutside() {
|
||||
showDropdown.value = false
|
||||
}
|
||||
|
||||
async function UpLoadImageToCache() {
|
||||
if (isEmpty(data.value.outImagePath)) {
|
||||
message.error('没有生成图片,不能上传到缓存区')
|
||||
return
|
||||
}
|
||||
let da = dialog.warning({
|
||||
title: '上传缓存区提示',
|
||||
content: '会将当前主题上传到缓存区,缓存区的图片可以在其他地方使用,是否继续?',
|
||||
positiveText: '继续',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
let res = await window.book.UpLoadImageToCache(
|
||||
reverseManageStore.selectBookTask.id,
|
||||
data.value.outImagePath
|
||||
)
|
||||
window.api.showGlobalMessage(res)
|
||||
da.destroy()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let drawerWidth = ref(window.innerWidth * 0.8)
|
||||
async function DownloadImageFromCache() {
|
||||
drawertype.value = 'outImagePath'
|
||||
showDrawer.value = true
|
||||
}
|
||||
|
||||
async function handleSelect(key) {
|
||||
showDropdown.value = false
|
||||
if (key == 'lock') {
|
||||
await ModifyLock()
|
||||
} else if (key == 'download') {
|
||||
await DownloadImage()
|
||||
} else if (key == 'upload') {
|
||||
await UpLoadImageToBookAndUpdateMessage()
|
||||
} else if (key == 'open') {
|
||||
await OpenBookTaskDetailImageFolder()
|
||||
} else if (key == 'uploadToCache') {
|
||||
await UpLoadImageToCache()
|
||||
} else if (key == 'downloadFromCache') {
|
||||
await DownloadImageFromCache()
|
||||
} else {
|
||||
message.error('未知操作')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -43,7 +43,7 @@ import { NSelect, NButton, useMessage, useDialog, NPopover, NIcon } from 'naive-
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { Download } from '@vicons/ionicons5'
|
||||
import { OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
import { BookImageCategory, OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
let softwareStore = useSoftwareStore()
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
@ -53,7 +53,7 @@ let image_options = ref([])
|
||||
let select = computed(() =>
|
||||
reverseManageStore.selectBookTask.imageCategory
|
||||
? reverseManageStore.selectBookTask.imageCategory
|
||||
: softwareStore.globalSetting.defaultImageMode
|
||||
: softwareStore.globalSetting.defaultImageMode ?? BookImageCategory.MJ
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
@ -8,49 +8,44 @@
|
||||
@update:value="handleUpdateValue"
|
||||
:options="options"
|
||||
/>
|
||||
<n-dropdown trigger="hover" :options="blockOptions" @select="ImageLockOperation">
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ZHUYANTUO"
|
||||
@click="ImageLockOperation('lock')"
|
||||
size="tiny"
|
||||
style="margin-left: 5px"
|
||||
>一键锁定</n-button
|
||||
<n-dropdown
|
||||
trigger="hover"
|
||||
:options="blockOptions"
|
||||
@select="dropdownSelectHandle"
|
||||
:render-option="renderOptionHandle"
|
||||
>
|
||||
<n-button text :style="style">
|
||||
<n-icon> <MenuOpenRound /> </n-icon>
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ZHUYANTUO"
|
||||
@click="OneToFourBookTask"
|
||||
size="tiny"
|
||||
style="margin-left: 5px"
|
||||
>一拆四</n-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, computed } from 'vue'
|
||||
import { useMessage, useDialog, NSelect, NButton, NDropdown } from 'naive-ui'
|
||||
<script setup>
|
||||
import { ref, onMounted, computed, render } from 'vue'
|
||||
import { useMessage, useDialog, NIcon, NSelect, NButton, NDropdown } from 'naive-ui'
|
||||
import { BookImageCategory, OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import MenuOpenRound from '../../Icon/MenuOpenRound.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NSelect, NButton, NDropdown },
|
||||
let props = defineProps({
|
||||
style: undefined
|
||||
})
|
||||
let style = ref(props.style)
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let select = computed(() =>
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let select = computed(() =>
|
||||
reverseManageStore.selectBookTask.imageCategory
|
||||
? reverseManageStore.selectBookTask.imageCategory
|
||||
: softwareStore.globalSetting.defaultImageMode
|
||||
)
|
||||
let options = ref([])
|
||||
: softwareStore.globalSetting.defaultImageMode ?? BookImageCategory.MJ
|
||||
)
|
||||
let options = ref([])
|
||||
|
||||
onMounted(async () => {
|
||||
debugger
|
||||
onMounted(async () => {
|
||||
// 获取生图下拉列表的方式
|
||||
await window.api.GetImageGenerateCategory((value) => {
|
||||
if (value.code == 0) {
|
||||
@ -59,9 +54,9 @@ export default defineComponent({
|
||||
}
|
||||
options.value = value.data
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
async function handleUpdateValue(value) {
|
||||
async function handleUpdateValue(value) {
|
||||
// 将值的修改保存进数据库中
|
||||
let res = await window.db.UpdateBookTaskData(reverseManageStore.selectBookTask.id, {
|
||||
imageCategory: value
|
||||
@ -72,13 +67,9 @@ export default defineComponent({
|
||||
}
|
||||
reverseManageStore.selectBookTask.imageCategory = value
|
||||
message.success('修改成功')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 土拍你
|
||||
* @param value
|
||||
*/
|
||||
async function ImageLockOperation(value) {
|
||||
async function ImageLockOperation(value) {
|
||||
let res = await window.book.ImageLockOperation(
|
||||
reverseManageStore.selectBookTask.id,
|
||||
value,
|
||||
@ -90,18 +81,71 @@ export default defineComponent({
|
||||
}
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
const element = res.data[i]
|
||||
let index = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == element.id
|
||||
)
|
||||
let index = reverseManageStore.selectBookTaskDetail.findIndex((item) => item.id == element.id)
|
||||
if (index != -1) {
|
||||
reverseManageStore.selectBookTaskDetail[index].imageLock = element.imageLock
|
||||
}
|
||||
}
|
||||
message.success(res.message)
|
||||
}
|
||||
}
|
||||
|
||||
// 进行一拆四操作
|
||||
async function OneToFourBookTask() {
|
||||
async function dropdownSelectHandle(key) {
|
||||
switch (key) {
|
||||
case 'lock':
|
||||
case 'unlock':
|
||||
await ImageLockOperation(key)
|
||||
break
|
||||
case 'downloadMJImage':
|
||||
await DownloadAllImage()
|
||||
break
|
||||
case 'oneToFour':
|
||||
await OneToFourBookTask()
|
||||
break
|
||||
default:
|
||||
message.error('未知操作')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
async function DownloadAllImage() {
|
||||
let da = dialog.warning({
|
||||
title: '采集所有图片提示',
|
||||
content:
|
||||
'即将开始采集所有的MJ生图图片,满足一下条件的分镜才会被采集:状态不为 error,有生图信息,有消息ID,没有生成图片,图片的有效期为24小时,是否继续?',
|
||||
positiveText: '继续',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
da?.destroy()
|
||||
let res = await window.book.GetImageUrlAndDownload(
|
||||
reverseManageStore.selectBookTask.id,
|
||||
OperateBookType.BOOKTASK,
|
||||
false
|
||||
)
|
||||
if (res.code == 1) {
|
||||
// 这边要修改下数据
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
const element = res.data[i]
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == element.id
|
||||
)
|
||||
if (findIndex != -1) {
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].outImagePath =
|
||||
element.data.outImagePath
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].subImagePath =
|
||||
element.data.subImagePath
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].mjMessage = element.data.mjMessage
|
||||
}
|
||||
}
|
||||
message.success(res.message)
|
||||
} else {
|
||||
message.error(res.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 进行一拆四操作
|
||||
async function OneToFourBookTask() {
|
||||
dialog.warning({
|
||||
title: '一拆四提示',
|
||||
content:
|
||||
@ -117,23 +161,35 @@ export default defineComponent({
|
||||
message.success(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
reverseManageStore,
|
||||
handleUpdateValue,
|
||||
OneToFourBookTask,
|
||||
softwareStore,
|
||||
ImageLockOperation,
|
||||
select,
|
||||
blockOptions: [
|
||||
function renderOptionHandle({ node, option }) {
|
||||
console.log('renderOptionHandle', node, option)
|
||||
if (option.key == 'downloadMJImage') {
|
||||
if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.MJ) {
|
||||
return node
|
||||
}
|
||||
} else {
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
let blockOptions = [
|
||||
{
|
||||
label: '一键锁定',
|
||||
key: 'lock'
|
||||
},
|
||||
{
|
||||
label: '一键解锁',
|
||||
key: 'unlock'
|
||||
},
|
||||
{
|
||||
label: 'MJ采集全部图片',
|
||||
key: 'downloadMJImage'
|
||||
},
|
||||
{
|
||||
label: '一拆四',
|
||||
key: 'oneToFour'
|
||||
}
|
||||
],
|
||||
options
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
</script>
|
||||
|
||||
@ -84,7 +84,7 @@
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
size="small"
|
||||
@click="GenerateImageAll"
|
||||
@click="GenerateImageAll(true)"
|
||||
>
|
||||
一键生图
|
||||
</n-button>
|
||||
@ -138,7 +138,13 @@ import VideoCanvas from '../../VideoSubtitle/VideoCanvas.vue'
|
||||
import { SubtitleSavePositionType } from '../../../../../define/enum/waterMarkAndSubtitle.ts'
|
||||
import { DEFINE_STRING } from '../../../../../define/define_string/index.ts'
|
||||
import Setting from './Setting.vue'
|
||||
import { BookType, OperateBookType } from '../../../../../define/enum/bookEnum.ts'
|
||||
import {
|
||||
BookBackTaskType,
|
||||
BookImageCategory,
|
||||
BookType,
|
||||
OperateBookType,
|
||||
TaskExecuteType
|
||||
} from '../../../../../define/enum/bookEnum.ts'
|
||||
import TranslateSetting from '../../Setting/TranslateSetting.vue'
|
||||
import { TranslateType } from '../../../../../define/enum/translate.ts'
|
||||
import { ContainsChineseOrPunctuation } from '../../../../../define/Tools/common.ts'
|
||||
@ -464,6 +470,10 @@ async function handleSelect(key) {
|
||||
await Translate('translate_english')
|
||||
break
|
||||
|
||||
case 'generate_space_image': //生成未生成的图片
|
||||
await GenerateImageAll(false)
|
||||
break
|
||||
|
||||
case 'translate_setting': // 翻译设置
|
||||
await Translate('translate_setting')
|
||||
break
|
||||
@ -780,18 +790,124 @@ async function TranslateService(from, to) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成所有图片
|
||||
* 根据指定类型为所有书籍任务生成图像
|
||||
* @param {String} type - 小说图像类别
|
||||
* @param {Boolean} cover - 是否覆盖现有图像
|
||||
*/
|
||||
async function GenerateImageAll() {
|
||||
let res = await window.book.GenerateImageAll(
|
||||
reverseManageStore.selectBookTask.id,
|
||||
reverseManageStore.selectBookTask.imageCategory
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
async function AddFluxImageAll(type, cover) {
|
||||
let messageName = DEFINE_STRING.BOOK.FLUX_API_IMAGE_GENERATE_RETURN
|
||||
let taskType = BookBackTaskType.FLUX_API_IMAGE
|
||||
if (type == BookImageCategory.FLUX_FORGE) {
|
||||
messageName = DEFINE_STRING.BOOK.FLUX_FORGE_IMAGE_GENERATE_RETURN
|
||||
taskType = BookBackTaskType.FLUX_FORGE_IMAGE
|
||||
} else if (type == BookImageCategory.FLUX_API) {
|
||||
messageName = DEFINE_STRING.BOOK.FLUX_API_IMAGE_GENERATE_RETURN
|
||||
taskType = BookBackTaskType.FLUX_API_IMAGE
|
||||
} else if (type == BookImageCategory.D3) {
|
||||
messageName = DEFINE_STRING.BOOK.D3_IMAGE_GENERATE_RETURN
|
||||
taskType = BookBackTaskType.D3_IMAGE
|
||||
} else if (type == BookImageCategory.SD) {
|
||||
messageName = DEFINE_STRING.BOOK.SD_IMAGE_GENERATE_RETURN
|
||||
taskType = BookBackTaskType.SD_IMAGE
|
||||
} else {
|
||||
message.error('未知的图像类别')
|
||||
return
|
||||
}
|
||||
// 这边过滤所有的锁定的分镜
|
||||
let bookTaskDetails = reverseManageStore.selectBookTaskDetail.filter((item) => !item.imageLock)
|
||||
|
||||
if (cover) {
|
||||
// 添加全部的任务
|
||||
let tasks = []
|
||||
for (let i = 0; i < bookTaskDetails.length; i++) {
|
||||
const element = bookTaskDetails[i]
|
||||
tasks.push({
|
||||
bookId: reverseManageStore.selectBook.id,
|
||||
type: taskType,
|
||||
executeType: TaskExecuteType.AUTO,
|
||||
bookTaskId: reverseManageStore.selectBookTask.id,
|
||||
bookTaskDetailId: element.id,
|
||||
messageName: messageName
|
||||
})
|
||||
}
|
||||
if (tasks.length <= 0) {
|
||||
message.error('没有需要生成的分镜')
|
||||
return
|
||||
}
|
||||
let res = await await window.task.AddMultiBookBackTask(tasks)
|
||||
window.api.showGlobalMessage(res)
|
||||
} else {
|
||||
// 添加未生成的任务
|
||||
let tasks = []
|
||||
for (let i = 0; i < bookTaskDetails.length; i++) {
|
||||
const element = bookTaskDetails[i]
|
||||
if (!element.mjMessage) {
|
||||
tasks.push({
|
||||
bookId: reverseManageStore.selectBook.id,
|
||||
type: taskType,
|
||||
executeType: TaskExecuteType.AUTO,
|
||||
bookTaskId: reverseManageStore.selectBookTask.id,
|
||||
bookTaskDetailId: element.id,
|
||||
messageName: messageName
|
||||
})
|
||||
}
|
||||
}
|
||||
if (tasks.length == 0) {
|
||||
message.error('没有未生成的分镜,或者都被锁定了')
|
||||
return
|
||||
}
|
||||
let res = await await window.task.AddMultiBookBackTask(tasks)
|
||||
window.api.showGlobalMessage(res)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成所有图片
|
||||
*/
|
||||
async function GenerateImageAll(cover = true) {
|
||||
let da = dialog.warning({
|
||||
title: '生成所有图片提示',
|
||||
content: `即将开始生成 ${cover ? '所有的' : '从未生成过的分镜'} 图片,当前的生图模式为 ${
|
||||
reverseManageStore.selectBookTask.imageCategory
|
||||
},开始执行会有1-20秒的延迟,除了被锁定的图片,其余的图片都会重新生成,是否继续?`,
|
||||
positiveText: '继续',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
try {
|
||||
da?.destroy()
|
||||
debugger
|
||||
if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.MJ) {
|
||||
let res = await window.mj.AddMJGenerateImageTask(
|
||||
reverseManageStore.selectBookTask.id,
|
||||
OperateBookType.BOOKTASK,
|
||||
DEFINE_STRING.BOOK.MJ_IMAGE_GENERATE_RETURN,
|
||||
cover
|
||||
)
|
||||
if (res?.code == 1) {
|
||||
message.success(res.message)
|
||||
} else {
|
||||
message.error(res.message)
|
||||
}
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.SD) {
|
||||
await AddFluxImageAll(BookImageCategory.SD, cover)
|
||||
} else if (
|
||||
reverseManageStore.selectBookTask.imageCategory == BookImageCategory.FLUX_FORGE
|
||||
) {
|
||||
await AddFluxImageAll(BookImageCategory.FLUX_FORGE, cover)
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.FLUX_API) {
|
||||
await AddFluxImageAll(BookImageCategory.FLUX_API, cover)
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.D3) {
|
||||
await AddFluxImageAll(BookImageCategory.D3, cover)
|
||||
} else {
|
||||
message.error('不支持的生图类型')
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
message.error(error.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -973,6 +1089,7 @@ let translateOptions = [
|
||||
}
|
||||
]
|
||||
let generateOptions = [
|
||||
{ label: '生成未出图分镜', key: 'generate_space_image' },
|
||||
{
|
||||
label: '停止生图',
|
||||
key: 'stop_image_generate'
|
||||
|
||||
@ -27,6 +27,7 @@ import DatatableAfterGpt from './DatatableAfterGpt.vue'
|
||||
import DatatableGenerateImage from './DatatableGenerateImage.vue'
|
||||
import ODataTableAction from '../Original/ODataTableAction.vue'
|
||||
import SDReversePrompt from './SDReversePrompt.vue'
|
||||
import BookTaskDetailOptions from '../Components/ManageBook/BookTaskDetailOptions.vue'
|
||||
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
@ -117,7 +118,9 @@ const columns = [
|
||||
},
|
||||
{
|
||||
// 参数
|
||||
title: '参数',
|
||||
title(row) {
|
||||
return h(BookTaskDetailOptions, { style: 'font-size: 24px;margin-left: 5px' })
|
||||
},
|
||||
key: 'parameter',
|
||||
width: '110',
|
||||
render(row, index) {
|
||||
@ -126,7 +129,7 @@ const columns = [
|
||||
},
|
||||
{
|
||||
title() {
|
||||
return h(DatatableHeaderImage)
|
||||
return h(DatatableHeaderImage, { style: 'font-size: 24px; margin-left: 5px' })
|
||||
},
|
||||
width: 300,
|
||||
className: 'empty-margin',
|
||||
|
||||
@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<div style="margin-bottom: 5px; margin-left: 5px; display: flex; align-items: center">
|
||||
<n-button :render-icon="renderIcon" size="small" type="info" @click="AddBookDialog()"
|
||||
<n-button size="small" strong secondary type="default">{{
|
||||
reverseManageStore.selectBook.name
|
||||
}}</n-button>
|
||||
<n-button
|
||||
style="margin-left: 5px"
|
||||
:render-icon="renderIcon"
|
||||
size="small"
|
||||
type="info"
|
||||
@click="AddBookDialog()"
|
||||
>新增</n-button
|
||||
>
|
||||
<n-button style="margin-left: 5px" size="small" type="info" @click="GenerateAllTaskImage()"
|
||||
@ -54,14 +62,15 @@ import {
|
||||
NDataTable,
|
||||
NIcon,
|
||||
NDropdown,
|
||||
NPerformantEllipsis
|
||||
NPerformantEllipsis,
|
||||
NTag
|
||||
} from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { AddSharp, Open } from '@vicons/ionicons5'
|
||||
import BookTaskListAction from './Components/ManageBook/BookTaskListAction.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { OperateBookType } from '../../../../define/enum/bookEnum'
|
||||
import { GetBookTaskDetailStatusLabel, OperateBookType } from '../../../../define/enum/bookEnum'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import { ResponseMessageType } from '../../../../define/enum/softwareEnum'
|
||||
import AddBookTask from './Components/ManageBook/AddBookTask.vue'
|
||||
@ -137,7 +146,10 @@ function createColumns() {
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
width: 100
|
||||
width: 100,
|
||||
render(row) {
|
||||
return renderStatus(row)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '失败原因',
|
||||
@ -185,6 +197,14 @@ function createOptions(row) {
|
||||
]
|
||||
}
|
||||
|
||||
function renderStatus(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{ bordered: false, type: GetBookTaskDetailStatusLabel(row.status).type },
|
||||
{ default: GetBookTaskDetailStatusLabel(row.status).label }
|
||||
)
|
||||
}
|
||||
|
||||
async function HDImage(value) {
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在进行高清检查。。。'
|
||||
@ -397,7 +417,7 @@ async function GenerateAllTaskImage() {
|
||||
[...checkedRowKeysRef.value],
|
||||
OperateBookType.ASSIGNBOOKTASK
|
||||
)
|
||||
window.api.showGlobalMessageDialog(res);
|
||||
window.api.showGlobalMessageDialog(res)
|
||||
softwareStore.spin.spinning = false
|
||||
}
|
||||
})
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
</n-popover>
|
||||
|
||||
<n-input
|
||||
:status="input_status"
|
||||
size="tiny"
|
||||
placeholder="请生成出图命令或是提示词"
|
||||
type="textarea"
|
||||
@ -178,7 +177,6 @@ async function SingleGenerateImage() {
|
||||
|
||||
// 下生图
|
||||
async function NextGenerateImage() {
|
||||
|
||||
let res = undefined
|
||||
let bookTaskDetails = reverseManageStore.selectBookTaskDetail.filter(
|
||||
(item, index) => index >= props.index && !item.imageLock
|
||||
|
||||
@ -382,6 +382,9 @@ async function AddFluxImageAll(type, cover) {
|
||||
if (type == BookImageCategory.FLUX_FORGE) {
|
||||
messageName = DEFINE_STRING.BOOK.FLUX_FORGE_IMAGE_GENERATE_RETURN
|
||||
taskType = BookBackTaskType.FLUX_FORGE_IMAGE
|
||||
} else if (type == BookImageCategory.FLUX_API) {
|
||||
messageName = DEFINE_STRING.BOOK.FLUX_API_IMAGE_GENERATE_RETURN
|
||||
taskType = BookBackTaskType.FLUX_API_IMAGE
|
||||
} else if (type == BookImageCategory.D3) {
|
||||
messageName = DEFINE_STRING.BOOK.D3_IMAGE_GENERATE_RETURN
|
||||
taskType = BookBackTaskType.D3_IMAGE
|
||||
@ -465,7 +468,7 @@ async function GenerateImageAll(cover = true) {
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.FLUX_FORGE) {
|
||||
await AddFluxImageAll(BookImageCategory.FLUX_FORGE, cover)
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.FLUX_API) {
|
||||
await AddFluxImageAll(BookImageCategory.FLUX_FORGE, cover)
|
||||
await AddFluxImageAll(BookImageCategory.FLUX_API, cover)
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.D3) {
|
||||
await AddFluxImageAll(BookImageCategory.D3, cover)
|
||||
} else {
|
||||
|
||||
@ -6,13 +6,11 @@
|
||||
classMame="cd-22223"
|
||||
:max-height="maxHeight"
|
||||
:loading="softwareStore.loading.originDatatableDataLoading"
|
||||
:row-key="rowKey"
|
||||
:columns="createColumns({})"
|
||||
:data="reverseManageStore.selectBookTaskDetail"
|
||||
:pagination="false"
|
||||
:bordered="false"
|
||||
:scroll-x="0"
|
||||
@update:checked-row-keys="handleCheck"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -30,7 +28,9 @@ import ODataTableHeaderPrompt from './ODatatableHeaderPrompt.vue'
|
||||
import ODatatablePrompt from './ODatatablePrompt.vue'
|
||||
import ODataTableAction from './ODataTableAction.vue'
|
||||
import DatatableHeaderGenerateImage from '../MJReverse/DatatableHeaderGenerateImage.vue'
|
||||
import DatatableHeaderImage from '../MJReverse/DatatableHeaderImage.vue'
|
||||
import DatatableGenerateImage from '../MJReverse/DatatableGenerateImage.vue'
|
||||
import BookTaskDetailOptions from '../Components/ManageBook/BookTaskDetailOptions.vue'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
@ -141,7 +141,9 @@ const createColumns = ({}) => {
|
||||
},
|
||||
{
|
||||
// 参数
|
||||
title: '参数',
|
||||
title(row) {
|
||||
return h(BookTaskDetailOptions, { style: 'font-size: 24px;margin-left: 5px' })
|
||||
},
|
||||
key: 'parameter',
|
||||
width: '130',
|
||||
render(row, index) {
|
||||
@ -151,7 +153,8 @@ const createColumns = ({}) => {
|
||||
{
|
||||
// 出图
|
||||
title(row) {
|
||||
return h(DatatableHeaderGenerateImage)
|
||||
// return h(DatatableHeaderGenerateImage)
|
||||
return h(DatatableHeaderImage, { style: 'font-size: 24px; margin-left: 5px' })
|
||||
},
|
||||
key: 'options',
|
||||
className: 'empty-margin',
|
||||
|
||||
12
src/renderer/src/components/Icon/DownloadRound.vue
Normal file
12
src/renderer/src/components/Icon/DownloadRound.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M16.59 9H15V4c0-.55-.45-1-1-1h-4c-.55 0-1 .45-1 1v5H7.41c-.89 0-1.34 1.08-.71 1.71l4.59 4.59c.39.39 1.02.39 1.41 0l4.59-4.59c.63-.63.19-1.71-.7-1.71zM5 19c0 .55.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1H6c-.55 0-1 .45-1 1z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
12
src/renderer/src/components/Icon/MenuOpenRound.vue
Normal file
12
src/renderer/src/components/Icon/MenuOpenRound.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M4 18h11c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1zm0-5h8c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1zM3 7c0 .55.45 1 1 1h11c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1zm17.3 7.88L17.42 12l2.88-2.88a.996.996 0 1 0-1.41-1.41L15.3 11.3a.996.996 0 0 0 0 1.41l3.59 3.59c.39.39 1.02.39 1.41 0c.38-.39.39-1.03 0-1.42z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
12
src/renderer/src/components/Icon/OpenInBrowserRound.vue
Normal file
12
src/renderer/src/components/Icon/OpenInBrowserRound.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M19 4H5a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h3c.55 0 1-.45 1-1s-.45-1-1-1H5V8h14v10h-3c-.55 0-1 .45-1 1s.45 1 1 1h3c1.1 0 2-.9 2-2V6a2 2 0 0 0-2-2zm-7.35 6.35l-2.79 2.79c-.32.32-.1.86.35.86H11v5c0 .55.45 1 1 1s1-.45 1-1v-5h1.79c.45 0 .67-.54.35-.85l-2.79-2.79c-.19-.2-.51-.2-.7-.01z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
14
src/renderer/src/components/Icon/UploadRound.vue
Normal file
14
src/renderer/src/components/Icon/UploadRound.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M10 16h4c.55 0 1-.45 1-1v-5h1.59c.89 0 1.34-1.08.71-1.71L12.71 3.7a.996.996 0 0 0-1.41 0L6.71 8.29c-.63.63-.19 1.71.7 1.71H9v5c0 .55.45 1 1 1zm-4 2h12c.55 0 1 .45 1 1s-.45 1-1 1H6c-.55 0-1-.45-1-1s.45-1 1-1z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
@ -2,7 +2,7 @@ import { messageDark, useMessage } from 'naive-ui'
|
||||
import { defineStore } from 'pinia'
|
||||
import { errorMessage, successMessage } from '../main/Public/generalTools'
|
||||
import { BookTaskStatus } from '../define/enum/bookEnum'
|
||||
import { Book } from '../model/book'
|
||||
import { Book } from '../model/book/book'
|
||||
import { GeneralResponse } from '../model/generalResponse'
|
||||
import { PresetModel } from '../model/preset'
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user