|
@@ -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;
|