Ver código fonte

文档合并

奇橙 1 ano atrás
pai
commit
61b032be91

+ 14 - 6
src/ajax/api/file.js

@@ -7,13 +7,21 @@ import request from "../request";
  * @returns {Promise<Object>}
  */
 const uploadFiles = (id, file) => {
-    return request.post(`/api/files/upload/${id}`, file, {
-        headers: {
-            "Content-Type": "multipart/form-data"
-        }
-    });
+  return request.post(`/api/files/upload/${id}`, file, {
+    headers: {
+      "Content-Type": "multipart/form-data"
+    }
+  });
+};
+const uploadExcels = (file) => {
+  return request.post("/api/document/excel/upload", file, {
+    headers: {
+      "Content-Type": "multipart/form-data"
+    }
+  });
 };
 
 export default {
-    uploadFiles
+  uploadFiles,
+  uploadExcels
 };

+ 24 - 20
src/ajax/api/message.js

@@ -1,22 +1,26 @@
 import request from "../request";
 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 连接已打开");
-    };
+  const wsParam = type === "report" ? "report" : "chat";
+  const wsUrl =
+    type === "excel"
+      ? "ws://smartai.com:8000/api/document/ws/excel"
+      : `ws://smartai.com:8000/api/${wsParam}/ws/${agentId}/${dialogId}?token=${token}`;
+  const ws = new WebSocket(wsUrl);
+  // 当 WebSocket 打开时...
+  ws.onopen = function (event) {
+    console.log("WebSocket 连接已打开");
+  };
 
-    // 当 WebSocket 关闭时...
-    ws.onclose = function (event) {
-        console.log(event.code);
-    };
+  // 当 WebSocket 关闭时...
+  ws.onclose = function (event) {
+    console.log(event.code);
+  };
 
-    // 当有错误发生时...
-    ws.onerror = function (error) {
-        console.error("WebSocket 出错: ", error);
-    };
-    return ws;
+  // 当有错误发生时...
+  ws.onerror = function (error) {
+    console.error("WebSocket 出错: ", error);
+  };
+  return ws;
 };
 
 /**
@@ -24,7 +28,7 @@ const create = (token, agentId, dialogId, type) => {
  * @returns {Promise<Object>}
  */
 const createDialog = (id) => {
-    return request.get(`/api/agent/get-chat-id/${id}`);
+  return request.get(`/api/agent/get-chat-id/${id}`);
 };
 
 /**
@@ -32,11 +36,11 @@ const createDialog = (id) => {
  * @returns {Promise<Object>}
  */
 const getDialogs = (id) => {
-    return request.get(`/api/agent/${id}/sessions`);
+  return request.get(`/api/agent/${id}/sessions`);
 };
 
 export default {
-    create,
-    createDialog,
-    getDialogs
+  create,
+  createDialog,
+  getDialogs
 };

+ 141 - 116
src/components/DialogWrap.vue

@@ -12,21 +12,14 @@
                 </footer>
             </div>
             <div class="section-suggestions">
-                <div
-                    :class="['section-suggestion', readonly ? 'disabled' : '']"
-                    v-for="(suggestion, key) in suggestions"
-                    :key="key"
-                    @click="selectSuggestion(suggestion)"
-                >
+                <div :class="['section-suggestion', readonly ? 'disabled' : '']"
+                    v-for="(suggestion, key) in suggestions" :key="key" @click="selectSuggestion(suggestion)">
                     {{ suggestion }}<icon-arrow-right />
                 </div>
             </div>
             <div class="dialog-list" v-if="dialogList.length > 0" :key="randomKey">
-                <div
-                    :class="['dialog-item', isSetting ? '' : 'dialog-absolute']"
-                    v-for="(item, key) in dialogList"
-                    :key="item.key"
-                >
+                <div :class="['dialog-item', isSetting ? '' : 'dialog-absolute']" v-for="(item, key) in dialogList"
+                    :key="item.key">
                     <div class="dialog-header" v-if="item?.question">
                         <div class="user-name" style="background-color: rgb(255, 110, 110)">
                             {{ userName.slice(0, 1) }}
@@ -38,55 +31,31 @@
                     <div class="dialog-header" v-if="item?.capacity">
                         <img alt="avatar" src="/src/assets/slider/logo.jpg" width="28" />
                     </div>
