Przeglądaj źródła

目标达成度-成绩管理

zhangjie 1 rok temu
rodzic
commit
e392c69ea0

+ 4 - 0
src/constants/enumerate.js

@@ -239,6 +239,10 @@ export const IMPORT_TEMPLATE_TYPE = {
   examStatistics: "TEMPLATE_EXAM_STATISTICS",
   // 课程知识点
   courseProperty: "COURSE_PROPERTY",
+  // 平时成绩
+  normalScore: "NORMAL_SCORE",
+  // 期末成绩
+  endScore: "END_SCORE",
 };
 // 印刷 -------------->
 // 印刷计划状态

+ 126 - 0
src/constants/menus-data.js

@@ -5412,4 +5412,130 @@ export default [
     sequence: 8,
     enable: true,
   },
+  {
+    id: "700",
+    name: "目标达成度",
+    url: "target",
+    type: "MENU",
+    parentId: "-1",
+    sequence: 9,
+    enable: true,
+  },
+  {
+    id: "701",
+    name: "目标达成度",
+    url: "courseTarget",
+    type: "MENU",
+    parentId: "700",
+    sequence: 1,
+    enable: true,
+  },
+  {
+    id: "702",
+    name: "成绩管理",
+    url: "TargetScoreManage",
+    type: "MENU",
+    parentId: "701",
+    sequence: 1,
+    enable: true,
+    urls: [],
+    buttons: [
+      {
+        id: "263",
+        name: "查询",
+        url: "Select",
+        type: "BUTTON",
+        parentId: "702",
+        sequence: 1,
+        enable: true,
+      },
+    ],
+    links: [
+      {
+        id: "268",
+        name: "管理成绩",
+        url: "detail",
+        type: "LINK",
+        parentId: "702",
+        sequence: 1,
+        enable: true,
+      },
+    ],
+    lists: [
+      {
+        id: "271",
+        name: "列表",
+        url: "List",
+        type: "LIST",
+        parentId: "13",
+        sequence: 1,
+        enable: true,
+      },
+    ],
+    conditions: [
+      {
+        id: "270",
+        name: "查询条件",
+        url: "Condition",
+        type: "CONDITION",
+        parentId: "13",
+        sequence: 2,
+        enable: true,
+      },
+    ],
+  },
+  {
+    id: "703",
+    name: "报告管理",
+    url: "TargetReportManage",
+    type: "MENU",
+    parentId: "701",
+    sequence: 2,
+    enable: true,
+    urls: [],
+    buttons: [
+      {
+        id: "263",
+        name: "查询",
+        url: "Select",
+        type: "BUTTON",
+        parentId: "703",
+        sequence: 1,
+        enable: true,
+      },
+    ],
+    links: [
+      {
+        id: "268",
+        name: "管理成绩",
+        url: "detail",
+        type: "LINK",
+        parentId: "703",
+        sequence: 1,
+        enable: true,
+      },
+    ],
+    lists: [
+      {
+        id: "271",
+        name: "列表",
+        url: "List",
+        type: "LIST",
+        parentId: "13",
+        sequence: 1,
+        enable: true,
+      },
+    ],
+    conditions: [
+      {
+        id: "270",
+        name: "查询条件",
+        url: "Condition",
+        type: "CONDITION",
+        parentId: "13",
+        sequence: 2,
+        enable: true,
+      },
+    ],
+  },
 ];

+ 69 - 0
src/modules/course/api.js

