From f81a35c10e6c697982b02540c93d302e654810c1 Mon Sep 17 00:00:00 2001
From: caorui <3165079241@qq.com>
Date: Fri, 4 Jul 2025 17:59:47 +0800
Subject: [PATCH] =?UTF-8?q?=E5=9C=BA=E6=99=AF=E4=B8=AD=E5=BF=83=E5=8A=A8?=
=?UTF-8?q?=E6=80=81=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/LinkUp/compoment/addDialogChunk.vue | 276 +++++++++++++-----
1 file changed, 199 insertions(+), 77 deletions(-)
diff --git a/src/views/LinkUp/compoment/addDialogChunk.vue b/src/views/LinkUp/compoment/addDialogChunk.vue
index e1cffdc..c4ab631 100644
--- a/src/views/LinkUp/compoment/addDialogChunk.vue
+++ b/src/views/LinkUp/compoment/addDialogChunk.vue
@@ -129,7 +129,10 @@
v-show="representation"
>
-
+
@@ -551,10 +554,11 @@
label-position="top"
style="margin: 0 10px"
>
-
+
@@ -628,6 +632,10 @@
+
+
+ 点击测试
+
@@ -772,11 +780,69 @@ export default {
},
currenrActiveNodeRef: "",
lastSelectedTokenIndex: -1,
- tokenCounter: 0,
representationData: representationData,
+ savedRange: null, // ⬅️ 用于存储当前 range
};
},
methods: {
+ async HitTesting() {
+ this.openLoading("处理");
+ // 使用示例:传入你这段 HTML 所在的 DOM 根节点
+ const root = document.querySelector("#editorContainer");
+ const parsed = this.extractEditorItems(root);
+ let data = this.drawShowList[this.drawSelectIndex].options;
+ let params = {
+ detailList: parsed,
+ flowId: this.sceneID,
+ stepID: data.stepID,
+ stepAccountId: data.step_acc_id,
+ actionName: data.apiName || data.plugName,
+ tableName: this.outsideFormData.tableName,
+ };
+ let res = await authApi(
+ "sysFlowStepConfigService",
+ "",
+ "saveOrUpdateConfig",
+ "",
+ params
+ );
+ if (res.status == "200") {
+ this.$vmNews("测试成功!", "success");
+ }
+ },
+ extractEditorItems(rootElement) {
+ const result = [];
+ const items = rootElement.querySelectorAll(".editorItem");
+
+ items.forEach((item) => {
+ const fieldName =
+ item.querySelector(".el-form-item__label")?.innerText.trim() || "";
+ const editor = item.querySelector(".content-editor");
+ if (!editor) return;
+
+ const html_label = editor.innerHTML.trim(); // 保留标签结构
+
+ let whereCondition = "";
+ editor.childNodes.forEach((node) => {
+ if (node.nodeType === Node.TEXT_NODE) {
+ whereCondition += node.textContent;
+ } else if (node.nodeType === Node.ELEMENT_NODE) {
+ whereCondition += node.getAttribute("data-token-text") || "";
+ }
+ });
+
+ // 替换中文符号为英文符号
+ whereCondition = whereCondition
+ .replace(/,/g, ",")
+ .replace(/(/g, "(")
+ .replace(/)/g, ")");
+
+ result.push({ fieldName, whereCondition, html_label });
+ });
+
+ return result;
+ },
+
/**
* 打开弹窗
* @param {string} sceneID 场景 ID
@@ -1592,10 +1658,20 @@ export default {
}
},
// 切换表时
- outsideSelectChange(val) {
+ async outsideSelectChange(val) {
if (val) {
this.outsideColumns = [];
- this.queryColumns(val);
+ // 更新当前步骤的步骤描述
+ this.drawShowList[this.drawSelectIndex].options.description =
+ this.description;
+ let params = {
+ flowId: this.sceneID,
+ id: this.drawShowList[this.drawSelectIndex].options.stepID,
+ tableName: val,
+ };
+ // 保存场景步骤数据
+ await this.SaveSceneStepData(params);
+ await this.queryColumns(val);
}
},
// 获取表字段
@@ -1773,7 +1849,24 @@ export default {
this.userList = [];
this.representation = false;
},
+ representationChange() {
+ if (!this.currenrActiveNodeRef) return;
+ const editor = this.$refs[this.currenrActiveNodeRef][0];
+ if (!editor) return;
+ // 创建 range 和 selection
+ const range = document.createRange();
+ const selection = window.getSelection();
+ // 将 range 定位到 editor 的最后一个子节点
+ range.selectNodeContents(editor);
+ range.collapse(false); // 折叠到末尾
+ // 清空现有选区并设置新 range
+ selection.removeAllRanges();
+ selection.addRange(range);
+ // 确保编辑器有焦点
+ editor.focus();
+ this.saveRange();
+ },
handleKeyDown(e, columnName, rowIndex) {
const editor = this.$refs["contentEditor" + columnName + rowIndex][0];
@@ -1799,20 +1892,6 @@ export default {
}
}
}
-
- // 清除token选中状态(除了特殊键)
- if (
- ![
- "Backspace",
- "Delete",
- "ArrowLeft",
- "ArrowRight",
- "ArrowUp",
- "ArrowDown",
- ].includes(e.key)
- ) {
- this.clearTokenSelection(columnName, rowIndex);
- }
},
// 清除token选中状态
clearTokenSelection(columnName, rowIndex) {
@@ -1822,29 +1901,27 @@ export default {
},
// 处理输入事件
handleInput(e, columnName, rowIndex) {
- // 清除token选中状态
- this.clearTokenSelection(columnName, rowIndex);
-
- // 强制更新computed属性
- this.$forceUpdate();
+ // this.clearTokenSelection(columnName, rowIndex);
+ this.saveRange();
},
// 处理编辑器点击
handleEditorClick(e, columnName, rowIndex) {
const editor = this.$refs["contentEditor" + columnName + rowIndex][0];
this.currenrActiveNodeRef = "contentEditor" + columnName + rowIndex;
- // 如果点击的不是token,清除选中状态
- if (
- !e.target.classList.contains("content-token") &&
- !e.target.closest(".content-token")
- ) {
- this.clearTokenSelection(columnName, rowIndex);
- }
+ // // 如果点击的不是token,清除选中状态
+ // if (
+ // !e.target.classList.contains("content-token") &&
+ // !e.target.closest(".content-token")
+ // ) {
+ // this.clearTokenSelection(columnName, rowIndex);
+ // }
- // 确保编辑器获得焦点
- if (e.target === editor || editor.contains(e.target)) {
- editor.focus();
- }
+ // // 确保编辑器获得焦点
+ // if (e.target === editor || editor.contains(e.target)) {
+ editor.focus();
+ this.saveRange();
+ // }
},
// 处理粘贴事件
handlePaste(e, columnName, rowIndex) {
@@ -1854,7 +1931,6 @@ export default {
// 处理编辑器获得焦点
handleEditorFocus(e, columnName, rowIndex) {
const editor = this.$refs["contentEditor" + columnName + rowIndex][0];
-
// 如果编辑器为空,设置光标到开始位置
if (this.isEmpty(columnName, rowIndex)) {
setTimeout(() => {
@@ -1900,6 +1976,7 @@ export default {
selection.addRange(range);
// 确保编辑器有焦点
editor.focus();
+ this.saveRange();
});
},
@@ -1925,13 +2002,14 @@ export default {
selection.addRange(range);
// 确保编辑器有焦点
editor.focus();
+ this.saveRange();
},
handleNodeSelected(path) {
this.selectedNode = path;
this.insertToken(path, "node-reference");
},
- handleTagSelected(label){
-
+ handleTagSelected(label) {
+ this.insertToken(label, "node-edit");
},
// 插入token到编辑器
insertToken(text, type) {
@@ -1942,46 +2020,64 @@ export default {
// 确保编辑器有焦点
editor.focus();
+ setTimeout(() => {
+ const token = this.createTokenElement(text, type);
+ const space = document.createTextNode(" ");
- const token = this.createTokenElement(text, type);
+ // 获取当前光标位置
+ const selection = window.getSelection();
+ let range = this.savedRange?.cloneRange();
- // 获取当前光标位置
- const selection = window.getSelection();
- if (selection.rangeCount > 0) {
- const range = selection.getRangeAt(0);
+ // fallback:没有保存 range,则使用当前选区
+ if (!range && selection.rangeCount > 0) {
+ range = selection.getRangeAt(0);
+ }
+
+ if (!range) {
+ // fallback:插入到末尾
+ editor.appendChild(token);
+ editor.appendChild(space);
+ this.setCursorToEnd();
+ this.$nextTick(() => {
+ if (!this.setCursorAfter(space)) {
+ this.setCursorToEnd();
+ }
+ });
+ return;
+ }
+
+ // 删除选中内容(若有)
range.deleteContents();
- // 插入token
- range.insertNode(token);
+ // 插入 token + 空格
+ const frag = document.createDocumentFragment();
+ frag.appendChild(token);
+ frag.appendChild(space);
+ range.insertNode(frag);
- // 在token后添加一个空格
- const space = document.createTextNode(" ");
- range.setStartAfter(token);
- range.insertNode(space);
+ // 设置光标到空格后
+ range.setStartAfter(space);
+ range.collapse(true);
+ selection.removeAllRanges();
+ selection.addRange(range);
- // 使用setTimeout确保DOM更新完成后设置光标
- setTimeout(() => {
- if (!this.setCursorAfter(space)) {
- // 如果设置失败,则设置到编辑器末尾
- this.setCursorToEnd();
- }
- }, 10); // 增加延迟时间确保DOM完全更新
- } else {
- // 如果没有选中区域,直接添加到末尾
- editor.appendChild(token);
- const space = document.createTextNode(" ");
- editor.appendChild(space);
+ // 更新 savedRange
+ this.savedRange = range.cloneRange();
- // 使用setTimeout确保DOM更新完成后设置光标
- setTimeout(() => {
+ this.$nextTick(() => {
if (!this.setCursorAfter(space)) {
this.setCursorToEnd();
}
- }, 10);
+ });
+
+ this.saveRange();
+ }, 10);
+ },
+ saveRange() {
+ const selection = window.getSelection();
+ if (selection.rangeCount > 0) {
+ this.savedRange = selection.getRangeAt(0).cloneRange();
}
-
- // 强制更新
- this.$forceUpdate();
},
// 设置光标到末尾
setCursorToEnd() {
@@ -2014,15 +2110,17 @@ export default {
},
// 创建token元素
createTokenElement(text, type) {
- const token = document.createElement("span");
- token.className = `content-token token-function`;
- token.contentEditable = false;
- token.setAttribute("data-token-id", ++this.tokenCounter);
- token.setAttribute("data-token-type", type);
- token.setAttribute("data-token-text", text);
+ let token = null;
+ token = document.createElement("span");
+ token.contentEditable = false;
+ token.setAttribute("data-token-text", text);
if (type === "node-reference") {
+ token.className = "content-token token-function";
token.innerHTML = ` ${text}`;
+ } else {
+ token.className = "content-token token-edit";
+ token.innerHTML = `${text}`;
}
return token;
},
@@ -2047,6 +2145,15 @@ export default {
this.currenrActiveNodeRef = "";
},
},
+ mounted() {
+ // 绑定事件监听器
+ const editor = this.$refs[this.currenrActiveNodeRef]?.[0];
+ if (editor) {
+ editor.addEventListener("mouseup", this.saveRange);
+ editor.addEventListener("keyup", this.saveRange);
+ editor.addEventListener("mouseleave", this.saveRange); // 鼠标移开也记录一次
+ }
+ },
};
@@ -2874,9 +2981,9 @@ export default {
user-select: none;
}
::v-deep .token-function {
- background: #e0e7ff;
- color: #5b21b6;
- border: 1px solid #8b5cf6;
+ background: #ecfdf5;
+ color: #047857;
+ border: 1px solid #10b981;
}
::v-deep .repContainer {
@@ -2915,7 +3022,7 @@ export default {
cursor: pointer;
}
-.repItem:hover .repItemValue{
+.repItem:hover .repItemValue {
color: #409eff;
}
@@ -2924,6 +3031,21 @@ export default {
font-size: 13px;
margin-left: 10px;
}
+
+.token-editable-content {
+ display: inline-block;
+ min-width: 1em;
+ padding: 0 2px;
+ border-bottom: 1px dashed #aaa;
+ cursor: text;
+ outline: none;
+}
+::v-deep .content-token.token-edit {
+ display: inline-flex !important;
+ color: #5b21b6;
+ font-weight: bold;
+ padding: 0;
+}