-                    <div
-                        class="dialog-footer"
-                        v-if="item.capacity"
-                        :style="{ display: dialogConfig.type === 'paper' ? 'inline-block' : 'block' }"
-                    >
-                        <div
-                            v-if="type === 'knowledge'"
-                            @click="openCapacity(key)"
-                            :class="[readonly || item.capacity.status === 'loading' ? 'disabled' : '']"
-                        >
+                    <div class="dialog-footer" v-if="item.capacity"
+                        :style="{ display: dialogConfig.type === 'paper' ? 'inline-block' : 'block' }">
+                        <div v-if="type === 'knowledge'" @click="openCapacity(key)"
+                            :class="[readonly || item.capacity.status === 'loading' ? 'disabled' : '']">
                             <a-spin :size="18" v-if="item.capacity.status === 'loading'" />
                             <icon-check-circle-fill :size="18" v-else />
                             <span>{{ item.capacity.status === "loading" ? "小数正在检索" : "查看检索信息" }}</span>
                             <!-- <b>{{ item.capacity.text }}</b> -->
-                            <icon-caret-right
-                                size="18"
-                                v-if="item.capacity.status === 'loaded' && !menuList[key]?.open"
-                            />
-                            <icon-caret-down
-                                size="18"
-                                v-if="item.capacity.status === 'loaded' && menuList[key]?.open"
-                            />
+                            <icon-caret-right size="18"
+                                v-if="item.capacity.status === 'loaded' && !menuList[key]?.open" />
+                            <icon-caret-down size="18"
+                                v-if="item.capacity.status === 'loaded' && menuList[key]?.open" />
                         </div>
-                        <div
-                            v-else
-                            v-show="item.capacity.status === 'loading'"
-                            :class="[readonly || item.capacity.status === 'loading' ? 'disabled' : '']"
-                        >
+                        <div v-else v-show="item.capacity.status === 'loading'"
+                            :class="[readonly || item.capacity.status === 'loading' ? 'disabled' : '']">
                             <a-spin :size="18" />
-                            <span
-                                >小数正在为您生成{{
-                                    dialogConfig.type === "paper"
-                                        ? "试卷"
-                                        : dialogConfig.type === "topic"
-                                        ? "试题"
-                                        : "答案"
-                                }}...</span
-                            >
+                            <span>正在为您合并
+                                }}...</span>
                         </div>
-                        <section
-                            v-if="type === 'knowledge' && item.capacity.status === 'loaded'"
-                            v-show="menuList[key].open"
-                        >
+                        <section v-if="type === 'knowledge' && item.capacity.status === 'loaded'"
+                            v-show="menuList[key].open">
                             <div v-if="item.capacity.data.list">
                                 <p v-for="(item, key) in item.capacity.data.list" :key="key">
-                                    <a-typography-paragraph
-                                        :ellipsis="{ rows: 1, css: true }"
-                                        :style="{ flex: 1, margin: '0' }"
-                                    >
+                                    <a-typography-paragraph :ellipsis="{ rows: 1, css: true }"
+                                        :style="{ flex: 1, margin: '0' }">
                                         {{ item }}
                                     </a-typography-paragraph>
                                 </p>
@@ -95,43 +64,35 @@
                                 <div v-for="(document, documentKey) in item.capacity.data.documents" :key="documentKey">
                                     <div @click="openDocument(key, documentKey)" :class="[readonly ? 'disabled' : '']">
                                         <span>{{ document.type }}</span>
-                                        <a-typography-paragraph
-                                            :ellipsis="{ rows: 1, css: true }"
-                                            :style="{ flex: 1, margin: '0' }"
-                                        >
+                                        <a-typography-paragraph :ellipsis="{ rows: 1, css: true }"
+                                            :style="{ flex: 1, margin: '0' }">
                                             <span>{{ document.title }}</span>
                                         </a-typography-paragraph>
                                         <span>
                                             <em v-for="(item, documentIndex) in document.list" :key="documentIndex">{{
                                                 item.title
-                                            }}</em>
+                                                }}</em>
                                         </span>
-                                        <icon-caret-down
-                                            size="12"
-                                            v-if="documentKey === menuList[key].documentOpenIndex"
-                                        />
+                                        <icon-caret-down size="12"
+                                            v-if="documentKey === menuList[key].documentOpenIndex" />
                                         <icon-caret-right size="12" v-else />
                                     </div>
                                     <div v-show="documentKey === menuList[key].documentOpenIndex">
                                         <p v-for="(item, index) in document.list" :key="index">
                                             <span>{{ item.title }}</span>
-                                            <a-typography-paragraph
-                                                :ellipsis="{ rows: 3, css: true }"
-                                                :style="{ flex: 1, margin: '0' }"
-                                            >
+                                            <a-typography-paragraph :ellipsis="{ rows: 3, css: true }"
+                                                :style="{ flex: 1, margin: '0' }">
                                                 <span style="color: rgba(153, 153, 153, 1); font-size: 12px">{{
                                                     item.content
-                                                }}</span>
+                                                    }}</span>
                                             </a-typography-paragraph>
                                         </p>
                                     </div>
                                 </div>
                             </div>
                         </section>
