2025-05-04 18:45:03 +08:00
|
|
|
|
<script setup lang="js">
|
|
|
|
|
import { onMounted, ref } from 'vue';
|
2025-05-02 22:08:36 +08:00
|
|
|
|
|
2025-05-04 18:45:03 +08:00
|
|
|
|
import { getAppList, sendWorkflow } from '#/api';
|
2025-05-02 22:08:36 +08:00
|
|
|
|
|
2025-05-04 18:45:03 +08:00
|
|
|
|
// 数据爬取工具列表
|
|
|
|
|
const tools = ref([
|
2025-05-02 22:08:36 +08:00
|
|
|
|
{
|
2025-05-04 18:45:03 +08:00
|
|
|
|
id: 1,
|
|
|
|
|
name: '工具一',
|
|
|
|
|
description: '这是一个用于抓取网页数据的工具',
|
|
|
|
|
content: '工具一的具体内容:支持多种网页抓取规则配置。',
|
|
|
|
|
path: '/tools/tool1',
|
2025-05-02 22:08:36 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2025-05-04 18:45:03 +08:00
|
|
|
|
id: 2,
|
|
|
|
|
name: '工具二',
|
|
|
|
|
description: '这是一个用于分析文本数据的工具',
|
|
|
|
|
content: '工具二的具体内容:支持自然语言处理和文本分析功能。',
|
|
|
|
|
path: '/tools/tool2',
|
2025-05-02 22:08:36 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2025-05-04 18:45:03 +08:00
|
|
|
|
id: 3,
|
|
|
|
|
name: '工具三',
|
|
|
|
|
description: '这是一个用于数据清洗的工具',
|
|
|
|
|
content: '工具三的具体内容:支持数据去重、格式化等操作。',
|
|
|
|
|
path: '/tools/tool3',
|
2025-05-02 22:08:36 +08:00
|
|
|
|
},
|
2025-05-04 18:45:03 +08:00
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 当前选中的工具
|
|
|
|
|
const selectedTool = ref(null);
|
|
|
|
|
|
|
|
|
|
// 抓取状态相关变量
|
|
|
|
|
const isFetching = ref(false);
|
|
|
|
|
const fetchStatus = ref('idle'); // idle | fetching | completed
|
|
|
|
|
|
|
|
|
|
// 保存抓取结果
|
|
|
|
|
const fetchResult = ref(null);
|
|
|
|
|
|
|
|
|
|
// 点击工具项时触发
|
|
|
|
|
const selectTool = (tool) => {
|
|
|
|
|
selectedTool.value = tool;
|
|
|
|
|
fetchStatus.value = 'idle'; // 重置抓取状态
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getChatflowList = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getAppList({
|
|
|
|
|
mode: '',
|
|
|
|
|
name: '',
|
|
|
|
|
});
|
|
|
|
|
tools.value = res.data;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 开始抓取逻辑
|
|
|
|
|
const startFetching = async () => {
|
|
|
|
|
if (!selectedTool.value) return;
|
|
|
|
|
|
|
|
|
|
// 更新状态为“抓取中”
|
|
|
|
|
isFetching.value = true;
|
|
|
|
|
fetchStatus.value = 'fetching';
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const res = await sendWorkflow(
|
|
|
|
|
{
|
|
|
|
|
appid: 'c736edd0-925d-4877-9223-56aab7342311',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
userId: '1562',
|
|
|
|
|
conversationId: '',
|
|
|
|
|
files: [],
|
|
|
|
|
inputs: {},
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 保存抓取结果
|
|
|
|
|
fetchResult.value = res.data.data.outputs.result;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
2025-05-02 22:08:36 +08:00
|
|
|
|
|
2025-05-04 18:45:03 +08:00
|
|
|
|
// 模拟抓取完成
|
|
|
|
|
isFetching.value = false;
|
|
|
|
|
fetchStatus.value = 'completed';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 下载文件逻辑
|
|
|
|
|
const downloadFile = () => {
|
|
|
|
|
if (!fetchResult.value) return;
|
|
|
|
|
|
|
|
|
|
// 使用抓取结果作为文件内容
|
|
|
|
|
const fileName = `${selectedTool.value.name}.txt`;
|
|
|
|
|
const fileContent = fetchResult.value;
|
|
|
|
|
|
|
|
|
|
// 创建 Blob 对象
|
|
|
|
|
const blob = new Blob([fileContent], { type: 'text/plain' });
|
|
|
|
|
|
|
|
|
|
// 创建下载链接
|
|
|
|
|
const link = document.createElement('a');
|
|
|
|
|
link.href = URL.createObjectURL(blob);
|
|
|
|
|
link.download = fileName;
|
|
|
|
|
|
|
|
|
|
// 触发下载
|
|
|
|
|
link.click();
|
|
|
|
|
|
|
|
|
|
// 释放 URL 对象
|
|
|
|
|
URL.revokeObjectURL(link.href);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getChatflowList();
|
|
|
|
|
});
|
2025-05-02 22:08:36 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2025-05-04 18:45:03 +08:00
|
|
|
|
<a-layout>
|
|
|
|
|
<!-- 右侧部分开始 -->
|
|
|
|
|
<a-layout :style="{ height: '100vh' }">
|
|
|
|
|
<!-- 右侧页面主体开始 -->
|
|
|
|
|
<a-layout-content
|
|
|
|
|
:style="{
|
|
|
|
|
margin: '12px 10px',
|
|
|
|
|
padding: '18px',
|
|
|
|
|
background: '#fff',
|
|
|
|
|
minHeight: '280px',
|
|
|
|
|
borderRadius: '4px',
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<!-- 左右布局容器 -->
|
|
|
|
|
<a-row
|
|
|
|
|
:gutter="16"
|
|
|
|
|
:style="{ height: 'calc(100vh - 100px)', overflow: 'hidden' }"
|
|
|
|
|
>
|
|
|
|
|
<!-- 左边:数据爬取工具列表 -->
|
|
|
|
|
<a-col
|
|
|
|
|
:span="6"
|
|
|
|
|
:style="{
|
|
|
|
|
height: '100%',
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
borderRight: '1px solid #e8e8e8',
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<a-card
|
|
|
|
|
title="数据爬取工具列表"
|
|
|
|
|
:bordered="false"
|
|
|
|
|
:style="{ height: '100%' }"
|
|
|
|
|
>
|
|
|
|
|
<a-list item-layout="horizontal" :data-source="tools">
|
|
|
|
|
<template #renderItem="{ item }">
|
|
|
|
|
<a-list-item @click="selectTool(item)">
|
|
|
|
|
<a-list-item-meta>
|
|
|
|
|
<template #title>
|
|
|
|
|
<span>{{ item.name }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</a-list-item-meta>
|
|
|
|
|
</a-list-item>
|
|
|
|
|
</template>
|
|
|
|
|
</a-list>
|
|
|
|
|
</a-card>
|
|
|
|
|
</a-col>
|
|
|
|
|
|
|
|
|
|
<!-- 右边:所选工具的内容 -->
|
|
|
|
|
<a-col
|
|
|
|
|
:span="18"
|
|
|
|
|
:style="{
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
justifyContent: 'flex-end',
|
|
|
|
|
height: '100%',
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<a-card
|
|
|
|
|
v-if="selectedTool"
|
|
|
|
|
title="工具"
|
|
|
|
|
:bordered="false"
|
|
|
|
|
:style="{ marginBottom: '20px' }"
|
|
|
|
|
>
|
|
|
|
|
<p>{{ selectedTool.name }}</p>
|
|
|
|
|
|
|
|
|
|
<!-- 抓取按钮和状态 -->
|
|
|
|
|
<div style="float: right; margin-top: 20px">
|
|
|
|
|
<a-button
|
|
|
|
|
type="primary"
|
|
|
|
|
style="margin-right: 12px"
|
|
|
|
|
:loading="isFetching"
|
|
|
|
|
@click="startFetching"
|
|
|
|
|
>
|
|
|
|
|
开始抓取
|
|
|
|
|
</a-button>
|
|
|
|
|
<a-button
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="downloadFile"
|
|
|
|
|
v-if="fetchStatus === 'completed'"
|
|
|
|
|
>
|
|
|
|
|
下载文件
|
|
|
|
|
</a-button>
|
|
|
|
|
</div>
|
|
|
|
|
</a-card>
|
|
|
|
|
<a-empty v-else description="请选择一个工具" />
|
|
|
|
|
</a-col>
|
|
|
|
|
</a-row>
|
|
|
|
|
</a-layout-content>
|
|
|
|
|
<!-- 右侧页面主体结束 -->
|
|
|
|
|
</a-layout>
|
|
|
|
|
<!-- 右侧部分结束 -->
|
|
|
|
|
</a-layout>
|
2025-05-02 22:08:36 +08:00
|
|
|
|
</template>
|