|
|
@@ -1,7 +1,7 @@
|
|
|
<template>
|
|
|
<footer class="wendangbaogaoshengcheng-footer" v-if="show_doc_rpt_footer">
|
|
|
<div class="upload-footer" v-show="doc_form_show">
|
|
|
- <div v-if="act_type === 3 && init_status" class="form-fold-btn" @click="handleFormFold">
|
|
|
+ <div v-show="act_type === 3 && init_status" class="form-fold-btn" @click="handleFormFold">
|
|
|
<icon-menu-fold :size="20" />
|
|
|
</div>
|
|
|
|
|
|
@@ -10,7 +10,7 @@
|
|
|
<div class="vertical-placeholder"></div>
|
|
|
|
|
|
<TextInputType1 v-if="act_type === 1" @change="handleTextChange" />
|
|
|
- <TextInputType2 v-if="act_type === 2" @change="handleTextChange" />
|
|
|
+ <TextInputType2 v-if="act_type === 2" :report_text="report_text" @change="handleTextChange" />
|
|
|
<TextInputType3 v-if="act_type === 3" @change="handleTextChange" />
|
|
|
|
|
|
<div class="vertical-placeholder"></div>
|
|
|
@@ -23,15 +23,19 @@
|
|
|
<a-upload :file-list="file_list" :multiple="true" :limit="MAX_ACCEPT_FILE" :auto-upload="false"
|
|
|
:show-upload-button="{ showOnExceedLimit: false }" accept=".pdf,.docx" @change="handleFileChange">
|
|
|
<template #upload-button>
|
|
|
- <a-tooltip :content="upload_warning_text">
|
|
|
- <a-button class="upload-button">
|
|
|
- <template #icon>
|
|
|
- <icon-upload />
|
|
|
- </template>
|
|
|
-
|
|
|
- <template #default>点击上传</template>
|
|
|
- </a-button>
|
|
|
- </a-tooltip>
|
|
|
+ <a-space>
|
|
|
+ <a-tooltip :content="upload_warning_text">
|
|
|
+ <a-button class="upload-button">
|
|
|
+ <template #icon>
|
|
|
+ <icon-upload />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #default>点击上传</template>
|
|
|
+ </a-button>
|
|
|
+ </a-tooltip>
|
|
|
+ <a-typography>{{ '(' + file_list.length + '/' + MAX_ACCEPT_FILE + ')' + "已上传/最大支持"
|
|
|
+ }}</a-typography>
|
|
|
+ </a-space>
|
|
|
</template>
|
|
|
|
|
|
<template #file-name="{ fileItem }">
|
|
|
@@ -50,16 +54,18 @@
|
|
|
|
|
|
|
|
|
<template v-if="act_type === 2 || act_type === 1 || show_start_btn">
|
|
|
+ <!-- <template v-if="act_type === 2 || act_type === 1 || is_first_generate"> -->
|
|
|
<div class="vertical-placeholder"></div>
|
|
|
|
|
|
<a-button :style="{ width: '500px' }" type="primary" @click="handleStart"
|
|
|
:disabled="start_status !== 1">开始</a-button>
|
|
|
</template>
|
|
|
</div>
|
|
|
-
|
|
|
<template v-if="act_type === 3 && show_chat_text_input">
|
|
|
+ <!-- <template v-if="act_type === 3 && !is_first_generate"> -->
|
|
|
<div class="message-input-container">
|
|
|
- <div v-show="!doc_form_show" class="form-fold-btn open" @click="handleFormOpen">
|
|
|
+ <!-- 按需求新修改为,小标题多轮对话中只允许问答不允许修改 先对该按钮做隐藏 -->
|
|
|
+ <div v-show="false && !doc_form_show" class="form-fold-btn open" @click="handleFormOpen">
|
|
|
<!-- <icon-menu-fold :size="20" /> -->
|
|
|
<a-space>
|
|
|
<icon-menu-unfold :size="20" />
|
|
|
@@ -75,7 +81,7 @@
|
|
|
</footer>
|
|
|
</template>
|
|
|
<script setup>
|
|
|
-import { ref, inject, computed } from "vue";
|
|
|
+import { ref, inject, computed, watch } from "vue";
|
|
|
import { Message } from '@arco-design/web-vue';
|
|
|
|
|
|
import MessageInputV2 from "./MessageInputV2.vue";
|
|
|
@@ -85,6 +91,7 @@ import TextInputType1 from './document-report/TextInputType1.vue'
|
|
|
import TextInputType2 from './document-report/TextInputType2.vue'
|
|
|
import TextInputType3 from './document-report/TextInputType3.vue'
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 与此组件有关的对话参数的文档可查看此文件同目录下的 DocumentReportFooter.md 文件
|
|
|
*/
|
|
|
@@ -116,6 +123,12 @@ const text_title = ref(""); // 单行文本:标题
|
|
|
const text_description = ref(""); // 多行文本:描述
|
|
|
const chat_message = ref(''); // 对话输入框的消息
|
|
|
|
|
|
+const is_clean = ref(1); // 是否是文档清洗
|
|
|
+const max_tokens = ref(0); // 默认最大tokens
|
|
|
+const tokens = ref(0); //上传文件的token数
|
|
|
+const report_text = ref(''); //生成报告回填的小标题及关键内容
|
|
|
+const file_type = ref(1); // 文件类型 1本地文件 2清洗后的连接文件
|
|
|
+
|
|
|
/**
|
|
|
* 是否是第一次 小标题生成
|
|
|
*/
|
|
|
@@ -160,15 +173,78 @@ const handleFormFold = () => {
|
|
|
const handleFormOpen = () => {
|
|
|
doc_form_show.value = true;
|
|
|
}
|
|
|
+// 订阅打开用户生成报告弹框事件
|
|
|
+helper.$bus.on('open-document-dialog', (item) => {
|
|
|
+ text_description.value = item.answer
|
|
|
+ report_text.value = text_description.value
|
|
|
+ // console.log(report_text.value, 999)
|
|
|
+ // console.log(text_description.value, 999)
|
|
|
+ console.log(item, 999)
|
|
|
+ let file_urls
|
|
|
+ /**
|
|
|
+ * 如果有文件,则使用文件链接,否则使用文件列表
|
|
|
+ * 否则使用文件列表
|
|
|
+ * */
|
|
|
+ if (item.file && item.file.file_url) {
|
|
|
+ file_urls = [item.file.file_url]
|
|
|
+ report_file_list.value = processFileUrls(file_urls)
|
|
|
+ file_list.value = report_file_list.value
|
|
|
+ file_type.value = 2
|
|
|
+ console.log(file_list.value, 999)
|
|
|
+ } else {
|
|
|
+ report_file_list.value = sub_title_file_list.value
|
|
|
+ file_list.value = report_file_list.value
|
|
|
+ file_type.value = 1
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO:判断是否进行了文档清洗
|
|
|
+ // 1.可以根据是否返回URL地址来判断,同时也可以使用用户设置的最大tolens和文件总tokens进行判断
|
|
|
+ // file_Type:1 本地 file_Type:2 链接
|
|
|
+ // type1:
|
|
|
+
|
|
|
+ // type2:
|
|
|
+ // const file_urls = [
|
|
|
+ // 'http:192.168.0.1:8000/static/file/test1.docx',
|
|
|
+ // 'http:192.168.0.1:8000/static/file/test2.docx'
|
|
|
+ // ]
|
|
|
+
|
|
|
+ console.log(file_list.value, 999)
|
|
|
+ // const file_list = he
|
|
|
+ handleFormOpen()
|
|
|
+
|
|
|
+})
|
|
|
+/**
|
|
|
+ * 文件链接处理为文件列表
|
|
|
+ * */
|
|
|
+const processFileUrls = (urls) => {
|
|
|
+ return urls.map(url => {
|
|
|
+ // 提取文件名
|
|
|
+ const name = url.split('/').pop();
|
|
|
+
|
|
|
+ // 创建并返回对象
|
|
|
+ return {
|
|
|
+ name: name,
|
|
|
+ percent: 0,
|
|
|
+ status: "clean",
|
|
|
+ file_url: url
|
|
|
+ };
|
|
|
+ });
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
* 文件处理
|
|
|
*/
|
|
|
const file_list = ref([]);
|
|
|
-const MAX_ACCEPT_FILE = 30;
|
|
|
+const MAX_ACCEPT_FILE = 80;
|
|
|
const file_total = computed(() => {
|
|
|
return file_list.value.length;
|
|
|
});
|
|
|
+/**
|
|
|
+ * 不同类型文件列表
|
|
|
+ * */
|
|
|
+const clear_file_list = ref([])
|
|
|
+const sub_title_file_list = ref([])
|
|
|
+const report_file_list = ref([])
|
|
|
|
|
|
/**
|
|
|
* 网络请求状态
|
|
|
@@ -183,7 +259,8 @@ const handleDefineReset = () => {
|
|
|
text_title.value = '';
|
|
|
text_description.value = '';
|
|
|
chat_message.value = '';
|
|
|
- is_first_generate.value = true;
|
|
|
+ // is_first_generate.value = true;
|
|
|
+ // 切换radio时先不重置该项
|
|
|
show_chat_text_input.value = false;
|
|
|
show_start_btn.value = true;
|
|
|
doc_form_show.value = true;
|
|
|
@@ -199,6 +276,11 @@ const handleDefineReset = () => {
|
|
|
const handleTextChange = (textObj) => {
|
|
|
text_title.value = textObj.title || '';
|
|
|
text_description.value = textObj.description || '';
|
|
|
+ is_clean.value = textObj.is_clean
|
|
|
+ if (textObj.max_tokens) {
|
|
|
+ max_tokens.value = textObj.max_tokens * 1000;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -216,7 +298,28 @@ const handleRadioChange = (value) => {
|
|
|
* @param fileList
|
|
|
*/
|
|
|
const handleFileChange = (fileList) => {
|
|
|
- file_list.value = fileList;
|
|
|
+ if (act_type.value == 1) {
|
|
|
+ clear_file_list.value = fileList
|
|
|
+ file_list.value = clear_file_list.value;
|
|
|
+ }
|
|
|
+ if (act_type.value == 2) {
|
|
|
+ // 如果上传文件时,文件列表中显示清洗后的链接文件,则清空文件列表后再添加
|
|
|
+ if (file_type.value == 2) {
|
|
|
+ report_file_list.value = fileList.filter(item => {
|
|
|
+ console.log(item, 999)
|
|
|
+ return (item.status != 'clean')
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ report_file_list.value = fileList
|
|
|
+ }
|
|
|
+ file_list.value = report_file_list.value;
|
|
|
+
|
|
|
+ }
|
|
|
+ if (act_type.value == 3) {
|
|
|
+ sub_title_file_list.value = fileList;
|
|
|
+ file_list.value = sub_title_file_list.value;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -236,7 +339,6 @@ const handleChatMessageUpdate = (msg) => {
|
|
|
*/
|
|
|
const getFIleParams = () => {
|
|
|
const formData = new FormData();
|
|
|
-
|
|
|
const f_list = file_list.value;
|
|
|
|
|
|
f_list.forEach((item) => {
|
|
|
@@ -261,7 +363,6 @@ const handleStart = async () => {
|
|
|
const action_type = act_type.value; // 操作类型
|
|
|
let title = text_title.value; // 标题
|
|
|
const f_list = file_list.value;
|
|
|
-
|
|
|
if (!action_type) {
|
|
|
showMsg('请选择类型');
|
|
|
return;
|
|
|
@@ -308,7 +409,7 @@ const handleStart = async () => {
|
|
|
// }
|
|
|
if (is_first_generate.value) {
|
|
|
// 第一次
|
|
|
- init_status.value = true; // 标记为已点击开始,显示收起按钮
|
|
|
+ // init_status.value = true; // 标记为已点击开始,显示收起按钮
|
|
|
} else {
|
|
|
// 非第一次
|
|
|
if (!chat_message.value) {
|
|
|
@@ -336,43 +437,53 @@ const handleStart = async () => {
|
|
|
// const dialog = await ajax.message.createDialog(agent_id);
|
|
|
|
|
|
// const chat_id = dialog.chat_id;
|
|
|
+ // 报告生成中如果是没有被清洗的文件,则需要上传文件,如果是清洗后的文件,则只需要上传file_type:2即可
|
|
|
+ let fm_data, uploadResult1, files_info, file_id_list, file_token_list, tempLocalStoreData
|
|
|
+ if (file_type.value == 1) {
|
|
|
+ // 文件参数数据
|
|
|
+ fm_data = getFIleParams();
|
|
|
+
|
|
|
+ uploadResult1 = await ajax.file.uploadFiles(agent_id, fm_data);
|
|
|
+ console.log(uploadResult1, '上传结果');
|
|
|
+
|
|
|
+ // const uploadResult2 = await ajax.file.uploadFile(agent_id, chat_id, fm_data);
|
|
|
+ // console.log(uploadResult2, '上传结果');
|
|
|
+
|
|
|
+ // if (uploadResult2.code !== 200) {
|
|
|
+ // // 失败: 接口值不为 200,接口异常
|
|
|
+ // start_status.value = 4;
|
|
|
+ // start_message.value = uploadResult2.msg;
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // console.log(uploadResult2, '文件上传结果');
|
|
|
+ files_info = uploadResult1.files; // 数组
|
|
|
+ file_id_list = files_info.map(item => item.id);
|
|
|
+ // console.log(file_id_list, '文件ID值');
|
|
|
+ file_token_list = files_info.map(item => item.tokens);
|
|
|
+ console.log(file_token_list, '文件信息');
|
|
|
+ tokens.value = file_token_list.reduce((acc, cur) => (Number(acc) + Number(cur)), 0)
|
|
|
+ console.log(tokens, 'tokens')
|
|
|
+ tempLocalStoreData = {
|
|
|
+ name: '文档报告生成',
|
|
|
|
|
|
- // 文件参数数据
|
|
|
- const fm_data = getFIleParams();
|
|
|
-
|
|
|
- const uploadResult1 = await ajax.file.uploadFiles(agent_id, fm_data);
|
|
|
- // console.log(uploadResult1, '上传结果');
|
|
|
-
|
|
|
- // const uploadResult2 = await ajax.file.uploadFile(agent_id, chat_id, fm_data);
|
|
|
- // console.log(uploadResult2, '上传结果');
|
|
|
-
|
|
|
- // if (uploadResult2.code !== 200) {
|
|
|
- // // 失败: 接口值不为 200,接口异常
|
|
|
- // start_status.value = 4;
|
|
|
- // start_message.value = uploadResult2.msg;
|
|
|
- // return;
|
|
|
- // }
|
|
|
-
|
|
|
- // console.log(uploadResult2, '文件上传结果');
|
|
|
- const files_info = uploadResult1.files; // 数组
|
|
|
- const file_id_list = files_info.map(item => item.id);
|
|
|
- // console.log(file_id_list, '文件ID值');
|
|
|
-
|
|
|
- let tempLocalStoreData = {
|
|
|
- name: '文档报告生成',
|
|
|
+ agent_id: agent_id,
|
|
|
+ // chat_id: chat_id,
|
|
|
|
|
|
- agent_id: agent_id,
|
|
|
- // chat_id: chat_id,
|
|
|
+ workflow: action_type,
|
|
|
|
|
|
- workflow: action_type,
|
|
|
+ upload_files: file_id_list,
|
|
|
+ title: title,
|
|
|
+ /**
|
|
|
+ * 当workflow值为2或者3时,存在sub_title参数值
|
|
|
+ */
|
|
|
+ sub_titles: text_description.value,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ if (file_type.value == 2) {
|
|
|
+ file_id_list = file_list.value.map(item => item.file_url);
|
|
|
+ }
|
|
|
|
|
|
- upload_files: file_id_list,
|
|
|
- title: title,
|
|
|
- /**
|
|
|
- * 当workflow值为2或者3时,存在sub_title参数值
|
|
|
- */
|
|
|
- sub_titles: text_description.value,
|
|
|
- };
|
|
|
|
|
|
if (action_type === 1) {
|
|
|
// 文档清洗
|
|
|
@@ -405,6 +516,7 @@ const handleStart = async () => {
|
|
|
* 当workflow值为2或者3时,存在sub_title参数值
|
|
|
*/
|
|
|
sub_titles: text_description.value,
|
|
|
+ file_type: file_type.value,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -426,7 +538,14 @@ const handleStart = async () => {
|
|
|
title_number: text_title.value || 8, // 小标题数量,默认值
|
|
|
title_style: text_description.value || '',
|
|
|
title_query: chat_message.value,
|
|
|
+ // 新增参数是否清洗,和文件token数
|
|
|
+ is_clean: is_clean.value,
|
|
|
+ tokens: tokens.value,
|
|
|
+
|
|
|
};
|
|
|
+ if (!is_clean.value) {
|
|
|
+ tempLocalStoreData.max_tokens = max_tokens.value;
|
|
|
+ }
|
|
|
|
|
|
if (is_first_generate.value) {
|
|
|
// 小标题生成
|
|
|
@@ -463,7 +582,21 @@ const handleStart = async () => {
|
|
|
start_message.value = err.message;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+/**
|
|
|
+ * 根据act_type 值,切换文件列表
|
|
|
+ * */
|
|
|
+watch(() => act_type.value, (val) => {
|
|
|
+ console.log(val);
|
|
|
+ if (val == 1) {
|
|
|
+ file_list.value = clear_file_list.value
|
|
|
+ } else if (val == 2) {
|
|
|
+ file_list.value = report_file_list.value
|
|
|
+ } else if (val == 3) {
|
|
|
+ file_list.value = sub_title_file_list.value
|
|
|
+ }
|
|
|
+}, {
|
|
|
+ immediate: true
|
|
|
+})
|
|
|
const upload_warning_text = `支持上传文件pdf、docx文档(最多${MAX_ACCEPT_FILE}个,每个大小不超过10MB)`;
|
|
|
const radio_qingxi_text = "对上传的文档进行清洗,输出生成清洗后的文档";
|
|
|
const radio_xiaobiaoti_text = "对上传文档进行内容总结和分类,生成小标题并提供相应的分类内容。"
|
|
|
@@ -554,6 +687,7 @@ const radio_shengcheng_text = "对上传的(经过清洗的)文档生成报告
|
|
|
overflow-y: auto;
|
|
|
padding-right: 5px;
|
|
|
}
|
|
|
+
|
|
|
.wendangbaogaoshengcheng-footer .arco-upload-list.arco-upload-list-type-text .arco-upload-list-item {
|
|
|
margin-top: 10px;
|
|
|
}
|