-                        <p
-                            v-if="type === 'knowledge' && item.answer"
-                            style="margin-top: 10px; font-size: 18px; font-weight: bold"
-                        >
+                        <p v-if="type === 'knowledge' && item.answer"
+                            style="margin-top: 10px; font-size: 18px; font-weight: bold">
                             答案生成结果
                         </p>
                         <p v-if="item.answer" :style="{ 'margin-top': type === 'knowledge' ? '12px' : '0' }">
@@ -177,17 +138,12 @@
                                             <div class="knowledge-footer">
                                                 <p>检索片段</p>
                                                 <p>
-                                                    <span
-                                                        v-for="(content, contentIndex) in knowledge.contents"
+                                                    <span v-for="(content, contentIndex) in knowledge.contents"
                                                         :key="contentIndex"
-                                                        :class="{ active: knowledge.page === contentIndex }"
-                                                        @click="
-                                                            () => {
-                                                                knowledge.page = contentIndex;
-                                                            }
-                                                        "
-                                                        >{{ contentIndex + 1 }}</span
-                                                    >
+                                                        :class="{ active: knowledge.page === contentIndex }" @click="() => {
+                                                            knowledge.page = contentIndex;
+                                                        }
+                                                            ">{{ contentIndex + 1 }}</span>
                                                 </p>
                                                 <p @click="goKnowledge(knowledge.id)">查看详情></p>
                                             </div>
@@ -249,12 +205,8 @@
         <!-- <div v-show="readonly" @click="stopWriting" class="dialog-writing-button">
             <icon-record-stop :size="20" style="margin-right: 4px" />停止生成
         </div> -->
-        <dialog-feedback
-            :showFeedback="showFeedback"
-            @handleCancel="handleCancel"
-            @handleOk="handleOk"
-            v-if="!isSetting"
-        />
+        <dialog-feedback :showFeedback="showFeedback" @handleCancel="handleCancel" @handleOk="handleOk"
+            v-if="!isSetting" />
     </div>
 </template>
 <script>
