瀏覽代碼

feat: 毕业要求达成度统计

zhangjie 1 年之前
父節點
當前提交
21779fb83d

+ 11 - 0
src/modules/target/api.js

@@ -165,3 +165,14 @@ export const courseExamineWeightDetail = (datas) => {
 export const courseExamineWeightSave = (datas) => {
   return $post("/api/admin/obe/course_weight/save", datas);
 };
+
+// 毕业要求达成度统计 ------------------->
+export const requirementStatisticsListPage = (datas) => {
+  return $postParam("/api/admin/obe/course_outline/page", datas);
+};
+export const requirementStatisticsRadar = (id) => {
+  return $postParam("/api/admin/obe/course_outline/delete", { id });
+};
+export const requirementStatisticsDetail = (id) => {
+  return $postParam("/api/admin/obe/course_outline/delete", { id });
+};

+ 80 - 0
src/modules/target/components/requirement-statistics/DetailRequirementStatistics.vue

@@ -0,0 +1,80 @@
+<template>
+  <el-dialog
+    class="page-dialog"
+    :visible.sync="modalIsShow"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    fullscreen
+    @close="closeHandle"
+  >
+    <div slot="title">{{ rowData.name }}</div>
+    <div class="mb-4 tab-btns">
+      <el-button
+        v-for="tab in tabs"
+        :key="tab.val"
+        size="medium"
+        :type="curTab == tab.val ? 'primary' : 'default'"
+        @click="selectMenu(tab.val)"
+        >{{ tab.name }}
+      </el-button>
+    </div>
+
+    <div v-if="modalIsShow">
+      <component :is="curTab" :row-data="rowData"></component>
+    </div>
+
+    <div slot="footer"></div>
+  </el-dialog>
+</template>
+
+<script>
+import RequirementStatisticsRadar from "./RequirementStatisticsRadar.vue";
+import RequirementStatisticsStatement from "./RequirementStatisticsStatement.vue";
+
+export default {
+  name: "detail-requirement-statistics",
+  components: {
+    RequirementStatisticsRadar,
+    RequirementStatisticsStatement,
+  },
+  props: {
+    rowData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      curTab: "RequirementStatisticsRadar",
+      tabs: [
+        {
+          name: "毕业要求达成度雷达图",
+          val: "RequirementStatisticsRadar",
+        },
+        {
+          name: "毕业要求达成情况详细报表",
+          val: "RequirementStatisticsStatement",
+        },
+      ],
+    };
+  },
+  methods: {
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    selectMenu(tab) {
+      this.curTab = tab;
+    },
+    closeHandle() {
+      this.curTab = "RequirementStatisticsRadar";
+    },
+  },
+};
+</script>

+ 79 - 0
src/modules/target/components/requirement-statistics/RequirementStatisticsRadar.vue

@@ -0,0 +1,79 @@
+<template>
+  <div class="part-box part-box-pad">
+    <el-row type="flex" :gutter="20">
+      <el-col :span="12">
+        <v-chart v-if="chartOption" :option="chartOption"></v-chart>
+      </el-col>
+      <el-col :span="12">
+        <el-table :data="dataList">
+          <el-table-column label="毕业要求" min-width="200">
+            <template slot-scope="scope">
+              {{ scope.$index + 1 }}.{{ scope.row.name }}
+            </template>
+          </el-table-column>
+          <el-table-column label="预期值" prop="预期值"></el-table-column>
+          <el-table-column label="实际值" prop="预期值"></el-table-column>
+          <el-table-column label="评价结果" prop="预期值"></el-table-column>
+          <el-table-column class-name="action-column" label="操作" width="100">
+            <template slot-scope="scope">
+              <el-tooltip placement="left">
+                <div slot="content">
+                  <el-table :data="scope.row.details" border>
+                    <el-table-column
+                      label="毕业要求指标"
+                      prop=""
+                      width="120"
+                    ></el-table-column>
+                    <el-table-column
+                      label="达成值"
+                      prop=""
+                      width="80"
+                    ></el-table-column>
+                  </el-table>
+                </div>
+                <el-button
+                  class="btn-primary"
+                  type="text"
+                  @click="toDetail(scope.row)"
+                  >查看详情</el-button
+                >
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { requirementStatisticsRadar } from "../../api";
+
+export default {
+  name: "requirement-statistics-radar",
+  props: {
+    rowData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      dataList: [],
+      chartOption: null,
+    };
+  },
+  methods: {
+    async getDetail() {
+      const res = await requirementStatisticsRadar({
+        cultureProgramId: this.rowData.id,
+      });
+      this.dataList = res || [];
+      this.updateChartOption();
+    },
+    updateChartOption() {},
+  },
+};
+</script>

