11
This commit is contained in:
91
src/components/workflow/AddIpBrainDialog.vue
Normal file
91
src/components/workflow/AddIpBrainDialog.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useWorkflowStore } from "../../stores/workflow.js";
|
||||
|
||||
const workflow = useWorkflowStore();
|
||||
const { ipBrainModalVisible, ipBrainProfileUrl, ipBrainCollecting } =
|
||||
storeToRefs(workflow);
|
||||
|
||||
const feedback = ref({ severity: "", message: "" });
|
||||
|
||||
const tipItems = [
|
||||
"输入账号主页或分享链接后点击「开始采集」按钮",
|
||||
"系统会自动打开浏览器并抓取数据,请保持网络连接正常",
|
||||
"无需任何手动操作,等待采集完成即可",
|
||||
"采集完成后会自动将 5 个视频标题添加到选题库中",
|
||||
];
|
||||
|
||||
function onCancel() {
|
||||
feedback.value = { severity: "", message: "" };
|
||||
workflow.closeIpBrainDialog();
|
||||
}
|
||||
|
||||
async function onStart() {
|
||||
feedback.value = { severity: "", message: "" };
|
||||
const result = await workflow.startIpBrainCollect();
|
||||
if (!result.ok) {
|
||||
feedback.value = { severity: "error", message: result.message };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog
|
||||
v-model:visible="ipBrainModalVisible"
|
||||
modal
|
||||
header="添加IP大脑"
|
||||
:style="{ width: '600px' }"
|
||||
:draggable="false"
|
||||
class="ip-brain-dialog"
|
||||
>
|
||||
<div class="space-y-4">
|
||||
<Message
|
||||
v-if="feedback.message"
|
||||
:severity="feedback.severity"
|
||||
:closable="false"
|
||||
class="w-full"
|
||||
>
|
||||
{{ feedback.message }}
|
||||
</Message>
|
||||
|
||||
<div>
|
||||
<label class="mb-2 block font-medium text-slate-200">
|
||||
账号主页或分享链接
|
||||
</label>
|
||||
<InputText
|
||||
v-model="ipBrainProfileUrl"
|
||||
type="text"
|
||||
size="large"
|
||||
class="w-full"
|
||||
placeholder="请输入抖音账号主页或用户分享链接,例如:https://www.douyin.com/user/..."
|
||||
:disabled="ipBrainCollecting"
|
||||
@keyup.enter="onStart"
|
||||
/>
|
||||
<p class="mt-2 text-xs text-slate-500">
|
||||
当前 IP 学习支持抖音账号主页、用户分享链接和短链接,程序会自动识别并采集最新
|
||||
5 个视频标题
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="elegant-tip-box rounded-lg p-3">
|
||||
<div class="text-sm text-slate-300">
|
||||
<div class="mb-1 font-medium">提示:</div>
|
||||
<ul class="list-inside list-disc space-y-1">
|
||||
<li v-for="(tip, i) in tipItems" :key="i">{{ tip }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<Button
|
||||
label="取消"
|
||||
severity="secondary"
|
||||
:disabled="ipBrainCollecting"
|
||||
@click="onCancel"
|
||||
/>
|
||||
<Button label="开始采集" :loading="ipBrainCollecting" @click="onStart" />
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
@@ -1,6 +1,8 @@
|
||||
<script setup>
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useWorkflowStore } from "../../stores/workflow.js";
|
||||
import AddIpBrainDialog from "./AddIpBrainDialog.vue";
|
||||
import VideoLinkDialog from "./VideoLinkDialog.vue";
|
||||
|
||||
const workflow = useWorkflowStore();
|
||||
const {
|
||||
@@ -13,7 +15,21 @@ const {
|
||||
otherRequirements,
|
||||
targetWords,
|
||||
recognizedContent,
|
||||
ipBenchmarks,
|
||||
ipBrainSelectedBenchmarkId,
|
||||
} = storeToRefs(workflow);
|
||||
|
||||
function onSelectBenchmark(id) {
|
||||
workflow.selectBenchmark(id);
|
||||
}
|
||||
|
||||
function onOpenVideoLink() {
|
||||
workflow.videoLinkModalVisible = true;
|
||||
}
|
||||
|
||||
function onOpenIpBrain() {
|
||||
workflow.ipBrainModalVisible = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -28,22 +44,63 @@ const {
|
||||
/>
|
||||
|
||||
<template v-if="ipMode === 'ipBrain'">
|
||||
<Button label="添加IP大脑" class="w-full" size="small" />
|
||||
<Button
|
||||
label="添加IP大脑"
|
||||
class="w-full"
|
||||
size="small"
|
||||
@click="onOpenIpBrain"
|
||||
/>
|
||||
|
||||
<div class="mt-3">
|
||||
<div class="dashboard-field-label">
|
||||
已学习到的对标
|
||||
<span class="dashboard-field-label--muted text-xs">(0/5)</span>
|
||||
<span class="dashboard-field-label--muted text-xs">
|
||||
({{ workflow.ipBenchmarkCount }}/5)
|
||||
</span>
|
||||
</div>
|
||||
<p v-if="ipBenchmarks.length === 0" class="dashboard-muted py-2">暂无对标</p>
|
||||
<div v-else class="py-1">
|
||||
<button
|
||||
v-for="item in ipBenchmarks"
|
||||
:key="item.id"
|
||||
type="button"
|
||||
class="benchmark-item"
|
||||
:class="{ 'benchmark-item--active': ipBrainSelectedBenchmarkId === item.id }"
|
||||
@click="onSelectBenchmark(item.id)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</button>
|
||||
</div>
|
||||
<p class="dashboard-muted py-2">暂无对标</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<div class="dashboard-field-label mb-2">选题库</div>
|
||||
<p class="dashboard-muted py-2 text-center text-sm">请先选择一个对标</p>
|
||||
<p
|
||||
v-if="!ipBrainSelectedBenchmarkId"
|
||||
class="dashboard-muted py-2 text-center text-sm"
|
||||
>
|
||||
请先选择一个对标
|
||||
</p>
|
||||
<p v-else-if="workflow.ipTopics.length === 0" class="dashboard-muted py-2 text-sm">
|
||||
采集完成后将显示视频标题
|
||||
</p>
|
||||
<ul v-else class="space-y-1 py-1 text-sm text-slate-300">
|
||||
<li v-for="(topic, index) in workflow.ipTopics" :key="topic.id">
|
||||
{{ index + 1 }}. {{ topic.title }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<AddIpBrainDialog />
|
||||
</template>
|
||||
|
||||
<template v-else-if="ipMode === 'videoWrite'">
|
||||
<Button label="打开视频链接" class="w-full" size="small" />
|
||||
<Button
|
||||
label="打开视频链接"
|
||||
class="w-full"
|
||||
size="small"
|
||||
@click="onOpenVideoLink"
|
||||
/>
|
||||
<div class="mt-3 space-y-1">
|
||||
<div class="dashboard-field-label flex items-center gap-1">
|
||||
<span>识别的原始内容</span>
|
||||
@@ -57,6 +114,7 @@ const {
|
||||
rows="10"
|
||||
/>
|
||||
</div>
|
||||
<VideoLinkDialog />
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
@@ -126,7 +184,7 @@ const {
|
||||
:min="50"
|
||||
:max="1500"
|
||||
size="small"
|
||||
class="w-24"
|
||||
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,20 +16,22 @@ const { scriptContent, editLanguage, editWordCount } = storeToRefs(workflow);
|
||||
class="dashboard-textarea-mono w-full"
|
||||
rows="12"
|
||||
/>
|
||||
<div class="flex flex-wrap items-center gap-2 pt-1">
|
||||
<InputNumber
|
||||
v-model="editWordCount"
|
||||
:min="100"
|
||||
:max="2000"
|
||||
size="small"
|
||||
class="w-28"
|
||||
/>
|
||||
<span class="text-xs text-slate-400">字</span>
|
||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 pt-2">
|
||||
<div class="flex shrink-0 items-center gap-2">
|
||||
<InputNumber
|
||||
v-model="editWordCount"
|
||||
:min="30"
|
||||
:max="2000"
|
||||
size="small"
|
||||
class="w-28 shrink-0"
|
||||
/>
|
||||
<span class="shrink-0 text-xs text-slate-400">字</span>
|
||||
</div>
|
||||
<Select
|
||||
v-model="editLanguage"
|
||||
:options="workflow.languages"
|
||||
size="small"
|
||||
class="w-36"
|
||||
class="min-w-36 shrink-0 ml-10"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex gap-2 pt-1">
|
||||
|
||||
90
src/components/workflow/VideoLinkDialog.vue
Normal file
90
src/components/workflow/VideoLinkDialog.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useWorkflowStore, executeVideoRewrite } from "../../stores/workflow.js";
|
||||
|
||||
const workflow = useWorkflowStore();
|
||||
const { videoLinkModalVisible, videoShareText, videoRewriting } = storeToRefs(workflow);
|
||||
|
||||
const feedback = ref({ severity: "", message: "" });
|
||||
|
||||
const tipItems = [
|
||||
"已支持抖音分享文本、抖音视频链接、抖音短链接",
|
||||
"支持直接视频文件 URL(如 .mp4、.mov 等)",
|
||||
"快手、小红书、B站、视频号分享链接目前会提示暂不支持",
|
||||
"使用 FUNASR 进行语音识别",
|
||||
"根据设置的仿写提示词生成仿写文案",
|
||||
];
|
||||
|
||||
function onCancel() {
|
||||
feedback.value = { severity: "", message: "" };
|
||||
workflow.videoLinkModalVisible = false;
|
||||
}
|
||||
|
||||
async function onRewrite() {
|
||||
feedback.value = { severity: "", message: "" };
|
||||
const result = await executeVideoRewrite(workflow);
|
||||
if (!result.ok) {
|
||||
feedback.value = { severity: "error", message: result.message };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog
|
||||
v-model:visible="videoLinkModalVisible"
|
||||
modal
|
||||
header="粘贴视频分享文本 - 快速仿写"
|
||||
:style="{ width: '600px' }"
|
||||
:draggable="false"
|
||||
class="ip-brain-dialog"
|
||||
>
|
||||
<div class="space-y-4">
|
||||
<Message
|
||||
v-if="feedback.message"
|
||||
:severity="feedback.severity"
|
||||
:closable="false"
|
||||
class="w-full"
|
||||
>
|
||||
{{ feedback.message }}
|
||||
</Message>
|
||||
|
||||
<div>
|
||||
<label class="mb-2 block font-medium text-slate-200">
|
||||
请粘贴视频分享文本或视频链接
|
||||
</label>
|
||||
<p class="mb-2 text-xs text-slate-500">
|
||||
支持抖音分享文本、抖音视频链接、抖音短链接,以及直接视频文件链接
|
||||
</p>
|
||||
<InputText
|
||||
v-model="videoShareText"
|
||||
type="text"
|
||||
size="large"
|
||||
class="w-full"
|
||||
placeholder="请输入分享文本、视频链接,或 mp4/mov/webm 等直链..."
|
||||
:disabled="videoRewriting"
|
||||
@keyup.enter="onRewrite"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="elegant-tip-box rounded-lg p-3">
|
||||
<div class="text-sm text-slate-300">
|
||||
<div class="mb-1 font-medium">提示:</div>
|
||||
<ul class="list-inside list-disc space-y-1">
|
||||
<li v-for="(tip, i) in tipItems" :key="i">{{ tip }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<Button
|
||||
label="取消"
|
||||
severity="secondary"
|
||||
:disabled="videoRewriting"
|
||||
@click="onCancel"
|
||||
/>
|
||||
<Button label="一键仿写" :loading="videoRewriting" @click="onRewrite" />
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
Reference in New Issue
Block a user