Jelajahi Sumber

修改替换bug及添加outcoms导出

yangg 6 bulan lalu
induk
melakukan
131b10db0d

+ 1 - 1
.env.development

@@ -3,7 +3,7 @@ ENV = 'development'
 port = 8080
 # base api
 VUE_APP_BASE_AI_API='https://ylaiapi.raycos.com.cn'
-VUE_APP_BASE_API = 'http://183.195.216.54:8084'
+VUE_APP_BASE_API = 'http://192.168.66.163:8084'
 #192.168.66.187
 #朱:192.168.66.163
 #测试服务器:121.36.251.245

File diff ditekan karena terlalu besar
+ 0 - 0
dist/index.html


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/css/chunk-03113d9f.937d7239.css


+ 1 - 0
dist/static/css/chunk-698f71b6.2563615b.css

@@ -0,0 +1 @@
+.gpu-list[data-v-4a5e348c]{padding:20px}.filter-section[data-v-4a5e348c]{margin-bottom:20px}.ml-15[data-v-4a5e348c]{margin-left:15px}.pagination[data-v-4a5e348c]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;margin-top:15px}.progress-wrapper[data-v-4a5e348c],.status-wrapper[data-v-4a5e348c]{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-4a5e348c]{padding:2px}.progress-wrapper[data-v-4a5e348c] .el-progress{line-height:1;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-4a5e348c] .el-progress .el-progress__text{font-size:12px!important;color:inherit;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-4a5e348c] .el-progress .el-progress-circle{margin:0;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-4a5e348c] .el-progress .el-progress-circle__path,.progress-wrapper[data-v-4a5e348c] .el-progress .el-progress-circle__track,.progress-wrapper[data-v-4a5e348c] .el-progress svg{-webkit-transition:none!important;transition:none!important}

+ 0 - 1
dist/static/css/chunk-70622314.b70e8a6b.css

@@ -1 +0,0 @@
-.gpu-list[data-v-dbb73c58]{padding:20px}.filter-section[data-v-dbb73c58]{margin-bottom:20px}.ml-15[data-v-dbb73c58]{margin-left:15px}.pagination[data-v-dbb73c58]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;margin-top:15px}.progress-wrapper[data-v-dbb73c58],.status-wrapper[data-v-dbb73c58]{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-dbb73c58]{padding:2px}.progress-wrapper[data-v-dbb73c58] .el-progress{line-height:1;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-dbb73c58] .el-progress .el-progress__text{font-size:12px!important;color:inherit;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-dbb73c58] .el-progress .el-progress-circle{margin:0;-webkit-transition:none!important;transition:none!important}.progress-wrapper[data-v-dbb73c58] .el-progress .el-progress-circle__path,.progress-wrapper[data-v-dbb73c58] .el-progress .el-progress-circle__track,.progress-wrapper[data-v-dbb73c58] .el-progress svg{-webkit-transition:none!important;transition:none!important}

File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/app.c3e74364.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/app.d25a2ba8.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-03113d9f.29ed12aa.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-03ae2181.dac25b79.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-0c9d75e0.0d27457e.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-16a60d86.4762b32a.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-194e2959.9fc4781d.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-2a8c4ce9.b0b9c4b9.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-35362080.6969975c.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-3ecbedba.397ad130.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-4444d405.72e151b2.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-48f27aa5.3126eb16.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-698f71b6.e11b40b8.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-70622314.13453a62.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-708604c0.3d587375.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-9888fb8a.3a28e939.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/chunk-cda0aa98.72b882b8.js


+ 10 - 0
src/api/knowledge.js

@@ -771,4 +771,14 @@ export function getSotaDetails(data) {
     method: 'post',
     data
   })
+}
+
+/* outcoms导出 sota-details/export_data_sota_details */
+
+export function exportOutcoms(data) {
+  return request({
+    url: 'sota-details/export_data_sota_details',
+    method: 'post',
+    data
+  })
 }

+ 59 - 2
src/views/middPage/list.vue

@@ -109,7 +109,7 @@
                 type="daterange"
                 range-separator="至"
                 start-placeholder="开始日期"
-                end-placeholder="结束日"
+                end-placeholder="结束日��"
                 value-format="yyyy-MM-dd"
               />
             </el-form-item> -->
@@ -350,6 +350,7 @@
                 >搜索</el-button
               >
               <el-button @click="resetSotaSearch" type="danger">重置</el-button>
+              <el-button @click="outExport" type="primary">导出</el-button>
             </el-form-item>
           </el-form>
         </div>