+ 143 - 0
src/modules/target/components/requirement-statistics/RequirementStatisticsStatement.vue

@@ -0,0 +1,143 @@
+<template>
+  <div class="part-box part-box-pad">
+    <el-table
+      :data="dataList"
+      border
+      :cell-style="cellStyleHandle"
+      :summary-method="getSummaries"
+      show-summary
+    >
+      <el-table-column label="课程信息" align="center">
+        <el-table-column label="课程名称(代码)" min-width="200">
+          <template slot-scope="scope">
+            {{ scope.row.courseName }}({{ scope.row.courseCode }})
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="学期"
+          prop="semesterName"
+          width="140"
+        ></el-table-column>
+        <el-table-column
+          label="学分"
+          prop="credit"
+          width="80"
+        ></el-table-column>
+      </el-table-column>
+      <el-table-column label="毕业要求" align="center">
+        <template v-if="hasSubRequirements">
+          <el-table-column
+            v-for="(column, cindex) in columns"
+            :key="cindex"
+            :label="column.name"
+            align="center"
+          >
+            <el-table-column
+              v-for="subr in column.subRequirements"
+              :key="subr.name"
+              align="center"
+              :prop="`${column.name}_${subr.name}`"
+            >
+              <template slot-scope="scope">
+                {{ scope.row[`${column.name}_${subr.name}`].value }}
+              </template>
+            </el-table-column>
+          </el-table-column>
+        </template>
+
+        <template v-else>
+          <el-table-column
+            v-for="(column, cindex) in columns"
+            :key="cindex"
+            :label="column.name"
+            align="center"
+            :prop="`${column.name}_null`"
+          >
+            <template slot-scope="scope">
+              <span>{{ scope.row[`${column.name}_null`].value }}</span>
+            </template>
+          </el-table-column>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import { requirementStatisticsDetail } from "../../api";
+
+export default {
+  name: "requirement-statistics-statement",
+  props: {
+    rowData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      dataList: [],
+      columns: [],
+      hasSubRequirements: false,
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    async getList() {
+      const res = await requirementStatisticsDetail({
+        cultureProgramId: this.rowData.id,
+      });
+      const tableData = res || [];
+      this.dataList = tableData.map((item, index) => {
+        if (!index) this.parseColumns(item.requirements);
+
+        const nitem = {
+          courseId: item.courseId,
+          courseCode: item.courseCode,
+          courseName: item.courseName,
+          canEdit: item.canEdit,
+        };
+        item.requirements.forEach((requirement) => {
+          requirement.subRequirements.forEach((subr) => {
+            nitem[`${requirement.name}_${subr.name + ""}`] = {
+              id: subr.id,
+              value: subr.scale || undefined,
+            };
+          });
+        });
+
+        return nitem;
+      });
+    },
+    parseColumns(requirements) {
+      this.hasSubRequirements = requirements.some(
+        (item) => item.subRequirements[0].name !== null
+      );
+      if (!this.hasSubRequirements) {
+        this.columns = requirements.map((item, index) => {
+          return { name: item.name, columnIndex: index + 1 };
+        });
+        return;
+      }
+
+      let cindex = 0;
+      this.columns = requirements.map((item) => {
+        return {
+          name: item.name,
+          subRequirements: item.subRequirements.map((subr) => {
+            return {
+              name: subr.name + "",
+              columnIndex: ++cindex,
+              content: subr.content,
+            };
+          }),
+        };
+      });
+    },
+  },
+};
+</script>

+ 4 - 3
src/modules/target/components/training-plan/TrainingPlanCourseMatrix.vue