@@ -531,7 +483,6 @@ export default defineComponent({
             scrollToEnd();
             helper.webSocket = ajax.message.create(helper.read("token"), props.agentId, props.dialogId, props.type);
             helper.webSocket.onmessage = (event) => {
-                console.log(JSON.parse(event.data));
                 const { type, message, step_message, files } = JSON.parse(event.data);
                 if (!loadingData.value) return;
                 if (type === "stream") {
@@ -571,11 +522,11 @@ export default defineComponent({
                 const data = addQuestion(question);
                 loadingData.value = addLoading(data);
                 const sendData =
-                    props.type === "report"
+                    props.type === "report" || props.type === "excel"
                         ? JSON.stringify(value)
                         : JSON.stringify({
-                              message: value
-                          });
+                            message: value
+                        });
                 helper.webSocket.send(sendData);
             });
             helper.$bus.on("clear-message", () => {
@@ -614,6 +565,7 @@ export default defineComponent({
 .dialog-header {
     display: flex;
     align-items: center;
+
     .dialog-span {
         color: rgba(51, 51, 51, 1);
         font-size: 14px;
@@ -631,9 +583,11 @@ export default defineComponent({
     justify-content: center;
     color: #fff;
 }
+
 .paper-download {
     padding-left: 50px;
-    > span {
+
+    >span {
         width: 26px;
         height: 26px;
         border-radius: 3px;
@@ -641,11 +595,13 @@ export default defineComponent({
         display: flex;
         align-items: center;
         justify-content: center;
+
         &:hover {
             background: rgba(150, 171, 185, 0.2);
         }
     }
 }
+
 .paper-wrap {
     display: flex;
     max-width: 200px;
@@ -653,35 +609,42 @@ export default defineComponent({
     margin-left: 40px;
     margin-bottom: 10px;
     cursor: pointer;
-    > img {
+
+    >img {
         width: 50px;
         margin-right: 10px;
     }
-    > span {
+
+    >span {
         flex: 1;
         white-space: nowrap;
         overflow: hidden;
         text-overflow: ellipsis;
-        > b {
+
+        >b {
             white-space: nowrap;
             overflow: hidden;
             text-overflow: ellipsis;
             display: block;
             width: 100%;
         }
-        > em {
+
+        >em {
             font-style: normal;
         }
     }
 }
+
 .knowledge-detail {
     width: 320px;
     padding-top: 20px;
+
     .knowledge-content {
         height: 300px;
         overflow-y: auto;
         line-height: 30px;
     }
+
     .knowledge-footer {
         border-top: 1px solid rgba(229, 229, 229, 1);
         margin-top: 20px;
@@ -689,27 +652,33 @@ export default defineComponent({
         display: flex;
         justify-content: space-between;
         align-items: center;
+
         p {
             &:nth-child(1) {
                 opacity: 0.8;
             }
+
             &:nth-child(2) {
                 flex: 1;
                 display: flex;
                 justify-content: left;
                 margin: 0 30px;
-                > span {
+
+                >span {
                     margin: 0 5px;
                     cursor: pointer;
+
                     &:hover,
                     &.active {
                         color: #00aea3;
                     }
                 }
             }
+
             &:nth-child(3) {
                 font-weight: bold;
                 cursor: pointer;
+
                 &:hover {
                     color: #00aea3;
                 }
@@ -717,31 +686,38 @@ export default defineComponent({
         }
     }
 }
+
 .knowledge-wrap {
     padding: 10px 0 20px 50px;
-    > header {
+
+    >header {
         display: flex;
         justify-content: space-between;
-        > p {
+
+        >p {
             &:nth-child(1) {
                 color: #7f7f7f;
                 font-weight: bold;
             }
+
             &:nth-child(2) {
                 cursor: pointer;
+
                 &:hover {
                     color: #00aea3;
                 }
             }
         }
     }
-    > section {
-        > div {
-            > div {
+
+    >section {
+        >div {
+            >div {
                 height: 40px;
                 display: inline-flex;
                 align-items: center;
-                > span {
+
+                >span {
                     &:nth-child(1) {
                         display: inline-block;
                         background-color: rgba(0, 174, 163, 0.2);
@@ -751,8 +727,10 @@ export default defineComponent({
                         margin-right: 5px;
                         font-size: 12px;
                     }
+
                     &:nth-child(2) {
                         cursor: pointer;
+
                         &:hover {
                             color: #00aea3;
                         }
@@ -762,30 +740,37 @@ export default defineComponent({
         }
     }
 }
+
 .dialog-absolute {
     .dialog-header {
         position: absolute;
+
         &:nth-child(1) {
             transform: translateY(10px);
         }
+
         &:nth-child(3) {
             transform: translateY(16px);
         }
     }
+
     .dialog-footer {
         margin-left: 50px;
+
         &:nth-child(2) {
             margin-left: 50px;
             padding-left: 0;
         }
     }
 }
+
 .dialog-flex-wrap {
     position: relative;
     flex: 1;
     margin-top: 16px;
     height: 100%;
 }
+
 .dialog-flex {
     position: absolute;
     left: 0;
@@ -795,9 +780,11 @@ export default defineComponent({
     overflow-y: auto;
     overflow-x: hidden;
 }
+
 .section-open {
     margin-top: 12px;
 }
+
 .dialog-file {
     width: 421px;
     height: 48px;
@@ -811,20 +798,24 @@ export default defineComponent({
     margin-bottom: 16px;
     padding: 0 8px;
 }
+
 .dialog-footer {
     border-radius: 12px;
     background-color: rgba(245, 247, 254, 1);
     padding: 12px 16px;
     margin: 16px 0;
+
     &:nth-child(2) {
         background-color: rgba(0, 0, 0, 0);
         margin: 0;
     }
-    > p {
+
+    >p {
         color: rgba(16, 16, 16, 1);
         font-size: 14px;
     }
-    > div {
+
+    >div {
         border: 1px solid rgba(64, 95, 234, 0.42);
         background-color: rgba(255, 255, 255, 1);
         color: rgba(16, 16, 16, 1);
@@ -835,40 +826,49 @@ export default defineComponent({
         align-items: center;
         cursor: pointer;
         height: 30px;
+
         &.disabled {
             cursor: not-allowed;
         }
+
         &:hover {
             background: rgb(245, 247, 254, 0.4);
         }
-        > span {
+
+        >span {
             margin: 0 8px;
         }
-        > b {
+
+        >b {
             margin-right: 8px;
         }
     }
-    > section {
+
+    >section {
         padding: 0 16px;
         background-color: #ffffff;
         border-radius: 12px;
         margin-top: 16px;
-        > p {
+
+        >p {
             display: inline-block;
             color: rgba(16, 16, 16, 1);
             font-size: 12px;
             margin-top: 16px;
             width: 100%;
         }
-        > div {
+
+        >div {
             margin-top: 4px;
             overflow: hidden;
             margin-bottom: 16px;
             display: inline-block;
             width: 100%;
-            > div {
+
+            >div {
                 margin-top: 8px;
-                > div {
+
+                >div {
                     &:nth-child(1) {
                         border-radius: 4px;
                         color: rgba(16, 16, 16, 1);
@@ -880,13 +880,16 @@ export default defineComponent({
                         align-items: center;
                         padding-right: 8px;
                         cursor: pointer;
+
                         &.disabled {
                             cursor: not-allowed;
                         }
+
                         &:hover {
                             background: rgba(229, 229, 229, 0.2);
                         }
-                        > span {
+
+                        >span {
                             &:nth-child(1) {
                                 background-color: rgba(0, 174, 163, 0.2);
                                 color: #00aea3;
@@ -895,14 +898,17 @@ export default defineComponent({
                                 padding: 0 4px;
                                 margin: 0 4px 0 0;
                             }
+
                             &:nth-child(3) {
                                 color: #00aea3;
                                 font-size: 12px;
+
                                 em {
                                     padding: 0 4px;
                                     font-style: normal;
                                     border-left: 1px solid rgba(64, 95, 234, 1);
                                     font-weight: bold;
+
                                     &:nth-child(1) {
                                         border: none;
                                     }
@@ -910,11 +916,13 @@ export default defineComponent({
                             }
                         }
                     }
+
                     &:nth-child(2) {
-                        > p {
+                        >p {
                             margin: 8px 0;
                             display: flex;
-                            > span {
+
+                            >span {
                                 transform: translateY(2px);
                                 color: #00aea3;
                                 font-weight: bold;
@@ -925,7 +933,8 @@ export default defineComponent({
                     }
                 }
             }
-            > p {
+
+            >p {
                 float: left;
                 width: 48%;
                 border-radius: 4px;
@@ -938,6 +947,7 @@ export default defineComponent({
                 padding: 0 8px;
                 display: flex;
                 align-items: center;
+
                 &:nth-child(odd) {
                     margin-right: 4%;
                 }
@@ -945,8 +955,10 @@ export default defineComponent({
         }
     }
 }
+
 .section-suggestions {
     margin: 12px 0 20px;
+
     .section-suggestion {
         width: 380px;
         height: 40px;
@@ -959,30 +971,37 @@ export default defineComponent({
         justify-content: space-between;
         cursor: pointer;
         margin-top: 8px;
+
         &.disabled {
             cursor: not-allowed;
         }
+
         &:hover {
             background: rgb(245, 247, 254);
         }
     }
 }
+
 .dialog-other {
     margin-bottom: 16px;
     display: flex;
     align-items: center;
     justify-content: space-between;
-    > p {
+
+    >p {
         display: flex;
         align-items: center;
+
         span {
             margin-left: 8px;
             color: rgba(16, 16, 16, 1);
             font-size: 12px;
         }
     }
-    > div {
+
+    >div {
         display: flex;
+
         p {
             display: flex;
             align-items: center;
@@ -993,23 +1012,28 @@ export default defineComponent({
             border: 1px solid rgba(229, 229, 229, 1);
             margin-left: 8px;
             cursor: pointer;
+
             &.disabled {
                 cursor: not-allowed;
             }
+
             &:hover {
                 background-color: rgba(245, 247, 254, 1);
             }
         }
     }
 }
+
 .feedback-title {
     color: rgba(102, 102, 102, 1);
     font-size: 12px;
     margin: 0 0 8px 4px;
 }
+
 .feedback-content {
     margin-bottom: 16px;
 }
+
 .dialog-writing-button {
     position: absolute;
     bottom: -30px;
@@ -1029,6 +1053,7 @@ export default defineComponent({
     justify-content: center;
     cursor: pointer;
     z-index: 10;
+
     &:hover {
         background: rgb(245, 247, 254);
     }

+ 111 - 111
src/components/DocumentCards.vue

@@ -10,37 +10,26 @@
             </div>
         </section>
         <footer v-if="hasUpload">
-            <a-popover
-                :popup-visible="showUpload"
-                position="tl"
-                @popup-visible-change="
-                    () => {
-                        showDeleteTooltip = false;
-                    }
-                "
-            >
+            <a-popover :popup-visible="showUpload" position="tl" @popup-visible-change="() => {
+                showDeleteTooltip = false;
+            }
+                ">
                 <div :class="{ 'text-hide': showUpload }" v-if="!uploadImg">
-                    <div
-                        @click="
-                            () => {
-                                showUpload = true;
-                            }
-                        "
-                    >
+                    <div @click="() => {
+                        showUpload = true;
+                    }
+                        ">
                         <img src="@/assets/document/3.svg" class="img-normal" v-if="!showUpload" />
                         <img src="@/assets/document/4.svg" class="img-hover" v-if="!showUpload" />
                         <img src="@/assets/document/5.svg" class="img-active" v-if="showUpload" />
                     </div>
-                    <p>已选择 {{ selectedKeys.length }}/{{ tableData.length }} 个文档</p>
+                    <p>已选择 {{ fileList.length }} 个文档</p>
                 </div>
                 <div class="text-narrow" v-else>
-                    <div
-                        @click="
-                            () => {
-                                showUpload = true;
-                            }
-                        "
-                    >
+                    <div @click="() => {
+                        showUpload = true;
+                    }
+                        ">
                         <img src="@/assets/document/6.svg" class="img-normal" v-if="!showUpload" />
                         <img src="@/assets/document/7.svg" class="img-hover" v-if="!showUpload" />
                         <img src="@/assets/document/8.svg" class="img-active" v-if="showUpload" />
@@ -50,29 +39,19 @@
                     <div :class="{ 'upload-wrap': true, 'upload-wrap-narrow': uploadImg }">
                         <header>
                             <p>{{ uploadImg ? "上传图片" : "文档解析站" }}</p>
-                            <div
-                                @click="
-                                    () => {
-                                        showUpload = false;
-                                    }
-                                "
-                            >
+                            <div @click="() => {
+                                showUpload = false;
+                            }
+                                ">
                                 <icon-close size="large" />
                             </div>
                         </header>
                         <div>
                             <section>
-                                <a-upload
-                                    draggable
-                                    :multiple="!uploadImg"
-                                    :limit="5"
-                                    @before-upload="onBeforeUpload"
-                                    @exceed-limit="onExceedLimit"
-                                    @before-remove="onBeforeRemove"
-                                    :custom-request="customRequest"
-                                    :show-upload-button="{ showOnExceedLimit: true }"
-                                    :accept="uploadImg ? '.png,.jpg' : '.xlsx‌'"
-                                >
+                                <a-upload draggable :multiple="!uploadImg" :limit="50" @before-upload="onBeforeUpload"
+                                    @exceed-limit="onExceedLimit" @before-remove="onBeforeRemove"
+                                    :custom-request="customRequest" :show-upload-button="{ showOnExceedLimit: true }"
+                                    :accept="uploadImg ? '.png,.jpg' : '.xlsx‌'">
                                     <template #upload-button>
                                         <div class="upload-main">
                                             <p>拖拽{{ uploadImg ? "图片" : "文档" }}到这里,或<span>点此上传</span></p>
@@ -83,20 +62,14 @@
                                     </template>
                                 </a-upload>
                             </section>
-                            <div v-if="!uploadImg">
+                            <div v-if="!uploadImg && false">
                                 <p>
                                     <span>已解析文件列表</span>
                                     <span>共{{ tableData.length }}个</span>
                                 </p>
                                 <div>
-                                    <a-table
-                                        :pagination="false"
-                                        row-key="name"
-                                        :columns="columns"
-                                        :data="tableData"
-                                        :row-selection="rowSelection"
-                                        v-model:selectedKeys="selectedKeys"
-                                    >
+                                    <a-table :pagination="false" row-key="name" :columns="columns" :data="tableData"
+                                        :row-selection="rowSelection" v-model:selectedKeys="selectedKeys">
                                         <template #methods="{ record }">
                                             <a-tooltip content="下载">
                                                 <div class="method-button" @click="downloadDocument(record)">
@@ -114,23 +87,13 @@
                                                         <p>删除后无法恢复,您是否删除?</p>
                                                         <div class="delete-buttons">
                                                             <div>
-                                                                <a-button
-                                                                    size="mini"
-                                                                    type="primary"
+                                                                <a-button size="mini" type="primary"
                                                                     style="margin-right: 10px"
-                                                                    @click="deleteDocument"
-                                                                    >确认</a-button
-                                                                >
-                                                                <a-button
-                                                                    size="mini"
-                                                                    type="outline"
-                                                                    @click="
-                                                                        () => {
-                                                                            showDeleteTooltip = false;
-                                                                        }
-                                                                    "
-                                                                    >取消</a-button
-                                                                >
+                                                                    @click="deleteDocument">确认</a-button>
+                                                                <a-button size="mini" type="outline" @click="() => {
+                                                                    showDeleteTooltip = false;
+                                                                }
+                                                                    ">取消</a-button>
                                                             </div>
                                                         </div>
                                                     </div>
@@ -144,12 +107,10 @@
                     </div>
                     <div class="bottom-buttons">
                         <div>
-                            <a-button type="outline" style="margin-right: 10px" @click="selectFiles(false)"
-                                >取消</a-button
-                            >
-                            <a-button type="primary" @click="selectFiles(true, 'paper')"
-                                >去合并({{ selectedKeys.length }})</a-button
-                            >
+                            <a-button type="outline" style="margin-right: 10px"
+                                @click="selectFiles(false)">取消</a-button>
+                            <a-button type="primary" @click="selectFiles(true, 'paper')">去合并({{ fileList.length
+                                }})</a-button>
                         </div>
                     </div>
                 </template>
@@ -167,21 +128,26 @@ export default defineComponent({
     props: ["data", "hasUpload", "hasSlider", "uploadImg", "isQuestion"],
     setup(props) {
         const showUpload = ref(false);
-        const { helper } = inject("$global");
+        const { helper, ajax } = inject("$global");
         const maxSize = 30 * 1024 * 1024;
-        let fileList = [];
+        let fileList = ref([]);
+        let formData = new FormData();
         const showDeleteTooltip = ref(false);
         const deleteId = ref("");
-        const selectFiles = (isSelect, type) => {
-            if (!isSelect) {
-                selectedKeys.value = [];
-            }
+        const selectFiles = async (isSelect, type) => {
+            fileList.value.forEach(file => {
+                formData.append('files', file)
+            });
+            await ajax.file.uploadExcels(formData);
             showUpload.value = false;
             helper.dialogConfig = {
                 isQuestion: props.isQuestion,
                 selectedKeys: selectedKeys.value,
                 type
             };
+            helper.$bus.emit("open-dialog", {
+                "action": "process"
+            });
         };
         const handleDeleteButton = (id) => {
             showDeleteTooltip.value = true;
@@ -195,19 +161,16 @@ export default defineComponent({
             return true;
         };
         const onExceedLimit = () => {
-            helper.message("error", `最多上传5个文件`);
+            helper.message("error", `最多上传50个文件`);
         };
         const customRequest = async (option) => {
             const { onSuccess, fileItem } = option;
-            const { file, uid } = fileItem;
-            fileList.push({
-                id: uid,
-                file
-            });
+            const { file } = fileItem;
+            fileList.value.push(file);
             onSuccess();
         };
         const onBeforeRemove = (data) => {
-            fileList = fileList.filter((item) => item.id !== data.uid);
+            fileList.value = fileList.value.filter((item) => item.id !== data.uid);
             return true;
         };
         const selectedKeys = ref([]);
@@ -263,9 +226,10 @@ export default defineComponent({
                 time: "2024.9.8"
             }
         ]);
-        const downloadDocument = (record) => {};
-        const deleteDocument = () => {};
+        const downloadDocument = (record) => { };
+        const deleteDocument = () => { };
         return {
+            fileList,
             selectedKeys,
             getAssetURL: helper.getAssetURL,
             showUpload,
@@ -290,24 +254,29 @@ export default defineComponent({
 .bottom-buttons {
     display: flex;
     justify-content: right;
-    > div {
+
+    >div {
         display: flex;
     }
 }
+
 .delete-buttons {
     margin-top: 10px;
     display: flex;
     justify-content: center;
 }
+
 .method-button {
     display: inline-block;
     padding: 4px 8px;
     border-radius: 5px;
     cursor: pointer;
+
     &:hover {
         background: rgba(150, 171, 185, 0.2);
     }
 }
+
 .upload-main {
     width: 800px;
     height: 109px;
@@ -315,50 +284,59 @@ export default defineComponent({
     margin: 0 auto;
     padding: 24px 0px 24px 277px;
     background-size: 100%;
-    > p {
+
+    >p {
         color: #000;
         font-weight: bold;
         margin-bottom: 5px;
         margin-top: 10px;
-        > span {
+
+        >span {
             color: #00aea3;
             text-decoration: underline;
         }
     }
-    > span {
+
+    >span {
         font-size: 13px;
         color: #7f7f7f;
     }
 }
+
 main {
     height: 100%;
     display: flex;
     flex-direction: column;
     overflow: hidden;
-    > section {
+
+    >section {
         overflow-y: auto;
         display: flex;
         flex-wrap: wrap;
         gap: 20px;
+
         &.section-full {
             flex: 1;
         }
-        > div {
+
+        >div {
             width: 382px;
             height: 120px;
             padding: 20px 24px;
             border-radius: 8px;
             display: flex;
-            > img {
+
+            >img {
                 width: 38px;
                 height: 38px;
                 margin-right: 12px;
             }
-            > div {
+
+            >div {
                 font-size: 18px;
                 font-weight: bold;
 
-                > span {
+                >span {
                     font-size: 15px;
                     font-weight: 400;
                     color: #797d7f;
@@ -373,11 +351,13 @@ main {
             }
         }
     }
-    > footer {
+
+    >footer {
         display: flex;
         justify-content: space-between;
         align-items: center;
-        > div {
+
+        >div {
             display: inline-flex;
             align-items: center;
             gap: 8px;
@@ -388,76 +368,93 @@ main {
             overflow: hidden;
             transition-duration: 0.3s;
             width: 250px;
+
             &.text-hide {
                 width: 110px;
                 overflow: hidden;
             }
+
             &.text-narrow {
                 width: 100px;
                 overflow: hidden;
-                > div > img {
+
+                >div>img {
                     width: 100px;
                 }
             }
-            > p {
+
+            >p {
                 overflow: hidden;
                 white-space: nowrap;
             }
-            > div {
+
+            >div {
                 cursor: pointer;
                 width: 110px;
                 height: 32px;
+
                 .img-normal {
                     display: block;
                 }
+
                 .img-hover {
                     display: none;
                 }
+
                 &:hover {
                     .img-normal {
                         display: none;
                     }
+
                     .img-hover {
                         display: block;
                     }
                 }
-                > img {
+
+                >img {
                     width: 110px;
                     height: 32px;
                 }
             }
         }
-        > section {
+
+        >section {
             display: flex;
             align-items: center;
             background: rgba(150, 171, 185, 0.2);
             border-radius: 20px;
             padding: 5px 10px;
-            > p {
+
+            >p {
                 margin-right: 5px;
             }
         }
     }
 }
+
 .upload-wrap {
     width: 800px;
     height: 300px;
     display: flex;
     flex-direction: column;
     padding-bottom: 30px;
+
     &.upload-wrap-narrow {
         height: 200px;
     }
-    > header {
+
+    >header {
         display: flex;
         align-items: center;
         justify-content: space-between;
         margin-bottom: 13px;
-        > p {
+
+        >p {
             font-size: 18px;
             font-weight: bold;
         }
-        > div {
+
+        >div {
             width: 38px;
             height: 38px;
             border-radius: 6px;
@@ -465,16 +462,19 @@ main {
             justify-content: center;
             align-items: center;
             display: flex;
+
             &:hover {
                 background: rgba(0, 0, 0, 0.05);
             }
         }
     }
-    > div {
+
+    >div {
         flex: 1;
         overflow-y: auto;
-        > div {
-            > p {
+
+        >div {
+            >p {
                 margin: 20px 0;
                 color: #7f7f7f;
                 font-size: 13px;

+ 8 - 9
src/views/Home.vue

@@ -4,9 +4,9 @@
         <div class="main">
             <div :class="{ 'history-wrap': true, 'history-wrap-open': !closeOthers && navIndex > -1 }">
                 <History :list="historyList" @set-new="() => {
-                        showDialog = false;
-                        selectId = '';
-                    }
+                    showDialog = false;
+                    selectId = '';
+                }
                     " :selectId="selectId" @handle-click="selectHistory" />
             </div>
             <div class="wrap">
@@ -53,13 +53,13 @@
                                 <div>
                                     <a-input :style="{ flex: '1' }" :placeholder="`请输入${item.variable_name}`"
                                         allow-clear @change="(event) => {
-                                                customChange(event, item.node_id, item.variable_name);
-                                            }
+                                            customChange(event, item.node_id, item.variable_name);
+                                        }
                                             " v-if="item.value_type === 1" />
                                     <a-upload v-else :style="{ width: '300px' }" :multiple="false" :limit="1"
                                         :custom-request="(option) => {
-                                                customRequest(option, item.node_id, item.variable_name);
-                                            }
+                                            customRequest(option, item.node_id, item.variable_name);
+                                        }
                                             " :show-upload-button="{ showOnExceedLimit: true }"
                                         accept=".pdf,.doc,.docx,.txt,.md,.ppt.pptx" />
                                 </div>
@@ -95,7 +95,6 @@ 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,
@@ -115,7 +114,7 @@ export default defineComponent({
     },
     setup() {
         // nav对应的问答类型,4文库问答,对应的是knowledge类型
-        const dialogType = ["report", "normal", "normal", "normal", "normal", "normal", "normal", "normal"];
+        const dialogType = ["report", "excel", "normal", "normal", "normal", "normal", "normal", "normal"];
         const { config, helper, ajax } = inject("$global");
         const closeOthers = ref(false);
         const swiperNumber = ref(5);