|
@@ -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;
|
|
|
|