@@ -465,6 +466,7 @@ import {
   categories,
   literResult,
   getSotaDetails,
+  exportOutcoms
 } from "@/api/knowledge";
 import axios from "axios";
 // 状态映射表
@@ -559,6 +561,61 @@ export default {
     },
   },
   methods: {
+    /* outcoms导出 */
+    async outExport() {
+      try {
+        // 添加确认对话框
+        await this.$confirm("确认要导出Outcomes数据吗?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        });
+
+        // 准备导出参数
+        const params = {
+          keyword: this.Sota_searchForm.keyword || undefined
+        };
+
+        // 调用导出接口
+        const response = await exportOutcoms(params);
+
+        if (response.status === 200) {
+          const downloadUrl = response.data.data.download_url;
+
+          // 显示下载链接对话框
+          await this.$alert(
+            `<div>
+              <p>导出成功!请点击下方链接下载文件:</p>
+              <p style="word-break: break-all;">
+                <a href="${downloadUrl}" target="_blank">${downloadUrl}</a>
+              </p>
+              <p>您也可以复制链接后在新窗口打开</p>
+            </div>`,
+            "下载链接",
+            {
+              dangerouslyUseHTMLString: true,
+              confirmButtonText: "复制链接",
+              callback: (action) => {
+                if (action === "confirm") {
+                  // 复制链接到剪贴板
+                  const textarea = document.createElement("textarea");
+                  textarea.value = downloadUrl;
+                  document.body.appendChild(textarea);
+                  textarea.select();
+                  document.execCommand("copy");
+                  document.body.removeChild(textarea);
+                  this.$message.success("链接已复制到剪贴板");
+                }
+              },
+            }
+          );
+        }
+      } catch (error) {
+        if (error === "cancel") return;
+        this.$message.error(error.message || "导出失败");
+        console.error("导出错误:", error);
+      }
+    },
     // 添加获取分类列表方法
     async fetchCategories() {
       try {
@@ -1015,7 +1072,7 @@ export default {
         );
         if (response.status !== 200) return;
         console.log(this.tagForm.tags);
-        this.$message.success("标签新成功");
+        this.$message.success("标签��新成功");
         this.tagDialogVisible = false;
         this.fetchGpuList(); // 刷新列表
       } catch (error) {

+ 108 - 45
src/views/project/components/dataList.vue

@@ -237,7 +237,7 @@
       width="50%"
       append-to-body
     >
-      <!-- 显示匹配到的结果 -->
+      <!-- 显示匹配 -->
       <div v-if="matchResults.length" class="match-results">
         <div
           v-for="(item, index) in matchResults"
@@ -351,7 +351,7 @@ export default {
       getstatusList: [], //状态列表
       customList: [], //客户列表
       productList: [], //产品列表
-      currentPhaseList: [], //阶段表
+      currentPhaseList: [], //阶段
       selectedTemplateIds: new Set(), // 新增: 用于存储所有已选择的模版ID
       isAllSelected: false, // 新增: 标记是否全选所有页
       selectedPageIds: new Map(), // 新增: 存储每页选中的ID
@@ -426,7 +426,7 @@ export default {
         <style>
           /* 保持原有样式 */
           body {
-            font-family: SimSun, serif;  // 使用宋体作为默认字体
+            font-family: SimSun, serif;  // 用宋体作为默认字体
             font-size: 12pt;
             line-height: 1.5;
             margin: 0;
@@ -790,7 +790,7 @@ export default {
       );
       if (!product) return "info";
 
-      // 根据不同阶段返回同的类型
+      // 根据不同阶段返回同的类型
       // 这里的判断逻辑需要根据实际的产品阶来调整
       switch (product.status) {
         case 1:
@@ -806,12 +806,12 @@ export default {
     /*目前状态  */
     getStatusName(statusId) {
       const status = this.getstatusList.find((item) => item.value === statusId);
-      return status ? status.label : "未状态";
+      return status ? status.label : "未��状态";
     },
 
     getStatusType(statusId) {
       // 这里可以根据不同状态返回不同的类型
-      // 可用的类型:success/warning/danger/info
+      // 可用的类型:success/warning/danger/info
       const status = this.getstatusList.find((item) => item.value === statusId);
       if (!status) return "info";
 
@@ -835,7 +835,7 @@ export default {
       return `${rate}%`;
     },
 
-    // 根据完成度返回对应CSS类名
+    // 根据完成度返回对应CSS类名
     getCompletionClass(rate) {
       if (!rate) return "completion-low";
       if (rate >= 100) return "completion-high";
@@ -897,7 +897,7 @@ export default {
       this.docAttr = template;
       const TemList = JSON.parse(template.data);
       /* this.$confirm("确定要替换此模版吗?", "提示", {
-        confirmButtonText: "确",
+        confirmButtonText: "确",
         cancelButtonText: "取消",
         type: "warning",
       }).then(() => { */
@@ -921,7 +921,7 @@ export default {
 
       this.batchReplaceLoading = true;
       try {
-        // 依次处理个选中的模版
+        // 依次处理个选中的模版
         for (const template of this.selectedBoundTemplates) {
           this.docAttr = template;
           const TemList = JSON.parse(template.data);
@@ -978,7 +978,7 @@ export default {
 
         // 调试用:打印每个匹配的详细信息
         this.matchResults.forEach((match) => {
-          // 据括号类型选择不同的切片方式
+          // 据括号类型选择不同的切片方式
           const content = match.startsWith("【")
             ? match.slice(1, -1)
             : match.slice(1, -1);
@@ -996,7 +996,7 @@ export default {
       return "other_location";
     },
 
-    // 修改式化请求参数的方法
+    // 修改式化请求参数的方法
     formatRequestParams(locations) {
       const locationArray = Array.isArray(locations) ? locations : [locations];
 
@@ -1079,7 +1079,7 @@ export default {
       return parsed;
     },
 
-    // 查内容是否包含表格或图片
+    // 查内容是否包含表格或图片
     containsTableOrImage(content) {
       return content.includes("<table") || content.includes("<img");
     },
@@ -1164,7 +1164,7 @@ export default {
       }
     },
 
-    // 修改单个替换方
+    // 修改单个替换方���
     async replaceItem(item) {
       try {
         const success = await this.processAndReplaceContent(this.TemList, item);
@@ -1189,11 +1189,10 @@ export default {
       try {
         // 收集所有匹配
         const allLocations = this.matchResults.map((item) => {
-          // 清理括号
           return item.replace(/[\[\]【】]/g, "");
         });
 
-        // 格式化所有位置的请求参数
+        // 格式化请求参数
         const params = {
           template_location: [],
           middle_layer_location: [],
@@ -1203,7 +1202,6 @@ export default {
 
         // 遍历所有位置并分类
         allLocations.forEach((location) => {
-          // 为每种类型创建对应长度的数组
           const type = this.getDocumentType(location);
           Object.keys(params).forEach((key) => {
             if (type === key) {
@@ -1214,7 +1212,8 @@ export default {
           });
         });
         params.project_id = this.currentData.id;
-        // 发送单个批量请求
+
+        // 发送批量请求
         const response = await axios.post(
           `${process.env.VUE_APP_BASE_API}/project-raw-data/batch-content`,
           params,
@@ -1233,16 +1232,47 @@ export default {
             this.TemList.forEach((el, index) => {
               let updatedContent = el.content;
 
-              // 遍历所有替内容和对应的匹配项
-              this.matchResults.forEach((item, idx) => {
-                const replacement = replacementContents[idx]?.content;
-                if (replacement) {
-                  // 处理表格和其他内容
-                  updatedContent = this.processTableContent(
-                    updatedContent,
-                    item,
-                    replacement
-                  );
+              // 遍历所有替换内容和对应匹配项
+              this.matchResults.forEach((item) => {
+                // 提取编号的函数只需定义一次
+                const getCodeFromItem = (searchItem) => {
+                  const cleanItem = searchItem.replace(/[\[\]【】]/g, "");
+                  const match = cleanItem.match(/([A-Z0-9]+-[A-Z]+-\d+-\d+)/);
+                  return match ? match[1] : null;
+                };
+
+                // 获取当前项的编号
+                  const currentCode = getCodeFromItem(item);
+                if (!currentCode) return; // 如果没有有效编号,跳过此项
+
+                // 查找匹配的替换内容
+                const matchedContent = replacementContents.find(
+                  (content) => content.template_location === currentCode
+                );
+                
+                if (matchedContent?.content) {
+                  // 构建替换内容
+                  const formattedReplacement = `
+                    <span class="replacement-content" data-code="${currentCode}">
+                      ${matchedContent.content}
+                    </span>
+                  `.trim();
+
+                    // 处理表格和其他内容
+                    updatedContent = this.processTableContent(
+                      updatedContent,
+                      item,
+                      formattedReplacement
+                    );
+
+                  // 记录日志
+                  if (process.env.NODE_ENV !== 'production') {
+                    console.log("替换信息:", {
+                      原始编号: currentCode,
+                      原始内容: item,
+                      替换内容: formattedReplacement,
+                    });
+                  }
                 }
               });
 
@@ -1275,16 +1305,58 @@ export default {
       return "other_location";
     },
 
-    // 修改处理格内容的方法,添加对多个替换的支持
+    // 修改处理���格内容的方法,添加对多个替换的支持
     processTableContent(content, searchItem, replacement) {
-      // 直接使用字符串替换,不处理 DOM
       if (!content || !searchItem) return content;
 
       try {
-        const regex = new RegExp(this.escapeRegExp(searchItem), "g");
-        return content.replace(regex, replacement);
+        // 提取搜索项中的编号
+        const getCodeFromItem = (item) => {
+          const cleanItem = item.replace(/[\[\]【】]/g, "");
+          const match = cleanItem.match(/([A-Z0-9]+-[A-Z]+-\d+-\d+)/);
+          return match ? match[1] : null;
+        };
+
+        const searchCode = getCodeFromItem(searchItem);
+        if (!searchCode) {
+          console.warn("无法从搜索项中提取编号:", searchItem);
+          return content;
+        }
+
+        const tempDiv = document.createElement("div");
+        tempDiv.innerHTML = content;
+
+        const cleanupContent = (html) => {
+          let cleaned = html.replace(/\s+/g, " ");
+          cleaned = cleaned.replace(/<\/span><span[^>]*>/g, "");
+          cleaned = cleaned.replace(/<span[^>]*>\s*<\/span>/g, "");
+          return cleaned;
+        };
+
+        const handleSplitContent = () => {
+          let currentHtml = tempDiv.innerHTML;
+          currentHtml = cleanupContent(currentHtml);
+
+          // 查找并替换匹配的内容
+          const pattern = new RegExp(
+            `\\[${searchCode}\\]|【${searchCode}】`,
+            "g"
+          );
+          currentHtml = currentHtml.replace(pattern, replacement);
+
+          tempDiv.innerHTML = currentHtml;
+        };
+
+        handleSplitContent();
+        return tempDiv.innerHTML;
       } catch (error) {
         console.error("替换内容时出错:", error);
+        console.error("错误详情:", {
+          原始内容: content.substring(0, 100) + "...",
+          搜索项: searchItem,
+          替换内容: replacement,
+          错误信息: error.message,
+        });
         return content;
       }
     },
@@ -1347,21 +1419,12 @@ export default {
       return html;
     },
 
-    // 更新 escapeRegExp 方法以支持两种括号类型
-    escapeRegExp(string) {
-      const isChinese = string.startsWith("【");
-      const content = isChinese
-        ? string.replace(/^【|】$/g, "")
-        : string.replace(/^\[|\]$/g, "");
-      const escaped = content.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
-      return isChinese ? `\\【${escaped}\\】` : `\\[${escaped}\\]`;
-    },
     /* 选择模版 */
     selTemplate(row) {
       this.currentData = row;
       this.selectedTemplates = []; // 重置选择
       this.selectedTemplateIds = new Set(row.documentIds || []); // 初始化已绑定的模版ID
-      this.templateQueryForm.page = 1; // 重置���
+      this.templateQueryForm.page = 1; // 重置码
       this.loadTemplateList();
     },
     // 处理模版分页变化
@@ -1577,7 +1640,7 @@ export default {
         return;
       }
 
-      // 获取绑定模版替换位置信息
+      // 获取绑定模版替换位置信息
       searchTemplateList({ ids: row.documentIds.join(",") || 0 })
         .then(async (res) => {
           if (res.status === 200) {
@@ -1667,7 +1730,7 @@ export default {
                     );
 
                     if (!isDuplicate) {
-                      // 如果不是重复项,添加到结果数组中
+                      // 如果不是重复项,��添加到结果数组中
                       return [...acc, current];
                     }
                     return acc;
@@ -1706,7 +1769,7 @@ export default {
     getCategoryTypeName(categoryId) {
       if (!categoryId) return "未分类";
       const product = this.productList.find((item) => item.id === categoryId);
-      return product && product.category ? product.category.name : "未知类";
+      return product && product.category ? product.category.name : "未知类";
     },
 
     getCategoryName(categoryId) {
@@ -2058,7 +2121,7 @@ export default {
   font-weight: bold;
 }
 
-// 添加PDF导相关样式
+// 添加PDF导相关样式
 .content {
   background: white;
 

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini