瀏覽代碼

课程权重设置调整

zhangjie 1 年之前
父節點
當前提交
e0c826de30

+ 1 - 0
src/modules/base/components/course-simple/CourseEvaluationManage.vue

@@ -23,6 +23,7 @@
         <el-table-column class-name="action-column" label="操作" width="80px">
           <template slot-scope="scope">
             <el-button
+              v-if="scope.row.type === 'CUSTOM'"
               class="btn-danger"
               type="text"
               @click="toDelete(scope.row)"

+ 1 - 2
src/modules/base/components/course-simple/CourseTargetManage.vue

@@ -97,8 +97,7 @@ export default {
         if (confirm !== "confirm") return;
       }
       this.curRow = {
-        courseCode: this.course.courseCode,
-        examId: this.course.examId,
+        teachCourseId: this.course.id,
         disabledDimensionIds: this.getDisabledDimensionIds(),
       };
       this.$refs.ModifyCourseTarget.open();

+ 136 - 191
src/modules/base/components/course-simple/CourseWeightManage.vue

@@ -10,74 +10,73 @@
       <p>4.目标整体权重应等于100%,用于计算课程整体达成度。</p>
     </div>
     <div class="part-box part-box-pad">
-      <el-table :data="tableSetData">
+      <el-table :data="tableSetData" style="max-width: 1000px" border>
         <el-table-column
-          prop="evaluationName"
+          prop="courseTargetName"
           label="评价方式"
-          width="140"
-          fixed="left"
         ></el-table-column>
-        <el-table-column v-for="(target, tindex) in dataList" :key="tindex">
-          <template slot="header">
-            <el-row type="flex" align="middle">
-              <el-col :span="10" :offset="2">
-                {{ target.courseTargetName }}
-              </el-col>
-              <el-col :span="12">
-                <span style="margin-right: 5px">目标整体权重</span>
-                <el-input-number
-                  v-model="targetTotalWeight[target.courseTargetId]"
-                  class="width-50"
-                  size="small"
-                  :min="0"
-                  :max="100"
-                  :step="1"
-                  step-strictly
-                  :controls="false"
-                >
-                </el-input-number>
-                <span style="margin-left: 5px">%</span>
-              </el-col>
-            </el-row>
+        <el-table-column label="平时成绩" width="160">
+          <template slot-scope="scope">
+            <div v-if="scope.row.type === 'sum'">
+              <el-input-number
+                v-model="customRate"
+                class="width-80"
+                size="small"
+                :min="0"
+                :max="100"
+                :step="1"
+                step-strictly
+                :controls="false"
+              >
+              </el-input-number>
+              <span style="margin-left: 5px">%</span>
+            </div>
+            <el-button
+              v-else
+              type="text"
+              class="btn-act-primary"
+              @click="toEdit(scope.row)"
+            >
+              查看详情
+            </el-button>
+          </template>
+        </el-table-column>
+        <el-table-column label="期末成绩" width="160">
+          <template slot-scope="scope">
+            <div v-if="scope.row.type === 'sum'">
+              <el-input-number
+                v-model="defaultRate"
+                class="width-80"
+                size="small"
+                :min="0"
+                :max="100"
+                :step="1"
+                step-strictly
+                :controls="false"
+              >
+              </el-input-number>
+              <span style="margin-left: 5px">%</span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="目标整体权重" width="160">
+          <template slot-scope="scope">
+            <div v-if="scope.row.type === 'sum'">100%</div>
+            <div v-else>
+              <el-input-number
+                v-model="scope.row.totalWeight"
+                class="width-50"
+                size="small"
+                :min="0"
+                :max="100"
+                :step="1"
+                step-strictly
+                :controls="false"
+              >
+              </el-input-number>
+              <span style="margin-left: 5px">%</span>
+            </div>
           </template>
-          <el-table-column min-width="340">
-            <template slot="header">
-              <el-row>
-                <el-col :span="10" :offset="2"> 权重 </el-col>
-              </el-row>
-            </template>
-            <template slot-scope="scope">
-              <el-row type="flex" align="middle">
-                <el-col :span="2">
-                  <el-checkbox
-                    v-if="scope.$index !== endRowNo"
-                    v-model="scope.row.targets[tindex].enable"
-                    :disabled="scope.row.targets[tindex].disabled"
-                    @change="enableChange(scope.$index, tindex)"
-                  ></el-checkbox>
-                </el-col>
-                <el-col :span="10">
-                  <span v-if="scope.$index === endRowNo">
-                    {{ scope.row.targets[tindex].weight }}
-                  </span>
-                  <el-input-number
-                    v-else
-                    v-model="scope.row.targets[tindex].weight"
-                    :disabled="!scope.row.targets[tindex].enable"
-                    class="width-80"
-                    size="small"
-                    :min="0"
-                    :max="100"
-                    :step="1"
-                    step-strictly
-                    :controls="false"
-                  >
-                  </el-input-number>
-                  <span style="margin-left: 5px">%</span>
-                </el-col>
-              </el-row>
-            </template>
-          </el-table-column>
         </el-table-column>
       </el-table>
       <div class="text-center" style="margin: 20px 0">
