|
@@ -24,7 +24,16 @@
|
|
|
<div class="create-operation">
|
|
|
<el-button><SvgIcon icon-class="background-img" />背景图</el-button>
|
|
|
<el-button><SvgIcon icon-class="template" />模板</el-button>
|
|
|
- <el-button><i class="el-icon-close"></i>退出编辑</el-button>
|
|
|
+ <el-button class="exit-edit">
|
|
|
+ <span><i class="el-icon-close"></i> 退出编辑</span>
|
|
|
+ <el-button class="save" type="primary">
|
|
|
+ <span @click="saveCoursewareContent"><SvgIcon icon-class="save" /> <span>保存</span></span>
|
|
|
+ <el-popover placement="bottom" popper-class="save-popover" trigger="click">
|
|
|
+ <div class="save-template">保存为模板</div>
|
|
|
+ <i slot="reference" class="el-icon-arrow-down"></i>
|
|
|
+ </el-popover>
|
|
|
+ </el-button>
|
|
|
+ </el-button>
|
|
|
</div>
|
|
|
|
|
|
<main ref="canvas" class="canvas">
|
|
@@ -41,16 +50,25 @@
|
|
|
gridTemplateRows: col.grid_template_rows,
|
|
|
}"
|
|
|
>
|
|
|
- <span class="drag-vertical-line start" :data-row="i" :data-col="j"></span>
|
|
|
- <component
|
|
|
- :is="componentList[grid.type]"
|
|
|
- v-for="(grid, k) in col.grid_list"
|
|
|
- :id="grid.id"
|
|
|
- :key="k"
|
|
|
- :style="{ gridArea: grid.grid_area }"
|
|
|
- @showSetting="showSetting"
|
|
|
- />
|
|
|
- <span class="drag-vertical-line end" :data-row="i" :data-col="j"></span>
|
|
|
+ <template v-for="(grid, k) in col.grid_list">
|
|
|
+ <span
|
|
|
+ v-if="k === 0"
|
|
|
+ :key="`start-${k}`"
|
|
|
+ class="drag-vertical-line"
|
|
|
+ :data-row="i"
|
|
|
+ :data-col="j"
|
|
|
+ :data-grid="k"
|
|
|
+ ></span>
|
|
|
+ <component
|
|
|
+ :is="componentList[grid.type]"
|
|
|
+ :id="grid.id"
|
|
|
+ ref="component"
|
|
|
+ :key="k"
|
|
|
+ :style="{ gridArea: grid.grid_area }"
|
|
|
+ @showSetting="showSetting"
|
|
|
+ />
|
|
|
+ <span :key="`end-${k}`" class="drag-vertical-line" :data-row="i" :data-col="j" :data-grid="k + 1"></span>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
<span class="drag-line" :data-row="i"></span>
|
|
|
</div>
|
|
@@ -74,6 +92,7 @@ export default {
|
|
|
provide() {
|
|
|
return {
|
|
|
getCurSettingId: () => this.curSettingId,
|
|
|
+ courseware_id: this.courseware_id,
|
|
|
};
|
|
|
},
|
|
|
data() {
|
|
@@ -84,7 +103,6 @@ export default {
|
|
|
book_id,
|
|
|
chapter_id,
|
|
|
data: {
|
|
|
- id: '',
|
|
|
background_image_url: '',
|
|
|
background_position: {
|
|
|
x: 0,
|
|
@@ -103,6 +121,7 @@ export default {
|
|
|
bookTypeOption,
|
|
|
curRow: -2,
|
|
|
curCol: -1,
|
|
|
+ curGrid: -1,
|
|
|
enterCanvas: false, // 是否进入画布
|
|
|
// 拖拽状态
|
|
|
drag: {
|
|
@@ -136,12 +155,13 @@ export default {
|
|
|
item.style.opacity = 0;
|
|
|
});
|
|
|
this.curCol = -1;
|
|
|
+ this.curGrid = -1;
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
created() {
|
|
|
- GetCoursewareContent({ id: this.courseware_id }).then((res) => {
|
|
|
- this.data = res.data;
|
|
|
+ GetCoursewareContent({ id: this.courseware_id }).then(({ content }) => {
|
|
|
+ if (content) this.data = JSON.parse(content);
|
|
|
});
|
|
|
},
|
|
|
mounted() {
|
|
@@ -157,7 +177,20 @@ export default {
|
|
|
this.$router.push({ path: '/chapter', query: { chapter_id: this.chapter_id, book_id: this.book_id } });
|
|
|
},
|
|
|
saveCoursewareContent() {
|
|
|
- SaveCoursewareContent({ id: this.courseware_id, category: 'NEW' }).then(() => {
|
|
|
+ let component_id_list = this.data.row_list.flatMap((row) =>
|
|
|
+ row.col_list.flatMap((col) => col.grid_list.map((grid) => grid.id)),
|
|
|
+ );
|
|
|
+
|
|
|
+ this.$refs.component.forEach((item) => {
|
|
|
+ item.saveCoursewareComponentContent();
|
|
|
+ });
|
|
|
+
|
|
|
+ SaveCoursewareContent({
|
|
|
+ id: this.courseware_id,
|
|
|
+ category: 'NEW',
|
|
|
+ content: JSON.stringify(this.data),
|
|
|
+ component_id_list,
|
|
|
+ }).then(() => {
|
|
|
this.$message.success('保存成功');
|
|
|
});
|
|
|
},
|
|
@@ -234,10 +267,10 @@ export default {
|
|
|
|
|
|
list.forEach((item, index) => {
|
|
|
if (index === minIndex) {
|
|
|
- const row = item.getAttribute('data-row');
|
|
|
- this.curRow = Number(row);
|
|
|
- const col = item.getAttribute('data-col');
|
|
|
- if (col) this.curCol = Number(col);
|
|
|
+ this.curRow = Number(item.getAttribute('data-row'));
|
|
|
+ this.curCol = Number(item.getAttribute('data-col') || -1);
|
|
|
+ this.curGrid = Number(item.getAttribute('data-grid') || -1);
|
|
|
+
|
|
|
item.style.opacity = 1;
|
|
|
} else {
|
|
|
item.style.opacity = 0;
|
|
@@ -256,15 +289,53 @@ export default {
|
|
|
this.drag.dragging = false;
|
|
|
}
|
|
|
|
|
|
- if (this.enterCanvas && this.curRow >= -1) {
|
|
|
- this.data.row_list.splice(this.curRow + 1, 0, this.calculateInsertedObject());
|
|
|
+ if (this.enterCanvas) {
|
|
|
+ if (this.curRow >= -1 && this.curCol <= -1) {
|
|
|
+ this.data.row_list.splice(this.curRow + 1, 0, this.calculateRowInsertedObject());
|
|
|
+ }
|
|
|
+ if (this.curRow >= -1 && this.curCol > -1 && this.curGrid > -1) {
|
|
|
+ this.calculateColObject();
|
|
|
+ }
|
|
|
}
|
|
|
this.enterCanvas = false;
|
|
|
},
|
|
|
/**
|
|
|
- * 计算插入的对象
|
|
|
+ * 计算列插入的对象
|
|
|
+ */
|
|
|
+ calculateColObject() {
|
|
|
+ let num = 0; // 计算当前行之前的所有 grid_list 的数量
|
|
|
+ for (let i = 0; i <= this.curRow; i++) {
|
|
|
+ this.data.row_list[i]?.col_list.forEach((item) => {
|
|
|
+ num += item.grid_list.length;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ const id = getRandomNumber(12);
|
|
|
+ const letter = String.fromCharCode(65 + num);
|
|
|
+ let col = this.data.row_list[this.curRow].col_list[this.curCol];
|
|
|
+
|
|
|
+ col.grid_list.splice(this.curGrid, 0, {
|
|
|
+ id,
|
|
|
+ grid_area: letter,
|
|
|
+ type: this.curType,
|
|
|
+ });
|
|
|
+
|
|
|
+ let grid_template_columns = '0';
|
|
|
+ col.grid_list.forEach((item, i) => {
|
|
|
+ if (i === col.grid_list.length - 1) grid_template_columns += ' auto 0';
|
|
|
+ else grid_template_columns += ' auto 16px';
|
|
|
+ });
|
|
|
+ col.grid_template_columns = grid_template_columns;
|
|
|
+
|
|
|
+ let grid_template_areas = '.';
|
|
|
+ col.grid_list.forEach(({ grid_area }) => {
|
|
|
+ grid_template_areas += ` ${grid_area} .`;
|
|
|
+ });
|
|
|
+ col.grid_template_areas = `"${grid_template_areas}"`;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 计算行插入的对象
|
|
|
*/
|
|
|
- calculateInsertedObject() {
|
|
|
+ calculateRowInsertedObject() {
|
|
|
let num = 0; // 计算当前行之前的所有 grid_list 的数量
|
|
|
for (let i = 0; i <= this.curRow; i++) {
|
|
|
this.data.row_list[i]?.col_list.forEach((item) => {
|
|
@@ -278,7 +349,7 @@ export default {
|
|
|
col_list: [
|
|
|
{
|
|
|
width: '100%',
|
|
|
- grid_template_areas: `'start ${letter} end'`,
|
|
|
+ grid_template_areas: `'. ${letter} .'`,
|
|
|
grid_template_columns: '0 auto 0',
|
|
|
grid_template_rows: 'auto',
|
|
|
grid_list: [
|
|
@@ -391,8 +462,13 @@ export default {
|
|
|
justify-content: center;
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
- .el-button {
|
|
|
+ .exit-edit {
|
|
|
+ padding: 4px 4px 4px 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ > .el-button {
|
|
|
height: 40px;
|
|
|
+ font-size: 16px;
|
|
|
font-weight: bold;
|
|
|
|
|
|
:deep > span {
|
|
@@ -400,6 +476,19 @@ export default {
|
|
|
column-gap: 8px;
|
|
|
align-items: center;
|
|
|
}
|
|
|
+
|
|
|
+ .save.el-button {
|
|
|
+ height: 32px;
|
|
|
+ margin-left: 8px;
|
|
|
+ font-size: 16px;
|
|
|
+
|
|
|
+ :deep > span {
|
|
|
+ display: flex;
|
|
|
+ column-gap: 4px;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: -1px;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -420,6 +509,18 @@ export default {
|
|
|
|
|
|
.col {
|
|
|
display: grid;
|
|
|
+
|
|
|
+ .drag-vertical-line:first-child {
|
|
|
+ left: -8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .drag-vertical-line:not(:first-child, :last-child) {
|
|
|
+ left: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .drag-vertical-line:last-child {
|
|
|
+ right: -4px;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -439,16 +540,6 @@ export default {
|
|
|
background-color: #379fff;
|
|
|
border-radius: 4px;
|
|
|
opacity: 0;
|
|
|
-
|
|
|
- &.start {
|
|
|
- right: 8px;
|
|
|
- grid-area: start;
|
|
|
- }
|
|
|
-
|
|
|
- &.end {
|
|
|
- left: 4px;
|
|
|
- grid-area: end;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -478,4 +569,20 @@ export default {
|
|
|
border-radius: 4px;
|
|
|
transform: translate(-40%, -40%);
|
|
|
}
|
|
|
+
|
|
|
+.save-popover {
|
|
|
+ width: 100px;
|
|
|
+ min-width: 100px;
|
|
|
+ padding: 4px;
|
|
|
+
|
|
|
+ .save-template {
|
|
|
+ padding: 4px 8px;
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #f1f1f1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|