V3.1.8
1. 添加软件高清倍率设置,实现自定义高清倍率(支持两倍、三倍和四倍,默认是两倍) 2. (聚合推文)新增导出草稿。可以依赖做好的草稿文件,只替换图片文件 3. (聚合推文)新增批量生成草稿 4. (聚合推文)修改小说批次任务进行详细界面操作为双击
This commit is contained in:
parent
f4d042f699
commit
0c5988ed41
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "3.1.7",
|
"version": "3.1.8",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "3.1.7",
|
"version": "3.1.8",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alicloud/alimt20181012": "^1.2.0",
|
"@alicloud/alimt20181012": "^1.2.0",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "3.1.7",
|
"version": "3.1.8",
|
||||||
"description": "An AI tool for image processing, video processing, and other functions.",
|
"description": "An AI tool for image processing, video processing, and other functions.",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "laitool.cn",
|
"author": "laitool.cn",
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -12,6 +12,7 @@ export class BookModel extends Realm.Object<BookModel> {
|
|||||||
oldVideoPath: string | null
|
oldVideoPath: string | null
|
||||||
srtPath: string | null
|
srtPath: string | null
|
||||||
audioPath: string | null
|
audioPath: string | null
|
||||||
|
draftDepend?: string // 草稿依赖
|
||||||
draftSrtStyle: string | null // 草稿字幕样式
|
draftSrtStyle: string | null // 草稿字幕样式
|
||||||
backgroundMusic: string | null // 背景音乐ID
|
backgroundMusic: string | null // 背景音乐ID
|
||||||
friendlyReminder: string | null // 友情提示
|
friendlyReminder: string | null // 友情提示
|
||||||
@ -38,6 +39,7 @@ export class BookModel extends Realm.Object<BookModel> {
|
|||||||
oldVideoPath: 'string?',
|
oldVideoPath: 'string?',
|
||||||
srtPath: 'string?',
|
srtPath: 'string?',
|
||||||
audioPath: 'string?',
|
audioPath: 'string?',
|
||||||
|
draftDepend: "string?",
|
||||||
draftSrtStyle: 'string?',
|
draftSrtStyle: 'string?',
|
||||||
backgroundMusic: 'string?',
|
backgroundMusic: 'string?',
|
||||||
friendlyReminder: 'string?',
|
friendlyReminder: 'string?',
|
||||||
|
|||||||
@ -43,6 +43,7 @@ export class BookTaskModel extends Realm.Object<BookTaskModel> {
|
|||||||
name: string
|
name: string
|
||||||
generateVideoPath: string | null
|
generateVideoPath: string | null
|
||||||
srtPath: string | null
|
srtPath: string | null
|
||||||
|
draftDepend?: string // 草稿依赖
|
||||||
audioPath: string | null
|
audioPath: string | null
|
||||||
draftSrtStyle: string | null // 草稿字幕样式
|
draftSrtStyle: string | null // 草稿字幕样式
|
||||||
backgroundMusic: string | null // 背景音乐ID
|
backgroundMusic: string | null // 背景音乐ID
|
||||||
@ -72,6 +73,7 @@ export class BookTaskModel extends Realm.Object<BookTaskModel> {
|
|||||||
name: 'string',
|
name: 'string',
|
||||||
generateVideoPath: 'string?',
|
generateVideoPath: 'string?',
|
||||||
srtPath: 'string?',
|
srtPath: 'string?',
|
||||||
|
draftDepend: "string?",
|
||||||
audioPath: 'string?',
|
audioPath: 'string?',
|
||||||
draftSrtStyle: 'string?',
|
draftSrtStyle: 'string?',
|
||||||
backgroundMusic: 'string?',
|
backgroundMusic: 'string?',
|
||||||
|
|||||||
@ -176,6 +176,27 @@ const migration = (oldRealm: Realm, newRealm: Realm) => {
|
|||||||
newBookTask[i].messageName = ''
|
newBookTask[i].messageName = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if (oldRealm.schemaVersion < 25) {
|
||||||
|
// const oldBookTask = oldRealm.objects('BookTaskDetail')
|
||||||
|
// const newBookTask = newRealm.objects('BookTaskDetail')
|
||||||
|
// for (let i = 0; i < oldBookTask.length; i++) {
|
||||||
|
// newBookTask[i].draftDepend = undefined
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (oldRealm.schemaVersion < 26) {
|
||||||
|
const oldBookTask = oldRealm.objects('BookTask')
|
||||||
|
const newBookTask = newRealm.objects('BookTask')
|
||||||
|
for (let i = 0; i < oldBookTask.length; i++) {
|
||||||
|
newBookTask[i].draftDepend = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oldRealm.schemaVersion < 27) {
|
||||||
|
const oldBookTask = oldRealm.objects('Book')
|
||||||
|
const newBookTask = newRealm.objects('Book')
|
||||||
|
for (let i = 0; i < oldBookTask.length; i++) {
|
||||||
|
newBookTask[i].draftDepend = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BaseRealmService extends BaseService {
|
export class BaseRealmService extends BaseService {
|
||||||
@ -217,7 +238,7 @@ export class BaseRealmService extends BaseService {
|
|||||||
BookTaskDetailModel
|
BookTaskDetailModel
|
||||||
],
|
],
|
||||||
path: this.dbpath,
|
path: this.dbpath,
|
||||||
schemaVersion: 24,
|
schemaVersion: 27,
|
||||||
migration: migration
|
migration: migration
|
||||||
}
|
}
|
||||||
this.realm = await Realm.open(config)
|
this.realm = await Realm.open(config)
|
||||||
|
|||||||
@ -232,7 +232,8 @@ export enum OperateBookType {
|
|||||||
BOOK = 'book', // 这个小说的所有批次
|
BOOK = 'book', // 这个小说的所有批次
|
||||||
BOOKTASK = 'bookTask', // 整个小说批次分镜合并
|
BOOKTASK = 'bookTask', // 整个小说批次分镜合并
|
||||||
BOOKTASKDETAIL = 'bookTaskDetail', // 单个分镜合并
|
BOOKTASKDETAIL = 'bookTaskDetail', // 单个分镜合并
|
||||||
UNDERBOOKTASK = 'underBookTask' // 执行小说批次任务的指定ID以及后面的所有的东西
|
UNDERBOOKTASK = 'underBookTask', // 执行小说批次任务的指定ID以及后面的所有的东西
|
||||||
|
ASSIGNBOOKTASK = 'assignBookTask' // 指定小说批次任务
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CopyImageType {
|
export enum CopyImageType {
|
||||||
|
|||||||
@ -241,14 +241,14 @@ export function BookIpc() {
|
|||||||
// 高清图片前检查,主要是检查图片大小
|
// 高清图片前检查,主要是检查图片大小
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
DEFINE_STRING.BOOK.CHECK_IMAGE_FILE_SIZE,
|
DEFINE_STRING.BOOK.CHECK_IMAGE_FILE_SIZE,
|
||||||
async (event, id, fileSize, operateBookType) =>
|
async (event, id: string | string[], fileSize: number, operateBookType: OperateBookType) =>
|
||||||
await bookImage.CheckImageFileSize(id, fileSize, operateBookType)
|
await bookImage.CheckImageFileSize(id, fileSize, operateBookType)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 开始执行高清图片
|
// 开始执行高清图片
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
DEFINE_STRING.BOOK.HD_IMAGE,
|
DEFINE_STRING.BOOK.HD_IMAGE,
|
||||||
async (event, id, scale, operateBookType) => await bookImage.HDImage(id, scale, operateBookType)
|
async (event, id: string | string[], scale: number, operateBookType: OperateBookType) => await bookImage.HDImage(id, scale, operateBookType)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 删除所有的生成图片
|
// 删除所有的生成图片
|
||||||
@ -310,7 +310,7 @@ export function BookIpc() {
|
|||||||
// 将小说任务添加到剪映草稿
|
// 将小说任务添加到剪映草稿
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
DEFINE_STRING.BOOK.ADD_JIANYING_DRAFT,
|
DEFINE_STRING.BOOK.ADD_JIANYING_DRAFT,
|
||||||
async (event, id, operateBookType) => await bookVideo.AddJianyingDraft(id, operateBookType)
|
async (event, id: string | string[], operateBookType: OperateBookType) => await bookVideo.AddJianyingDraft(id, operateBookType)
|
||||||
)
|
)
|
||||||
//#endregion
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,335 +1,370 @@
|
|||||||
import path from "path";
|
import path from 'path'
|
||||||
import { define } from "../../define/define";
|
import { define } from '../../define/define'
|
||||||
import { Tools } from "../tools";
|
import { Tools } from '../tools'
|
||||||
import { DEFINE_STRING } from "../../define/define_string";
|
import { DEFINE_STRING } from '../../define/define_string'
|
||||||
import { get, has } from "lodash";
|
import { get, has } from 'lodash'
|
||||||
const util = require('util');
|
const util = require('util')
|
||||||
const { spawn, exec } = require('child_process');
|
const { spawn, exec } = require('child_process')
|
||||||
const execAsync = util.promisify(exec);
|
const execAsync = util.promisify(exec)
|
||||||
const fspromises = require("fs").promises;
|
const fspromises = require('fs').promises
|
||||||
|
|
||||||
export class PublicMethod {
|
export class PublicMethod {
|
||||||
constructor(global) {
|
constructor(global) {
|
||||||
this.global = global;
|
this.global = global
|
||||||
this.tools = new Tools();
|
this.tools = new Tools()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改config.json文件中的指定的属性
|
||||||
|
* @param {*} value 0: 要修改的数据 1: 要修改的属性 2: 是否需要解析
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async SaveConfigJsonProperty(value) {
|
||||||
|
try {
|
||||||
|
let data = value[0]
|
||||||
|
let property = value[1]
|
||||||
|
let parse = value[2]
|
||||||
|
if (parse) {
|
||||||
|
data = JSON.parse(value[0])
|
||||||
|
}
|
||||||
|
let json_path = path.join(global.config.project_path, 'scripts/config.json')
|
||||||
|
// 判断文件是不是存在
|
||||||
|
let isExit = await this.tools.checkExists(json_path)
|
||||||
|
let json_data = {}
|
||||||
|
if (!isExit) {
|
||||||
|
const dirPath = path.dirname(json_path)
|
||||||
|
await fspromises.mkdir(dirPath, { recursive: true })
|
||||||
|
await fspromises.writeFile(json_path, '{}')
|
||||||
|
} else {
|
||||||
|
const o_data = await fspromises.readFile(json_path, 'utf8')
|
||||||
|
// 将读取的 JSON 字符串转换为 JavaScript 对象
|
||||||
|
let obj = JSON.parse(o_data)
|
||||||
|
json_data = obj
|
||||||
|
}
|
||||||
|
json_data[property] = data
|
||||||
|
|
||||||
|
await fspromises.writeFile(json_path, JSON.stringify(json_data))
|
||||||
|
return {
|
||||||
|
code: 1
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改config.json文件中的指定的属性
|
* 返回当前项目的config.json文件中的指定的属性信息,若是没有传入属性,则返回所有的信息
|
||||||
* @param {*} value 0: 要修改的数据 1: 要修改的属性 2: 是否需要解析
|
* @param {Array} value 0 要获取的属性 1 返回的默认值
|
||||||
* @returns
|
* @param {Boolean} ckeck 是否需要校验属性不存在
|
||||||
*/
|
* @returns
|
||||||
async SaveConfigJsonProperty(value) {
|
*/
|
||||||
|
async GetConfigJson(value, ckeck = true) {
|
||||||
|
try {
|
||||||
|
value = JSON.parse(value)
|
||||||
|
let srt_config_path = path.join(global.config.project_path, 'scripts/config.json')
|
||||||
|
let data = await this.tools.getJsonFilePropertyValue(
|
||||||
|
srt_config_path,
|
||||||
|
value[0],
|
||||||
|
value[1],
|
||||||
|
ckeck
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
code: 1,
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改生成图片的任务队列数据
|
||||||
|
* @param {传入的要修改的数据数组} value
|
||||||
|
*/
|
||||||
|
async ModifyImageTaskList(value) {
|
||||||
|
this.global.fileQueue.enqueue(
|
||||||
|
async () => {
|
||||||
try {
|
try {
|
||||||
let data = value[0];
|
let task_list_path = path.join(this.global.config.project_path, 'scripts/task_list.json')
|
||||||
let property = value[1];
|
let isE = await this.tools.checkExists(task_list_path)
|
||||||
let parse = value[2];
|
if (!isE) {
|
||||||
if (parse) {
|
throw new Error('任务队列文件不存在。请先添加 批次任务')
|
||||||
data = JSON.parse(value[0])
|
}
|
||||||
}
|
let task_list_json = JSON.parse(await fspromises.readFile(task_list_path, 'utf-8'))
|
||||||
let json_path = path.join(global.config.project_path, "scripts/config.json");
|
// 循环循环数据。修改
|
||||||
// 判断文件是不是存在
|
for (let i = 0; i < value.length; i++) {
|
||||||
let isExit = await this.tools.checkExists(json_path);
|
const element = value[i]
|
||||||
let json_data = {};
|
let index = task_list_json.task_list.findIndex((item) => item.id == element.id)
|
||||||
if (!isExit) {
|
task_list_json.task_list[index] = element
|
||||||
const dirPath = path.dirname(json_path);
|
}
|
||||||
await fspromises.mkdir(dirPath, { recursive: true });
|
await fspromises.writeFile(task_list_path, JSON.stringify(task_list_json))
|
||||||
await fspromises.writeFile(json_path, '{}');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const o_data = await fspromises.readFile(json_path, 'utf8');
|
|
||||||
// 将读取的 JSON 字符串转换为 JavaScript 对象
|
|
||||||
let obj = JSON.parse(o_data);
|
|
||||||
json_data = obj;
|
|
||||||
}
|
|
||||||
json_data[property] = data;
|
|
||||||
|
|
||||||
await fspromises.writeFile(json_path, JSON.stringify(json_data));
|
|
||||||
return {
|
|
||||||
code: 1
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
'modifyFile',
|
||||||
/**
|
'modifyFile',
|
||||||
* 返回当前项目的config.json文件中的指定的属性信息,若是没有传入属性,则返回所有的信息
|
'task_list'
|
||||||
* @param {Array} value 0 要获取的属性 1 返回的默认值
|
)
|
||||||
* @param {Boolean} ckeck 是否需要校验属性不存在
|
this.global.fileQueue.setSubBatchCompletionCallback(
|
||||||
* @returns
|
'modifyFile',
|
||||||
*/
|
'task_list',
|
||||||
async GetConfigJson(value, ckeck = true) {
|
async (failedTasks) => {
|
||||||
try {
|
// 报错
|
||||||
value = JSON.parse(value)
|
if (failedTasks.length > 0) {
|
||||||
let srt_config_path = path.join(global.config.project_path, "scripts/config.json");
|
let message = ''
|
||||||
let data = await this.tools.getJsonFilePropertyValue(srt_config_path, value[0], value[1], ckeck);
|
failedTasks.forEach(({ taskId, error }) => {
|
||||||
return {
|
message += `${taskId}-, \n 错误信息: ${error}` + '\n'
|
||||||
code: 1,
|
})
|
||||||
data: data
|
throw new Error(message)
|
||||||
}
|
// this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
||||||
} catch (error) {
|
// code: 0,
|
||||||
throw error;
|
// message: message
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
||||||
|
// code: 1,
|
||||||
|
// message: "修改成功"
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高清指定的文件夹
|
||||||
|
* @param {要高清的文件夹} folder
|
||||||
|
*/
|
||||||
|
async ImproveFolder(folder) {
|
||||||
|
try {
|
||||||
|
let bakPath = path.join(this.global.config.project_path, 'tmp/bak')
|
||||||
|
let oldInput = path.join(this.global.config.project_path, 'tmp/' + folder)
|
||||||
|
let newInput = path.join(this.global.config.project_path, 'tmp/bak/' + folder)
|
||||||
|
// 创建文件夹
|
||||||
|
let existFolder = await this.tools.checkExists(bakPath)
|
||||||
|
if (!existFolder) {
|
||||||
|
await fspromises.mkdir(bakPath, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
let isExistNewFolder = await this.tools.checkExists(newInput)
|
||||||
|
if (isExistNewFolder) {
|
||||||
|
await fspromises.rm(newInput, { recursive: true, force: true })
|
||||||
|
}
|
||||||
|
// 备份文件
|
||||||
|
await fspromises.rename(oldInput, newInput)
|
||||||
|
//创建同名的文件,用作输出
|
||||||
|
await fspromises.mkdir(oldInput, { recursive: true })
|
||||||
|
|
||||||
|
// 开始高清
|
||||||
|
let command = `"${path.join(
|
||||||
|
define.package_path,
|
||||||
|
'Improve/rnv.exe'
|
||||||
|
)}" -i "${newInput}" -o "${oldInput}" -s ${this.global.config.hdScale ?? 2}`
|
||||||
|
let out = await execAsync(command, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' })
|
||||||
|
console.log(out)
|
||||||
|
await this.ModifyTaskStatus('out_folder', folder, 'video_improvied')
|
||||||
|
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
|
||||||
|
out_folder: folder,
|
||||||
|
status: 'video_improvied'
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
await this.ModifyTaskStatus('out_folder', folder, 'video_improvie_error')
|
||||||
|
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
|
||||||
|
out_folder: folder,
|
||||||
|
status: 'video_improvie_error'
|
||||||
|
})
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改生成图片的任务队列数据
|
* 生成SD相对的JSON文件。删除反推的txt文件
|
||||||
* @param {传入的要修改的数据数组} value
|
*/
|
||||||
*/
|
async AddWebuiJson() {
|
||||||
async ModifyImageTaskList(value) {
|
try {
|
||||||
this.global.fileQueue.enqueue(async () => {
|
// 读取所有txt文件
|
||||||
try {
|
let txtfile = await this.tools.getFilesWithExtensions(
|
||||||
let task_list_path = path.join(this.global.config.project_path, "scripts/task_list.json");
|
path.join(this.global.config.project_path, 'tmp/input_crop'),
|
||||||
let isE = await this.tools.checkExists(task_list_path);
|
'.txt'
|
||||||
if (!isE) {
|
)
|
||||||
throw new Error("任务队列文件不存在。请先添加 批次任务");
|
let image = await this.tools.getFilesWithExtensions(
|
||||||
}
|
path.join(this.global.config.project_path, 'tmp/input_crop'),
|
||||||
let task_list_json = JSON.parse(await fspromises.readFile(task_list_path, "utf-8"));
|
'.png'
|
||||||
// 循环循环数据。修改
|
)
|
||||||
for (let i = 0; i < value.length; i++) {
|
let promptJson = await this.tools.getFilesWithExtensions(
|
||||||
const element = value[i];
|
path.join(this.global.config.project_path, 'tmp/input_crop'),
|
||||||
let index = task_list_json.task_list.findIndex(item => item.id == element.id);
|
'.json'
|
||||||
task_list_json.task_list[index] = element;
|
)
|
||||||
}
|
|
||||||
await fspromises.writeFile(task_list_path, JSON.stringify(task_list_json));
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}, "modifyFile", "modifyFile", "task_list")
|
|
||||||
this.global.fileQueue.setSubBatchCompletionCallback("modifyFile", "task_list", async (failedTasks) => {
|
|
||||||
// 报错
|
|
||||||
if (failedTasks.length > 0) {
|
|
||||||
let message = "";
|
|
||||||
failedTasks.forEach(({ taskId, error }) => {
|
|
||||||
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
|
|
||||||
});
|
|
||||||
throw new Error(message);
|
|
||||||
// this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
|
||||||
// code: 0,
|
|
||||||
// message: message
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
|
||||||
// code: 1,
|
|
||||||
// message: "修改成功"
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
return true;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// json 已经存在,不做后续处理
|
||||||
/**
|
if (image.length == promptJson.length) {
|
||||||
* 高清指定的文件夹
|
return {
|
||||||
* @param {要高清的文件夹} folder
|
code: 1
|
||||||
*/
|
|
||||||
async ImproveFolder(folder) {
|
|
||||||
try {
|
|
||||||
let bakPath = path.join(this.global.config.project_path, "tmp/bak");
|
|
||||||
let oldInput = path.join(this.global.config.project_path, "tmp/" + folder);
|
|
||||||
let newInput = path.join(this.global.config.project_path, "tmp/bak/" + folder)
|
|
||||||
// 创建文件夹
|
|
||||||
let existFolder = await this.tools.checkExists(bakPath);
|
|
||||||
if (!existFolder) {
|
|
||||||
await fspromises.mkdir(bakPath, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
let isExistNewFolder = await this.tools.checkExists(newInput);
|
|
||||||
if (isExistNewFolder) {
|
|
||||||
await fspromises.rm(newInput, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
// 备份文件
|
|
||||||
await fspromises.rename(oldInput, newInput);
|
|
||||||
//创建同名的文件,用作输出
|
|
||||||
await fspromises.mkdir(oldInput, { recursive: true });
|
|
||||||
|
|
||||||
// 开始高清
|
|
||||||
let command = `"${path.join(define.package_path, "Improve/rnv.exe")}" -i "${newInput}" -o "${oldInput}"`;
|
|
||||||
let out = await execAsync(command, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' });
|
|
||||||
console.log(out);
|
|
||||||
await this.ModifyTaskStatus('out_folder', folder, "video_improvied");
|
|
||||||
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
|
|
||||||
out_folder: folder,
|
|
||||||
status: "video_improvied"
|
|
||||||
})
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
await this.ModifyTaskStatus('out_folder', folder, "video_improvie_error");
|
|
||||||
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
|
|
||||||
out_folder: folder,
|
|
||||||
status: "video_improvie_error"
|
|
||||||
})
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if (txtfile.length != image.length) {
|
||||||
* 生成SD相对的JSON文件。删除反推的txt文件
|
throw new Error('关键词文件和图片数量对不上,请检查!!')
|
||||||
*/
|
}
|
||||||
async AddWebuiJson() {
|
let sd_config = JSON.parse(await fspromises.readFile(define.sd_setting, 'utf-8'))
|
||||||
try {
|
|
||||||
// 读取所有txt文件
|
|
||||||
let txtfile = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, 'tmp/input_crop'), '.txt');
|
|
||||||
let image = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, 'tmp/input_crop'), '.png');
|
|
||||||
let promptJson = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, 'tmp/input_crop'), '.json');
|
|
||||||
|
|
||||||
// json 已经存在,不做后续处理
|
for (let i = 0; i < image.length; i++) {
|
||||||
if (image.length == promptJson.length) {
|
const element = image[i]
|
||||||
return {
|
let txtpath = element.split('.png')[0] + '.txt'
|
||||||
code: 1,
|
let prompt = await fspromises.readFile(txtpath, 'utf-8')
|
||||||
}
|
// console.log(txtpath)
|
||||||
}
|
let obj = {}
|
||||||
|
obj.model = sd_config.setting.type
|
||||||
if (txtfile.length != image.length) {
|
obj.api = sd_config.setting.webui_api_url + 'sdapi/v1/img2img'
|
||||||
throw new Error("关键词文件和图片数量对不上,请检查!!")
|
obj.webui_config = {
|
||||||
}
|
sampler_name: sd_config.webui.sampler_name,
|
||||||
let sd_config = JSON.parse(await fspromises.readFile(define.sd_setting, 'utf-8'));
|
prompt: prompt + ',' + sd_config.webui.prompt,
|
||||||
|
negative_prompt: sd_config.webui.negative_prompt,
|
||||||
for (let i = 0; i < image.length; i++) {
|
batch_size: 1,
|
||||||
const element = image[i];
|
steps: sd_config.webui.steps,
|
||||||
let txtpath = element.split('.png')[0] + '.txt';
|
cfg_scale: sd_config.webui.cfg_scale,
|
||||||
let prompt = await fspromises.readFile(txtpath, 'utf-8');
|
denoising_strength: sd_config.webui.denoising_strength,
|
||||||
// console.log(txtpath)
|
width: sd_config.webui.width,
|
||||||
let obj = {}
|
height: sd_config.webui.height,
|
||||||
obj.model = sd_config.setting.type;
|
seed: sd_config.setting.seed,
|
||||||
obj.api = sd_config.setting.webui_api_url + 'sdapi/v1/img2img';
|
init_images: element
|
||||||
obj.webui_config = {
|
|
||||||
sampler_name: sd_config.webui.sampler_name,
|
|
||||||
prompt: prompt + ',' + sd_config.webui.prompt,
|
|
||||||
negative_prompt: sd_config.webui.negative_prompt,
|
|
||||||
batch_size: 1,
|
|
||||||
steps: sd_config.webui.steps,
|
|
||||||
cfg_scale: sd_config.webui.cfg_scale,
|
|
||||||
denoising_strength: sd_config.webui.denoising_strength,
|
|
||||||
width: sd_config.webui.width,
|
|
||||||
height: sd_config.webui.height,
|
|
||||||
seed: sd_config.setting.seed,
|
|
||||||
init_images: element,
|
|
||||||
}
|
|
||||||
obj.adetailer = sd_config.webui.adetailer;
|
|
||||||
|
|
||||||
// 写入
|
|
||||||
await fspromises.writeFile(element + '.json', JSON.stringify(obj));
|
|
||||||
// 删除对应的txt文件
|
|
||||||
await fspromises.unlink(txtpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
obj.adetailer = sd_config.webui.adetailer
|
||||||
|
|
||||||
/**
|
// 写入
|
||||||
* 获取当前项目的生图任务列表
|
await fspromises.writeFile(element + '.json', JSON.stringify(obj))
|
||||||
*/
|
// 删除对应的txt文件
|
||||||
async GetImageTask() {
|
await fspromises.unlink(txtpath)
|
||||||
try {
|
}
|
||||||
let json_path = path.join(this.global.config.project_path, "scripts/task_list.json");
|
|
||||||
let isExit = await this.tools.checkExists(json_path);
|
return {
|
||||||
if (!isExit) {
|
code: 1
|
||||||
return {
|
}
|
||||||
code: 1,
|
} catch (error) {
|
||||||
data: null
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let json_data = JSON.parse(await fspromises.readFile(json_path));
|
|
||||||
return {
|
/**
|
||||||
code: 1,
|
* 获取当前项目的生图任务列表
|
||||||
data: json_data
|
*/
|
||||||
}
|
async GetImageTask() {
|
||||||
} catch (error) {
|
try {
|
||||||
return {
|
let json_path = path.join(this.global.config.project_path, 'scripts/task_list.json')
|
||||||
code: 0,
|
let isExit = await this.tools.checkExists(json_path)
|
||||||
message: error
|
if (!isExit) {
|
||||||
}
|
return {
|
||||||
|
code: 1,
|
||||||
|
data: null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
let json_data = JSON.parse(await fspromises.readFile(json_path))
|
||||||
|
return {
|
||||||
|
code: 1,
|
||||||
|
data: json_data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
message: error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* 修改任务的状态
|
||||||
* 修改任务的状态
|
* @param {查找的类型 id out_folder} type
|
||||||
* @param {查找的类型 id out_folder} type
|
* @param {查找的类型} id
|
||||||
* @param {查找的类型} id
|
* @param {新的状态} newStatus
|
||||||
* @param {新的状态} newStatus
|
*/
|
||||||
*/
|
async ModifyTaskStatus(type, id, newStatus) {
|
||||||
async ModifyTaskStatus(type, id, newStatus) {
|
this.global.fileQueue.enqueue(
|
||||||
this.global.fileQueue.enqueue(async () => {
|
async () => {
|
||||||
try {
|
|
||||||
// 将修改数据写入到一个并发为 1 的队列中
|
|
||||||
let tmp_task = await fspromises.readFile(path.join(this.global.config.project_path, 'scripts/task_list.json'), 'utf-8');
|
|
||||||
console.log(tmp_task)
|
|
||||||
let task = JSON.parse(tmp_task);
|
|
||||||
if (type == "id") {
|
|
||||||
let index = task.task_list.findIndex(item => item.id == id);
|
|
||||||
if (index < 0) {
|
|
||||||
throw new Error("传入的数据未找到");
|
|
||||||
} else {
|
|
||||||
task.task_list[index].status = newStatus;
|
|
||||||
}
|
|
||||||
} else if (type == "out_folder") {
|
|
||||||
let index = task.task_list.findIndex(item => item.out_folder == id);
|
|
||||||
if (index < 0) {
|
|
||||||
throw new Error("传入的数据未找到");
|
|
||||||
} else {
|
|
||||||
task.task_list[index].status = newStatus;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error("输入类型错误")
|
|
||||||
}
|
|
||||||
await fspromises.writeFile(path.join(this.global.config.project_path, 'scripts/task_list.json'), JSON.stringify(task));
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}, "modifyFile", "modifyFile", "task_list")
|
|
||||||
this.global.fileQueue.setSubBatchCompletionCallback("modifyFile", "task_list", async (failedTasks) => {
|
|
||||||
// 报错
|
|
||||||
if (failedTasks.length > 0) {
|
|
||||||
let message = "";
|
|
||||||
failedTasks.forEach(({ taskId, error }) => {
|
|
||||||
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
|
|
||||||
});
|
|
||||||
|
|
||||||
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
|
||||||
code: 0,
|
|
||||||
message: message
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定文件夹下面特定条件的文件夹
|
|
||||||
* @param {指定的文件夹目录} parentFolder
|
|
||||||
* @param {查询条件 start end include} condition
|
|
||||||
* @param {查询的值} value
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async getSubFolderList(parentFolder, condition, value) {
|
|
||||||
try {
|
try {
|
||||||
// console.log(value);
|
// 将修改数据写入到一个并发为 1 的队列中
|
||||||
let folders = await fspromises.readdir(parentFolder, { withFileTypes: true });
|
let tmp_task = await fspromises.readFile(
|
||||||
folders = folders.filter(item => item.isDirectory())
|
path.join(this.global.config.project_path, 'scripts/task_list.json'),
|
||||||
.map(item => item.name)
|
'utf-8'
|
||||||
|
)
|
||||||
if (condition == "start") {
|
console.log(tmp_task)
|
||||||
folders = folders.filter(item => item.startsWith(value));
|
let task = JSON.parse(tmp_task)
|
||||||
} else if (condition == "end") {
|
if (type == 'id') {
|
||||||
folders = folders.filter(item => item.endsWith(value));
|
let index = task.task_list.findIndex((item) => item.id == id)
|
||||||
} else if (condition == "include") {
|
if (index < 0) {
|
||||||
//包含过滤
|
throw new Error('传入的数据未找到')
|
||||||
folders = folders.filter(item => item.includes(value));
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error("条件参数错误");
|
task.task_list[index].status = newStatus
|
||||||
}
|
}
|
||||||
return folders;
|
} else if (type == 'out_folder') {
|
||||||
|
let index = task.task_list.findIndex((item) => item.out_folder == id)
|
||||||
|
if (index < 0) {
|
||||||
|
throw new Error('传入的数据未找到')
|
||||||
|
} else {
|
||||||
|
task.task_list[index].status = newStatus
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('输入类型错误')
|
||||||
|
}
|
||||||
|
await fspromises.writeFile(
|
||||||
|
path.join(this.global.config.project_path, 'scripts/task_list.json'),
|
||||||
|
JSON.stringify(task)
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'modifyFile',
|
||||||
|
'modifyFile',
|
||||||
|
'task_list'
|
||||||
|
)
|
||||||
|
this.global.fileQueue.setSubBatchCompletionCallback(
|
||||||
|
'modifyFile',
|
||||||
|
'task_list',
|
||||||
|
async (failedTasks) => {
|
||||||
|
// 报错
|
||||||
|
if (failedTasks.length > 0) {
|
||||||
|
let message = ''
|
||||||
|
failedTasks.forEach(({ taskId, error }) => {
|
||||||
|
message += `${taskId}-, \n 错误信息: ${error}` + '\n'
|
||||||
|
})
|
||||||
|
|
||||||
|
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
||||||
|
code: 0,
|
||||||
|
message: message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定文件夹下面特定条件的文件夹
|
||||||
|
* @param {指定的文件夹目录} parentFolder
|
||||||
|
* @param {查询条件 start end include} condition
|
||||||
|
* @param {查询的值} value
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getSubFolderList(parentFolder, condition, value) {
|
||||||
|
try {
|
||||||
|
// console.log(value);
|
||||||
|
let folders = await fspromises.readdir(parentFolder, { withFileTypes: true })
|
||||||
|
folders = folders.filter((item) => item.isDirectory()).map((item) => item.name)
|
||||||
|
|
||||||
|
if (condition == 'start') {
|
||||||
|
folders = folders.filter((item) => item.startsWith(value))
|
||||||
|
} else if (condition == 'end') {
|
||||||
|
folders = folders.filter((item) => item.endsWith(value))
|
||||||
|
} else if (condition == 'include') {
|
||||||
|
//包含过滤
|
||||||
|
folders = folders.filter((item) => item.includes(value))
|
||||||
|
} else {
|
||||||
|
throw new Error('条件参数错误')
|
||||||
|
}
|
||||||
|
return folders
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -101,22 +101,30 @@ export class BookImage {
|
|||||||
* @param scale 高清的倍率
|
* @param scale 高清的倍率
|
||||||
* @param operateBookType 操作的类型(支持BOOK,BOOKTASK两种)
|
* @param operateBookType 操作的类型(支持BOOK,BOOKTASK两种)
|
||||||
*/
|
*/
|
||||||
async HDImage(id: string, scale: number, operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
async HDImage(id: string | string[], scale: number, operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
||||||
try {
|
try {
|
||||||
if (scale <= 0 || scale > 4) {
|
if (scale <= 0 || scale > 4) {
|
||||||
throw new Error('高清倍率只能是2,3,4')
|
throw new Error('高清倍率只能是2,3,4')
|
||||||
}
|
}
|
||||||
let bookTasks = undefined as Book.SelectBookTask[]
|
let bookTasks = [] as Book.SelectBookTask[]
|
||||||
if (operateBookType == OperateBookType.BOOK) {
|
if (operateBookType == OperateBookType.BOOK) {
|
||||||
// 获取所有的小说批次任务
|
// 获取所有的小说批次任务
|
||||||
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
||||||
bookId: id
|
bookId: id as string
|
||||||
})).bookTasks
|
})).bookTasks
|
||||||
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
||||||
// 获取当前的小说批次任务
|
// 获取当前的小说批次任务
|
||||||
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
||||||
id: id
|
id: id as string
|
||||||
})).bookTasks
|
})).bookTasks
|
||||||
|
} else if (operateBookType == OperateBookType.ASSIGNBOOKTASK) {
|
||||||
|
for (let i = 0; i < id.length; i++) {
|
||||||
|
const element = id[i];
|
||||||
|
let tmpBookTask = (await this.bookServiceBasic.GetBookTaskData({
|
||||||
|
id: element
|
||||||
|
})).bookTasks
|
||||||
|
bookTasks.push(...tmpBookTask)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("不支持的操作类型,请检查")
|
throw new Error("不支持的操作类型,请检查")
|
||||||
}
|
}
|
||||||
@ -195,20 +203,29 @@ export class BookImage {
|
|||||||
* @param fileSize 单个图片的文件大小
|
* @param fileSize 单个图片的文件大小
|
||||||
* @param operateBookType 操作的类型(支持BOOK,BOOKTASK两种)
|
* @param operateBookType 操作的类型(支持BOOK,BOOKTASK两种)
|
||||||
*/
|
*/
|
||||||
async CheckImageFileSize(id: string, fileSize: number, operateBookType: OperateBookType) {
|
async CheckImageFileSize(id: string | string[], fileSize: number, operateBookType: OperateBookType) {
|
||||||
try {
|
try {
|
||||||
let bookTasks = undefined as Book.SelectBookTask[]
|
let bookTasks = [] as Book.SelectBookTask[]
|
||||||
if (operateBookType == OperateBookType.BOOK) {
|
if (operateBookType == OperateBookType.BOOK) {
|
||||||
// 获取所有的小说批次任务
|
// 获取所有的小说批次任务
|
||||||
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
||||||
bookId: id
|
bookId: id as string
|
||||||
})).bookTasks
|
})).bookTasks
|
||||||
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
||||||
// 获取当前的小说批次任务
|
// 获取当前的小说批次任务
|
||||||
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
||||||
id: id
|
id: id as string
|
||||||
})).bookTasks
|
})).bookTasks
|
||||||
} else {
|
} else if (operateBookType == OperateBookType.ASSIGNBOOKTASK) {
|
||||||
|
for (let i = 0; i < id.length; i++) {
|
||||||
|
const element = id[i];
|
||||||
|
let tempBookTask = (await this.bookServiceBasic.GetBookTaskData({
|
||||||
|
id: element
|
||||||
|
})).bookTasks
|
||||||
|
bookTasks.push(...tempBookTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
throw new Error("不支持的操作类型,请检查")
|
throw new Error("不支持的操作类型,请检查")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,38 +1,24 @@
|
|||||||
import { OperateBookType } from "../../../define/enum/bookEnum";
|
import { OperateBookType } from "../../../define/enum/bookEnum";
|
||||||
import { Book } from "../../../model/book";
|
import { Book } from "../../../model/book";
|
||||||
import { errorMessage, successMessage } from "../../Public/generalTools";
|
import { errorMessage, successMessage } from "../../Public/generalTools";
|
||||||
import { BookService } from "../../../define/db/service/Book/bookService";
|
|
||||||
import { BookTaskService } from "../../../define/db/service/Book/bookTaskService";
|
|
||||||
import { GeneralResponse } from "../../../model/generalResponse";
|
import { GeneralResponse } from "../../../model/generalResponse";
|
||||||
import { Setting } from '../../../main/setting/setting'
|
import { Setting } from '../../../main/setting/setting'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { CheckFolderExistsOrCreate } from "../../../define/Tools/file";
|
import { CheckFolderExistsOrCreate } from "../../../define/Tools/file";
|
||||||
import { BookTaskDetailService } from "../../../define/db/service/Book/bookTaskDetailService";
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { ClipDraft } from '../../Public/clipDraft'
|
import { ClipDraft } from '../../Public/clipDraft'
|
||||||
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
|
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
|
||||||
|
import { isEmpty } from "lodash";
|
||||||
|
import JianyingService from "../jianying/jianyingService";
|
||||||
|
|
||||||
export class BookVideo {
|
export class BookVideo {
|
||||||
bookService: BookService
|
|
||||||
bookTaskService: BookTaskService
|
|
||||||
setting: Setting
|
setting: Setting
|
||||||
bookTaskDetailService: BookTaskDetailService
|
|
||||||
bookServiceBasic: BookServiceBasic
|
bookServiceBasic: BookServiceBasic
|
||||||
|
jianyingService: JianyingService
|
||||||
constructor() {
|
constructor() {
|
||||||
this.setting = new Setting(global)
|
this.setting = new Setting(global)
|
||||||
this.bookServiceBasic = new BookServiceBasic()
|
this.bookServiceBasic = new BookServiceBasic()
|
||||||
}
|
this.jianyingService = new JianyingService()
|
||||||
|
|
||||||
async InitService() {
|
|
||||||
if (!this.bookService) {
|
|
||||||
this.bookService = await BookService.getInstance()
|
|
||||||
}
|
|
||||||
if (!this.bookTaskService) {
|
|
||||||
this.bookTaskService = await BookTaskService.getInstance()
|
|
||||||
}
|
|
||||||
if (!this.bookTaskDetailService) {
|
|
||||||
this.bookTaskDetailService = await BookTaskDetailService.getInstance()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -44,23 +30,22 @@ export class BookVideo {
|
|||||||
async UseBookVideoDataToBookTask(id: string, operateBookType: OperateBookType) {
|
async UseBookVideoDataToBookTask(id: string, operateBookType: OperateBookType) {
|
||||||
try {
|
try {
|
||||||
console.log(id, operateBookType)
|
console.log(id, operateBookType)
|
||||||
await this.InitService();
|
|
||||||
let book = undefined as Book.SelectBook;
|
let book = undefined as Book.SelectBook;
|
||||||
let bookTasks = undefined as Book.SelectBookTask[];
|
let bookTasks = undefined as Book.SelectBookTask[];
|
||||||
if (operateBookType == OperateBookType.BOOK) {
|
if (operateBookType == OperateBookType.BOOK) {
|
||||||
book = this.bookService.GetBookDataById(id);
|
book = await this.bookServiceBasic.GetBookDataById(id);
|
||||||
if (book == null) {
|
if (book == null) {
|
||||||
throw new Error('未找到对应的小说')
|
throw new Error('未找到对应的小说')
|
||||||
}
|
}
|
||||||
bookTasks = this.bookTaskService.GetBookTaskData({
|
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
|
||||||
bookId: id,
|
bookId: id,
|
||||||
}).data;
|
})).bookTasks;
|
||||||
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
||||||
let bookTask = this.bookTaskService.GetBookTaskDataById(id);
|
let bookTask = await this.bookServiceBasic.GetBookTaskDataById(id);
|
||||||
if (bookTask == null) {
|
if (bookTask == null) {
|
||||||
throw new Error('未找到对应的小说任务')
|
throw new Error('未找到对应的小说任务')
|
||||||
}
|
}
|
||||||
book = this.bookService.GetBookDataById(bookTask.bookId);
|
book = await this.bookServiceBasic.GetBookDataById(bookTask.bookId);
|
||||||
if (book == null) {
|
if (book == null) {
|
||||||
throw new Error('未找到对应的小说')
|
throw new Error('未找到对应的小说')
|
||||||
}
|
}
|
||||||
@ -117,9 +102,9 @@ export class BookVideo {
|
|||||||
await CheckFolderExistsOrCreate(path.dirname(configPath));
|
await CheckFolderExistsOrCreate(path.dirname(configPath));
|
||||||
|
|
||||||
// 开始配置
|
// 开始配置
|
||||||
let bookTaskDetail = this.bookTaskDetailService.GetBookTaskData({
|
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailData({
|
||||||
bookTaskId: bookTask.id
|
bookTaskId: bookTask.id
|
||||||
}).data;
|
});
|
||||||
|
|
||||||
let configData = {
|
let configData = {
|
||||||
srt_time_information: [],
|
srt_time_information: [],
|
||||||
@ -144,14 +129,7 @@ export class BookVideo {
|
|||||||
start_time: element.startTime,
|
start_time: element.startTime,
|
||||||
end_time: element.endTime,
|
end_time: element.endTime,
|
||||||
timeLimit: `${element.startTime} -- ${element.endTime}`,
|
timeLimit: `${element.startTime} -- ${element.endTime}`,
|
||||||
subValue: element.subValue?.map(item => {
|
subValue: element.subValue,
|
||||||
return {
|
|
||||||
start_time: item.startTime,
|
|
||||||
end_time: item.endTime,
|
|
||||||
srt_value: item.srtValue,
|
|
||||||
id: item.id
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
character_tags: [],
|
character_tags: [],
|
||||||
gpt_prompt: element.gptPrompt,
|
gpt_prompt: element.gptPrompt,
|
||||||
mjMessage: element.mjMessage,
|
mjMessage: element.mjMessage,
|
||||||
@ -179,28 +157,29 @@ export class BookVideo {
|
|||||||
* @param operateBookType
|
* @param operateBookType
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async AddJianyingDraft(id: string, operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
async AddJianyingDraft(id: string | string[], operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
||||||
try {
|
try {
|
||||||
await this.InitService();
|
|
||||||
console.log(id, operateBookType)
|
console.log(id, operateBookType)
|
||||||
let book = undefined as Book.SelectBook
|
let book = undefined as Book.SelectBook
|
||||||
let bookTasks = undefined as Book.SelectBookTask[]
|
let bookTasks = [] as Book.SelectBookTask[]
|
||||||
if (operateBookType == OperateBookType.BOOK) {
|
if (operateBookType == OperateBookType.ASSIGNBOOKTASK) {
|
||||||
book = this.bookService.GetBookDataById(id);
|
if (id.length <= 0) {
|
||||||
if (book == null) {
|
throw new Error("没有找到小说批次任务,请检查");
|
||||||
throw new Error("没有找到对应的小说数据,请检查");
|
}
|
||||||
|
for (let i = 0; i < id.length; i++) {
|
||||||
|
const element = id[i];
|
||||||
|
let tempBookTask = await this.bookServiceBasic.GetBookTaskDataById(element as string);
|
||||||
|
bookTasks.push(tempBookTask)
|
||||||
|
book = await this.bookServiceBasic.GetBookDataById(tempBookTask.bookId);
|
||||||
}
|
}
|
||||||
bookTasks = this.bookTaskService.GetBookTaskData({
|
|
||||||
bookId: id
|
|
||||||
}).data.bookTasks
|
|
||||||
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
} else if (operateBookType == OperateBookType.BOOKTASK) {
|
||||||
// 直接获取对应的数据
|
// 直接获取对应的数据
|
||||||
let tempBookTask = this.bookTaskService.GetBookTaskDataById(id);
|
let tempBookTask = await this.bookServiceBasic.GetBookTaskDataById(id as string);
|
||||||
if (tempBookTask == null) {
|
if (tempBookTask == null) {
|
||||||
throw new Error("没有找到小说批次任务,请检查");
|
throw new Error("没有找到小说批次任务,请检查");
|
||||||
}
|
}
|
||||||
bookTasks = [tempBookTask]
|
bookTasks = [tempBookTask]
|
||||||
book = this.bookService.GetBookDataById(tempBookTask.bookId);
|
book = await this.bookServiceBasic.GetBookDataById(tempBookTask.bookId);
|
||||||
if (book == null) {
|
if (book == null) {
|
||||||
throw new Error
|
throw new Error
|
||||||
}
|
}
|
||||||
@ -213,26 +192,38 @@ export class BookVideo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 判断是不是生成单个,每次生成都要修改一下配置文件
|
// 判断是不是生成单个,每次生成都要修改一下配置文件
|
||||||
// TODO 后面这个地方要修改
|
|
||||||
// 调用生成草稿的方法
|
// 调用生成草稿的方法
|
||||||
|
|
||||||
let result = []
|
let result = []
|
||||||
for (let i = 0; i < bookTasks.length; i++) {
|
for (let i = 0; i < bookTasks.length; i++) {
|
||||||
const element = bookTasks[i];
|
const element = bookTasks[i];
|
||||||
await this.GenerateConfigFile(book, element);
|
// 判断是不是又依赖的草稿,又依赖的草稿,对于依赖的草稿进行操作
|
||||||
// 数据处理完毕,开始输出
|
|
||||||
let clipDraft = new ClipDraft(global, [element.name, {
|
if ((!isEmpty(element.draftDepend) && operateBookType != OperateBookType.ASSIGNBOOKTASK) || (operateBookType == OperateBookType.ASSIGNBOOKTASK && !isEmpty(book.draftDepend))) {
|
||||||
srt_path: element.srtPath,
|
let draft_name = `${book.name}_${element.name}`;
|
||||||
audio_path: element.audioPath,
|
if (draft_name == element.draftDepend) {
|
||||||
draft_srt_style: element.draftSrtStyle ? element.draftSrtStyle : "0",
|
throw new Error("生成的草稿名称和依赖的草稿名称一样,请检查");
|
||||||
background_music: element.backgroundMusic,
|
}
|
||||||
friendly_reminder: element.friendlyReminder ? element.friendlyReminder : "0",
|
await this.jianyingService.GenerateDraftFromDepend(
|
||||||
}])
|
operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.draftDepend : element.draftDepend,
|
||||||
let res = await clipDraft.addDraft();
|
element.imageFolder, draft_name);
|
||||||
if (res.code == 0) {
|
result.push(draft_name);
|
||||||
throw new Error(res.message)
|
} else {
|
||||||
|
await this.GenerateConfigFile(book, element);
|
||||||
|
// 数据处理完毕,开始输出
|
||||||
|
let clipDraft = new ClipDraft(global, [element.name, {
|
||||||
|
srt_path: operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.srtPath : element.srtPath,
|
||||||
|
audio_path: operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.audioPath : element.audioPath,
|
||||||
|
draft_srt_style: operateBookType == OperateBookType.ASSIGNBOOKTASK ? (book.draftSrtStyle ? book.draftSrtStyle : '0') : (element.draftSrtStyle ? element.draftSrtStyle : "0"),
|
||||||
|
background_music: operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.backgroundMusic : element.backgroundMusic,
|
||||||
|
friendly_reminder: operateBookType == OperateBookType.ASSIGNBOOKTASK ? (book.friendlyReminder ? book.bookFolderPath : '0') : (element.friendlyReminder ? element.friendlyReminder : "0"),
|
||||||
|
}])
|
||||||
|
let res = await clipDraft.addDraft();
|
||||||
|
if (res.code == 0) {
|
||||||
|
throw new Error(res.message)
|
||||||
|
}
|
||||||
|
result.push(res.draft_name);
|
||||||
}
|
}
|
||||||
result.push(res.draft_name);
|
|
||||||
}
|
}
|
||||||
return successMessage(result, `${result.join('\n')} ${'\n'} 剪映草稿添加成功`, "BookTask_AddJianyingDraft")
|
return successMessage(result, `${result.join('\n')} ${'\n'} 剪映草稿添加成功`, "BookTask_AddJianyingDraft")
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { CheckFileOrDirExist, DeleteFolderAllFile } from '../../../define/Tools/file';
|
import { CheckFileOrDirExist, CopyFileOrFolder, DeleteFolderAllFile, GetFilesWithExtensions } from '../../../define/Tools/file';
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { ValidateJson } from '../../../define/Tools/validate';
|
import { ValidateJson } from '../../../define/Tools/validate';
|
||||||
import { FfmpegOptions } from '../ffmpegOptions';
|
import { FfmpegOptions } from '../ffmpegOptions';
|
||||||
@ -38,7 +38,7 @@ class JianyingService {
|
|||||||
* @param projectDir 项目目录
|
* @param projectDir 项目目录
|
||||||
* @param packagePath 包路径
|
* @param packagePath 包路径
|
||||||
*/
|
*/
|
||||||
async GetDraftFrameAndText(draftDir: string, projectDir: string, packagePath: string) {
|
public async GetDraftFrameAndText(draftDir: string, projectDir: string, packagePath: string) {
|
||||||
try {
|
try {
|
||||||
// 获取草稿文件路径
|
// 获取草稿文件路径
|
||||||
let draftJsonPath = path.resolve(draftDir, "draft_content.json");
|
let draftJsonPath = path.resolve(draftDir, "draft_content.json");
|
||||||
@ -101,6 +101,81 @@ class JianyingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param draftName
|
||||||
|
* @param imageFolder
|
||||||
|
* 1、找到对应的依赖的草稿文件,
|
||||||
|
* 2、直接复制一个全新的草稿文件
|
||||||
|
* 3、解析复制出来的草稿文件
|
||||||
|
* 3、找到主轴,只能替换主轴的图片
|
||||||
|
* 3、找到对应的图片文件夹,然后替换对应的图片
|
||||||
|
*/
|
||||||
|
public async GenerateDraftFromDepend(dependDraftName: string, imageFolder: string, draftName: string) {
|
||||||
|
console.log(draftName);
|
||||||
|
let dependDraftPath = path.resolve(global.config.draft_path, dependDraftName);
|
||||||
|
if (!await CheckFileOrDirExist(dependDraftPath)) {
|
||||||
|
throw new Error("依赖的草稿文件不存在,请检查");
|
||||||
|
}
|
||||||
|
let draftPath = path.resolve(global.config.draft_path, draftName);
|
||||||
|
if (await CheckFileOrDirExist(draftPath)) {
|
||||||
|
// 删除文件夹
|
||||||
|
await DeleteFolderAllFile(draftPath, true);
|
||||||
|
}
|
||||||
|
// 复制
|
||||||
|
await CopyFileOrFolder(dependDraftPath, draftPath)
|
||||||
|
|
||||||
|
let images = await GetFilesWithExtensions(imageFolder, ['.png']);
|
||||||
|
|
||||||
|
// 开始处理数据
|
||||||
|
let draftJsonPath = path.resolve(draftPath, "draft_content.json");
|
||||||
|
if (!await CheckFileOrDirExist(draftJsonPath)) {
|
||||||
|
throw new Error("剪映草稿文件数据文件不存在,请先检查");
|
||||||
|
}
|
||||||
|
// 读取草稿文件内容
|
||||||
|
let draftJsonString = await fs.promises.readFile(draftJsonPath, "utf-8");
|
||||||
|
if (!ValidateJson(draftJsonString)) {
|
||||||
|
throw new Error("剪映草稿文件格式错误,请检查");
|
||||||
|
}
|
||||||
|
let draftJson = JSON.parse(draftJsonString);
|
||||||
|
let draftTracks = draftJson.tracks;
|
||||||
|
if (draftTracks.length <= 0) {
|
||||||
|
throw new Error("剪映草稿文件格式错误,没有轨道,请检查");
|
||||||
|
}
|
||||||
|
|
||||||
|
let videoTrack = draftTracks[0];// 只处理主轨道
|
||||||
|
if (videoTrack.type !== "video") {
|
||||||
|
throw new Error("剪映草稿文件格式错误,主轨道不是Video,请检查");
|
||||||
|
}
|
||||||
|
let videoTrackSegments = videoTrack.segments;
|
||||||
|
if (videoTrackSegments.length <= 0) {
|
||||||
|
throw new Error("剪映草稿文件格式错误,主轨道没有对应的图片节点,请检查");
|
||||||
|
}
|
||||||
|
let segmentMaterialNodes = [];
|
||||||
|
for (let i = 0; i < videoTrackSegments.length; i++) {
|
||||||
|
const element = videoTrackSegments[i];
|
||||||
|
let materialId = element.material_id;
|
||||||
|
let materialNode = this.FindNode(draftJson.materials.videos, "id", materialId);
|
||||||
|
segmentMaterialNodes.push(materialNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (images.length !== segmentMaterialNodes.length) {
|
||||||
|
throw new Error("当前新增的任务对应的图片数量和依赖的草稿的主轨道的图片数量不一致,请检查");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接修改
|
||||||
|
for (let i = 0; i < segmentMaterialNodes.length; i++) {
|
||||||
|
const element = segmentMaterialNodes[i];
|
||||||
|
if (!images[i]) {
|
||||||
|
throw new Error("图片数量不对应,请检查");
|
||||||
|
}
|
||||||
|
element.path = images[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 好了 写出草稿文件
|
||||||
|
await fs.promises.writeFile(draftJsonPath, JSON.stringify(draftJson), "utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在节点数组中查找指定类型和值的节点
|
* 在节点数组中查找指定类型和值的节点
|
||||||
* @param nodes 节点数组
|
* @param nodes 节点数组
|
||||||
|
|||||||
1
src/model/Setting/softwareSetting.d.ts
vendored
1
src/model/Setting/softwareSetting.d.ts
vendored
@ -39,5 +39,6 @@ declare namespace SoftwareSettingModel {
|
|||||||
space_image: string = undefined // 空白图片
|
space_image: string = undefined // 空白图片
|
||||||
gpt_key: string = undefined // GPT KEY,
|
gpt_key: string = undefined // GPT KEY,
|
||||||
laiApiSelect: string = undefined // LaiAPI选择
|
laiApiSelect: string = undefined // LaiAPI选择
|
||||||
|
hdScale: number = 2 // HD缩放
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3
src/model/book.d.ts
vendored
3
src/model/book.d.ts
vendored
@ -13,6 +13,7 @@ declare namespace Book {
|
|||||||
oldVideoPath?: string,
|
oldVideoPath?: string,
|
||||||
srtPath?: string,
|
srtPath?: string,
|
||||||
audioPath?: string,
|
audioPath?: string,
|
||||||
|
draftDepend?: string, // 草稿依赖
|
||||||
imageFolder?: string,
|
imageFolder?: string,
|
||||||
draftSrtStyle?: string | null // 草稿字幕样式
|
draftSrtStyle?: string | null // 草稿字幕样式
|
||||||
backgroundMusic?: string | null // 背景音乐ID
|
backgroundMusic?: string | null // 背景音乐ID
|
||||||
@ -54,6 +55,7 @@ declare namespace Book {
|
|||||||
generateVideoPath?: string,
|
generateVideoPath?: string,
|
||||||
srtPath?: string,
|
srtPath?: string,
|
||||||
audioPath?: string,
|
audioPath?: string,
|
||||||
|
draftDepend?: string,
|
||||||
draftSrtStyle?: string | null // 草稿字幕样式
|
draftSrtStyle?: string | null // 草稿字幕样式
|
||||||
backgroundMusic?: string | null // 背景音乐ID
|
backgroundMusic?: string | null // 背景音乐ID
|
||||||
friendlyReminder?: string | null // 友情提示
|
friendlyReminder?: string | null // 友情提示
|
||||||
@ -147,6 +149,7 @@ declare namespace Book {
|
|||||||
bookTaskId?: string
|
bookTaskId?: string
|
||||||
videoPath?: string // 视频地址
|
videoPath?: string // 视频地址
|
||||||
audioPath?: string // 音频地址
|
audioPath?: string // 音频地址
|
||||||
|
draftDepend?: string // 草稿依赖
|
||||||
word?: string // 文案
|
word?: string // 文案
|
||||||
oldImage?: string // 旧图片(用于SD的图生图)
|
oldImage?: string // 旧图片(用于SD的图生图)
|
||||||
afterGpt?: string // GPT生成的文案
|
afterGpt?: string // GPT生成的文案
|
||||||
|
|||||||
@ -239,7 +239,7 @@ const book = {
|
|||||||
await ipcRenderer.invoke(DEFINE_STRING.BOOK.GENERATE_IMAGE_ALL, bookTaskId, imageCategory),
|
await ipcRenderer.invoke(DEFINE_STRING.BOOK.GENERATE_IMAGE_ALL, bookTaskId, imageCategory),
|
||||||
|
|
||||||
// 高清图片前检查
|
// 高清图片前检查
|
||||||
CheckImageFileSize: async (id, fileSize, operateBookType) =>
|
CheckImageFileSize: async (id: string | string[], fileSize: number, operateBookType: OperateBookType) =>
|
||||||
await ipcRenderer.invoke(
|
await ipcRenderer.invoke(
|
||||||
DEFINE_STRING.BOOK.CHECK_IMAGE_FILE_SIZE,
|
DEFINE_STRING.BOOK.CHECK_IMAGE_FILE_SIZE,
|
||||||
id,
|
id,
|
||||||
@ -248,7 +248,7 @@ const book = {
|
|||||||
),
|
),
|
||||||
|
|
||||||
// 高清图片任务
|
// 高清图片任务
|
||||||
HDImage: async (id, scale, operateBookType) =>
|
HDImage: async (id: string | string[], scale: number, operateBookType: OperateBookType) =>
|
||||||
await ipcRenderer.invoke(DEFINE_STRING.BOOK.HD_IMAGE, id, scale, operateBookType),
|
await ipcRenderer.invoke(DEFINE_STRING.BOOK.HD_IMAGE, id, scale, operateBookType),
|
||||||
|
|
||||||
// 将小说视频相关的设置添加到小说任务批次
|
// 将小说视频相关的设置添加到小说任务批次
|
||||||
@ -260,7 +260,7 @@ const book = {
|
|||||||
),
|
),
|
||||||
|
|
||||||
// 添加数据到剪映草稿
|
// 添加数据到剪映草稿
|
||||||
AddJianyingDraft: async (id, operateBookType) =>
|
AddJianyingDraft: async (id: string | string[], operateBookType: OperateBookType) =>
|
||||||
await ipcRenderer.invoke(DEFINE_STRING.BOOK.ADD_JIANYING_DRAFT, id, operateBookType)
|
await ipcRenderer.invoke(DEFINE_STRING.BOOK.ADD_JIANYING_DRAFT, id, operateBookType)
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -48,7 +48,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: ['bookTask'],
|
props: ['bookTask'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
|
||||||
let message = useMessage()
|
let message = useMessage()
|
||||||
let dialog = useDialog()
|
let dialog = useDialog()
|
||||||
let bookTask = ref(props.bookTask)
|
let bookTask = ref(props.bookTask)
|
||||||
@ -63,7 +62,6 @@ export default defineComponent({
|
|||||||
* @param e
|
* @param e
|
||||||
*/
|
*/
|
||||||
async function ReSetBookTaskDetail(e) {
|
async function ReSetBookTaskDetail(e) {
|
||||||
|
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
dialog.warning({
|
dialog.warning({
|
||||||
title: '重置小说任务',
|
title: '重置小说任务',
|
||||||
@ -115,15 +113,28 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function hdImageFunc(id, operateBookType) {
|
async function hdImageFunc(id, operateBookType) {
|
||||||
softwareStore.spin.spinning = true
|
let da = dialog.warning({
|
||||||
softwareStore.spin.tip = '正在高清中。。。'
|
title: '高清提示',
|
||||||
let res = await window.book.HDImage(id, 4, operateBookType)
|
content: `是否确认高清,当前的高清倍数为 ${softwareStore.globalSetting.hdScale} 倍,是否继续?`,
|
||||||
softwareStore.spin.spinning = false
|
positiveText: '继续',
|
||||||
if (res.code == 1) {
|
negativeText: '取消',
|
||||||
message.success('高清成功')
|
onPositiveClick: async () => {
|
||||||
} else {
|
da.destroy()
|
||||||
message.error(res.message)
|
softwareStore.spin.spinning = true
|
||||||
}
|
softwareStore.spin.tip = '正在高清中。。。'
|
||||||
|
let res = await window.book.HDImage(
|
||||||
|
id,
|
||||||
|
softwareStore.globalSetting.hdScale ?? 2,
|
||||||
|
operateBookType
|
||||||
|
)
|
||||||
|
softwareStore.spin.spinning = false
|
||||||
|
if (res.code == 1) {
|
||||||
|
message.success('高清成功')
|
||||||
|
} else {
|
||||||
|
message.error(res.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,10 +182,10 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
async function ClipDraft(e) {
|
async function ClipDraft(e) {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
dialog.info({
|
dialog.info({
|
||||||
closeOnEsc: false,
|
closeOnEsc: false,
|
||||||
title: '生成草稿前检查',
|
title: `生成草稿前检查 ${bookTask.value.name}`,
|
||||||
maskClosable: false,
|
maskClosable: false,
|
||||||
content: () =>
|
content: () =>
|
||||||
h(ManageBookTaskGenerateInformation, { bookTask: bookTask.value, type: 'bookTask' })
|
h(ManageBookTaskGenerateInformation, { bookTask: bookTask.value, type: 'bookTask' })
|
||||||
|
|||||||
@ -46,15 +46,30 @@
|
|||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
<n-form-item label="选择剪映草稿" path="backgroundMusic">
|
||||||
|
<div>
|
||||||
|
<div style="color: red">
|
||||||
|
注意:选择的草稿主轨道的图片数量要和当前的相同,会生成新的草稿并且只会替换图片,保留其余的数据
|
||||||
|
</div>
|
||||||
|
<n-select
|
||||||
|
style="width: 300px"
|
||||||
|
v-model:value="bookTask.draftDepend"
|
||||||
|
filterable
|
||||||
|
placeholder="选择样式"
|
||||||
|
:options="draftSelect"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</n-form-item>
|
||||||
<n-form-item path="backgroundMusic">
|
<n-form-item path="backgroundMusic">
|
||||||
<n-button :disabled="type == 'book'" type="info" @click="UseBookVideoDataToBookTask">{{
|
<n-button :disabled="type == 'book'" type="info" @click="UseBookVideoDataToBookTask"
|
||||||
type == bookTask ? '应用主小说相关数据' : '当前就是用的主小说的数据'
|
>应用主小说相关数据</n-button
|
||||||
}}</n-button>
|
>
|
||||||
<n-button type="info" style="margin-left: 10px" @click="SaveVideoData">保存数据</n-button>
|
<n-button type="info" style="margin-left: 10px" @click="SaveVideoData">保存数据</n-button>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<div v-if="type == 'bookTask'" style="color: red">注意:在生成草稿前要先保存数据</div>
|
<div v-if="type == 'bookTask'" style="color: red">注意:在生成草稿前要先保存数据</div>
|
||||||
<div v-else style="color: red">
|
<div v-else style="color: red">
|
||||||
注意:在生成草稿前要先保存数据,当前会生成全部的草稿,全部会使用上面的参数
|
注意:在生成草稿前要先保存数据,当前会生成选择的草稿,全部会使用上面的参数
|
||||||
</div>
|
</div>
|
||||||
<n-form-item style="display: flex; justify-content: flex-end">
|
<n-form-item style="display: flex; justify-content: flex-end">
|
||||||
<n-button type="info" style="margin-left: 10px" @click="AddJianyingDraft">生成草稿</n-button>
|
<n-button type="info" style="margin-left: 10px" @click="AddJianyingDraft">生成草稿</n-button>
|
||||||
@ -62,136 +77,166 @@
|
|||||||
</n-form>
|
</n-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { useMessage, NForm, NFormItem, NButton, NIcon, NInput, NSelect } from 'naive-ui'
|
import { useMessage, NForm, NFormItem, NButton, NIcon, NInput, NSelect } from 'naive-ui'
|
||||||
import { FolderOpen } from '@vicons/ionicons5'
|
import { FolderOpen } from '@vicons/ionicons5'
|
||||||
import { OperateBookType } from '../../../../../../define/enum/bookEnum'
|
import { OperateBookType } from '../../../../../../define/enum/bookEnum'
|
||||||
|
import { useReverseManageStore } from '../../../../../../stores/reverseManage'
|
||||||
|
|
||||||
export default defineComponent({
|
let props = defineProps({
|
||||||
components: { NForm, NFormItem, NButton, NIcon, NInput, NSelect, FolderOpen },
|
bookTask: undefined,
|
||||||
props: ['bookTask', 'type'],
|
type: undefined,
|
||||||
setup(props) {
|
selectBookTask: []
|
||||||
let bookTask = ref(props.bookTask)
|
})
|
||||||
|
|
||||||
let type = ref(props.type)
|
let bookTask = ref(props.bookTask)
|
||||||
let backgroundMusicOptions = ref([])
|
let type = ref(props.type)
|
||||||
let message = useMessage()
|
|
||||||
onMounted(async () => {
|
let backgroundMusicOptions = ref([])
|
||||||
// 获取初始化的背景音乐列表
|
let message = useMessage()
|
||||||
await window.api.GetBackgroundMusicConfigList((value) => {
|
let draftSelect = ref([])
|
||||||
if (value.code == 0) {
|
let reverseManageStore = useReverseManageStore()
|
||||||
message.error(value.message)
|
|
||||||
return
|
onMounted(async () => {
|
||||||
}
|
// 获取草稿文件列表
|
||||||
for (let i = 0; i < value.value.length; i++) {
|
window.api.getDraftFileList((value) => {
|
||||||
const element = value.value[i]
|
value.forEach((element) => {
|
||||||
let obj = {
|
let obj = {
|
||||||
label: element.name,
|
label: element,
|
||||||
value: element.id
|
value: element
|
||||||
}
|
}
|
||||||
backgroundMusicOptions.value.push(obj)
|
draftSelect.value.push(obj)
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
/**
|
// 获取初始化的背景音乐列表
|
||||||
* 选择对应的字幕文件
|
await window.api.GetBackgroundMusicConfigList((value) => {
|
||||||
*/
|
if (value.code == 0) {
|
||||||
async function SelectSrtFile() {
|
message.error(value.message)
|
||||||
window.api.SelectFile(['srt'], (value) => {
|
return
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bookTask.value.srtPath = value.value
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
for (let i = 0; i < value.value.length; i++) {
|
||||||
/**
|
const element = value.value[i]
|
||||||
* 选择对应的配音文件
|
let obj = {
|
||||||
*/
|
label: element.name,
|
||||||
async function SelectMusicFile() {
|
value: element.id
|
||||||
window.api.SelectFile(['mp3', 'wav'], (value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bookTask.value.audioPath = value.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用主小说相关数据
|
|
||||||
*/
|
|
||||||
async function UseBookVideoDataToBookTask() {
|
|
||||||
if (type.value == 'book') {
|
|
||||||
message.error('当前状态这个按钮不可用')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let res = await window.book.UseBookVideoDataToBookTask(
|
|
||||||
bookTask.value.id,
|
|
||||||
OperateBookType.BOOKTASK
|
|
||||||
)
|
|
||||||
|
|
||||||
if (res.code == 0) {
|
|
||||||
message.error(res.message)
|
|
||||||
} else {
|
|
||||||
// 将数据写回去
|
|
||||||
bookTask.value.backgroundMusic = res.data.backgroundMusic
|
|
||||||
bookTask.value.friendlyReminder = res.data.friendlyReminder
|
|
||||||
bookTask.value.draftSrtStyle = res.data.draftSrtStyle
|
|
||||||
bookTask.value.srtPath = res.data.srtPath
|
|
||||||
bookTask.value.audioPath = res.data.audioPath
|
|
||||||
|
|
||||||
message.success('应用主小说相关数据成功')
|
|
||||||
}
|
}
|
||||||
|
backgroundMusicOptions.value.push(obj)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存数据
|
* 选择对应的字幕文件
|
||||||
*/
|
*/
|
||||||
async function SaveVideoData() {
|
async function SelectSrtFile() {
|
||||||
let res = await window.db.UpdateBookTaskData(bookTask.value.id, {
|
window.api.SelectFile(['srt'], (value) => {
|
||||||
srtPath: bookTask.value.srtPath,
|
if (value.code == 0) {
|
||||||
audioPath: bookTask.value.audioPath,
|
message.error(value.message)
|
||||||
backgroundMusic: bookTask.value.backgroundMusic,
|
return
|
||||||
friendlyReminder: bookTask.value.friendlyReminder,
|
|
||||||
draftSrtStyle: bookTask.value.draftSrtStyle
|
|
||||||
})
|
|
||||||
if (res.code == 0) {
|
|
||||||
message.error('保存小说批次数据失败')
|
|
||||||
} else {
|
|
||||||
message.success('保存小说批次数据成功')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
bookTask.value.srtPath = value.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加草稿
|
* 选择对应的配音文件
|
||||||
*/
|
*/
|
||||||
async function AddJianyingDraft() {
|
async function SelectMusicFile() {
|
||||||
let res = await window.book.AddJianyingDraft(bookTask.value.id, OperateBookType.BOOKTASK)
|
window.api.SelectFile(['mp3', 'wav'], (value) => {
|
||||||
window.api.showGlobalMessageDialog(res)
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
bookTask.value.audioPath = value.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
/**
|
||||||
bookTask,
|
* 应用主小说相关数据
|
||||||
type,
|
*/
|
||||||
AddJianyingDraft,
|
async function UseBookVideoDataToBookTask() {
|
||||||
SelectSrtFile,
|
if (type.value == 'book') {
|
||||||
SelectMusicFile,
|
message.error('当前状态这个按钮不可用')
|
||||||
SaveVideoData,
|
return
|
||||||
UseBookVideoDataToBookTask,
|
|
||||||
backgroundMusicOptions,
|
|
||||||
rules: {
|
|
||||||
srtPath: [
|
|
||||||
{ required: true, message: '请选择背景音乐', trigger: ['input', 'blur', 'change'] }
|
|
||||||
],
|
|
||||||
audioPath: [
|
|
||||||
{ required: true, message: '请选择音频文件', trigger: ['input', 'blur', 'change'] }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
let res = await window.book.UseBookVideoDataToBookTask(
|
||||||
|
bookTask.value.id,
|
||||||
|
OperateBookType.BOOKTASK
|
||||||
|
)
|
||||||
|
|
||||||
|
if (res.code == 0) {
|
||||||
|
message.error(res.message)
|
||||||
|
} else {
|
||||||
|
// 将数据写回去
|
||||||
|
bookTask.value.backgroundMusic = res.data.backgroundMusic
|
||||||
|
bookTask.value.friendlyReminder = res.data.friendlyReminder
|
||||||
|
bookTask.value.draftSrtStyle = res.data.draftSrtStyle
|
||||||
|
bookTask.value.srtPath = res.data.srtPath
|
||||||
|
bookTask.value.audioPath = res.data.audioPath
|
||||||
|
|
||||||
|
message.success('应用主小说相关数据成功')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存数据
|
||||||
|
*/
|
||||||
|
async function SaveVideoData() {
|
||||||
|
console.log('SaveVideoData', bookTask.value)
|
||||||
|
if (props.type == 'book') {
|
||||||
|
let res = await window.db.UpdateBookData(bookTask.value.id, {
|
||||||
|
srtPath: bookTask.value.srtPath,
|
||||||
|
audioPath: bookTask.value.audioPath,
|
||||||
|
backgroundMusic: bookTask.value.backgroundMusic,
|
||||||
|
friendlyReminder: bookTask.value.friendlyReminder,
|
||||||
|
draftSrtStyle: bookTask.value.draftSrtStyle,
|
||||||
|
draftDepend: bookTask.value.draftDepend
|
||||||
|
})
|
||||||
|
if (res.code == 0) {
|
||||||
|
message.error(res.message)
|
||||||
|
} else {
|
||||||
|
message.success('保存小说数据成功')
|
||||||
|
}
|
||||||
|
} else if (props.type == 'bookTask') {
|
||||||
|
let res = await window.db.UpdateBookTaskData(bookTask.value.id, {
|
||||||
|
srtPath: bookTask.value.srtPath,
|
||||||
|
audioPath: bookTask.value.audioPath,
|
||||||
|
backgroundMusic: bookTask.value.backgroundMusic,
|
||||||
|
friendlyReminder: bookTask.value.friendlyReminder,
|
||||||
|
draftSrtStyle: bookTask.value.draftSrtStyle,
|
||||||
|
draftDepend: bookTask.value.draftDepend
|
||||||
|
})
|
||||||
|
if (res.code == 0) {
|
||||||
|
message.error(res.message)
|
||||||
|
} else {
|
||||||
|
message.success('保存小说批次数据成功')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error('未知的操作类型,请检查')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加草稿
|
||||||
|
*/
|
||||||
|
async function AddJianyingDraft() {
|
||||||
|
if (props.type == 'book') {
|
||||||
|
let res = await window.book.AddJianyingDraft(
|
||||||
|
props.selectBookTask,
|
||||||
|
OperateBookType.ASSIGNBOOKTASK
|
||||||
|
)
|
||||||
|
window.api.showGlobalMessageDialog(res)
|
||||||
|
} else if (props.type == 'bookTask') {
|
||||||
|
let res = await window.book.AddJianyingDraft(bookTask.value.id, OperateBookType.BOOKTASK)
|
||||||
|
window.api.showGlobalMessageDialog(res)
|
||||||
|
} else {
|
||||||
|
message.error('未知的操作类型,请检查')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let rules = ref({
|
||||||
|
srtPath: [{ required: true, message: '请选择背景音乐', trigger: ['input', 'blur', 'change'] }],
|
||||||
|
audioPath: [{ required: true, message: '请选择音频文件', trigger: ['input', 'blur', 'change'] }]
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="margin-bottom: 5px; margin-left: 5px; display: flex; align-items: center">
|
<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 :render-icon="renderIcon" size="small" type="info" @click="AddBookDialog()"
|
||||||
>新增</n-button
|
>新增</n-button
|
||||||
>
|
>
|
||||||
<n-button style="margin-left: 5px" size="small" type="info" @click="HDImageAll"
|
<n-button style="margin-left: 5px" size="small" type="info" @click="HDImageAll()"
|
||||||
>一键高清</n-button
|
>一键高清</n-button
|
||||||
>
|
>
|
||||||
<n-button style="margin-left: 5px" type="info" size="small" @click="DraftAll"
|
<n-button style="margin-left: 5px" type="info" size="small" @click="DraftAll()"
|
||||||
>一键草稿</n-button
|
>一键草稿</n-button
|
||||||
>
|
>
|
||||||
<n-button style="margin-left: 5px" type="info" size="small" @click="VideoAll"
|
<n-button style="margin-left: 5px" type="info" size="small" @click="VideoAll()"
|
||||||
>一键视频</n-button
|
>一键视频</n-button
|
||||||
>
|
>
|
||||||
<n-button style="margin-left: 5px" type="info" size="small" @click="ResetAll"
|
<n-button style="margin-left: 5px" type="info" size="small" @click="ResetAll()"
|
||||||
>一键重置</n-button
|
>一键重置</n-button
|
||||||
>
|
>
|
||||||
<n-button style="margin-left: 5px" type="info" size="small" @click="DeleteAll"
|
<n-button style="margin-left: 5px" type="info" size="small" @click="DeleteAll()"
|
||||||
>一键删除</n-button
|
>一键删除</n-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -26,11 +26,13 @@
|
|||||||
:data="reverseManageStore.bookTaskData"
|
:data="reverseManageStore.bookTaskData"
|
||||||
:scroll-x="800"
|
:scroll-x="800"
|
||||||
:row-props="rowProps"
|
:row-props="rowProps"
|
||||||
|
:row-key="rowKey"
|
||||||
|
@update:checked-row-keys="handleCheck"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||||
import { useMessage, useDialog, NButton, NDataTable, NIcon, NWatermark } from 'naive-ui'
|
import { useMessage, useDialog, NButton, NDataTable, NIcon, NWatermark } from 'naive-ui'
|
||||||
import { useReverseManageStore } from '../../../../stores/reverseManage'
|
import { useReverseManageStore } from '../../../../stores/reverseManage'
|
||||||
@ -42,198 +44,208 @@ import { OperateBookType } from '../../../../define/enum/bookEnum'
|
|||||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||||
import { ResponseMessageType } from '../../../../define/enum/softwareEnum'
|
import { ResponseMessageType } from '../../../../define/enum/softwareEnum'
|
||||||
import AddBookTask from './Components/ManageBook/AddBookTask.vue'
|
import AddBookTask from './Components/ManageBook/AddBookTask.vue'
|
||||||
|
import ManageBookTaskGenerateInformation from './Components/ManageBook/ManageBookTaskGenerateInformation.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
let reverseManageStore = useReverseManageStore()
|
||||||
components: {
|
let softwareStore = useSoftwareStore()
|
||||||
NButton,
|
let dialog = useDialog()
|
||||||
NDataTable,
|
const router = useRouter()
|
||||||
BookTaskListAction,
|
let message = useMessage()
|
||||||
NWatermark
|
let columns = createColumns()
|
||||||
},
|
const checkedRowKeysRef = ref([])
|
||||||
|
onMounted(async () => {
|
||||||
|
window.api.setEventListen([DEFINE_STRING.BOOK.MAIN_DATA_RETURN], (value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (value.type == ResponseMessageType.HD_IMAGE) {
|
||||||
|
softwareStore.spin.tip = `正在高清中 ${value.data.current} / ${value.data.total}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
setup() {
|
onUnmounted(() => {
|
||||||
let reverseManageStore = useReverseManageStore()
|
window.api.removeEventListen([DEFINE_STRING.BOOK.MAIN_DATA_RETURN])
|
||||||
let softwareStore = useSoftwareStore()
|
})
|
||||||
let dialog = useDialog()
|
|
||||||
const router = useRouter()
|
function rowKey(row) {
|
||||||
let message = useMessage()
|
return row.id
|
||||||
onMounted(async () => {
|
}
|
||||||
window.api.setEventListen([DEFINE_STRING.BOOK.MAIN_DATA_RETURN], (value) => {
|
|
||||||
if (value.code == 0) {
|
function handleCheck(rowKeys) {
|
||||||
message.error(value.message)
|
checkedRowKeysRef.value = rowKeys
|
||||||
return
|
}
|
||||||
}
|
|
||||||
if (value.type == ResponseMessageType.HD_IMAGE) {
|
function createColumns() {
|
||||||
softwareStore.spin.tip = `正在高清中 ${value.data.current} / ${value.data.total}`
|
return [
|
||||||
}
|
{
|
||||||
})
|
type: 'selection'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'No.',
|
||||||
|
key: 'no',
|
||||||
|
width: 80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
key: 'name',
|
||||||
|
width: 130
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '风格',
|
||||||
|
key: 'styleList'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '前缀',
|
||||||
|
key: 'prefix',
|
||||||
|
width: 130
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
key: 'status',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 215,
|
||||||
|
fixed: 'right',
|
||||||
|
render(row, index) {
|
||||||
|
return h(BookTaskListAction, {
|
||||||
|
bookTask: row
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高清数据
|
||||||
|
*/
|
||||||
|
async function hdImageFunc(id, operateBookType) {
|
||||||
|
softwareStore.spin.spinning = true
|
||||||
|
softwareStore.spin.tip = '正在高清中。。。'
|
||||||
|
let res = await window.book.HDImage(id, 4, operateBookType)
|
||||||
|
softwareStore.spin.spinning = false
|
||||||
|
if (res.code == 1) {
|
||||||
|
message.success('高清成功')
|
||||||
|
} else {
|
||||||
|
message.error(res.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一键高清全部
|
||||||
|
*/
|
||||||
|
async function HDImageAll() {
|
||||||
|
console.log('一键高清', checkedRowKeysRef.value)
|
||||||
|
if (checkedRowKeysRef.value.length == 0) {
|
||||||
|
message.error('请选择要高清的数据')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
softwareStore.spin.spinning = true
|
||||||
|
softwareStore.spin.tip = '正在进行高清检查。。。'
|
||||||
|
let checkImage = await window.book.CheckImageFileSize(
|
||||||
|
[...checkedRowKeysRef.value],
|
||||||
|
10240,
|
||||||
|
OperateBookType.ASSIGNBOOKTASK
|
||||||
|
)
|
||||||
|
softwareStore.spin.spinning = false
|
||||||
|
if (checkImage.code == 0) {
|
||||||
|
message.error(checkImage.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 高清检查完成
|
||||||
|
if (checkImage.data && checkImage.data.length > 0) {
|
||||||
|
// 出现了图片大的,用户判断是不是需要高清
|
||||||
|
let msg = checkImage.data.map((item, index) => {
|
||||||
|
return item.outImagePath + '\n'
|
||||||
})
|
})
|
||||||
|
dialog.warning({
|
||||||
onUnmounted(() => {
|
title: '高清警告',
|
||||||
window.api.removeEventListen([DEFINE_STRING.BOOK.MAIN_DATA_RETURN])
|
content: '下面的图片大于10MB,是否继续高清?' + '\n' + msg,
|
||||||
|
positiveText: '确定',
|
||||||
|
negativeText: '取消',
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
alert('确认高清')
|
||||||
|
await hdImageFunc([...checkedRowKeysRef.value], OperateBookType.ASSIGNBOOKTASK)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
// 没有就直接高清
|
||||||
|
await hdImageFunc([...checkedRowKeysRef.value], OperateBookType.ASSIGNBOOKTASK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createColumns() {
|
async function AddBookDialog() {
|
||||||
return [
|
message.info('新增' + reverseManageStore.selectBook.id)
|
||||||
{
|
dialog.create({
|
||||||
title: 'No.',
|
title: '新增小说批次任务',
|
||||||
key: 'no',
|
showIcon: false,
|
||||||
width: 80
|
content: () => h(AddBookTask),
|
||||||
},
|
style: { width: '600px' }
|
||||||
{
|
})
|
||||||
title: '名称',
|
}
|
||||||
key: 'name',
|
|
||||||
width: 130
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '风格',
|
|
||||||
key: 'styleList'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '前缀',
|
|
||||||
key: 'prefix',
|
|
||||||
width: 130
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '状态',
|
|
||||||
key: 'status',
|
|
||||||
width: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
width: 215,
|
|
||||||
fixed: 'right',
|
|
||||||
render(row, index) {
|
|
||||||
|
|
||||||
return h(BookTaskListAction, {
|
|
||||||
bookTask: row
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 高清数据
|
* 一键生成草稿
|
||||||
*/
|
*/
|
||||||
async function hdImageFunc(id, operateBookType) {
|
async function DraftAll() {
|
||||||
softwareStore.spin.spinning = true
|
if (checkedRowKeysRef.value.length == 0) {
|
||||||
softwareStore.spin.tip = '正在高清中。。。'
|
message.error('请选择要生成草稿的任务')
|
||||||
let res = await window.book.HDImage(id, 4, operateBookType)
|
return
|
||||||
softwareStore.spin.spinning = false
|
}
|
||||||
if (res.code == 1) {
|
// 草稿弹窗
|
||||||
message.success('高清成功')
|
dialog.info({
|
||||||
} else {
|
closeOnEsc: false,
|
||||||
message.error(res.message)
|
title: `生成草稿前检查 ${reverseManageStore.selectBook.name}`,
|
||||||
}
|
maskClosable: false,
|
||||||
}
|
content: () =>
|
||||||
|
h(ManageBookTaskGenerateInformation, {
|
||||||
/**
|
bookTask: reverseManageStore.selectBook,
|
||||||
* 一键高清全部
|
type: 'book',
|
||||||
*/
|
selectBookTask: [...checkedRowKeysRef.value]
|
||||||
async function HDImageAll() {
|
|
||||||
alert('高清全部')
|
|
||||||
softwareStore.spin.spinning = true
|
|
||||||
softwareStore.spin.tip = '正在进行高清检查。。。'
|
|
||||||
let checkImage = await window.book.CheckImageFileSize(
|
|
||||||
reverseManageStore.selectBook.id,
|
|
||||||
10240,
|
|
||||||
OperateBookType.BOOK
|
|
||||||
)
|
|
||||||
softwareStore.spin.spinning = false
|
|
||||||
if (checkImage.code == 0) {
|
|
||||||
message.error(checkImage.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 高清检查完成
|
|
||||||
if (checkImage.data && checkImage.data.length > 0) {
|
|
||||||
// 出现了图片大的,用户判断是不是需要高清
|
|
||||||
let msg = checkImage.data.map((item, index) => {
|
|
||||||
return item.outImagePath + '\n'
|
|
||||||
})
|
|
||||||
dialog.warning({
|
|
||||||
title: '高清警告',
|
|
||||||
content: '下面的图片大于10MB,是否继续高清?' + '\n' + msg,
|
|
||||||
positiveText: '确定',
|
|
||||||
negativeText: '取消',
|
|
||||||
onPositiveClick: async () => {
|
|
||||||
alert('确认高清')
|
|
||||||
await hdImageFunc(reverseManageStore.selectBook.id, OperateBookType.BOOK)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// 没有就直接高清
|
|
||||||
await hdImageFunc(reverseManageStore.selectBook.id, OperateBookType.BOOK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function AddBookDialog() {
|
|
||||||
message.info('新增' + reverseManageStore.selectBook.id)
|
|
||||||
dialog.create({
|
|
||||||
title: '新增小说批次任务',
|
|
||||||
showIcon: false,
|
|
||||||
content: () => h(AddBookTask),
|
|
||||||
style: { width: '600px' }
|
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一键生成草稿
|
* 一键生成视频
|
||||||
*/
|
*/
|
||||||
async function DraftAll() {
|
async function VideoAll() {
|
||||||
alert('草稿全部')
|
alert('视频全部')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一键生成视频
|
* 一键重置
|
||||||
*/
|
*/
|
||||||
async function VideoAll() {
|
async function ResetAll() {
|
||||||
alert('视频全部')
|
alert('重置全部')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一键重置
|
* 一键删除
|
||||||
*/
|
*/
|
||||||
async function ResetAll() {
|
async function DeleteAll() {
|
||||||
alert('重置全部')
|
alert('删除全部')
|
||||||
}
|
}
|
||||||
|
const renderIcon = () => {
|
||||||
/**
|
return h(NIcon, null, {
|
||||||
* 一键删除
|
default: () => h(AddSharp, { size: '40', color: 'white' }, {})
|
||||||
*/
|
})
|
||||||
async function DeleteAll() {
|
}
|
||||||
alert('删除全部')
|
const rowProps = (row) => {
|
||||||
}
|
return {
|
||||||
|
style: 'cursor: pointer;',
|
||||||
return {
|
ondblclick: async () => {
|
||||||
reverseManageStore,
|
// message.info(row.id)
|
||||||
AddBookDialog,
|
reverseManageStore.selectBookTask = row
|
||||||
HDImageAll,
|
softwareStore.spin.spinning = true
|
||||||
DraftAll,
|
softwareStore.spin.tip = '正在加载数据'
|
||||||
VideoAll,
|
// 跳转
|
||||||
ResetAll,
|
router.push({ name: 'manage_book', params: { id: row.id } })
|
||||||
DeleteAll,
|
|
||||||
columns: createColumns(),
|
|
||||||
renderIcon() {
|
|
||||||
return h(NIcon, null, {
|
|
||||||
default: () => h(AddSharp, { size: '40', color: 'white' }, {})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
rowProps: (row) => {
|
|
||||||
return {
|
|
||||||
style: 'cursor: pointer;',
|
|
||||||
onClick: async () => {
|
|
||||||
// message.info(row.id)
|
|
||||||
reverseManageStore.selectBookTask = row
|
|
||||||
softwareStore.spin.spinning = true
|
|
||||||
softwareStore.spin.tip = '正在加载数据'
|
|
||||||
// 跳转
|
|
||||||
router.push({ name: 'manage_book', params: { id: row.id } })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="height: 100%">
|
<div style="height: 100%">
|
||||||
<ManageBook style="height: 100%" v-if="softwareStore.softWare.reverse_display_show" />
|
<ManageBook style="height: 100%" v-if="softwareStore.softWare.reverse_display_show" />
|
||||||
<n-split v-else direction="horizontal" :min="0.4" :max="0.8" :default-size="0.6" height="100%">
|
<n-split v-else direction="horizontal" :min="0.4" :max="0.8" :default-size="0.4" height="100%">
|
||||||
<template #1> <ManageBook style="height: 100%" /> </template>
|
<template #1> <ManageBook style="height: 100%" /> </template>
|
||||||
<template #2>
|
<template #2>
|
||||||
<ManageBookTask style="height: 100%" />
|
<ManageBookTask style="height: 100%" />
|
||||||
|
|||||||
@ -46,14 +46,24 @@
|
|||||||
<template #unchecked> 亮 </template>
|
<template #unchecked> 亮 </template>
|
||||||
</n-switch>
|
</n-switch>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="人物场景选择模式" style="margin-left: 20px">
|
<n-form-item label="选择高清倍率" style="margin-left: 20px">
|
||||||
|
<n-select
|
||||||
|
size="small"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="hdSelectOptions"
|
||||||
|
v-model:value="formValue.hdScale"
|
||||||
|
style="width: 120px"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item style="margin-left: 20px" label="人物场景选择模式">
|
||||||
<n-select
|
<n-select
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
:options="character_select_model_options"
|
:options="character_select_model_options"
|
||||||
v-model:value="formValue.character_select_model"
|
v-model:value="formValue.character_select_model"
|
||||||
style="width: 120px"
|
style="width: 120px"
|
||||||
/>
|
>
|
||||||
|
</n-select>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item style="margin-left: 20px"
|
<n-form-item style="margin-left: 20px"
|
||||||
><n-checkbox v-model:checked="formValue.window_wh_bm_remember"
|
><n-checkbox v-model:checked="formValue.window_wh_bm_remember"
|
||||||
@ -212,12 +222,27 @@ export default defineComponent({
|
|||||||
theme: softwareStore.globalSetting.theme,
|
theme: softwareStore.globalSetting.theme,
|
||||||
character_select_model: window.config.character_select_model,
|
character_select_model: window.config.character_select_model,
|
||||||
window_wh_bm_remember: window.config.window_wh_bm_remember,
|
window_wh_bm_remember: window.config.window_wh_bm_remember,
|
||||||
laiApiSelect: window.config.laiApiSelect ? window.config.laiApiSelect : LaiAPIType.MAIN
|
laiApiSelect: window.config.laiApiSelect ? window.config.laiApiSelect : LaiAPIType.MAIN,
|
||||||
|
hdScale: window.config.hdScale ?? 2
|
||||||
})
|
})
|
||||||
let show = ref(false)
|
let show = ref(false)
|
||||||
let gpt_options = ref([])
|
let gpt_options = ref([])
|
||||||
let gpt_model_options = ref([])
|
let gpt_model_options = ref([])
|
||||||
let character_select_model_options = ref([])
|
let character_select_model_options = ref([])
|
||||||
|
let hdSelectOptions = ref([
|
||||||
|
{
|
||||||
|
label: '2倍',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '3倍',
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '4倍',
|
||||||
|
value: 4
|
||||||
|
}
|
||||||
|
])
|
||||||
let dialog = useDialog()
|
let dialog = useDialog()
|
||||||
let loading = ref(false)
|
let loading = ref(false)
|
||||||
/**
|
/**
|
||||||
@ -472,6 +497,7 @@ export default defineComponent({
|
|||||||
AddGptPrompt,
|
AddGptPrompt,
|
||||||
character_select_model_options,
|
character_select_model_options,
|
||||||
softwareStore,
|
softwareStore,
|
||||||
|
hdSelectOptions,
|
||||||
ModifyTranslateSetting,
|
ModifyTranslateSetting,
|
||||||
laiApiOptions: [
|
laiApiOptions: [
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user