@@ -107,9 +106,9 @@
         </el-table-column>
         <el-table-column label="考核/评价环节及目标分值">
           <el-table-column
-            v-for="(ename, eindex) in evaluationData"
-            :key="ename"
-            :label="ename"
+            v-for="(item, eindex) in evaluationList"
+            :key="item.evaluationId"
+            :label="item.evaluationName"
           >
             <template slot-scope="scope">
               {{
@@ -127,17 +126,26 @@
         </el-table-column>
       </el-table>
     </div>
+
+    <!-- ModifyTargetEvaluation -->
+    <modify-target-evaluation
+      ref="ModifyTargetEvaluation"
+      :sources="evaluationSources"
+      :target="curTarget"
+      @modified="targetEvaluationModified"
+    ></modify-target-evaluation>
   </div>
 </template>
 
 <script>
 import { courseWeightDetail, courseWeightSave } from "../../api";
-import { omit, pick } from "lodash";
 import { calcSum } from "@/plugins/utils";
 import { mapState, mapActions } from "vuex";
+import ModifyTargetEvaluation from "./ModifyTargetEvaluation.vue";
 
 export default {
   name: "course-weight-manage",
+  components: { ModifyTargetEvaluation },
   props: {
     course: {
       type: Object,
@@ -148,20 +156,20 @@ export default {
   },
   data() {
     return {
-      dataList: [],
       defaultRate: 0,
       customRate: 0,
       tableSetData: [],
-      targetTotalWeight: {},
-      evaluationData: [],
+      evaluationList: [],
       resultDataList: [],
+      curTarget: {},
+      evaluationSources: [],
       loading: false,
     };
   },
   computed: {
     ...mapState("base", ["cwStatus"]),
-    endRowNo() {
-      return this.tableSetData.length - 1;
+    lastNo() {
+      return this.evaluationList.length - 1;
     },
   },
   mounted() {
@@ -184,74 +192,53 @@ export default {
       });
       this.defaultRate = res.defaultRate;
       this.customRate = res.customRate;
-      this.dataList = res.submitForm || [];
-      this.transformData(this.dataList);
+      this.transformData(res.submitForm || []);
     },
     transformData(data) {
       if (!data || !data.length) return [];
 
-      const tableSetData = [];
-      const evaluationMap = {};
-      const targetTotalWeight = {};
-      data[0].evaluationList.forEach((item, index) => {
-        evaluationMap[item.evaluationName] = index;
+      this.evaluationList = data[0].evaluationList.slice(0, -1).map((item) => {
+        return { ...item };
       });
 
-      this.evaluationData = data[0].evaluationList.map(
-        (item) => item.evaluationName
-      );
-
-      data.forEach((target) => {
-        targetTotalWeight[target.courseTargetId] = target.totalWeight;
-        const targetData = {
-          ...omit(target, ["evaluationList"]),
-          totalWeight: target.totalWeight || 0,
-        };
+      this.tableSetData = data;
+      this.tableSetData.push({
+        type: "sum",
+        courseTargetId: "",
+        courseTargetName: "合计",
+      });
+    },
+    toEdit(row) {
+      this.curTarget = row;
+      this.updateEvaluationSources();
+      this.$refs.ModifyTargetEvaluation.open();
+    },
+    updateEvaluationSources() {
+      const unvalidEvaluations = [];
+      this.tableSetData.forEach((item) => {
+        if (item.type === "sum") return;
+        if (item.courseTargetId === this.curTarget.courseTargetId) return;
 
-        target.evaluationList.forEach((item) => {
-          const index = evaluationMap[item.evaluationName];
-          if (!tableSetData[index]) {
-            tableSetData[index] = {
-              evaluationName: item.evaluationName,
-              targets: [],
-            };
-          }
-          tableSetData[index].targets.push({
-            ...targetData,
-            enable: item.enable,
-            disabled: false,
-            weight: item.weight || 0,
-            targetScore: item.targetScore || 0,
-          });
-        });
+        unvalidEvaluations.push(
+          ...item.evaluationList
+            .filter((elem) => elem.enable)
+            .map((elem) => elem.evaluationId)
+        );
       });
 
-      this.targetTotalWeight = targetTotalWeight;
-      this.tableSetData = tableSetData;
-      this.updateSetDataDisabled();
+      this.evaluationSources = this.evaluationList.filter(
+        (item) => !unvalidEvaluations.includes(item.evaluationId)
+      );
     },
-    updateSetDataDisabled() {
-      this.tableSetData.forEach((item, tindex) => {
-        const hasTargetWeight = item.targets.some((t) => t.weight);
-        item.targets.forEach((t) => {
-          if (hasTargetWeight) {
-            t.disabled = !t.weight;
-          } else {
-            t.disabled = false;
-          }
-        });
+    targetEvaluationModified(data) {
+      const valDict = {};
+      data.forEach((item) => {
+        valDict[item.evaluationId] = item.weight;
       });
-    },
-    enableChange(rowIndex, tindex) {
-      const target = this.tableSetData[rowIndex].targets[tindex];
-      if (!target.enable) {
-        target.weight = 0;
-        target.targetScore = 0;
-      }
-      this.tableSetData[rowIndex].targets.forEach((item, dindex) => {
-        if (dindex !== tindex) {
-          item.disabled = target.enable;
-        }
+      this.curTarget.evaluationList.forEach((evaluation, index) => {
+        if (index === this.lastNo) return;
+        evaluation.enable = valDict[evaluation.evaluationId] !== undefined;
+        evaluation.weight = valDict[evaluation.evaluationId] || null;
       });
     },
     getEvaluationSumScore(evaluationList) {
@@ -269,56 +256,32 @@ export default {
         }
       }
     },
-    updateDataList() {
-      const evaluationData = {};
-      this.tableSetData.forEach((item) => {
-        item.targets.forEach((elem) => {
-          const key = `${item.evaluationName}_${elem.courseTargetId}`;
-          evaluationData[key] = pick(elem, ["enable", "weight", "targetScore"]);
-        });
-      });
-
-      this.dataList.forEach((target) => {
-        target.totalWeight = this.targetTotalWeight[target.courseTargetId];
-        target.evaluationList.forEach((item) => {
-          const key = `${item.evaluationName}_${target.courseTargetId}`;
-          Object.assign(item, evaluationData[key]);
-        });
-      });
-    },
     updateResultDataList() {
       // 更新合计
-      const tatolEvaluation = this.evaluationData.map(
-        (evaluationName, eindex) => {
-          const targetScore = calcSum(
-            this.dataList.map(
-              (item) => item.evaluationList[eindex].targetScore || 0
-            )
-          );
-          return {
-            evaluationName,
-            enable: true,
-            weight: null,
-            targetScore,
-          };
-        }
-      );
+      const dataList = this.tableSetData.slice(0, -1);
+      const tatolEvaluation = this.evaluationList.map((evaluation, eindex) => {
+        const targetScore = calcSum(
+          dataList.map((item) => item.evaluationList[eindex].targetScore || 0)
+        );
+        return {
+          evaluationName: evaluation.evaluationName,
+          enable: true,
+          weight: null,
+          targetScore,
+        };
+      });
       this.resultDataList = [
-        ...this.dataList,
+        ...dataList,
         {
           courseTargetId: "total",
           courseTargetName: "合计",
           degreeRequirement: "",
-          totalWeight: calcSum(
-            this.dataList.map((item) => item.totalWeight || 0)
-          ),
+          totalWeight: calcSum(dataList.map((item) => item.totalWeight || 0)),
           evaluationList: tatolEvaluation,
         },
       ];
     },
     checkDataList() {
-      if (!this.dataList.length) return;
-
       // 整体权重设置
       if (!this.customRate) {
         this.$message.error("请输入平均成绩权重");
@@ -333,43 +296,25 @@ export default {
         return;
       }
 
+      const dataList = this.tableSetData.slice(0, -1);
+
       // 目标整体权重
-      if (Object.values(this.targetTotalWeight).some((item) => !item)) {
+      if (dataList.some((item) => !item.totalWeight)) {
         this.$message.error("请设置所有目标的目标整体权重");
         return;
       }
       const totalWeight = calcSum(
-        Object.values(this.targetTotalWeight).map((item) => item || 0)
+        dataList.map((item) => item.totalWeight || 0)
       );
       if (totalWeight !== 100) {
         this.$message.error("目标整体权重合计不等于100%");
         return;
       }
 
-      // 目标权重统计
-      const unvalidTargets = [];
-      const tableData = this.tableSetData.slice(0, -1);
-      this.dataList.forEach((target, tindex) => {
-        const totalWeight = calcSum(
-          tableData.map((item) => item.targets[tindex].weight || 0)
-        );
-        if (totalWeight !== 100) {
-          unvalidTargets.push(target.courseTargetName);
-        }
-      });
-      if (unvalidTargets.length) {
-        this.$message.error(
-          `${unvalidTargets.join()}评价方式权重合计不等于100%`
-        );
-        return;
-      }
-
       return true;
     },
     async submit() {
       if (this.loading) return;
-      this.updateDataList();
-
       if (!this.checkDataList()) return;
 
       this.loading = true;
@@ -377,7 +322,7 @@ export default {
         teachCourseId: this.course.id,
         defaultRate: this.defaultRate,
         customRate: this.customRate,
-        submitForm: this.dataList,
+        submitForm: this.tableSetData.slice(0, -1),
       }).catch(() => {});
       this.loading = false;
       if (!res) return;

+ 140 - 0
src/modules/base/components/course-simple/ModifyTargetEvaluation.vue

@@ -0,0 +1,140 @@
+<template>
+  <el-dialog
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <el-form label-width="80px">
+      <el-form-item label="评价方式:">
+        <el-select
+          v-model="selectedEvaluationIds"
+          placeholder="请选择评卷方式"
+          class="width-full"
+          multiple
+          @change="selectChange"
+        >
+          <el-option
+            v-for="item in sources"
+            :key="item.evaluationId"
+            :value="item.evaluationId"
+            :label="item.evaluationName"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <el-table :data="dataList" border>
+      <el-table-column
+        prop="evaluationName"
+        label="评价方式"
+        min-width="120"
+      ></el-table-column>
+      <el-table-column prop="courseCode" label="权重" width="130">
+        <template slot-scope="scope">
+          <el-input-number
+            v-model="scope.row.weight"
+            class="width-80"
+            size="small"
+            :min="0"
+            :max="100"
+            :step="1"
+            step-strictly
+            :controls="false"
+          >
+          </el-input-number>
+          <span style="margin-left: 5px">%</span>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <div slot="footer">
+      <el-button type="primary" @click="submit">确认</el-button>
+      <el-button @click="cancel">取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { calcSum } from "@/plugins/utils";
+
+export default {
+  name: "modify-target-evaluation",
+  props: {
+    target: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    sources: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      dataList: [],
+      selectedEvaluationIds: [],
+    };
+  },
+  computed: {
+    title() {
+      return `${this.target.courseTargetName}平时成绩组成详情`;
+    },
+  },
+  methods: {
+    visibleChange() {
+      this.dataList = this.target.evaluationList
+        .slice(0, -1)
+        .filter((item) => item.enable)
+        .map((item) => {
+          return { ...item };
+        });
+      this.selectedEvaluationIds = this.dataList.map(
+        (item) => item.evaluationId
+      );
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    selectChange() {
+      const selectData = this.sources.filter((item) =>
+        this.selectedEvaluationIds.includes(item.evaluationId)
+      );
+      const count = selectData.length;
+      const weight = Math.floor(100 / count);
+      const sData = 100 % count;
+      this.dataList = selectData.map((item, index) => {
+        return {
+          ...item,
+          weight: index === count - 1 ? weight + sData : weight,
+        };
+      });
+    },
+    async submit() {
+      if (!this.dataList.length) {
+        this.$message.error("请选择评价方式");
+        return;
+      }
+      if (calcSum(this.dataList.map((item) => item.weight)) !== 100) {
+        this.$message.error("权重综合不等于100%");
+        return;
+      }
+
+      this.$emit("modified", this.dataList);
+      this.cancel();
+    },
+  },
+};
+</script>

+ 3 - 10
src/modules/base/components/course-simple/SelectDimensionDialog.vue

@@ -98,17 +98,10 @@ export default {
     };
   },
   watch: {
-    course: {
+    "course.teachCourseId": {
       immediate: true,
       handler(val, oldVal) {
-        if (!val) return;
-        if (
-          val.examId &&
-          val.courseCode &&
-          (!oldVal ||
-            oldVal.examId !== val.examId ||
-            oldVal.courseCode !== val.courseCode)
-        ) {
+        if (val !== oldVal) {
           this.getTree();
         }
       },
@@ -133,7 +126,7 @@ export default {
       });
     },
     async getTree() {
-      if (!this.course.examId || !this.course.courseCode) return;
+      if (!this.course.teachCourseId) return;
 
       const data = await courseDimensionTree({
         teachCourseId: this.course.teachCourseId,

+ 3 - 1
src/modules/course/components/NormalScoreManage.vue

@@ -116,7 +116,9 @@ export default {
     await this.toPage(1);
 
     if (this.dataList[0] && this.dataList[0].change) {
-      this.$notify.warning("课程管理评价方式发生变化,请重新导入平时成绩");
+      this.$notify.warning(
+        "评价方式与已保存不一致,请重新设置权重及导入新的平时成绩"
+      );
     }
   },
   methods: {