|
@@ -4,6 +4,7 @@
|
|
v-model="comList"
|
|
v-model="comList"
|
|
@add="onAdd"
|
|
@add="onAdd"
|
|
@update="onDragEnd"
|
|
@update="onDragEnd"
|
|
|
|
+ @end="onDragComplete"
|
|
group="itxst"
|
|
group="itxst"
|
|
animation="300"
|
|
animation="300"
|
|
:style="draggableStyle"
|
|
:style="draggableStyle"
|
|
@@ -260,7 +261,7 @@ export default {
|
|
handler(val) {
|
|
handler(val) {
|
|
if (val == null) return;
|
|
if (val == null) return;
|
|
const newComList = JSON.parse(JSON.stringify(val));
|
|
const newComList = JSON.parse(JSON.stringify(val));
|
|
-
|
|
|
|
|
|
+
|
|
// 比较新旧值,只有在真正变化时才更新
|
|
// 比较新旧值,只有在真正变化时才更新
|
|
if (JSON.stringify(this.comList) !== JSON.stringify(newComList)) {
|
|
if (JSON.stringify(this.comList) !== JSON.stringify(newComList)) {
|
|
this.comList = newComList;
|
|
this.comList = newComList;
|
|
@@ -268,7 +269,7 @@ export default {
|
|
/* console.log("val", val);
|
|
/* console.log("val", val);
|
|
this.comList = JSON.parse(JSON.stringify(val));
|
|
this.comList = JSON.parse(JSON.stringify(val));
|
|
console.log("comList", this.comList); */
|
|
console.log("comList", this.comList); */
|
|
- /* console.log("val", val);
|
|
|
|
|
|
+ /* console.log("val", val);
|
|
this.comList = this.carefulCopy(val);
|
|
this.comList = this.carefulCopy(val);
|
|
console.log("comList", this.comList); */
|
|
console.log("comList", this.comList); */
|
|
},
|
|
},
|
|
@@ -324,26 +325,85 @@ export default {
|
|
this.initCategoryList();
|
|
this.initCategoryList();
|
|
this.type = this.$route.query.type;
|
|
this.type = this.$route.query.type;
|
|
this.templateId = this.$route.query.templateId;
|
|
this.templateId = this.$route.query.templateId;
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.updateDirectoryNumbers(); // 初始化目录序号
|
|
|
|
+ });
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
|
|
+ /* 拖拽 修改目录序号*/
|
|
|
|
+ onDragComplete() {
|
|
|
|
+ console.log("拖动结束");
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.updateDirectoryNumbers();
|
|
|
|
+ this.$emit("onRebuild", this.comList);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ updateDirectoryNumbers() {
|
|
|
|
+ let levelCounters = {};
|
|
|
|
+ this.comList.forEach((module, moduleIndex) => {
|
|
|
|
+ if (module.attrs) {
|
|
|
|
+ module.attrs.forEach((attr) => {
|
|
|
|
+ if (attr.type === "Directory") {
|
|
|
|
+ const newNumber = this.generateNumberedContent(
|
|
|
|
+ moduleIndex,
|
|
|
|
+ attr.level,
|
|
|
|
+ levelCounters
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // 只更新 number 属性,完全不触及 content
|
|
|
|
+ if (!attr.hasOwnProperty("number")) {
|
|
|
|
+ this.$set(attr, "number", newNumber);
|
|
|
|
+ } else {
|
|
|
|
+ attr.number = newNumber;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ generateNumberedContent(moduleIndex, level, levelCounters) {
|
|
|
|
+ return this.generateLevelPrefix(moduleIndex, level, levelCounters);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ generateLevelPrefix(moduleIndex, level, levelCounters) {
|
|
|
|
+ let prefix = [];
|
|
|
|
+
|
|
|
|
+ for (let i = 1; i <= level; i++) {
|
|
|
|
+ if (i === 1) {
|
|
|
|
+ prefix.push(moduleIndex + 1);
|
|
|
|
+ } else {
|
|
|
|
+ if (!levelCounters[i]) {
|
|
|
|
+ levelCounters[i] = 1;
|
|
|
|
+ } else {
|
|
|
|
+ levelCounters[i]++;
|
|
|
|
+ }
|
|
|
|
+ prefix.push(levelCounters[i]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return prefix.join(".");
|
|
|
|
+ },
|
|
|
|
+
|
|
carefulCopy(items) {
|
|
carefulCopy(items) {
|
|
- return items.map(item => {
|
|
|
|
|
|
+ return items.map((item) => {
|
|
const newItem = { ...item };
|
|
const newItem = { ...item };
|
|
-
|
|
|
|
|
|
+
|
|
// 深拷贝 attrs 数组
|
|
// 深拷贝 attrs 数组
|
|
if (Array.isArray(newItem.attrs)) {
|
|
if (Array.isArray(newItem.attrs)) {
|
|
- newItem.attrs = newItem.attrs.map(attr => ({...attr}));
|
|
|
|
|
|
+ newItem.attrs = newItem.attrs.map((attr) => ({ ...attr }));
|
|
}
|
|
}
|
|
|
|
|
|
// 深拷贝 content,如果它是一个对象或数组
|
|
// 深拷贝 content,如果它是一个对象或数组
|
|
- if (typeof newItem.content === 'object' && newItem.content !== null) {
|
|
|
|
|
|
+ if (typeof newItem.content === "object" && newItem.content !== null) {
|
|
newItem.content = JSON.parse(JSON.stringify(newItem.content));
|
|
newItem.content = JSON.parse(JSON.stringify(newItem.content));
|
|
}
|
|
}
|
|
|
|
|
|
// 处理特殊的 type,如 Table
|
|
// 处理特殊的 type,如 Table
|
|
- if (newItem.type === 'Table') {
|
|
|
|
|
|
+ if (newItem.type === "Table") {
|
|
newItem.tableHeader = [...newItem.tableHeader];
|
|
newItem.tableHeader = [...newItem.tableHeader];
|
|
- newItem.tableData = newItem.tableData.map(row => ({...row}));
|
|
|
|
|
|
+ newItem.tableData = newItem.tableData.map((row) => ({ ...row }));
|
|
}
|
|
}
|
|
|
|
|
|
// 保留其他属性的引用
|
|
// 保留其他属性的引用
|
|
@@ -574,10 +634,17 @@ export default {
|
|
this.$emit("onDelete", index);
|
|
this.$emit("onDelete", index);
|
|
},
|
|
},
|
|
onEdit(e, state) {
|
|
onEdit(e, state) {
|
|
- this.comList = this.comList.map((it) => {
|
|
|
|
|
|
+ this.comList = this.comList.map((it, index) => {
|
|
it.isEdit = 2;
|
|
it.isEdit = 2;
|
|
|
|
+
|
|
|
|
+ // 当切换到编辑状态时,对当前项进行 attrs 过滤
|
|
|
|
+ if (index === e && state === 1) {
|
|
|
|
+ this.filterAttrs(it);
|
|
|
|
+ }
|
|
|
|
+
|
|
return it;
|
|
return it;
|
|
});
|
|
});
|
|
|
|
+
|
|
if (state == 1) {
|
|
if (state == 1) {
|
|
this.comList[e].isEdit = 1;
|
|
this.comList[e].isEdit = 1;
|
|
this.onSetActive(e);
|
|
this.onSetActive(e);
|
|
@@ -585,6 +652,17 @@ export default {
|
|
|
|
|
|
this.$emit("onRebuild", this.comList);
|
|
this.$emit("onRebuild", this.comList);
|
|
},
|
|
},
|
|
|
|
+
|
|
|
|
+ // 新增 filterAttrs 方法
|
|
|
|
+ filterAttrs(item) {
|
|
|
|
+ // 从 content 中提取所有 {{}} 包裹的 ID
|
|
|
|
+ const contentIds = (item.content.match(/{{([^}]+)}}/g) || []).map(
|
|
|
|
+ (match) => match.slice(2, -2).trim()
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // 过滤 attrs,只保留在 content 中出现的 ID
|
|
|
|
+ item.attrs = item.attrs.filter((attr) => contentIds.includes(attr.id));
|
|
|
|
+ },
|
|
onAdd(e) {
|
|
onAdd(e) {
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|