@@ -0,0 +1,69 @@
+import { $postParam, $post } from "@/plugins/axios";
+
+// 成绩管理列表
+export const targetScoreListPage = (datas) => {
+  return $postParam("/api/admin/course/degree/score/list", datas);
+};
+// 成绩管理-平时成绩 ------------------->
+// 成绩管理-导入平时成绩-下载模版
+export const scoreTemplateDownload = (datas) => {
+  return $postParam("/api/admin/course/degree/score/template_download", datas, {
+    responseType: "blob",
+  });
+};
+// 成绩管理-平时成绩列表
+export const normalScoreListPage = (datas) => {
+  return $postParam("/api/admin/course/degree/score/normal/list", datas);
+};
+// 成绩管理-平时成绩编辑
+export const normalScoreEdit = (datas) => {
+  return $post("/api/admin/course/degree/score/normal/edit", datas);
+};
+// 成绩管理-平时成绩保存
+export const normalScoreSave = (datas) => {
+  return $post("/api/admin/course/degree/score/normal/save", datas);
+};
+// 成绩管理-平时成绩启用/禁用
+export const normalScoreEnable = ({ id, enable }) => {
+  return $postParam("/api/admin/course/degree/score/normal/enable", {
+    id,
+    enable,
+  });
+};
+// 成绩管理-期末成绩 ------------------->
+// 成绩管理-导入期末成绩-下载模版
+export const endScoreTemplateDownload = (datas) => {
+  return $postParam(
+    "/api/admin/course/degree/score/end_exam/template_download",
+    datas,
+    {
+      responseType: "blob",
+    }
+  );
+};
+// 成绩管理-期末成绩列表
+export const endScoreListPage = (datas) => {
+  return $postParam("/api/admin/course/degree/score/end_exam/list", datas);
+};
+// 成绩管理-期末成绩编辑
+export const endScoreEdit = (datas) => {
+  return $post("/api/admin/course/degree/score/end_exam/edit", datas);
+};
+// 成绩管理-期末成绩保存
+export const endScoreSave = (datas) => {
+  return $post("/api/admin/course/degree/score/end_exam/save", datas);
+};
+// 成绩管理-期末成绩启用/禁用
+export const endScoreEnable = ({ id, enable }) => {
+  return $postParam("/api/admin/course/degree/score/end_exam/enable", {
+    id,
+    enable,
+  });
+};
+// 成绩管理-保存试卷蓝图
+export const endScorePaperPositiveSave = (datas) => {
+  return $post(
+    "/api/admin/course/degree/score/end_exam/paper_positive/save",
+    datas
+  );
+};

+ 140 - 0
src/modules/course/components/EndScoreManage.vue