@@ -158,7 +158,7 @@ export default {
           requirement.subRequirements.forEach((subr) => {
             nitem[`${requirement.name}_${subr.name + ""}`] = {
               id: subr.id,
-              value: subr.content || undefined,
+              value: subr.scale || undefined,
             };
           });
         });
@@ -185,6 +185,7 @@ export default {
             return {
               name: subr.name + "",
               columnIndex: ++cindex,
+              content: subr.content,
             };
           }),
         };
@@ -229,14 +230,14 @@ export default {
         saveData = this.dataList.map((item) => {
           return {
             id: item[key].id,
-            content: item[key].value,
+            scale: item[key].value,
           };
         });
       } else {
         saveData = [
           {
             id: row[key].id,
-            content: row[key].value,
+            scale: row[key].value,
           },
         ];
       }

+ 130 - 0
src/modules/target/views/RequirementStatistics.vue

@@ -0,0 +1,130 @@
+<template>
+  <div class="training-plan-manage">
+    <div class="part-box part-box-filter part-box-flex">
+      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
+        <template v-if="checkPrivilege('condition', 'condition')">
+          <el-form-item label="专业:">
+            <org-select v-model="filter.orgId" placeholder="学院"></org-select>
+          </el-form-item>
+          <el-form-item label="专业名称:">
+            <el-input
+              v-model.trim="filter.name"
+              placeholder="专业名称"
+              clearable
+            ></el-input>
+          </el-form-item>
+        </template>
+        <el-form-item label-width="0px">
+          <el-button
+            v-if="checkPrivilege('button', 'select')"
+            type="primary"
+            @click="search"
+            >查询</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <div class="part-box part-box-pad">
+      <el-table ref="TableList" :data="dataList">
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column prop="name" label="培养方案名称"> </el-table-column>
+        <el-table-column prop="professionalName" label="专业">
+        </el-table-column>
+        <el-table-column prop="targetCount" label="毕业要求达成值" width="120">
+        </el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          width="100"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <el-button
+              v-if="checkPrivilege('link', 'detail')"
+              class="btn-primary"
+              type="text"
+              @click="toDetail(scope.row)"
+              >查看详情</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="part-page">
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :pager-count="5"
+          :current-page="current"
+          :total="total"
+          :page-size="size"
+          @current-change="toPage"
+          @size-change="pageSizeChange"
+        >
+        </el-pagination>
+      </div>
+    </div>
+    <!-- DetailRequirementStatistics -->
+    <detail-requirement-statistics
+      v-if="checkPrivilege('link', 'detail')"
+      ref="DetailRequirementStatistics"
+      :row-data="curRow"
+    ></detail-requirement-statistics>
+  </div>
+</template>
+
+<script>
+import { trainingPlanListPage } from "../api";
+import DetailRequirementStatistics from "../components/requirement-statistics/DetailRequirementStatistics.vue";
+
+export default {
+  name: "training-plan-manage",
+  components: { DetailRequirementStatistics },
+  data() {
+    return {
+      filter: {
+        orgId: "",
+        professionalName: "",
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: [],
+      curRow: {},
+    };
+  },
+  mounted() {
+    this.toPage(1);
+  },
+  methods: {
+    async getList() {
+      if (!this.checkPrivilege("list", "list")) return;
+
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
+      };
+      const data = await trainingPlanListPage(datas);
+      this.dataList = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    search() {
+      this.toPage(1);
+    },
+    toDetail(row) {
+      this.curRow = row;
+      this.$refs.DetailRequirementStatistics.open();
+    },
+  },
+};
+</script>

+ 2 - 2
src/plugins/VueCharts.js

@@ -13,7 +13,7 @@ import {
   LineChart,
   // PieChart,
   // ScatterChart,
-  // RadarChart,
+  RadarChart,
   BoxplotChart,
 } from "echarts/charts";
 
@@ -34,7 +34,7 @@ use([
   LineChart,
   // PieChart,
   // ScatterChart,
-  // RadarChart,
+  RadarChart,
   BoxplotChart,
   GridComponent,
   TitleComponent,