场景中心动态配置

This commit is contained in:
caorui 2025-07-04 17:59:47 +08:00
parent 66427493fc
commit f81a35c10e
1 changed files with 199 additions and 77 deletions

View File

@ -129,7 +129,10 @@
v-show="representation"
>
<div class="repContainer">
<el-tabs v-model="representationActiveName">
<el-tabs
v-model="representationActiveName"
@tab-click="representationChange"
>
<el-tab-pane label="动态内容" name="first"></el-tab-pane>
<el-tab-pane label="表达式" name="second"></el-tab-pane>
</el-tabs>
@ -551,10 +554,11 @@
label-position="top"
style="margin: 0 10px"
>
<div ref="editorContainer">
<div id="editorContainer">
<div
v-for="(row, rowIndex) in outsideColumns"
:key="rowIndex"
class="editorItem"
>
<el-form-item :label="row.column_name">
<div class="editor-container">
@ -628,6 +632,10 @@
</el-form>
</el-collapse-item>
</el-collapse>
<div>
<el-button @click="HitTesting">点击测试</el-button>
</div>
</div>
</el-tab-pane>
</el-tabs>
@ -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);
// 使setTimeoutDOM
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();
// 使setTimeoutDOM
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 = `<i class="el-icon-connection"></i> ${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); //
}
},
};
</script>
@ -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;
}
</style>