@@ -0,0 +1,140 @@
+<template>
+  <div class="end-score-manage">
+    <div class="part-box part-box-pad box-justify">
+      <p></p>
+      <div>
+        <el-button type="success" @click="toImport">导入期末成绩</el-button>
+        <el-button type="success" @click="toSetBlue">设置试卷蓝图</el-button>
+      </div>
+    </div>
+    <div class="part-box part-box-pad">
+      <el-table :data="dataList">
+        <el-table-column type="index" label="序号" width="70"></el-table-column>
+        <el-table-column prop="targetName" label="姓名"></el-table-column>
+        <el-table-column prop="targetName" label="学号"></el-table-column>
+        <el-table-column prop="targetValue" label="成绩"> </el-table-column>
+        <el-table-column prop="targetValue" label="成绩明细"> </el-table-column>
+        <el-table-column class-name="action-column" label="操作" width="120px">
+          <template slot-scope="scope">
+            <el-button
+              class="btn-primary"
+              type="text"
+              @click="toEdit(scope.row)"
+              >编辑</el-button
+            >
+            <el-button
+              :class="scope.row.enable ? 'btn-danger' : 'btn-primary'"
+              type="text"
+              @click="toEnable(scope.row)"
+              >{{ scope.row.enable ? "禁用" : "启用" }}</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- ModifyEndScore -->
+    <modify-end-score
+      ref="ModifyEndScore"
+      :instance="curRow"
+      @modified="getList"
+    ></modify-end-score>
+    <!-- ImportFile -->
+    <import-file
+      ref="ImportFile"
+      title="导入期末成绩"
+      :upload-url="uploadUrl"
+      :format="['xls', 'xlsx']"
+      :download-handle="() => downloadTemplate('endScore')"
+      :download-filename="dfilename"
+      :auto-upload="false"
+      @upload-success="getList"
+    ></import-file>
+  </div>
+</template>
+
+<script>
+import { endScoreListPage, endScoreEnable } from "../api";
+import ModifyEndScore from "./ModifyEndScore.vue";
+import ImportFile from "@/components/ImportFile.vue";
+
+export default {
+  name: "end-score-manage",
+  components: { ModifyEndScore, ImportFile },
+  props: {
+    course: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      filter: {
+        examId: "",
+        courseCode: "",
+        paperNumber: "",
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: [],
+      curRow: {},
+      // import
+      uploadUrl: "/api/admin/course/degree/score/end_exam/import",
+      dfilename: "期末成绩导入模板.xlsx",
+    };
+  },
+  mounted() {
+    this.filter = this.$objAssign(this.filter, this.course);
+    // this.toPage(1);
+  },
+  methods: {
+    async getList() {
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
+      };
+      const data = await endScoreListPage(datas);
+      this.dataList = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    toImport() {
+      this.$refs.ImportFile.open();
+    },
+    toSetBlue() {
+      // TODO:
+    },
+    toEdit(row) {
+      this.curRow = { ...row };
+      this.$refs.ModifyEndScore.open();
+      // TODO:
+    },
+    async toEnable(row) {
+      const action = row.enable ? "禁用" : "启用";
+      const confirm = await this.$confirm(
+        `确定要${action}考生【${row.examStudentName}】的成绩吗?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      const enable = !row.enable;
+      await endScoreEnable({
+        id: row.id,
+        enable,
+      });
+      row.enable = enable;
+      this.$message.success("操作成功!");
+    },
+  },
+};
+</script>

+ 13 - 0
src/modules/course/components/ModifyEndScore.vue

@@ -0,0 +1,13 @@
+<template>
+  <div class="ModifyEndScore">ModifyEndScore</div>
+</template>
+
+<script>
+export default {
+  name: "ModifyEndScore",
+  data() {
+    return {};
+  },
+  methods: {},
+};
+</script>

+ 13 - 0
src/modules/course/components/ModifyNormalScore.vue

@@ -0,0 +1,13 @@
+<template>
+  <div class="ModifyNormalScore">ModifyNormalScore</div>
+</template>
+
+<script>
+export default {
+  name: "ModifyNormalScore",
+  data() {
+    return {};
+  },
+  methods: {},
+};
+</script>

+ 137 - 0
src/modules/course/components/NormalScoreManage.vue

@@ -0,0 +1,137 @@
+<template>
+  <div class="normal-score-manage">
+    <div class="part-box part-box-pad box-justify">
+      <p>请根据权重管理里权重项导入相应的平时成绩</p>
+      <div>
+        <el-button type="success" @click="toImport">导入平时成绩</el-button>
+      </div>
+    </div>
+    <div class="part-box part-box-pad">
+      <el-table :data="dataList">
+        <el-table-column type="index" label="序号" width="70"></el-table-column>
+        <el-table-column prop="targetName" label="姓名"></el-table-column>
+        <el-table-column prop="targetName" label="学号"></el-table-column>
+        <el-table-column prop="targetValue" label="毕业要求指标">
+        </el-table-column>
+        <el-table-column class-name="action-column" label="操作" width="120px">
+          <template slot-scope="scope">
+            <el-button
+              class="btn-primary"
+              type="text"
+              @click="toEdit(scope.row)"
+              >编辑</el-button
+            >
+            <el-button
+              :class="scope.row.enable ? 'btn-danger' : 'btn-primary'"
+              type="text"
+              @click="toEnable(scope.row)"
+              >{{ scope.row.enable ? "禁用" : "启用" }}</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- ModifyNormalScore -->
+    <modify-normal-score
+      ref="ModifyNormalScore"
+      :instance="curRow"
+      @modified="getList"
+    ></modify-normal-score>
+    <!-- ImportFile -->
+    <import-file
+      ref="ImportFile"
+      title="导入平时成绩"
+      :upload-url="uploadUrl"
+      :format="['xls', 'xlsx']"
+      :download-handle="() => downloadTemplate('normalScore')"
+      :download-filename="dfilename"
+      :auto-upload="false"
+      @upload-success="getList"
+    ></import-file>
+  </div>
+</template>
+
+<script>
+import { normalScoreListPage, normalScoreEnable } from "../api";
+import ModifyNormalScore from "./ModifyNormalScore.vue";
+import ImportFile from "@/components/ImportFile.vue";
+
+export default {
+  name: "normal-score-manage",
+  components: { ModifyNormalScore, ImportFile },
+  props: {
+    course: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      filter: {
+        examId: "",
+        courseCode: "",
+        paperNumber: "",
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: [],
+      curRow: {},
+      // import
+      uploadUrl: "/api/admin/course/degree/score/import",
+      dfilename: "平时成绩导入模板.xlsx",
+    };
+  },
+  mounted() {
+    this.filter = this.$objAssign(this.filter, this.course);
+    // this.toPage(1);
+  },
+  methods: {
+    async getList() {
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
+      };
+      const data = await normalScoreListPage(datas);
+      this.dataList = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    toImport() {
+      // TODO:
+      this.$refs.ImportFile.open();
+    },
+    toEdit(row) {
+      this.curRow = { ...row };
+      this.$refs.ModifyNormalScore.open();
+      // TODO:
+    },
+    async toEnable(row) {
+      const action = row.enable ? "禁用" : "启用";
+      const confirm = await this.$confirm(
+        `确定要${action}考生【${row.examStudentName}】的成绩吗?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      const enable = !row.enable;
+      await normalScoreEnable({
+        id: row.id,
+        enable,
+      });
+      row.enable = enable;
+      this.$message.success("操作成功!");
+    },
+  },
+};
+</script>

+ 82 - 0
src/modules/course/components/TargetScoreDetail.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="target-score-detail">
+    <el-dialog
+      class="page-dialog"
+      :visible.sync="modalIsShow"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      fullscreen
+    >
+      <div slot="title">
+        成绩管理<span class="color-gray ml-2"
+          >{{ course.courseName }}({{ course.courseCode }})</span
+        >
+      </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" :course="course"></component>
+      </div>
+
+      <div slot="footer"></div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import NormalScoreManage from "./NormalScoreManage.vue";
+import EndScoreManage from "./EndScoreManage.vue";
+
+export default {
+  name: "target-score-detail",
+  components: {
+    NormalScoreManage,
+    EndScoreManage,
+  },
+  props: {
+    course: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      curTab: "NormalScoreManage",
+      tabs: [
+        {
+          name: "平时成绩管理",
+          val: "NormalScoreManage",
+        },
+        {
+          name: "期末成绩管理",
+          val: "EndScoreManage",
+        },
+      ],
+    };
+  },
+  methods: {
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    selectMenu(tab) {
+      this.curTab = tab;
+    },
+  },
+};
+</script>

