1086 lines
33 KiB
Vue
1086 lines
33 KiB
Vue
<template>
|
||
<div>
|
||
<n-data-table
|
||
id="1111"
|
||
:max-height="maxHeight"
|
||
:row-key="rowKey"
|
||
:columns="columns"
|
||
:data="data"
|
||
:pagination="false"
|
||
:bordered="false"
|
||
:scroll-x="0"
|
||
@update:checked-row-keys="handleCheck"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
ref,
|
||
h,
|
||
onMounted,
|
||
defineComponent,
|
||
onUnmounted,
|
||
watch,
|
||
toRaw,
|
||
render,
|
||
onBeforeUnmount
|
||
} from 'vue'
|
||
import {
|
||
NDataTable,
|
||
NImage,
|
||
useMessage,
|
||
NInput,
|
||
NButton,
|
||
NSwitch,
|
||
NPopover,
|
||
useDialog,
|
||
NCheckbox,
|
||
NSelect,
|
||
NIcon
|
||
} from 'naive-ui'
|
||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||
import ModifyPromptChinese from '../Components/ModifyPromptChinese.vue'
|
||
import InputDialogContent from './Components/InputDialogContent.vue'
|
||
import DataTableShowGenerateImage from './Components/DataTableShowGenerateImage.vue'
|
||
import { cloneDeep, debounce, isEmpty, min } from 'lodash'
|
||
import SelectImageStyle from '../Components/SelectImageStyle.vue'
|
||
import DataTableCharacterAndScene from './Components/DataTableCharacterAndScene.vue'
|
||
import DataTablePromptRow from './Components/DataTablePromptRow.vue'
|
||
import DataTableGptPromptRow from './Components/DataTableGptPromptRow.vue'
|
||
import DataTableParameterRow from './Components/DataTableParameterRow.vue'
|
||
import { Reload } from '@vicons/ionicons5'
|
||
import {
|
||
checkStringValueAddPrefix,
|
||
checkStringValueAddSuffix,
|
||
checkStringValueDeletePrefix
|
||
} from '../../../../main/generalTools'
|
||
|
||
export default defineComponent({
|
||
components: {
|
||
NImage,
|
||
NDataTable,
|
||
NInput,
|
||
NButton,
|
||
ModifyPromptChinese,
|
||
NSwitch,
|
||
NPopover,
|
||
NCheckbox,
|
||
SelectImageStyle,
|
||
Reload,
|
||
NIcon
|
||
},
|
||
props: ['initData', 'prefix_prompt', 'suffix_prompt', 'tags', 'InitTags'],
|
||
setup(props) {
|
||
console.log('输出文件夹位置', props.initData)
|
||
let data = ref(props.initData)
|
||
let tags = ref(props.tags)
|
||
let message = useMessage()
|
||
let dialog = useDialog()
|
||
let selectKey = ref([])
|
||
let promptChineseRef = ref(null)
|
||
let maxHeight = ref(null)
|
||
let prefix_prompt = ref(props.prefix_prompt)
|
||
let suffix_prompt = ref(props.suffix_prompt)
|
||
|
||
let titleCharacterAndSceneRef = ref(null)
|
||
let dataCharacterAndSceneRef = ref(null)
|
||
|
||
let prefix_prompt_ref = ref(null)
|
||
let suffix_prompt_ref = ref(null)
|
||
let selectStyle = ref([])
|
||
let characterSelectModel = ref(
|
||
window.config.character_select_model ? window.config.character_select_model : 'tag'
|
||
)
|
||
|
||
let AutoSaveDataJsonDebounced = debounce(AutoSaveDataJson, 3000)
|
||
let SaveDataJsonDebounced = debounce(AutoSaveDataJson, 1000)
|
||
|
||
let image_generate_category = ref(
|
||
window.config.image_generate_category ? window.config.image_generate_category : 'sd'
|
||
)
|
||
|
||
watch(
|
||
() => props.initData,
|
||
async (newVal) => {
|
||
data.value = newVal
|
||
if (window.config.auto_save) {
|
||
console.log('自动保存数据')
|
||
AutoSaveDataJsonDebounced()
|
||
}
|
||
},
|
||
{ deep: true }
|
||
)
|
||
|
||
watch(
|
||
() => props.tags,
|
||
async (newVal) => {
|
||
debugger
|
||
tags.value = newVal
|
||
// 同步修改 selectStyle.value 的值
|
||
for (let i = 0; i < selectStyle.value.length; i++) {
|
||
let index = tags.value.style_tags?.findIndex(
|
||
(item) => item.key == selectStyle.value[i].key
|
||
)
|
||
if (selectStyle.value[i].type == 'style_main' && index != null && index != -1) {
|
||
selectStyle.value[i] = tags.value.style_tags[index]
|
||
}
|
||
}
|
||
}
|
||
)
|
||
|
||
watch(
|
||
() => props.prefix_prompt,
|
||
(newVal) => {
|
||
prefix_prompt.value = newVal
|
||
},
|
||
{ deep: true }
|
||
)
|
||
|
||
watch(
|
||
() => props.suffix_prompt,
|
||
(newVal) => {
|
||
suffix_prompt.value = newVal
|
||
},
|
||
{ deep: true }
|
||
)
|
||
|
||
/**
|
||
* 自动保存数据到json文件
|
||
*/
|
||
async function AutoSaveDataJson() {
|
||
await window.api.AutoSaveDataJson(JSON.stringify(toRaw(data.value)), (value) => {
|
||
if (value.code == 0) {
|
||
message.error('数据保存错误,错误信息:' + value.message)
|
||
return
|
||
}
|
||
})
|
||
}
|
||
|
||
const createColumns = ({}) => {
|
||
return [
|
||
{
|
||
title: 'No.',
|
||
key: 'no',
|
||
width: 50,
|
||
fixed: 'left'
|
||
},
|
||
{
|
||
title: '字幕',
|
||
key: 'srt',
|
||
width: '180',
|
||
fixed: 'left',
|
||
render(row) {
|
||
let tmp
|
||
if (row.subValue.length > 0) {
|
||
tmp = row.subValue.map((item) =>
|
||
h('div', { style: 'display:flex; height : auto; margin: 2px 0' }, [
|
||
h(NInput, {
|
||
size: 'tiny',
|
||
value: item.srt_value
|
||
})
|
||
])
|
||
)
|
||
} else {
|
||
tmp = h('div', { style: 'display:flex; height : auto; margin: 2px 0' }, [
|
||
h(NInput, {
|
||
type: 'textarea',
|
||
autosize: { minRows: 3, maxRows: 6 },
|
||
size: 'tiny',
|
||
value: row.after_gpt
|
||
})
|
||
])
|
||
}
|
||
return tmp
|
||
}
|
||
},
|
||
{
|
||
// 修改title,往里面添加添加一个下拉选择框
|
||
title(row, index) {
|
||
return h(DataTableCharacterAndScene, {
|
||
ref: titleCharacterAndSceneRef,
|
||
type: 'title',
|
||
row: row,
|
||
characterSelectModel: characterSelectModel,
|
||
func: {
|
||
refreshTagData: async () => {
|
||
try {
|
||
await props.InitTags()
|
||
message.success('人物角色刷新成功')
|
||
} catch (error) {
|
||
message.error('人物角色刷新失败,请重试' + error.toString())
|
||
}
|
||
}
|
||
}
|
||
})
|
||
},
|
||
className: 'prompt_row',
|
||
key: 'character',
|
||
width: '200',
|
||
render(row, index) {
|
||
return h(DataTableCharacterAndScene, {
|
||
ref: dataCharacterAndSceneRef,
|
||
type: 'data',
|
||
row: row,
|
||
tags: tags,
|
||
characterSelectModel: characterSelectModel
|
||
})
|
||
}
|
||
},
|
||
{
|
||
title(row, index) {
|
||
return h(DataTableGptPromptRow, {
|
||
type: 'title',
|
||
row: row,
|
||
index: index,
|
||
tags: tags,
|
||
func: {
|
||
translateAll: TranslateAll,
|
||
addPrefix: AddPrefix,
|
||
addSuffix: AddSuffix,
|
||
selectGenerateImagesStyle: SelectGenerateImagesStyle
|
||
}
|
||
})
|
||
},
|
||
key: 'gpt_prompt',
|
||
className: 'prompt_row',
|
||
resizable: true,
|
||
minWidth: 300,
|
||
width: '500',
|
||
render(row, index) {
|
||
return h(DataTableGptPromptRow, {
|
||
type: 'data',
|
||
row: row,
|
||
index: index,
|
||
func: {
|
||
nextGptPrompt: NextGptPrompt,
|
||
singlePrompt: SinglePrompt
|
||
}
|
||
})
|
||
}
|
||
},
|
||
{
|
||
// 提示词命令
|
||
title(row, index) {
|
||
return h(DataTablePromptRow, {
|
||
type: 'title',
|
||
row: row,
|
||
index: index,
|
||
func: {
|
||
mJBadPromptCheck: MJBadPromptCheck,
|
||
mergePrompt: MergePrompt
|
||
}
|
||
})
|
||
},
|
||
key: 'prompt',
|
||
width: '300',
|
||
className: 'prompt_row',
|
||
render(row, index) {
|
||
return h(DataTablePromptRow, {
|
||
type: 'data',
|
||
row: row,
|
||
index: index,
|
||
func: {
|
||
nextGenerateImage: NextGenerateImage
|
||
}
|
||
})
|
||
}
|
||
},
|
||
{
|
||
// 参数
|
||
title(row, index) {
|
||
return h(DataTableParameterRow, {
|
||
type: 'title',
|
||
row: row,
|
||
index: index,
|
||
image_generate_category: image_generate_category
|
||
})
|
||
},
|
||
key: 'parameter',
|
||
width: '130',
|
||
render(row, index) {
|
||
return h(DataTableParameterRow, {
|
||
type: `data_${image_generate_category.value}`,
|
||
row: row,
|
||
index: index
|
||
})
|
||
}
|
||
},
|
||
{
|
||
// 出图
|
||
title(row, index) {
|
||
return h(DataTableShowGenerateImage, {
|
||
initData: row,
|
||
index: index,
|
||
type: 'title',
|
||
image_generate_category: image_generate_category,
|
||
func: {
|
||
mJGetImage: MJGetImage
|
||
}
|
||
})
|
||
},
|
||
key: 'options',
|
||
className: 'prompt_row',
|
||
width: '300',
|
||
render(row, index) {
|
||
return h(DataTableShowGenerateImage, {
|
||
initData: row,
|
||
index: index,
|
||
type: 'data'
|
||
})
|
||
}
|
||
}
|
||
]
|
||
}
|
||
let isSaved = false
|
||
// 监听control+s 保存数据
|
||
let saveListener = function (event) {
|
||
debugger
|
||
if (event.ctrlKey && event.key === 's') {
|
||
event.preventDefault()
|
||
if (!isSaved) {
|
||
console.log('User pressed Ctrl+S')
|
||
SaveDataJsonDebounced()
|
||
isSaved = true
|
||
}
|
||
} else {
|
||
isSaved = false
|
||
}
|
||
}
|
||
|
||
onMounted(async () => {
|
||
// 直接或整个cinfig文件
|
||
await window.api.GetConfigJson(JSON.stringify([null, {}]), async (value) => {
|
||
debugger
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
let image_style_list = value.data.image_style
|
||
let customize_image_style_list = value.data.customize_image_style
|
||
await window.api.GetImageStyleInfomation(JSON.stringify(image_style_list), (value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
selectStyle.value = value.data
|
||
})
|
||
|
||
for (let i = 0; i < customize_image_style_list.length; i++) {
|
||
const element = customize_image_style_list[i]
|
||
selectStyle.value.push({
|
||
key: element,
|
||
type: 'style_main'
|
||
})
|
||
}
|
||
})
|
||
|
||
// 判断data中的数据是不是有chinese text
|
||
|
||
window.api.setEventListen([DEFINE_STRING.TRANSLATE_RETURN_REFRESH, window.id], (value) => {
|
||
if (value.code == 0) {
|
||
message.error('返回数据错误')
|
||
return
|
||
}
|
||
// 直接
|
||
let index = data.value.findIndex((item) => item.id == value.rowId)
|
||
if (index < 0) {
|
||
message.error('翻译后修改源数据,对应数据ID未找到')
|
||
return
|
||
}
|
||
data.value[index].gpt_prompt = value.data
|
||
})
|
||
getMaxHeight()
|
||
|
||
window.api.setEventListen(
|
||
[DEFINE_STRING.SD_ORIGINAL_GENERATE_IMAGE_RETURN, window.id],
|
||
(value) => {
|
||
if (value.code == 0) {
|
||
message.error('生成图片错误,错误信息如下:' + value.message)
|
||
return
|
||
}
|
||
// 修改data中的数据
|
||
for (let i = 0; i < data.value.length; i++) {
|
||
if (data.value[i].id == value.id) {
|
||
data.value[i].subImagePath = value.data.subImagePath.map(
|
||
(item) => 'file://' + item.replaceAll('\\', '/') + '?time=' + new Date().getTime()
|
||
)
|
||
data.value[i].outImagePath =
|
||
'file://' +
|
||
value.data.outImagePath.replaceAll('\\', '/') +
|
||
'?time=' +
|
||
new Date().getTime()
|
||
break
|
||
}
|
||
}
|
||
}
|
||
)
|
||
window.addEventListener('keydown', saveListener)
|
||
|
||
let div = document.getElementsByClassName('prompt_row')
|
||
for (let i = 0; i < div.length; i++) {
|
||
div[i].style.padding = '0px 5px'
|
||
}
|
||
|
||
// 监听MJ信息的监听任务的返回
|
||
|
||
window.api.setEventListen(
|
||
[DEFINE_STRING.DISCORD.MAIN_DISCORD_MESSAGE_CHANGE, window.id],
|
||
(value) => {
|
||
mainDiscordMessageChanged(value)
|
||
}
|
||
)
|
||
|
||
await props.InitTags()
|
||
})
|
||
|
||
onBeforeUnmount(async () => {
|
||
debugger
|
||
await AutoSaveDataJson()
|
||
})
|
||
|
||
// 接收Discord的修改信息
|
||
async function mainDiscordMessageChanged(value) {
|
||
if (value.code == 0) {
|
||
message.error('Discord返回错误,错误信息如下:' + value.message)
|
||
return
|
||
}
|
||
|
||
// 处理数据
|
||
if (value.type == 'created') {
|
||
debugger
|
||
console.log('接收Discord的创建消息', value)
|
||
// 找到对应ID的data数据
|
||
|
||
let index = data.value.findIndex((item) => item.id == value.id)
|
||
if (index < 0) {
|
||
message.error('未找到对应的数据')
|
||
return
|
||
}
|
||
delete value.type
|
||
delete value.code
|
||
data.value[index]['mj_message'] = value
|
||
} else if (value.type == 'updated') {
|
||
console.log('接收Discord的更新消息', value)
|
||
// 修改对应的数据
|
||
let index = data.value.findIndex((item) => item.mj_message?.message_id == value.message_id)
|
||
if (index < 0) {
|
||
message.error('未找到对应的数据')
|
||
return
|
||
}
|
||
// 修改数据
|
||
if (value.image_click != null && value.image_click != '') {
|
||
data.value[index]['outImagePath'] = value.image_click
|
||
}
|
||
delete value.type
|
||
delete value.code
|
||
|
||
data.value[index]['mj_message'] = value
|
||
} else if (value.type == 'delete') {
|
||
console.log('接收Discord的删除消息', value)
|
||
} else if (value.type == 'finished') {
|
||
console.log('接收Discord的完成消息', value)
|
||
// 修改对应的数据
|
||
let index = data.value.findIndex((item) => item.mj_message?.image_id == value.image_id)
|
||
if (index < 0) {
|
||
message.error('未找到对应的数据')
|
||
return
|
||
}
|
||
|
||
data.value[index]['outImagePath'] = value.image_path
|
||
|
||
delete value.type
|
||
delete value.code
|
||
value.progress = 100
|
||
value.message_id = value.message_id
|
||
|
||
data.value[index]['mj_message'] = value
|
||
|
||
// 返回后端分割图片(传入图片地址,返回分割后的图片地址数组)
|
||
await window.mj.ImageSplit(
|
||
JSON.stringify([value.image_path, data.value[index].name]),
|
||
(value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
// 修改数据
|
||
data.value[index]['outImagePath'] = value.data.outImagePath
|
||
data.value[index]['subImagePath'] = value.data.subImagePath
|
||
}
|
||
)
|
||
} else {
|
||
message.error('未知的操作类型')
|
||
}
|
||
}
|
||
|
||
onUnmounted(() => {
|
||
window.api.removeEventListen(DEFINE_STRING.TRANSLATE_RETURN_REFRESH)
|
||
window.api.removeEventListen(DEFINE_STRING.DISCORD.MAIN_DISCORD_MESSAGE_CHANGE)
|
||
window.removeEventListener('keydown', saveListener)
|
||
})
|
||
|
||
/**
|
||
* 将翻译添加到队列中的方式
|
||
* @param {要翻译的数据(数组)} translateData
|
||
* @param {原语言(zh,en)} from
|
||
* @param {目标语言(zh,en)} to
|
||
* @param {是否显示弹窗} isShow
|
||
*/
|
||
async function TranslatePrompt(translateData, from, to) {
|
||
console.log(translateData)
|
||
await window.api.TranslatePrompt([translateData, from, to, window.id, true], (value) => {
|
||
debugger
|
||
console.log(value)
|
||
})
|
||
}
|
||
|
||
// 计算当前程序界面的高度,减去上下的高度,设置maxHegiht
|
||
async function getMaxHeight() {
|
||
let height = window.innerHeight
|
||
maxHeight.value = height - 150
|
||
}
|
||
|
||
// 监听程序界面的高度变化
|
||
window.onresize = function () {
|
||
getMaxHeight()
|
||
}
|
||
|
||
// 添加前缀的弹窗
|
||
const AddPrefix = () => {
|
||
// 判断当前数据是不是存在
|
||
// 处理数据。获取当前的所有的数据
|
||
let dialogWidth = 400
|
||
let dialogHeight = 150
|
||
dialog.create({
|
||
title: '添加前缀',
|
||
showIcon: false,
|
||
closeOnEsc: false,
|
||
content: () =>
|
||
h(InputDialogContent, {
|
||
ref: prefix_prompt_ref,
|
||
initData: prefix_prompt.value,
|
||
placeholder: '请输入前缀'
|
||
}),
|
||
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||
maskClosable: false,
|
||
onClose: async () => {
|
||
prefix_prompt.value = prefix_prompt_ref.value.data
|
||
// 保存通用前缀
|
||
await window.api.SaveCopywritingInformation(
|
||
[prefix_prompt_ref.value.data, 'prefix_prompt', false],
|
||
(value) => {
|
||
if (value.code == 0) {
|
||
message.error('保存前缀错误,错误信息如下:' + value.message)
|
||
return
|
||
}
|
||
}
|
||
)
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 选择生成图片的风格
|
||
*/
|
||
async function SelectGenerateImagesStyle() {
|
||
debugger
|
||
// 判断当前数据是不是存在
|
||
// 处理数据。获取当前的所有的数据
|
||
let dialogWidth = window.innerWidth * 0.8
|
||
let dialogHeight = window.innerHeight * 0.9
|
||
// ImportWordAndSrt
|
||
dialog.create({
|
||
showIcon: false,
|
||
closeOnEsc: false,
|
||
content: () =>
|
||
h(SelectImageStyle, {
|
||
selectStyle: toRaw(selectStyle.value),
|
||
height: dialogHeight,
|
||
tags: tags
|
||
}),
|
||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
||
maskClosable: false,
|
||
onClose: async () => {
|
||
// 重新加载数据
|
||
let tmp_arr = []
|
||
|
||
let cus_arr = []
|
||
|
||
for (let i = 0; i < selectStyle.value.length; i++) {
|
||
debugger
|
||
const element = selectStyle.value[i]
|
||
// 判断是不是主风格
|
||
if (element.type == 'style_main') {
|
||
cus_arr.push(element.key)
|
||
} else {
|
||
tmp_arr.push(element.id)
|
||
}
|
||
}
|
||
|
||
// 将当前的风格保存
|
||
await window.api.SaveCopywritingInformation(
|
||
[JSON.stringify(tmp_arr), 'image_style', true],
|
||
async (value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
|
||
await window.api.SaveCopywritingInformation(
|
||
[JSON.stringify(cus_arr), 'customize_image_style', true],
|
||
() => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
message.success('保存成功')
|
||
}
|
||
)
|
||
}
|
||
)
|
||
}
|
||
})
|
||
}
|
||
|
||
// 添加后缀的弹窗
|
||
const AddSuffix = () => {
|
||
// 判断当前数据是不是存在
|
||
// 处理数据。获取当前的所有的数据
|
||
let dialogWidth = 400
|
||
let dialogHeight = 150
|
||
dialog.create({
|
||
title: '添加后缀',
|
||
showIcon: false,
|
||
closeOnEsc: false,
|
||
content: () =>
|
||
h(InputDialogContent, {
|
||
ref: suffix_prompt_ref,
|
||
initData: suffix_prompt.value,
|
||
placeholder: '请输入后缀'
|
||
}),
|
||
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||
maskClosable: false,
|
||
onClose: async () => {
|
||
suffix_prompt.value = suffix_prompt_ref.value.data
|
||
await window.api.SaveCopywritingInformation(
|
||
[suffix_prompt_ref.value.data, 'suffix_prompt', false],
|
||
(value) => {
|
||
if (value.code == 0) {
|
||
message.error('保存前缀错误,错误信息如下:' + value.message)
|
||
return
|
||
}
|
||
}
|
||
)
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 添加MJ敏感词检查
|
||
*/
|
||
async function MJBadPromptCheck() {
|
||
await window.mj.MJBadPromptCheck(JSON.stringify(toRaw(data.value)), (value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
debugger
|
||
// 先将所有的数据设置为false
|
||
for (let i = 0; i < data.value.length; i++) {
|
||
data.value[i].mj_message = data.value[i].mj_message ? data.value[i].mj_message : {}
|
||
data.value[i].mj_message['hasBadPrompt'] = false
|
||
}
|
||
|
||
// 判断返回的ID数据是不是为空,不为空,修改数据
|
||
if (value.data.length > 0) {
|
||
let message_text = ''
|
||
|
||
for (let i = 0; i < value.data.length; i++) {
|
||
const element = value.data[i]
|
||
message_text += ',' + element.no.toString()
|
||
let index = data.value.findIndex((item) => item.id == element.id)
|
||
if (index < 0) {
|
||
message.error('未找到对应的数据')
|
||
return
|
||
}
|
||
data.value[index].mj_message = data.value[index].mj_message
|
||
? data.value[index].mj_message
|
||
: {}
|
||
data.value[index].mj_message['hasBadPrompt'] = true
|
||
}
|
||
|
||
let show_text = `检测到 ${value.data.length} 条敏感词,分别在第 ${message_text.substring(
|
||
1
|
||
)} 行。有红色框标识。请检查`
|
||
window.api.showGlobalMessageDialog({
|
||
code: 0,
|
||
message: show_text
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 将当前和下面的所有的数据生成图片
|
||
* @param {*} row
|
||
*/
|
||
async function NextGenerateImage(row, ca = 'sd') {
|
||
let index = data.value.findIndex((item) => item.id == row.id)
|
||
let tempData = []
|
||
for (let i = index; i < data.value.length; i++) {
|
||
const element = data.value[i]
|
||
tempData.push(element)
|
||
}
|
||
// 判断当前的生图模式
|
||
if (ca == 'sd') {
|
||
// 生成SD生图
|
||
await window.api.OriginalSDImageGenerate(
|
||
[JSON.stringify(tempData), true, true],
|
||
(value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
message.success('添加SD生图任务成功')
|
||
}
|
||
)
|
||
} else if (ca == 'mj') {
|
||
// MJ生图
|
||
await window.mj.OriginalMJImageGenerate([JSON.stringify(tempData), true, true], (value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
message.success('添加MJ生图任务成功')
|
||
})
|
||
} else if (ca == 'd3') {
|
||
} else {
|
||
message.error('生图的类别错误')
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 往下继续推理
|
||
* @param value 当前行数据
|
||
*/
|
||
async function NextGptPrompt(row) {
|
||
let index = data.value.findIndex((item) => item.id == row.id)
|
||
let tempData = []
|
||
for (let i = index; i < data.value.length; i++) {
|
||
const element = data.value[i]
|
||
tempData.push(element)
|
||
}
|
||
|
||
await window.api.GPTPrompt(
|
||
[JSON.stringify(tempData), true, JSON.stringify(toRaw(data.value))],
|
||
(value) => {
|
||
console.log('添加推理任务成功')
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
message.success('添加推理任务成功')
|
||
}
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 单句推理
|
||
* @param row
|
||
*/
|
||
async function SinglePrompt(row) {
|
||
await window.api.GPTPrompt(
|
||
[JSON.stringify([toRaw(row)]), false, JSON.stringify(toRaw(data.value))],
|
||
(value) => {
|
||
console.log('添加推理任务成功')
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
message.success('添加推理任务成功')
|
||
}
|
||
)
|
||
}
|
||
|
||
function containsChineseOrPunctuation(str) {
|
||
return /[\u4e00-\u9fa5]|[\u3000-\u301e\u2013\u2014\u2018\u2019\u201c\u201d\u2026\u203b\uff08\uff09\uff1a\uff1b\uff1f\uff01\uff0c\u3001\uff0e\u3002\uff1f\uff01\u2018\u2019\u201c\u201d]/.test(
|
||
str
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 翻译传入的数据
|
||
* @param {*} key 翻译的类型
|
||
*/
|
||
async function TranslateAll(key) {
|
||
debugger
|
||
// 将中文翻译成英文
|
||
if (key == 'english') {
|
||
let tmp_d = []
|
||
for (let i = 0; i < data.value.length; i++) {
|
||
const element = cloneDeep(data.value[i])
|
||
if (containsChineseOrPunctuation(element.gpt_prompt)) {
|
||
tmp_d.push(element)
|
||
}
|
||
}
|
||
// 检查是不是有中文
|
||
// 开始翻译
|
||
let t = [tmp_d, 'zh', 'en', false, false]
|
||
await window.mj.TranslateReturnNowTask(JSON.stringify(t), (value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
message.success('添加翻译任务成功')
|
||
})
|
||
} else if (key == 'chinese') {
|
||
debugger
|
||
let t = [[...toRaw(data.value)], 'en', 'zh', false, false]
|
||
await window.mj.TranslateReturnNowTask(JSON.stringify(t), (value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
message.success('添加翻译任务成功')
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* SD 模式合并名并
|
||
* @param character_string
|
||
* @param scene_string
|
||
* @param gpt_prompt
|
||
*/
|
||
function SDMergePrompt(element) {
|
||
let character_string = ''
|
||
element.character_tags?.forEach((item) => {
|
||
character_string += ', ' + item.prompt
|
||
if (item.lora && item.lora != '无' && item.lora_weight) {
|
||
character_string += `, <lora:${item.lora}:${item.lora_weight}>`
|
||
}
|
||
})
|
||
// 判断 character_string 有数据,有的话删除第一个逗号
|
||
character_string = checkStringValueDeletePrefix(character_string, ',')
|
||
|
||
// 获取当前的场景提示词
|
||
let scene_string = ''
|
||
element.scene_tags?.forEach((item) => {
|
||
scene_string += ', ' + item.prompt
|
||
})
|
||
|
||
let style_string = ''
|
||
|
||
selectStyle.value.forEach((item) => {
|
||
if (item.type && item.type == 'style_main') {
|
||
style_string += ', ' + item.prompt
|
||
}
|
||
})
|
||
|
||
// 判断 scene_string 有数据,有的话删除第一个逗号
|
||
scene_string = checkStringValueDeletePrefix(scene_string, ',')
|
||
style_string = checkStringValueDeletePrefix(style_string, ',')
|
||
style_string = checkStringValueAddSuffix(style_string, ',')
|
||
|
||
return `${style_string} ${checkStringValueAddSuffix(
|
||
character_string,
|
||
', '
|
||
)}${checkStringValueAddSuffix(scene_string, ', ')}${checkStringValueAddSuffix(
|
||
element.gpt_prompt,
|
||
', '
|
||
)}`
|
||
}
|
||
|
||
/**
|
||
* 将所有的数据进行拼接
|
||
* @param prefix 前缀
|
||
* @param character_string 人物提示词
|
||
* @param scene_string 场景提示词
|
||
* @param gpt_prompt GPT提示词
|
||
* @param suffix 后缀
|
||
*/
|
||
function MJMergePrompt(prefix, element, suffix) {
|
||
debugger
|
||
let character_string = ''
|
||
let cref_url = ''
|
||
element.character_tags?.forEach((item) => {
|
||
character_string += ', ' + item.prompt
|
||
if (item.image_url && item.image_url != '' && item.cref_cw) {
|
||
cref_url += ` ${item.image_url} `
|
||
}
|
||
})
|
||
// 判断cref_url 是不是有数据,有的话添加 --cref
|
||
cref_url = checkStringValueAddPrefix(cref_url, ' --cref ')
|
||
|
||
if (element.character_tags && element.character_tags.length > 0) {
|
||
cref_url = checkStringValueAddSuffix(cref_url, ` --cw ${element.character_tags[0].cref_cw} `)
|
||
}
|
||
// 判断 character_string 有数据,有的话删除第一个逗号
|
||
character_string = checkStringValueDeletePrefix(character_string, ',')
|
||
|
||
// 获取当前的场景提示词
|
||
let scene_string = ''
|
||
element.scene_tags?.forEach((item) => {
|
||
scene_string += ', ' + item.prompt
|
||
})
|
||
// 判断 scene_string 有数据,有的话删除第一个逗号
|
||
scene_string = checkStringValueDeletePrefix(scene_string, ',')
|
||
|
||
// 获取当前的自定义风格
|
||
|
||
let style_string = ''
|
||
let style_url = ''
|
||
let sw = 0
|
||
|
||
selectStyle.value.forEach((item) => {
|
||
if (item.type && item.type == 'style_main') {
|
||
style_string += ', ' + item.prompt
|
||
if (sw == 0) {
|
||
sw = item.sref_sw
|
||
}
|
||
if (!isEmpty(item.image_url)) {
|
||
let url = item.image_url ? item.image_url : ''
|
||
style_url += ' ' + url
|
||
}
|
||
}
|
||
})
|
||
|
||
style_url = checkStringValueAddPrefix(style_url, '--sref ')
|
||
style_url = checkStringValueAddSuffix(style_url, ` --sw ${sw}`)
|
||
style_string = checkStringValueDeletePrefix(style_string, ',')
|
||
style_string = checkStringValueAddSuffix(style_string, ', ')
|
||
|
||
return ` ${style_string} ${checkStringValueAddSuffix(
|
||
prefix,
|
||
', '
|
||
)}${checkStringValueAddSuffix(character_string, ', ')}${checkStringValueAddSuffix(
|
||
scene_string,
|
||
', '
|
||
)}${checkStringValueAddSuffix(element.gpt_prompt, ', ')} ${checkStringValueAddSuffix(
|
||
suffix,
|
||
' '
|
||
)} ${cref_url} ${style_url}`
|
||
}
|
||
|
||
/**
|
||
* 生成提示词
|
||
*/
|
||
async function MergePrompt(key) {
|
||
try {
|
||
debugger
|
||
// 判断该当前是不是有风格
|
||
// 获取当前的风格ID
|
||
let style_str = ''
|
||
for (let i = 0; i < selectStyle.value.length; i++) {
|
||
const element = selectStyle.value[i]
|
||
style_str += element.english_style + ','
|
||
}
|
||
|
||
// 获取当前的前缀和后缀
|
||
let prefix = prefix_prompt.value ? prefix_prompt.value : ''
|
||
let suffix = suffix_prompt.value ? suffix_prompt.value : ''
|
||
|
||
for (let i = 0; i < data.value.length; i++) {
|
||
const element = data.value[i]
|
||
let end_prompt = ''
|
||
if (key == null) {
|
||
// 判断当前的分类是什么,通过分类来判断合并提示词
|
||
if (image_generate_category.value == 'sd') {
|
||
end_prompt = SDMergePrompt(element)
|
||
} else if (image_generate_category.value == 'mj') {
|
||
end_prompt = MJMergePrompt(prefix, element, suffix)
|
||
} else if (image_generate_category.value == 'd3') {
|
||
message.error('该分类暂时不可用')
|
||
return
|
||
} else {
|
||
message.error('合并提示词错误:未知的合并提示词类型')
|
||
return
|
||
}
|
||
} else if (key == 'mj_merge') {
|
||
end_prompt = MJMergePrompt(prefix, element, suffix)
|
||
} else if (key == 'sd_merge') {
|
||
end_prompt = SDMergePrompt(element)
|
||
} else {
|
||
message.error('合并提示词错误:未知的合并提示词类型')
|
||
return
|
||
}
|
||
// 风格 + 前缀 + 人物 + 场景 + 词 + 后缀
|
||
data.value[i].prompt = end_prompt
|
||
}
|
||
} catch (error) {
|
||
message.error('生成提示词错误,错误信息如下:' + error.message)
|
||
}
|
||
}
|
||
|
||
/**
|
||
*
|
||
*/
|
||
async function MJGetImage() {
|
||
let pa = []
|
||
// MJ采集图片
|
||
for (let i = 0; i < data.value.length; i++) {
|
||
const item = data.value[i]
|
||
// 一般进度大于 50 会出现图片,
|
||
if (!item.mj_message) {
|
||
return
|
||
}
|
||
if (item.mj_message.progress && item.mj_message.progress == 100) {
|
||
// 判断 image_path 是不是存在。
|
||
if (item.mj_message.image_id && !item.mj_message.image_path) {
|
||
// 通过当前的image_id获取图片
|
||
pa.push(item)
|
||
}
|
||
}
|
||
}
|
||
|
||
if (pa.length > 0) {
|
||
window.mj.GetGeneratedMJImageAndSplit(JSON.stringify(pa), (value) => {
|
||
if (value.code == 0) {
|
||
message.error(value.message)
|
||
return
|
||
}
|
||
// 修改数据
|
||
for (let i = 0; i < value.data.length; i++) {
|
||
const element = value.data[i]
|
||
// 修改对应的数据
|
||
let index = data.value.findIndex((item) => item.id == element.id)
|
||
if (index < 0) {
|
||
message.error('未找到对应的数据')
|
||
return
|
||
}
|
||
data.value[index].outImagePath = element.outImagePath
|
||
data.value[index].subImagePath = element.subImagePath
|
||
data.value[index].mj_message.image_click = element.result
|
||
data.value[index].mj_message.image_path = element.image_path
|
||
}
|
||
})
|
||
} else {
|
||
message.error('没有找到可以自动下载图片的数据,可以手动粘贴链接分割')
|
||
return
|
||
}
|
||
}
|
||
|
||
return {
|
||
data,
|
||
columns: createColumns({}),
|
||
selectStyle,
|
||
rowKey: (row) => row.id,
|
||
handleCheck(rowKeys) {
|
||
selectKey.value = rowKeys
|
||
},
|
||
promptChineseRef,
|
||
TranslatePrompt,
|
||
TranslateAll,
|
||
maxHeight,
|
||
prefix_prompt_ref,
|
||
suffix_prompt_ref,
|
||
characterSelectModel,
|
||
image_generate_category,
|
||
titleCharacterAndSceneRef,
|
||
dataCharacterAndSceneRef
|
||
}
|
||
}
|
||
})
|
||
</script>
|