LaiTool 3.1.3
This commit is contained in:
parent
8500fd3446
commit
595cbe8374
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "laitool",
|
||||
"version": "3.1.2",
|
||||
"version": "3.1.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "laitool",
|
||||
"version": "3.1.2",
|
||||
"version": "3.1.3",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@alicloud/alimt20181012": "^1.2.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "laitool",
|
||||
"version": "3.1.2",
|
||||
"version": "3.1.3",
|
||||
"description": "An AI tool for image processing, video processing, and other functions.",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "laitool.cn",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -144,6 +144,7 @@ if (!app.isPackaged) {
|
||||
|
||||
define['remotemj_api'] = 'https://api.laitool.net/'
|
||||
define['serverUrl'] = 'http://lapi.laitool.cn'
|
||||
// define['serverUrl'] = 'http://localhost:1578'
|
||||
define['hkServerUrl'] = 'https://laitool.net/'
|
||||
define['bakServerUrl'] = 'https://laitool.net/'
|
||||
define['API'] = 'f85d39ed5a40fd09966f13f12b6cf0f0'
|
||||
|
||||
@ -125,7 +125,11 @@ export const DEFINE_STRING = {
|
||||
INIT_SERVER_GPT_OPTIONS: 'INIT_SERVER_GPT_OPTIONS',
|
||||
GET_AI_SETTING: 'GET_AI_SETTING',
|
||||
SAVE_AI_SETTING: 'SAVE_AI_SETTING',
|
||||
SYNC_GPT_KEY: "SYNC_GPT_KEY"
|
||||
SYNC_GPT_KEY: "SYNC_GPT_KEY",
|
||||
/**
|
||||
* GPT流式返回的监听
|
||||
*/
|
||||
GPT_STREAM_RETURN: "GPT_STREAM_RETURN"
|
||||
},
|
||||
|
||||
QUEUE_BATCH: {
|
||||
|
||||
@ -13,20 +13,166 @@ import {
|
||||
GetKimiErrorResponse,
|
||||
GetOpenAISuccessResponse,
|
||||
GetRixApiErrorResponse
|
||||
} from '../../define/response/openAIResponse.ts'
|
||||
} from '../../define/response/openAIResponse'
|
||||
import axios from 'axios'
|
||||
import { ValidateJson } from '../../define/Tools/validate.ts'
|
||||
import { ValidateJson } from '../../define/Tools/validate'
|
||||
import { RetryWithBackoff } from '../../define/Tools/common'
|
||||
const { v4: uuidv4 } = require('uuid') // 引入UUID库来生成唯一标识符
|
||||
let tools = new Tools()
|
||||
|
||||
export class Writing extends ServiceBase {
|
||||
pm: PublicMethod
|
||||
constructor(global) {
|
||||
super()
|
||||
this.global = global
|
||||
this.pm = new PublicMethod(global)
|
||||
axios.defaults.baseURL = define.serverUrl
|
||||
}
|
||||
|
||||
/**
|
||||
* AI 请求发送
|
||||
* @param {*} setting
|
||||
* @param {*} aiData
|
||||
* @param {*} word
|
||||
* @returns
|
||||
*/
|
||||
async AIRequest(setting, aiData, word): Promise<string> {
|
||||
// 开始请求AI
|
||||
let axiosRes = await axios.post('/api/Forward/ForwardWord', {
|
||||
promptTypeId: setting.gptType,
|
||||
promptId: setting.gptData,
|
||||
gptUrl: aiData.gpt_url + '/v1/chat/completions',
|
||||
model: aiData.model,
|
||||
machineId: global.machineId,
|
||||
apiKey: aiData.api_key,
|
||||
word: word
|
||||
})
|
||||
|
||||
// 判断返回的状态,如果是失败的话直接返回错误信息
|
||||
if (axiosRes.status != 200) {
|
||||
throw new Error('请求失败')
|
||||
}
|
||||
let dataRes = axiosRes.data
|
||||
if (dataRes.code == 1) {
|
||||
// 获取成功
|
||||
// 解析返回的数据
|
||||
return GetOpenAISuccessResponse(dataRes.data);
|
||||
|
||||
} else {
|
||||
// 系统报错
|
||||
if (dataRes.code == 5000) {
|
||||
throw new Error('系统错误,错误信息如下:' + dataRes.message)
|
||||
} else {
|
||||
// 处理不同类型的错误消息
|
||||
if (setting.gptAI == 'laiapi') {
|
||||
throw new Error(GetRixApiErrorResponse(dataRes.data))
|
||||
} else if (setting.gptAI == 'kimi') {
|
||||
throw new Error(GetKimiErrorResponse(dataRes.data))
|
||||
} else if (setting.gptAI == 'doubao') {
|
||||
throw new Error(GetDoubaoErrorResponse(dataRes.data))
|
||||
} else {
|
||||
throw new Error(dataRes.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 流式请求接口
|
||||
* @param setting
|
||||
* @param aiData
|
||||
* @param word
|
||||
*/
|
||||
async AIRequestStream(setting, aiData, word, oldData: string) {
|
||||
let body = {
|
||||
promptTypeId: setting.gptType,
|
||||
promptId: setting.gptData,
|
||||
gptUrl: aiData.gpt_url,
|
||||
model: aiData.model,
|
||||
machineId: global.machineId,
|
||||
apiKey: aiData.api_key,
|
||||
word: word
|
||||
}
|
||||
var myHeaders = new Headers();
|
||||
myHeaders.append("User-Agent", "Apifox/1.0.0 (https://apifox.com)");
|
||||
myHeaders.append("Content-Type", "application/json");
|
||||
|
||||
var requestOptions = {
|
||||
method: 'POST',
|
||||
headers: myHeaders,
|
||||
body: JSON.stringify(body),
|
||||
};
|
||||
|
||||
let resData = oldData;
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(define.serverUrl + "/api/Forward/ForwardWordStream", requestOptions)
|
||||
.then(response => {
|
||||
if (!response.body) {
|
||||
throw new Error('ReadableStream not yet supported in this browser.');
|
||||
}
|
||||
const reader = response.body.getReader();
|
||||
return new ReadableStream({
|
||||
start(controller) {
|
||||
function push() {
|
||||
reader.read().then(({
|
||||
done,
|
||||
value
|
||||
}) => {
|
||||
if (done) {
|
||||
controller.close();
|
||||
resolve(resData)
|
||||
return;
|
||||
}
|
||||
// 假设服务器发送的是文本数据
|
||||
const text = new TextDecoder().decode(value);
|
||||
resData += text
|
||||
// 将数据返回前端
|
||||
global.newWindow[0].win.webContents.send(DEFINE_STRING.GPT.GPT_STREAM_RETURN, resData)
|
||||
controller.enqueue(value); // 可选:将数据块放入流中
|
||||
push();
|
||||
}).catch(err => {
|
||||
controller.error(err);
|
||||
reject(err)
|
||||
});
|
||||
}
|
||||
push();
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
async SplitWord(word: string, wordCount: number) {
|
||||
let word_list = word.split('\n')
|
||||
let new_word = []
|
||||
let tmp_str = ''
|
||||
let result = []
|
||||
for (let i = 0; i < word_list.length; i++) {
|
||||
const element = word_list[i];
|
||||
if (tmp_str.length + element.length > wordCount) {
|
||||
result.push({
|
||||
index: i,
|
||||
word: new_word.join('\n')
|
||||
})
|
||||
|
||||
new_word = []
|
||||
tmp_str = ""
|
||||
new_word.push(element);
|
||||
} else {
|
||||
tmp_str += ',' + element
|
||||
new_word.push(element);
|
||||
}
|
||||
}
|
||||
result.push({
|
||||
index: word_list.length,
|
||||
word: new_word.join('\n')
|
||||
})
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 文案处理,GPT进行推理
|
||||
* @param {*} setting
|
||||
@ -67,48 +213,38 @@ export class Writing extends ServiceBase {
|
||||
if (isEmpty(word)) {
|
||||
throw new Error('请先设置文案')
|
||||
}
|
||||
let result = ''
|
||||
if (setting.isSplit) {
|
||||
// 这边拆分文案
|
||||
let spiltWord = await this.SplitWord(word, setting.splitNumber)
|
||||
console.log(spiltWord)
|
||||
for (let i = 0; i < spiltWord.length; i++) {
|
||||
const element = spiltWord[i];
|
||||
if (setting.isStream) {
|
||||
result += await RetryWithBackoff(async () => {
|
||||
return await this.AIRequestStream(setting, aiData, element.word, result)
|
||||
}, 3, 1000) + '\n'
|
||||
} else {
|
||||
result = await RetryWithBackoff(async () => {
|
||||
return await this.AIRequest(setting, aiData, word)
|
||||
}, 3, 1000)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (setting.isStream) {
|
||||
result += await RetryWithBackoff(async () => {
|
||||
return await this.AIRequestStream(setting, aiData, word, '')
|
||||
}, 3, 1000) + '\r\n\n'
|
||||
} else {
|
||||
result = await RetryWithBackoff(async () => {
|
||||
return await this.AIRequest(setting, aiData, word)
|
||||
}, 3, 1000)
|
||||
}
|
||||
}
|
||||
// let tasks =
|
||||
|
||||
// 开始请求AI
|
||||
let axiosRes = await axios.post('/api/Forward/ForwardWord', {
|
||||
promptTypeId: setting.gptType,
|
||||
promptId: setting.gptData,
|
||||
gptUrl: aiData.gpt_url,
|
||||
model: aiData.model,
|
||||
machineId: this.global.machineId,
|
||||
apiKey: aiData.api_key,
|
||||
word: word
|
||||
})
|
||||
|
||||
// 判断返回的状态,如果是失败的话直接返回错误信息
|
||||
if (axiosRes.status != 200) {
|
||||
throw new Error('请求失败')
|
||||
}
|
||||
let dataRes = axiosRes.data
|
||||
if (dataRes.code == 1) {
|
||||
// 获取成功
|
||||
// 解析返回的数据
|
||||
return successMessage(
|
||||
GetOpenAISuccessResponse(dataRes.data),
|
||||
'请求成功',
|
||||
'Writing_ActionStart'
|
||||
)
|
||||
} else {
|
||||
// 系统报错
|
||||
if (dataRes.code == 5000) {
|
||||
throw new Error('系统错误,错误信息如下:' + dataRes.message)
|
||||
} else {
|
||||
// 处理不同类型的错误消息
|
||||
if (setting.gptAI == 'laiapi') {
|
||||
throw new Error(GetRixApiErrorResponse(dataRes.data))
|
||||
} else if (setting.gptAI == 'kimi') {
|
||||
throw new Error(GetKimiErrorResponse(dataRes.data))
|
||||
} else if (setting.gptAI == 'doubao') {
|
||||
throw new Error(GetDoubaoErrorResponse(dataRes.data))
|
||||
} else {
|
||||
throw new Error(dataRes.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
// ExecuteConcurrently
|
||||
return successMessage(result, "执行文案相关任务成功", 'Writing_ActionStart');
|
||||
} catch (error) {
|
||||
return errorMessage(
|
||||
'执行文案相关任务失败,失败信息如下:' + error.toString(),
|
||||
@ -311,8 +447,7 @@ export class Writing extends ServiceBase {
|
||||
iii = i
|
||||
sss = data[i].after_gpt
|
||||
let srt_value = data[i].text
|
||||
current_text = `字幕: “${srt_value}” 和文案第${text_count + 1} 行数据 “${
|
||||
textData[text_count].after_gpt
|
||||
current_text = `字幕: “${srt_value}” 和文案第${text_count + 1} 行数据 “${textData[text_count].after_gpt
|
||||
}” 数据不匹配(检查一下上下文)`
|
||||
let start_time = data[i].start
|
||||
let end_time = data[i].end
|
||||
@ -403,7 +538,7 @@ export class Writing extends ServiceBase {
|
||||
textData.push(obj)
|
||||
}
|
||||
}
|
||||
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
||||
global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
||||
code: 0,
|
||||
message: current_text
|
||||
})
|
||||
@ -102,6 +102,9 @@
|
||||
>
|
||||
设置
|
||||
</n-button>
|
||||
<div style="margin-left: 10px">
|
||||
<MonitorStatus />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right-button">
|
||||
@ -134,6 +137,7 @@ import { TranslateType } from '../../../../../define/enum/translate'
|
||||
import { ContainsChineseOrPunctuation } from '../../../../../define/Tools/common'
|
||||
import ImportWordAndSrt from '../../Original/Components/ImportWordAndSrt.vue'
|
||||
import GetWaterMaskRectangle from '../../Watermark/GetWaterMaskRectangle.vue'
|
||||
import MonitorStatus from './MonitorStatus.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -141,7 +145,8 @@ export default defineComponent({
|
||||
NCheckbox,
|
||||
NDropdown,
|
||||
NDivider,
|
||||
GetWaterMaskRectangle
|
||||
GetWaterMaskRectangle,
|
||||
MonitorStatus
|
||||
},
|
||||
|
||||
setup() {
|
||||
|
||||
195
src/renderer/src/components/Book/Components/MonitorStatus.vue
Normal file
195
src/renderer/src/components/Book/Components/MonitorStatus.vue
Normal file
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center; font-size: 12px; font-weight: bold">
|
||||
<div style="border: 1px dashed #ccc; padding: 5px">
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 75px">提示词:</div>
|
||||
<n-progress
|
||||
type="line"
|
||||
style="width: 100px; cursor: pointer"
|
||||
status="info"
|
||||
:percentage="gptPromptPercentage"
|
||||
@click="ErrorPosition('gptPrompt')"
|
||||
rail-color="#bbb"
|
||||
indicator-placement="inside"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style="display: flex; align-items: center"
|
||||
v-if="
|
||||
reverseManageStore.selectBook.type == 'mj_reverse' ||
|
||||
reverseManageStore.selectBook.type == 'sd_reverse'
|
||||
"
|
||||
>
|
||||
<div style="width: 75px">反推提示词:</div>
|
||||
<n-progress
|
||||
type="line"
|
||||
:class="test"
|
||||
style="width: 100px; cursor: pointer"
|
||||
status="info"
|
||||
:percentage="reversePromptPercentage"
|
||||
@click="ErrorPosition('reverseGptPrompt')"
|
||||
rail-color="#bbb"
|
||||
indicator-placement="inside"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="border: 1px dashed #ccc; padding: 5px; margin-left: 5px">
|
||||
<div style="display: flex; align-items: center">
|
||||
<div>提示词命令:</div>
|
||||
<n-progress
|
||||
type="line"
|
||||
style="width: 100px; cursor: pointer"
|
||||
status="info"
|
||||
:percentage="promptPercentage"
|
||||
rail-color="#bbb"
|
||||
@click="ErrorPosition('prompt')"
|
||||
indicator-placement="inside"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="border: 1px dashed #ccc; padding: 5px; margin-left: 5px">
|
||||
<div style="display: flex; align-items: center">
|
||||
<div>出图:</div>
|
||||
<n-progress
|
||||
type="line"
|
||||
style="width: 100px; cursor: pointer"
|
||||
status="info"
|
||||
:percentage="imagePercentage"
|
||||
@click="ErrorPosition('image')"
|
||||
rail-color="#bbb"
|
||||
indicator-placement="inside"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { NProgress, useMessage } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
let gptPromptPercentage = ref(0)
|
||||
let promptPercentage = ref(0)
|
||||
let imagePercentage = ref(0)
|
||||
let reversePromptPercentage = ref(0)
|
||||
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let message = useMessage()
|
||||
|
||||
let test = ref('error-class')
|
||||
|
||||
// 计算所有的数据的百分比
|
||||
function ComputePercentage() {
|
||||
debugger
|
||||
if (
|
||||
reverseManageStore &&
|
||||
reverseManageStore.selectBookTaskDetail &&
|
||||
reverseManageStore.selectBookTaskDetail.length > 0
|
||||
) {
|
||||
let total = reverseManageStore.selectBookTaskDetail.length
|
||||
let gptPromptCount = 0
|
||||
let promptCount = 0
|
||||
let imageCount = 0
|
||||
let reversePromptCount = 0
|
||||
reverseManageStore.selectBookTaskDetail.forEach((item) => {
|
||||
if (!isEmpty(item.gptPrompt)) {
|
||||
gptPromptCount++
|
||||
}
|
||||
if (!isEmpty(item.prompt)) {
|
||||
promptCount++
|
||||
}
|
||||
|
||||
// 计算图片的百分比。这个条件比较复杂
|
||||
if (item.outImagePath) {
|
||||
imageCount++
|
||||
}
|
||||
|
||||
if (item.reversePrompt && item.reversePrompt.length > 0) {
|
||||
reversePromptCount++
|
||||
}
|
||||
})
|
||||
|
||||
// 计算推理提示词的百分比
|
||||
gptPromptPercentage.value = Math.floor((gptPromptCount / total) * 100)
|
||||
|
||||
// 计算合并提示词的百分比
|
||||
promptPercentage.value = Math.floor((promptCount / total) * 100)
|
||||
|
||||
imagePercentage.value = Math.floor((imageCount / total) * 100)
|
||||
|
||||
reversePromptPercentage.value = Math.floor((reversePromptCount / total) * 100)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 这边开始计算
|
||||
ComputePercentage()
|
||||
|
||||
// 这边开始定时执行计算
|
||||
setInterval(() => {
|
||||
ComputePercentage()
|
||||
}, 5000)
|
||||
})
|
||||
|
||||
function ErrorPosition(type) {
|
||||
let index = -1
|
||||
softwareStore.skipRowIndex = 0
|
||||
if (type == 'gptPrompt') {
|
||||
// 找到第一个空的提示词数据
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
if (isEmpty(reverseManageStore.selectBookTaskDetail[i].gptPrompt)) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (type == 'reverseGptPrompt') {
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
let element = reverseManageStore.selectBookTaskDetail[i]
|
||||
if (!element.reversePrompt || element.reversePrompt.length <= 0) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (type == 'prompt') {
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
if (isEmpty(reverseManageStore.selectBookTaskDetail[i].prompt)) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (type == 'image') {
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
if (isEmpty(reverseManageStore.selectBookTaskDetail[i].outImagePath)) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
message.error('未知的操作类型')
|
||||
return
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
message.success('全部已完成,不必跳转')
|
||||
return
|
||||
}
|
||||
|
||||
softwareStore.skip = {
|
||||
skipRowIndex: index + 1,
|
||||
clickCount: softwareStore.skip.clickCount++
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.error-class {
|
||||
color: red;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-data-table
|
||||
ref="datatable"
|
||||
:columns="columns"
|
||||
:data="reverseManageStore.selectBookTaskDetail"
|
||||
:max-height="maxHeight"
|
||||
@ -10,8 +11,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, h } from 'vue'
|
||||
import { useMessage, NDataTable, NImage, NInput } from 'naive-ui'
|
||||
import { ref, onMounted, defineComponent, watch, h } from 'vue'
|
||||
import { useMessage, NDataTable, NImage } from 'naive-ui'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import DataTableShowGenerateImage from '../../Original/Components/DataTableShowGenerateImage.vue'
|
||||
@ -33,6 +34,17 @@ export default defineComponent({
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let message = useMessage()
|
||||
let maxHeight = ref(0)
|
||||
let datatable = ref(null)
|
||||
|
||||
watch(
|
||||
() => softwareStore.skip,
|
||||
(newValue) => {
|
||||
let doc = document.querySelectorAll('.n-data-table-tr')
|
||||
let sk = doc[newValue.skipRowIndex]
|
||||
datatable.value.scrollTo({ el: sk })
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
const createColumns = () => [
|
||||
{
|
||||
@ -152,7 +164,8 @@ export default defineComponent({
|
||||
softwareStore,
|
||||
reverseManageStore,
|
||||
maxHeight,
|
||||
columns: createColumns()
|
||||
columns: createColumns(),
|
||||
datatable
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="display: flex">
|
||||
<n-button strong secondary @click="ReturnMain" size="small">返回</n-button>
|
||||
<n-divider vertical style="height: 30px" />
|
||||
@ -58,6 +59,10 @@
|
||||
>设置</n-button
|
||||
>
|
||||
</div>
|
||||
<div style="margin-left: 10px">
|
||||
<MonitorStatus />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -68,6 +73,7 @@ import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import ImportWordAndSrt from '../Components/ImportWord/ImportWordAndSrt.vue'
|
||||
import CharacterAnalyze from '../Components/PresetLibrary/CharacterAnalyze.vue'
|
||||
import PromptSetting from '../../Original/Components/PromptSetting.vue'
|
||||
import MonitorStatus from '../Components/MonitorStatus.vue'
|
||||
import {
|
||||
BookBackTaskType,
|
||||
BookImageCategory,
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-data-table
|
||||
ref="datatable"
|
||||
id="1111"
|
||||
classMame="cd-22223"
|
||||
:max-height="maxHeight"
|
||||
:loading="softwareStore.loading.originDatatableDataLoading"
|
||||
:row-key="rowKey"
|
||||
@ -16,31 +18,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
h,
|
||||
onMounted,
|
||||
defineComponent,
|
||||
onUnmounted,
|
||||
watch,
|
||||
toRaw,
|
||||
render,
|
||||
onBeforeUnmount,
|
||||
provide,
|
||||
nextTick
|
||||
} from 'vue'
|
||||
import {
|
||||
NDataTable,
|
||||
NImage,
|
||||
useMessage,
|
||||
NInput,
|
||||
NButton,
|
||||
NSwitch,
|
||||
NPopover,
|
||||
useDialog,
|
||||
NCheckbox,
|
||||
NIcon
|
||||
} from 'naive-ui'
|
||||
import { ref, h, onMounted, watch } from 'vue'
|
||||
import { NDataTable, useMessage } from 'naive-ui'
|
||||
import DatatableHeaderAfterGpt from '../Components/DatatableHeaderAfterGpt.vue'
|
||||
import DatatableAfterGpt from '../Components/DatatableAfterGpt.vue'
|
||||
import ODatatableHeaderCharacterAndScene from './ODataTableHeaderCharacterAndScene.vue'
|
||||
@ -54,11 +33,21 @@ import DatatableHeaderGenerateImage from '../Components/DatatableHeaderGenerateI
|
||||
import DatatableGenerateImage from '../Components/DatatableGenerateImage.vue'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { set } from 'lodash'
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let maxHeight = ref(0)
|
||||
let message = useMessage()
|
||||
let datatable = ref(null)
|
||||
|
||||
watch(
|
||||
() => softwareStore.skip,
|
||||
(newValue) => {
|
||||
let doc = document.querySelectorAll('.n-data-table-tr')
|
||||
let sk = doc[newValue.skipRowIndex]
|
||||
datatable.value.scrollTo({ el: sk })
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
setTimeout(() => {
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
</n-form-item>
|
||||
<n-form-item label="选择预设" path="gptData">
|
||||
<n-select
|
||||
style="width: 160px"
|
||||
style="width: 200px"
|
||||
v-model:value="formValue.gptData"
|
||||
:options="gptDataOptions"
|
||||
placeholder="请选择提示词数据"
|
||||
@ -37,6 +37,25 @@
|
||||
<n-button type="primary" @click="ActionStart">开始生成</n-button>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<n-form :model="formValue" inline label-placement="left">
|
||||
<n-form-item path="isStream">
|
||||
<n-checkbox label="是否流式发送" v-model:checked="formValue.isStream" />
|
||||
</n-form-item>
|
||||
<n-form-item path="isSplit">
|
||||
<n-checkbox label="是否拆分发送" v-model:checked="formValue.isSplit" />
|
||||
</n-form-item>
|
||||
<n-form-item label="每次发送字符" path="splitNumber">
|
||||
<n-input-number
|
||||
v-model:value="formValue.splitNumber"
|
||||
:min="1"
|
||||
:show-button="false"
|
||||
:max="99999"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item path="splitNumber">
|
||||
<div style="color: red">注意:爆款开头不要分段发送</div>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</div>
|
||||
<div style="display: flex; width: 100%">
|
||||
<div style="flex: 1; margin-right: 10px">
|
||||
@ -61,21 +80,46 @@
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||
import { useMessage, useDialog, NForm, NFormItem, NInput, NSelect, NButton, NIcon } from 'naive-ui'
|
||||
import {
|
||||
useMessage,
|
||||
useDialog,
|
||||
NForm,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NSelect,
|
||||
NButton,
|
||||
NIcon,
|
||||
NCheckbox,
|
||||
NInputNumber
|
||||
} from 'naive-ui'
|
||||
import { SettingsOutline } from '@vicons/ionicons5'
|
||||
import ManageAISetting from './ManageAISetting.vue'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NForm, NFormItem, NInput, NSelect, NButton, NIcon, SettingsOutline },
|
||||
components: {
|
||||
NForm,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NSelect,
|
||||
NButton,
|
||||
NIcon,
|
||||
SettingsOutline,
|
||||
NCheckbox,
|
||||
NInputNumber
|
||||
},
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let formValue = ref({
|
||||
gptType: undefined,
|
||||
gptData: undefined,
|
||||
gptAI: undefined
|
||||
gptAI: undefined,
|
||||
isStream: true,
|
||||
isSplit: false,
|
||||
splitNumber: 1000
|
||||
})
|
||||
let oldWord = ref(undefined)
|
||||
let newWord = ref(undefined)
|
||||
@ -110,8 +154,41 @@ export default defineComponent({
|
||||
allPromptDataOptions.value = gptRes.data.promptData
|
||||
}
|
||||
|
||||
function debounce(func, wait) {
|
||||
let timeoutId
|
||||
let shouldExecute = true
|
||||
|
||||
return function (...args) {
|
||||
const context = this
|
||||
if (shouldExecute) {
|
||||
func.apply(context, args)
|
||||
shouldExecute = false
|
||||
timeoutId = setTimeout(() => {
|
||||
shouldExecute = true
|
||||
}, wait)
|
||||
} else {
|
||||
clearTimeout(timeoutId)
|
||||
timeoutId = setTimeout(() => {
|
||||
shouldExecute = true
|
||||
}, wait)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let UpdateWord = debounce((value) => {
|
||||
newWord.value = value
|
||||
}, 500)
|
||||
|
||||
onMounted(async () => {
|
||||
await InitServerGptOptions()
|
||||
// 这边监听流式返回数据
|
||||
window.api.setEventListen([DEFINE_STRING.GPT.GPT_STREAM_RETURN], (value) => {
|
||||
UpdateWord(value)
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.api.removeEventListen(DEFINE_STRING.GPT.GPT_STREAM_RETURN)
|
||||
})
|
||||
|
||||
let ruleObj = (errorMessage) => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div id="video-canvas">
|
||||
<video ref="videoRef" muted :src="videoSrc" id="video" autoplay></video>
|
||||
<video style="width: 800px" ref="videoRef" muted :src="videoSrc" id="video" autoplay></video>
|
||||
<canvas
|
||||
ref="canvasRef"
|
||||
@mousemove="handleMouseMove"
|
||||
@ -91,10 +91,7 @@ export default defineComponent({
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let videoRef = ref(null)
|
||||
let canvasRef = ref(null)
|
||||
let videoSrc = ref(
|
||||
props.videoSrc ||
|
||||
'D:\\文\\物价暴跌百万倍,我成了神豪-七猫\\1\\价暴跌百万倍,我成了神豪1_output_crop_00001.mp4'
|
||||
)
|
||||
let videoSrc = ref(props.videoSrc)
|
||||
let type = ref(props.type ? props.type : SubtitleSavePositionType.MAIN_VIDEO)
|
||||
let mark = ref(props.mark)
|
||||
let videoWidth = ref(props.videoWidth == null ? 800 : props.videoWidth)
|
||||
@ -120,7 +117,6 @@ export default defineComponent({
|
||||
setTimeout(() => {
|
||||
video.play()
|
||||
isPlaying.value = true
|
||||
debugger
|
||||
let { width, height } = video.getBoundingClientRect()
|
||||
canvasRef.value.width = width
|
||||
canvasRef.value.height = height
|
||||
|
||||
@ -26,6 +26,10 @@ export const useSoftwareStore = defineStore('software', {
|
||||
},
|
||||
globalSetting: {} as SoftwareSettingModel.GlobalSetting,
|
||||
show_logger: false, // 是否显示日志
|
||||
skip: {
|
||||
skipRowIndex: 0, // 表格跳转的行数
|
||||
clickCount: 0
|
||||
},
|
||||
componentSize: [], // 组件尺寸(通用的选项)
|
||||
SoftColor: null, // 按钮颜色
|
||||
loading: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user