Explorar el Código

删除组件问题、选择组件排列、删除问题、章节上移下移

dsy hace 1 día
padre
commit
32623893d7

+ 11 - 0
src/api/book.js

@@ -64,6 +64,17 @@ export function ChapterDeleteCourseware(data) {
 }
 
 /**
+ * @description 移动树节点(教材章节结构)
+ * @param {object} data
+ */
+export function ChapterMoveTreeNode(data) {
+  return http.post(
+    `${process.env.VUE_APP_EepServer}?MethodName=book_chapter_manager-MoveTreeNode_BookChapterStruct`,
+    data,
+  );
+}
+
+/**
  * @description 修改章节
  * @param {object} data
  */

+ 49 - 45
src/views/book/courseware/create/components/CreateCanvas.vue

@@ -73,10 +73,13 @@
                   ref="component"
                   :key="`grid-${grid.id}`"
                   :class="[grid.id]"
+                  :data-row="i"
+                  :data-col="j"
+                  :data-grid="k"
                   :border-color="computedBorderColor(row.row_id)"
                   :style="computedGridStyle(grid, row.row_id)"
-                  :delete-component="deleteComponent(i, j, k)"
                   :component-move="componentMove(i, j, k)"
+                  @deleteComponent="deleteComponent"
                   @showSetting="showSetting"
                   @changeData="changeData"
                 />
@@ -699,54 +702,55 @@ export default {
     },
     /**
      * 删除组件
-     * @param {number} i 行
-     * @param {number} j 列
-     * @param {number} k 格子
+     * @param {String} id 组件 id
      */