+ 15 - 0
src/modules/course/router.js

@@ -0,0 +1,15 @@
+import TargetScoreManage from "./views/TargetScoreManage.vue";
+import TargetReportManage from "./views/TargetReportManage.vue";
+
+export default [
+  {
+    path: "/course/target-score-manage",
+    name: "TargetScoreManage",
+    component: TargetScoreManage,
+  },
+  {
+    path: "/course/target-report-manage",
+    name: "TargetReportManage",
+    component: TargetReportManage,
+  },
+];

+ 121 - 0
src/modules/course/views/TargetReportManage.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="target-report-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')">
+          <secp-select
+            v-model="filter"
+            defaultSelectExam
+            @exam-default="search"
+          ></secp-select>
+        </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 label="课程(代码)">
+          <template slot-scope="scope">
+            {{ scope.row.courseName | defaultFieldFilter }}({{
+              scope.row.courseCode | defaultFieldFilter
+            }})
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="paperNumber"
+          label="试卷编码"
+          min-width="200"
+        ></el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          width="140"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <el-button
+              v-if="checkPrivilege('link', 'preview')"
+              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>
+  </div>
+</template>
+
+<script>
+import { targetScoreListPage } from "../api";
+
+export default {
+  name: "target-report-manage",
+  data() {
+    return {
+      filter: {
+        semesterId: "",
+        examId: "",
+        courseCode: "",
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: [],
+      curRow: {},
+    };
+  },
+  methods: {
+    async getList() {
+      if (!this.checkPrivilege("list", "list")) return;
+
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
+      };
+      const data = await targetScoreListPage(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;
+    },
+  },
+};
+</script>

+ 134 - 0
src/modules/course/views/TargetScoreManage.vue

@@ -0,0 +1,134 @@
+<template>
+  <div class="target-score-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')">
+          <secp-select
+            v-model="filter"
+            defaultSelectExam
+            @exam-default="search"
+          ></secp-select>
+        </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 label="课程(代码)">
+          <template slot-scope="scope">
+            {{ scope.row.courseName | defaultFieldFilter }}({{
+              scope.row.courseCode | defaultFieldFilter
+            }})
+          </template>
+        </el-table-column>
+        <el-table-column prop="paperNumber" label="试卷编码"></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>
+    <!-- TargetScoreDetail -->
+    <target-score-detail
+      ref="TargetScoreDetail"
+      :course="curRow"
+    ></target-score-detail>
+  </div>
+</template>
+
+<script>
+import { targetScoreListPage } from "../api";
+import TargetScoreDetail from "../components/TargetScoreDetail.vue";
+
+export default {
+  name: "target-score-manage",
+  components: { TargetScoreDetail },
+  data() {
+    return {
+      filter: {
+        semesterId: "",
+        examId: "",
+        courseCode: "",
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: [
+        {
+          id: 2, //主键
+          examId: 2, //考试id
+          courseCode: "科目编码", //科目编码
+          courseName: "科目名称", //科目名称
+          paperNumber: "试卷编号", //试卷编号
+          paperType: "A", //试卷类型
+        },
+      ],
+      curRow: {},
+    };
+  },
+  methods: {
+    async getList() {
+      if (!this.checkPrivilege("list", "list")) return;
+
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
+      };
+      const data = await targetScoreListPage(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.TargetScoreDetail.open();
+    },
+  },
+};
+</script>

+ 2 - 0
src/router.js

@@ -13,6 +13,7 @@ import print from "./modules/print/router";
 import stmms from "./modules/stmms/router";
 import analysis from "./modules/analysis/router";
 import mark from "./modules/mark/router";
+import course from "./modules/course/router";
 // card part
 import card from "./modules/card/router";
 // admin
@@ -66,6 +67,7 @@ let router = new Router({
         ...stmms,
         ...analysis,
         ...mark,
+        ...course,
       ],
     },
     { ...login },