奇橙 1 yıl önce
ebeveyn
işleme
bfee8b1c95

+ 19 - 0
src/ajax/api/file.js

@@ -0,0 +1,19 @@
+import request from "../request";
+
+/**
+ * 上传文档
+ * @param {string} id - agentId
+ * @param {files} files - files
+ * @returns {Promise<Object>}
+ */
+const uploadFiles = (id, file) => {
+    return request.post(`/api/files/upload/${id}`, file, {
+        headers: {
+            "Content-Type": "multipart/form-data"
+        }
+    });
+};
+
+export default {
+    uploadFiles
+};

+ 3 - 2
src/ajax/api/message.js

@@ -1,6 +1,7 @@
 import request from "../request";
-const create = (token, agentId, dialogId) => {
-    const ws = new WebSocket(`ws://smartai.com:8000/api/chat/ws/${agentId}/${dialogId}?token=${token}`);
+const create = (token, agentId, dialogId, type) => {
+    const wsParam = type === "report" ? "report" : "chat";
+    const ws = new WebSocket(`ws://smartai.com:8000/api/${wsParam}/ws/${agentId}/${dialogId}?token=${token}`);
     // 当 WebSocket 打开时...
     ws.onopen = function (event) {
         console.log("WebSocket 连接已打开");

+ 3 - 1
src/ajax/index.js

@@ -3,12 +3,14 @@ import agent from "./api/agent";
 import knowledge from "./api/knowledge";
 import document from "./api/document";
 import message from "./api/message";
+import file from "./api/file";
 const api = {
     user,
     agent,
     knowledge,
     document,
-    message
+    message,
+    file
 };
 
 export default api;

+ 15 - 11
src/components/DialogWrap.vue

@@ -144,14 +144,14 @@
                             答案生成结果
                         </p>
                         <p v-if="item.answer" :style="{ 'margin-top': type === 'knowledge' ? '12px' : '0' }">
-                            <span v-if="dialogConfig.type === 'paper'" class="paper-wrap">
+                            <span v-if="type === 'paper'" class="paper-wrap">
                                 <img src="@/assets/question/word.svg" />
                                 <span>
                                     <b>黄冈试卷考试题</b>
                                     <em>DOCX,13.19KB</em>
                                 </span>
                             </span>
-                            <span v-else>{{ item.answer }}</span>
+                            <span v-else v-html="item.answer"></span>
                         </p>
                     </div>
                     <div class="dialog-footer" v-else>
@@ -525,11 +525,12 @@ export default defineComponent({
         });
         onMounted(() => {
             scrollToEnd();
-            helper.webSocket = ajax.message.create(helper.read("token"), props.agentId, props.dialogId);
+            helper.webSocket = ajax.message.create(helper.read("token"), props.agentId, props.dialogId, props.type);
             helper.webSocket.onmessage = (event) => {
-                const { type, message, category } = JSON.parse(event.data);
+                console.log(JSON.parse(event.data));
+                const { type, message, step_message } = JSON.parse(event.data);
                 if (type === "stream") {
-                    answerData.value += message;
+                    answerData.value += props.type === "report" ? step_message + "<br />" : message;
                     if (answerData.value && !isLoaded.value) {
                         answerLoaded();
                     }
@@ -548,13 +549,16 @@ export default defineComponent({
             };
             helper.$bus.on("send-message", (value) => {
                 dialogConfig.value = helper.dialogConfig;
-                const data = addQuestion(value);
+                const question = props.type === "report" ? value.inputs.report_name : value;
+                const data = addQuestion(question);
                 loadingData.value = addLoading(data);
-                helper.webSocket.send(
-                    JSON.stringify({
-                        message: value
-                    })
-                );
+                const sendData =
+                    props.type === "report"
+                        ? JSON.stringify(value)
+                        : JSON.stringify({
+                              message: value
+                          });
+                helper.webSocket.send(sendData);
             });
             helper.$bus.on("clear-message", () => {
                 dialogList.splice(0);

+ 2 - 2
src/components/Slider.vue

@@ -14,13 +14,13 @@
         </section>
         <a-popover position="rt">
             <footer>
-                <div style="background-color: rgb(255, 110, 110)">{{ userName.slice(0, 1) }}</div>
+                <div style="background-color: rgb(255, 110, 110)">{{ userName?.slice(0, 1) }}</div>
                 <p>{{ userName }}</p>
             </footer>
             <template #content>
                 <div class="user-popover">
                     <header>
-                        <div style="background-color: rgb(255, 110, 110)">{{ userName.slice(0, 1) }}</div>
+                        <div style="background-color: rgb(255, 110, 110)">{{ userName?.slice(0, 1) }}</div>
                         <p>{{ userName }}</p>
                     </header>
                     <section>

+ 101 - 6
src/views/Home.vue

@@ -57,16 +57,41 @@
                         <footer v-if="navIndex !== -2 && navIndex !== 0">
                             <message-input :readonly="readonly" eventName="open-dialog" />
                         </footer>
-                        <footer v-if="navIndex === 0" class="upload-footer">
+                        <footer v-if="navIndex === 0 && !showDialog" class="upload-footer">
                             <p><span>标题</span></p>
-                            <div><a-input :style="{ flex: '1' }" placeholder="请输入标题" allow-clear /></div>
+                            <div>
+                                <a-input
+                                    :style="{ flex: '1' }"
+                                    placeholder="请输入标题"
+                                    allow-clear
+                                    v-model="uploadTitle"
+                                />
+                            </div>
                             <div>
                                 <p><span>请上传文档</span></p>
-                                <a-upload :style="{ width: '110px' }" action="/" />
+                            </div>
+                            <div>
+                                <a-upload
+                                    :style="{ width: '300px' }"
+                                    :multiple="false"
+                                    :limit="1"
+                                    :custom-request="customRequest1"
+                                    :show-upload-button="{ showOnExceedLimit: true }"
+                                    accept=".pdf,.doc,.docx,.txt,.md,.ppt.pptx"
+                                />
                             </div>
                             <div>
                                 <p><span>请上传中心动态</span></p>
-                                <a-upload :style="{ width: '110px' }" action="/" />
+                            </div>
+                            <div>
+                                <a-upload
+                                    :style="{ width: '300px' }"
+                                    :multiple="false"
+                                    :limit="1"
+                                    :custom-request="customRequest2"
+                                    :show-upload-button="{ showOnExceedLimit: true }"
+                                    accept=".pdf,.doc,.docx,.txt,.md,.ppt.pptx"
+                                />
                             </div>
                             <a-button :style="{ width: '500px' }" type="primary" @click="beginCombine">开始</a-button>
                         </footer>
@@ -99,6 +124,7 @@ import DocumentAnswer from "./DocumentAnswer.vue";
 import DocumentQuestion from "./DocumentQuestion.vue";
 import Analysis from "./Analysis.vue";
 import { defineComponent, ref, onMounted, inject, onBeforeUnmount } from "vue";
+import { write } from "clipboard-polyfill";
 export default defineComponent({
     components: {
         Right,
@@ -118,8 +144,9 @@ export default defineComponent({
     },
     setup() {
         // nav对应的问答类型,4文库问答,对应的是knowledge类型
-        const dialogType = ["knowledge", "normal", "normal", "normal", "normal", "normal", "normal", "normal"];
+        const dialogType = ["report", "normal", "normal", "normal", "normal", "normal", "normal", "normal"];
         const { config, helper, ajax } = inject("$global");
+        const uploadTitle = ref("");
         const closeOthers = ref(false);
         const swiperNumber = ref(5);
         const navIndex = ref(-1);
@@ -186,10 +213,75 @@ export default defineComponent({
             dialogList.value = [];
             showDialog.value = true;
             initDialog.value = true;
+            const sendData = {
+                chatHistory: [],
+                name: "报告生成",
+                description: "报告生成",
+                inputs: {
+                    report_name: `标题:${uploadTitle.value}\n请上传周报:${reportData.name1}\n请上传中心动态:${reportData.name2}\n`,
+                    id: "Report-PRcYL",
+                    data: [
+                        {
+                            id: "VariableNode-UB934",
+                            name: "标题",
+                            file_path: "",
+                            value: uploadTitle.value
+                        },
+                        {
+                            id: "InputFileNode-d2865",
+                            name: "请上传周报",
+                            file_path: reportData.url1,
+                            value: ""
+                        },
+                        {
+                            id: "InputFileNode-a4516",
+                            name: "请上传中心动态",
+                            file_path: reportData.url2,
+                            value: ""
+                        }
+                    ]
+                }
+            };
             setTimeout(() => {
-                helper.$bus.emit("send-message", "开始");
+                helper.$bus.emit("send-message", sendData);
             }, 200);
         };
+        const reportData = {
+            title: "",
+            url1: "",
+            name1: "",
+            url2: "",
+            name2: ""
+        };
+        const customRequest1 = async (option) => {
+            const { name, url } = await customRequest(option);
+            reportData.url1 = url;
+            reportData.name1 = name;
+        };
+        const customRequest2 = async (option) => {
+            const { name, url } = await customRequest(option);
+            reportData.url2 = url;
+            reportData.name2 = name;
+        };
+        const customRequest = async (option) => {
+            const { onSuccess, fileItem } = option;
+            const { file, uid, name } = fileItem;
+            const fileList = [];
+            fileList.push({
+                id: uid,
+                file
+            });
+            onSuccess();
+            const formData = new FormData();
+            fileList.forEach((item) => {
+                formData.append("file", item.file);
+            });
+            const data = await ajax.file.uploadFiles(agentIds.value[navIndex.value], formData);
+            return {
+                name,
+                url: data.file_path
+            };
+        };
         onMounted(async () => {
             const agents = await ajax.agent.getAgents();
             agentIds.value = agents.map((data) => data.id);
@@ -209,6 +301,9 @@ export default defineComponent({
             helper.$bus.off("open-dialog");
         });
         return {
+            uploadTitle,
+            customRequest1,
+            customRequest2,
             historyList,
             beginCombine,
             selectId,

+ 1 - 1
src/views/Register.vue

@@ -42,7 +42,7 @@ export default defineComponent({
             const result = await ajax.user.register(username.value, password.value);
             if (result) {
                 helper.write("userName", String(result.username));
-                helper.goLink("/");
+                helper.goLink("/login");
             }
         };
         return {