-    deleteComponent(i, j, k) {
-      return () => {
-        const gridList = this.data.row_list[i].col_list[j].grid_list;
-        let delRow = gridList[k].row; // 删除的 grid 的 row
-        let delW = gridList[k].width; // 删除的 grid 的 width
-        gridList.splice(k, 1);
-
-        // 如果删除后没有 grid 了则删除列
-        const colList = this.data.row_list[i].col_list[j];
-        if (colList.grid_list.length === 0) {
-          this.data.row_list[i].col_list.splice(j, 1);
-          let width_list = this.data.row_list[i].width_list;
-          const delW = width_list[j];
-          width_list.splice(j, 1);
-          this.data.row_list[i].width_list = width_list.map((item) => {
-            return `${Number(item.replace('fr', '')) + Number(delW.replace('fr', '') / width_list.length)}fr`;
-          });
-        }
+    deleteComponent(id) {
+      const attrs = this.findChildComponentByKey(`grid-${id}`)?.$attrs;
+      if (!attrs) return;
+      const i = Number(attrs['data-row']);
+      const j = Number(attrs['data-col']);
+      const k = Number(attrs['data-grid']);
+      const gridList = this.data.row_list[i].col_list[j].grid_list;
+      let delRow = gridList[k].row; // 删除的 grid 的 row
+      let delW = gridList[k].width; // 删除的 grid 的 width
+      gridList.splice(k, 1);
+
+      // 如果删除后没有 grid 了则删除列
+      const colList = this.data.row_list[i].col_list[j];
+      if (colList.grid_list.length === 0) {
+        this.data.row_list[i].col_list.splice(j, 1);
+        let width_list = this.data.row_list[i].width_list;
+        const delW = width_list[j];
+        width_list.splice(j, 1);
+        this.data.row_list[i].width_list = width_list.map((item) => {
+          return `${Number(item.replace('fr', '')) + Number(delW.replace('fr', '') / width_list.length)}fr`;
+        });
+      }
 
-        // 如果删除后没有列了则删除行
-        if (this.data.row_list[i].col_list.length === 0) {
-          this.data.row_list.splice(i, 1);
-        }
+      // 如果删除后没有列了则删除行
+      if (this.data.row_list[i].col_list.length === 0) {
+        this.data.row_list.splice(i, 1);
+      }
 
-        // 如果删除后还有 grid 则重新计算 grid 的 row 和 width
-        if (gridList?.length > 0) {
-          let delNum = gridList.filter(({ row }) => row === delRow).length;
-          let diff = Number(delW.replace('fr', '')) / delNum;
-          if (delNum === 0) {
-            // 删除 grid 后面的 row 都减 1
-            gridList.forEach((item) => {
-              if (item.row > delRow) {
-                item.row -= 1;
-              }
-            });
-          } else {
-            gridList.forEach((item) => {
-              if (item.row === delRow) {
-                item.width = `${Number(item.width.replace('fr', '')) + diff}fr`;
-              }
-            });
-          }
+      // 如果删除后还有 grid 则重新计算 grid 的 row 和 width
+      if (gridList?.length > 0) {
+        let delNum = gridList.filter(({ row }) => row === delRow).length;
+        let diff = Number(delW.replace('fr', '')) / delNum;
+        if (delNum === 0) {
+          // 删除 grid 后面的 row 都减 1
+          gridList.forEach((item) => {
+            if (item.row > delRow) {
+              item.row -= 1;
+            }
+          });
+        } else {
+          gridList.forEach((item) => {
+            if (item.row === delRow) {
+              item.width = `${Number(item.width.replace('fr', '')) + diff}fr`;
+            }
+          });
         }
-      };
+      }
     },
     computedColStyle(col) {
       let grid = col.grid_list;

+ 6 - 4
src/views/book/courseware/create/components/common/ModuleMixin.js

@@ -29,10 +29,6 @@ const mixin = {
       type: String,
       required: true,
     },
-    deleteComponent: {
-      type: Function,
-      required: true,
-    },
     componentMove: {
       type: Function,
       required: true,
@@ -98,6 +94,12 @@ const mixin = {
       this.$emit('showSetting', this.data.property, this.data.type, this.id);
     },
     /**
+     * @description 删除组件
+     */
+    deleteComponent() {
+      this.$emit('deleteComponent', this.id);
+    },
+    /**
      * @description 更新property属性
      * @param {String} type 类型
      * @param {Object} attr 属性

+ 5 - 1
src/views/book/courseware/create/components/question/select/Select.vue

@@ -13,7 +13,7 @@
           <span class="multilingual" @click="openMultilingual(i)">
             <SvgIcon icon-class="multilingual" class-name="multilingual" width="12" height="12" />
           </span>
-          <span class="delete" @click="deleteOption">
+          <span class="delete" @click="deleteOption(i)">
             <SvgIcon icon-class="delete-2" width="12" height="12" />
           </span>
         </li>
@@ -124,6 +124,10 @@ export default {
      * @param {number} index 选项索引
      */
     deleteOption(index) {
+      if (this.data.option_list.length <= 2) {
+        this.$message.warning('请至少保留两个选项');
+        return;
+      }
       this.data.option_list.splice(index, 1);
     },
     handlerMindMap() {

+ 1 - 1
src/views/book/courseware/preview/components/select/SelectPreview.vue

@@ -6,7 +6,7 @@
     <div class="main">
       <ul
         class="option-list"
-        :style="{ flexDirection: data.property.arrange_type === arrangeTypeList[0].value ? 'column' : 'row' }"
+        :style="{ flexDirection: data.property.arrange_type === arrangeTypeList[0].value ? 'row' : 'column' }"
       >
         <li
           v-for="({ content, mark, multilingual, paragraph_list }, i) in data.option_list"

+ 47 - 13
src/views/personal_workbench/project/ProductionEditorialManage.vue

@@ -31,24 +31,27 @@
           <span class="title-cell">操作</span>
         </div>
         <div
-          v-for="{
-            id,
-            name,
-            deep,
-            producer_list,
-            is_leaf_chapter,
-            is_root,
-            is_inherited_producer,
-            is_inherited_auditor,
-            auditor_desc,
-            status_name,
-          } in node_list"
+          v-for="(
+            {
+              id,
+              name,
+              deep,
+              producer_list,
+              is_leaf_chapter,
+              is_root,
+              is_inherited_producer,
+              is_inherited_auditor,
+              auditor_desc,
+              status_name,
+            },
+            i
+          ) in node_list"
           :key="id"
           :class="['catalogue', { active: curSelectId === id }]"
           @click="selectActiveChapter(id, is_leaf_chapter === 'true')"
         >
           <div
-            :class="['chapter-title', 'nowrap-ellipsis', { courseware: is_leaf_chapter === 'true' }]"
+            :class="['chapter-title', 'nowrap-ellipsis', { courseware: isEnable(is_leaf_chapter) }]"
             :style="computedNameStyle(deep)"
             :title="name"
           >
@@ -70,6 +73,23 @@
           </div>
           <div class="status">{{ status_name }}</div>
           <div class="operator">
+            <template v-if="isEnable(is_leaf_chapter)">
+              <span
+                v-if="i > 0 && node_list[i - 1].is_leaf_chapter === 'true'"
+                class="link"
+                @click="moveChapterTreeNode(i, 0)"
+              >
+                上移
+              </span>
+              <span
+                v-if="i < node_list.length - 1 && node_list[i + 1].is_leaf_chapter === 'true'"
+                class="link"
+                @click="moveChapterTreeNode(i, 1)"
+              >
+                下移
+              </span>
+            </template>
+
             <span
               v-if="is_root !== 'true'"
               class="link"
@@ -142,6 +162,7 @@ import {
   ChapterSetProducer,
   ChapterUpdateChapter,
   ChapterUpdateCoursewareName,
+  ChapterMoveTreeNode,
 } from '@/api/book';
 import { isEnable } from '@/views/book/courseware/data/common';
 
@@ -369,6 +390,19 @@ export default {
           this.$message.error(`设置制作人失败: ${error}`);
         });
     },
+    /**
+     * 章节节点上移下移
+     * @param {number} i - 当前节点索引
+     * @param {number} dest_position - 目标位置 0上移 1下移
+     */
+    moveChapterTreeNode(i, dest_position) {
+      const id = this.node_list[i].id;
+      const dest_id = this.node_list[dest_position === 0 ? i - 1 : i + 1].id;
+      ChapterMoveTreeNode({ id, dest_id, dest_position }).then(() => {
+        this.getBookChapterStructExpandList();
+        this.$message.success('章节移动成功');
+      });
+    },
   },
 };
 </script>