Ver código fonte

feat: 培养方案中间

zhangjie 1 ano atrás
pai
commit
2533eee261
24 arquivos alterados com 1436 adições e 32 exclusões
  1. 14 0
      src/constants/enumerate.js
  2. 1 0
      src/modules/login/views/Login.vue
  3. 59 15
      src/modules/target/api.js
  4. 45 0
      src/modules/target/components/course-outline/CourseOutlineBase.vue
  5. 204 0
      src/modules/target/components/course-outline/CourseOutlineKnowledge.vue
  6. 141 0
      src/modules/target/components/course-outline/CourseOutlineTarget.vue
  7. 86 0
      src/modules/target/components/course-outline/DetailCourseOutline.vue
  8. 166 0
      src/modules/target/components/course-outline/ModifyCourseOutline.vue
  9. 131 0
      src/modules/target/components/course-outline/ModifyCourseOutlineKnowledge.vue
  10. 229 0
      src/modules/target/components/course-outline/ModifyCourseOutlineTarget.vue
  11. 101 0
      src/modules/target/components/course-outline/ModifyCourseOutlineTargetPredict.vue
  12. 1 1
      src/modules/target/components/training-plan/DetailTrainingPlan.vue
  13. 1 1
      src/modules/target/components/training-plan/ModifyTrainingPlan.vue
  14. 4 4
      src/modules/target/components/training-plan/ModifyTrainingPlanRequirementPredict.vue
  15. 2 2
      src/modules/target/components/training-plan/ModifyTrainingPlanTarget.vue
  16. 1 1
      src/modules/target/components/training-plan/TrainingPlanBase.vue
  17. 0 1
      src/modules/target/components/training-plan/TrainingPlanCourse.vue
  18. 2 2
      src/modules/target/components/training-plan/TrainingPlanCourseMatrix.vue
  19. 4 0
      src/modules/target/components/training-plan/TrainingPlanMatrix.vue
  20. 15 2
      src/modules/target/components/training-plan/TrainingPlanTarget.vue
  21. 216 0
      src/modules/target/views/CourseOutlineManage.vue
  22. 3 3
      src/modules/target/views/TrainingPlanManage.vue
  23. 8 0
      src/plugins/filters.js
  24. 2 0
      src/router.js

+ 14 - 0
src/constants/enumerate.js

@@ -389,3 +389,17 @@ export const SCORE_POLICY_TYPE = {
   MAX: "最高分",
   MIN: "最低分",
 };
+
+// target
+export const EVALUATION_MODE = {
+  THEORY_EXAMINATION: "理论考试类",
+  EXAMINE: "考查类",
+  COURSE_DESIGN: "课程设计类",
+  GRADUATE_DESIGN: "毕业设计类",
+};
+export const COURSE_TYPE = {
+  ENGINEERING_BASIC: "工程基础类课程",
+  MAJOR_BASIC: "专业基础类课程",
+  MAJOR: "专业类课程",
+  ENGINEERING_PRACTICE_AND_GRADUATE_DESIGN: "工程实践与毕业设计(论文)",
+};

+ 1 - 0
src/modules/login/views/Login.vue

@@ -32,6 +32,7 @@
             placeholder="请输入你的密码"
             name="password"
             clearable
+            show-password
           >
           </el-input>
         </el-form-item>

+ 59 - 15
src/modules/target/api.js

@@ -2,52 +2,59 @@ import { $postParam, $post } from "@/plugins/axios";
 
 // 培养方案管理 ------------------->
 export const trainingPlanListPage = (datas) => {
-  return $postParam("/admin/obe/culture/program/page", datas);
+  return $postParam("/api/admin/obe/culture/program/page", datas);
 };
 export const deleteTrainingPlan = (id) => {
-  return $postParam("/admin/obe/culture/program/remove", { id });
+  return $postParam("/api/admin/obe/culture/program/remove", { id });
 };
 export const copyTrainingPlan = (id) => {
-  return $postParam("/admin/obe/culture/program/copy", { id });
+  return $postParam("/api/admin/obe/culture/program/copy", { id });
 };
 export const updateTrainingPlan = (datas) => {
-  return $post("/admin/obe/culture/program/save", datas);
+  return $post("/api/admin/obe/culture/program/save", datas);
+};
+export const updateTrainingPlanDescription = (datas) => {
+  return $post("/api/admin/obe/culture/program/description/save", datas);
 };
 
 // 培养方案管理-培养目标 ------------------->
 export const trainingPlanTargetListPage = (datas) => {
-  return $postParam("/admin/obe/culture/program/target/list", datas);
+  return $postParam("/api/admin/obe/culture/program/target/list", datas);
 };
 export const deleteTrainingPlanTarget = (id) => {
-  return $postParam("/admin/obe/culture/program/target/remove", { id });
+  return $postParam("/api/admin/obe/culture/program/target/remove", { id });
 };
 export const updateTrainingPlanTarget = (datas) => {
-  return $post("/admin/obe/culture/program/target/save", datas);
+  return $post("/api/admin/obe/culture/program/target/save", datas);
 };
 
 // 培养方案管理-毕业要求 ------------------->
 export const trainingPlanRequirementListPage = (datas) => {
-  return $postParam("/admin/obe/culture/program/requirement/list", datas);
+  return $postParam("/api/admin/obe/culture/program/requirement/list", datas);
 };
 export const addTrainingPlanRequirementNode = (id) => {
-  return $postParam("/admin/obe/culture/program/requirement/node_add", { id });
+  return $postParam("/api/admin/obe/culture/program/requirement/node_add", {
+    id,
+  });
 };
 export const deleteTrainingPlanRequirementNode = (id) => {
-  return $postParam("/admin/obe/culture/program/requirement/remove", { id });
+  return $postParam("/api/admin/obe/culture/program/requirement/remove", {
+    id,
+  });
 };
 export const updateTrainingPlanRequirement = (datas) => {
-  return $post("/admin/obe/culture/program/requirement/save", datas);
+  return $post("/api/admin/obe/culture/program/requirement/save", datas);
 };
 export const updateTrainingPlanRequirementPredict = (datas) => {
-  return $post("/api/admin/basic/professional/save", datas);
+  return $post("/api/admin/obe/culture/program/requirement/expect/save", datas);
 };
 
 // 培养方案管理-培养目标与毕业要求关系矩阵 ------------------->
 export const trainingPlanMatrixListPage = (datas) => {
-  return $postParam("/admin/obe/culture/program/target/matrix/get", datas);
+  return $postParam("/api/admin/obe/culture/program/target/matrix/get", datas);
 };
 export const updateRrainingPlanMatrix = (datas) => {
-  return $post("/admin/obe/culture/program/target/matrix/save", datas);
+  return $post("/api/admin/obe/culture/program/target/matrix/save", datas);
 };
 
 // 培养方案管理-课程体系 ------------------->
@@ -61,7 +68,7 @@ export const sortRrainingPlanCourse = (datas) => {
   return $post("/api/admin/obe/culture/program/course/sort", datas);
 };
 export const trainingPlanCourseQueryList = (datas) => {
-  return $post("/admin/obe/culture/program/course/query_list", datas);
+  return $postParam("/api/admin/obe/culture/program/course/query_list", datas);
 };
 export const trainingPlanCourseSave = (datas) => {
   return $post("/api/admin/obe/culture/program/course/save", datas);
@@ -76,3 +83,40 @@ export const trainingPlanCourseMatrixSave = (datas) => {
     silence: true,
   });
 };
+
+// 课程大纲管理 ------------------->
+export const courseOutlineListPage = (datas) => {
+  return $postParam("/api/admin/obe/course_outline/page", datas);
+};
+export const deleteCourseOutline = (id) => {
+  return $postParam("/api/admin/obe/course_outline/delete", { id });
+};
+export const updateCourseOutline = (datas) => {
+  return $post("/api/admin/obe/course_outline/save", datas);
+};
+// 课程大纲管理-课程目标 ------------------->
+export const courseOutlineTargetListPage = (datas) => {
+  return $postParam("/api/admin/obe/course_target/list", datas);
+};
+export const deleteCourseOutlineTarget = (id) => {
+  return $postParam("/api/admin/obe/culture/program/target/remove", { id });
+};
+export const updateCourseOutlineTarget = (datas) => {
+  return $post("/api/admin/obe/culture/program/target/save", datas);
+};
+export const updateCourseOutlineTargetPredict = (datas) => {
+  return $post("/api/admin/basic/professional/save", datas);
+};
+// 课程大纲管理-知识点 ------------------->
+export const courseOutlineKnowledgeListPage = (datas) => {
+  return $postParam("/api/admin/obe/culture/program/course/list", datas);
+};
+export const deleteCourseOutlineKnowledge = (id) => {
+  return $post("/api/admin/obe/culture/program/course/remove", { id });
+};
+export const sortCourseOutlineKnowledge = (datas) => {
+  return $post("/api/admin/obe/culture/program/course/sort", datas);
+};
+export const updateCourseOutlineKnowledge = (datas) => {
+  return $post("/api/admin/basic/professional/save", datas);
+};

+ 45 - 0
src/modules/target/components/course-outline/CourseOutlineBase.vue

@@ -0,0 +1,45 @@
+<template>
+  <div class="course-outline-base part-box part-box-pad">
+    <el-descriptions title="课程大纲" :column="1" size="medium">
+      <el-descriptions-item label="课程大纲名称">
+        {{ rowData.outlineName }}
+      </el-descriptions-item>
+      <el-descriptions-item label="课程名称">
+        {{ rowData.professionalName }}
+      </el-descriptions-item>
+      <el-descriptions-item label="学分">
+        {{ rowData.credit }}
+      </el-descriptions-item>
+      <el-descriptions-item label="考核方式">
+        {{ rowData.evaluationMode | evaluationModeFilter }}
+      </el-descriptions-item>
+      <el-descriptions-item label="课程类别">
+        {{ rowData.courseType | courseTypeFilter }}
+      </el-descriptions-item>
+      <el-descriptions-item label="修读学期">
+        {{ rowData.semesterName }}
+      </el-descriptions-item>
+      <el-descriptions-item label="所属培养方案">
+        {{ rowData.cultureProgramName }}
+      </el-descriptions-item>
+    </el-descriptions>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "course-outline-base",
+  props: {
+    rowData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {};
+  },
+  methods: {},
+};
+</script>

+ 204 - 0
src/modules/target/components/course-outline/CourseOutlineKnowledge.vue

@@ -0,0 +1,204 @@
+<template>
+  <div class="course-outline-knowledge">
+    <div class="part-box part-box-pad">
+      <div class="box-justify mb-2">
+        <div></div>
+        <div>
+          <el-button type="primary" @click="toAdd">新增知识点</el-button>
+        </div>
+      </div>
+      <el-table
+        ref="TableList"
+        :data="dataList"
+        row-key="id"
+        default-expand-all
+      >
+        <el-table-column label="知识点"> </el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          width="140"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <el-button
+              class="btn-primary"
+              type="text"
+              @click="toEdit(scope.row, 'up')"
+              >编辑</el-button
+            >
+            <el-button
+              class="btn-danger"
+              type="text"
+              @click="toDelete(scope.row)"
+              >删除</el-button
+            >
+            <el-button
+              v-if="checkMoveValid(scope.row, 'up')"
+              class="btn-primary"
+              type="text"
+              @click="toMove(scope.row, 'up')"
+              >上移</el-button
+            >
+            <el-button
+              v-if="checkMoveValid(scope.row, 'down')"
+              class="btn-primary"
+              type="text"
+              @click="toMove(scope.row, 'down')"
+              >下移</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- ModifyCourseOutlineKnowledge -->
+    <modify-course-outline-knowledge
+      ref="ModifyCourseOutlineKnowledge"
+      :instance="curRow"
+      :main-options="mainOptions"
+      @modified="getList"
+    ></modify-course-outline-knowledge>
+  </div>
+</template>
+
+<script>
+import {
+  courseOutlineKnowledgeListPage,
+  deleteCourseOutlineKnowledge,
+  sortCourseOutlineKnowledge,
+} from "../../api";
+
+import ModifyCourseOutlineKnowledge from "./ModifyCourseOutlineKnowledge.vue";
+
+export default {
+  name: "course-outline-knowledge",
+  components: {
+    ModifyCourseOutlineKnowledge,
+  },
+  props: {
+    rowData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      dataList: [],
+      curRow: {},
+      mainOptions: [],
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    async getList() {
+      const data = await courseOutlineKnowledgeListPage({
+        cultureProgramId: this.rowData.id,
+      });
+      this.dataList = data || [];
+      this.mainOptions = this.dataList.map((item) => {
+        return {
+          id: item.id,
+          name: item.name,
+        };
+      });
+    },
+    toAdd() {
+      this.curRow = {};
+      this.$refs.ModifyCourseOutlineKnowledge.open();
+    },
+    toEdit(row) {
+      this.curRow = row;
+      this.$refs.ModifyCourseOutlineKnowledge.open();
+    },
+    exchangeSortNumber(row1, row2) {
+      const sortNum = row1.sortNum;
+      row1.sortNum = row2.sortNum;
+      row2.sortNum = sortNum;
+    },
+    checkMoveValid(row, type) {
+      if (row.children) {
+        const rowIndex = this.dataList.findIndex((item) => item.id === row.id);
+        if (type === "up") {
+          return rowIndex !== 0;
+        } else {
+          return rowIndex !== this.dataList.length - 1;
+        }
+      } else {
+        let row = {};
+        let rowIndex = 0;
+        this.dataList.forEach((item) => {
+          item.children.forEach((elem, index) => {
+            if (elem.id === row.id) {
+              row = item;
+              rowIndex = index;
+            }
+          });
+        });
+        if (type === "up") {
+          return rowIndex !== 0;
+        } else {
+          return rowIndex !== row.children.length - 1;
+        }
+      }
+    },
+    toMove(row, type) {
+      if (row.children) {
+        const rowIndex = this.dataList.findIndex((item) => item.id === row.id);
+        this.toMoveRow(this.dataList, rowIndex, type);
+      } else {
+        let row = {};
+        let rowIndex = 0;
+        this.dataList.forEach((item) => {
+          item.children.forEach((elem, index) => {
+            if (elem.id === row.id) {
+              row = item;
+              rowIndex = index;
+            }
+          });
+        });
+        this.toMoveRow(row.children, rowIndex, type);
+      }
+    },
+    async toMoveRow(dataList, rowIndex, type) {
+      const row1 = dataList[rowIndex];
+      const row2 =
+        type === "up" ? dataList[rowIndex - 1] : dataList[rowIndex + 1];
+
+      this.exchangeSortNumber(row1, row2);
+
+      const datas = dataList.map((item, index) => {
+        return {
+          id: item.id,
+          sortNum: item.sortNum,
+        };
+      });
+
+      const res = await sortCourseOutlineKnowledge(datas).catch(() => {
+        this.exchangeSortNumber(row1, row2);
+      });
+      if (!res) return;
+
+      this.dataList.sort((a, b) => a.sortNum - b.sortNum);
+    },
+    async toDelete(row) {
+      const confirm = await this.$confirm(
+        `确定要删除知识点【${row.courseName}】吗?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      await deleteCourseOutlineKnowledge(row.id);
+      this.$message.success("删除成功!");
+      this.getList();
+    },
+  },
+};
+</script>

+ 141 - 0
src/modules/target/components/course-outline/CourseOutlineTarget.vue

@@ -0,0 +1,141 @@
+<template>
+  <div class="course-outline-target">
+    <div class="part-box part-box-pad">
+      <div class="box-justify mb-2">
+        <div></div>
+        <div>
+          <el-button type="primary" icon="el-icon-add" @click="toAdd"
+            >新增课程目标</el-button
+          >
+          <el-button type="primary" icon="el-icon-add" @click="toPredict"
+            >预期值</el-button
+          >
+        </div>
+      </div>
+      <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="课程目标" width="160">
+        </el-table-column>
+        <el-table-column prop="name" label="预期值" width="160">
+        </el-table-column>
+        <el-table-column prop="detail" label="内容" min-width="300">
+        </el-table-column>
+        <el-table-column prop="dimensionList" label="指标点">
+          <template slot-scope="scope">
+            <p v-for="item in scope.row.dimensionList" :key="item.id">
+              {{ item.name }}({{ item.code }})
+            </p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          width="120"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <el-button
+              class="btn-primary"
+              type="text"
+              @click="toEdit(scope.row)"
+              >编辑</el-button
+            >
+            <el-button
+              class="btn-danger"
+              type="text"
+              @click="toDelete(scope.row)"
+              >删除</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- ModifyCourseOutlineTarget -->
+    <modify-course-outline-target
+      ref="ModifyCourseOutlineTarget"
+      :instance="curRow"
+      @modified="getList"
+    ></modify-course-outline-target>
+    <!-- ModifyCourseOutlineTargetPredict -->
+    <modify-course-outline-target-predict
+      ref="ModifyCourseOutlineTargetPredict"
+      :instance="curRow"
+      @modified="getList"
+    ></modify-course-outline-target-predict>
+  </div>
+</template>
+
+<script>
+import {
+  courseOutlineTargetListPage,
+  deleteCourseOutlineTarget,
+} from "../../api";
+import ModifyCourseOutlineTarget from "./ModifyCourseOutlineTarget.vue";
+import ModifyCourseOutlineTargetPredict from "./ModifyCourseOutlineTargetPredict.vue";
+
+export default {
+  name: "course-outline-target",
+  components: { ModifyCourseOutlineTarget, ModifyCourseOutlineTargetPredict },
+  props: {
+    rowData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalForm: {
+        description: "",
+      },
+      dataList: [],
+      curRow: {},
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    async getList() {
+      const datas = {
+        cultureProgramId: this.rowData.id,
+      };
+      const data = await courseOutlineTargetListPage(datas);
+      this.dataList = data || [];
+    },
+    toAdd() {
+      this.curRow = { cultureProgramId: this.rowData.id };
+      this.$refs.ModifyCourseOutlineTarget.open();
+    },
+    toPredict() {
+      this.curRow = { cultureProgramId: this.rowData.id };
+      this.$refs.ModifyCourseOutlineTargetPredict.open();
+    },
+    toEdit(row) {
+      this.curRow = row;
+      this.$refs.ModifyCourseOutlineTarget.open();
+    },
+    async toDelete(row) {
+      const confirm = await this.$confirm(
+        `确定要删除培养目标【${row.name}】吗?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      await deleteCourseOutlineTarget(row.id);
+      this.$message.success("删除成功!");
+      this.deletePageLastItem();
+    },
+  },
+};
+</script>

+ 86 - 0
src/modules/target/components/course-outline/DetailCourseOutline.vue

@@ -0,0 +1,86 @@
+<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 CourseOutlineBase from "./CourseOutlineBase.vue";
+import CourseOutlineTarget from "./CourseOutlineTarget.vue";
+import CourseOutlineKnowledge from "./CourseOutlineKnowledge.vue";
+
+export default {
+  name: "detail-course-outline",
+  components: {
+    CourseOutlineBase,
+    CourseOutlineTarget,
+    CourseOutlineKnowledge,
+  },
+  props: {
+    rowData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      curTab: "CourseOutlineBase",
+      tabs: [
+        {
+          name: "基本信息",
+          val: "CourseOutlineBase",
+        },
+        {
+          name: "培养目标",
+          val: "CourseOutlineTarget",
+        },
+        {
+          name: "知识点",
+          val: "CourseOutlineKnowledge",
+        },
+      ],
+    };
+  },
+  methods: {
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    selectMenu(tab) {
+      this.curTab = tab;
+    },
+    closeHandle() {
+      this.curTab = "CourseOutlineBase";
+    },
+  },
+};
+</script>

+ 166 - 0
src/modules/target/components/course-outline/ModifyCourseOutline.vue

@@ -0,0 +1,166 @@
+<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
+      ref="modalFormComp"
+      :model="modalForm"
+      :key="modalForm.id"
+      :rules="rules"
+      label-width="100px"
+    >
+      <el-form-item prop="name" label="课程大纲名称:">
+        <el-input
+          v-model.trim="modalForm.name"
+          placeholder="课程大纲名称"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="courseId" label="课程:">
+        <course-select
+          v-model="modalForm.courseId"
+          placeholder="课程"
+        ></course-select>
+      </el-form-item>
+      <el-form-item prop="evaluationMode" label="考核方式:">
+        <el-select
+          v-model="modalForm.evaluationMode"
+          placeholder="请选择"
+          clearable
+        >
+          <el-option
+            v-for="(val, key) in EVALUATION_MODE"
+            :key="key"
+            :value="key"
+            :label="val"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="courseType" label="课程类别:">
+        <el-select
+          v-model="modalForm.courseType"
+          placeholder="请选择"
+          clearable
+        >
+          <el-option
+            v-for="(val, key) in COURSE_TYPE"
+            :key="key"
+            :value="key"
+            :label="val"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="semesterId" label="修读学期:">
+        <semester-select
+          v-model="modalForm.semesterId"
+          placeholder="修读学期"
+          :org-id="userOrgId"
+        ></semester-select>
+      </el-form-item>
+      <el-form-item prop="cultureProgramId" label="所属专业:">
+        <professional-select
+          v-model="modalForm.cultureProgramId"
+          placeholder="所属专业"
+          :org-id="userOrgId"
+        ></professional-select>
+      </el-form-item>
+    </el-form>
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button @click="cancel">取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { updateCourseOutline } from "../../api";
+import { EVALUATION_MODE, COURSE_TYPE } from "@/constants/enumerate";
+
+const initModalForm = {
+  id: null,
+  name: "",
+  courseId: "",
+  evaluationMode: "",
+  courseType: "",
+  cultureProgramId: "",
+};
+
+export default {
+  name: "modify-course-outline",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      EVALUATION_MODE,
+      COURSE_TYPE,
+      modalForm: { ...initModalForm },
+      rules: {
+        name: [
+          { required: true, message: "请输入课程大纲名称", trigger: "change" },
+          {
+            message: "课程大纲名称不能超过30个字",
+            max: 30,
+            trigger: "change",
+          },
+        ],
+        professionalId: [
+          { required: true, message: "请选择专业", trigger: "change" },
+        ],
+      },
+    };
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "课程大纲";
+    },
+  },
+  methods: {
+    visibleChange() {
+      this.modalForm = this.$objAssign(initModalForm, this.instance);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const data = await updateCourseOutline(this.modalForm).catch(() => {});
+      this.isSubmit = false;
+
+      if (!data) return;
+
+      this.$message.success("修改成功!");
+      this.$emit("modified");
+      this.cancel();
+    },
+  },
+};
+</script>

+ 131 - 0
src/modules/target/components/course-outline/ModifyCourseOutlineKnowledge.vue

@@ -0,0 +1,131 @@
+<template>
+  <el-dialog
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="600px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :key="modalForm.id"
+      :rules="rules"
+      label-width="120px"
+    >
+      <el-form-item label="所属知识点:">
+        <el-select
+          v-model="modalForm.parentId"
+          placeholder="请选择"
+          filterable
+          clearable
+        >
+          <el-option
+            v-for="item in mainOptions"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="name" label="知识点名称:">
+        <el-input
+          v-model.trim="modalForm.name"
+          placeholder="知识点名称"
+          clearable
+        ></el-input>
+      </el-form-item>
+    </el-form>
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button @click="cancel">取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { updateCourseOutlineKnowledge } from "../../api";
+
+const initModalForm = {
+  id: null,
+  parentId: "",
+  name: "",
+};
+
+export default {
+  name: "modify-course-outline-knowledge",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    mainOptions: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: { ...initModalForm },
+      rules: {
+        name: [
+          { required: true, message: "请输入知识点名称", trigger: "change" },
+          {
+            message: "知识点名称不能超过30个字",
+            max: 30,
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "知识点";
+    },
+  },
+  methods: {
+    visibleChange() {
+      this.modalForm = this.$objAssign(initModalForm, this.instance);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const data = await updateCourseOutlineKnowledge(this.modalForm).catch(
+        () => {}
+      );
+      this.isSubmit = false;
+
+      if (!data) return;
+
+      this.$message.success("修改成功!");
+      this.$emit("modified");
+      this.cancel();
+    },
+  },
+};
+</script>

+ 229 - 0
src/modules/target/components/course-outline/ModifyCourseOutlineTarget.vue

@@ -0,0 +1,229 @@
+<template>
+  <div>
+    <el-dialog
+      class="modify-course-outline-target"
+      :visible.sync="modalIsShow"
+      :title="title"
+      top="10vh"
+      width="600px"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      @open="visibleChange"
+    >
+      <el-form
+        ref="modalFormComp"
+        :model="modalForm"
+        :rules="rules"
+        :key="modalForm.id"
+        label-width="100px"
+      >
+        <el-form-item prop="targetName" label="课程目标名称:">
+          <el-input
+            v-model.trim="modalForm.targetName"
+            placeholder="请输入课程目标名称"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="dimensionIdList" label="毕业要求指标点:">
+          <el-button
+            type="text"
+            class="btn-act-primary"
+            icon="el-icon-circle-plus-outline"
+            @click="toSelectDimension"
+            >选择知识点</el-button
+          >
+          <el-table
+            v-if="dimensionList.length"
+            :data="dimensionList"
+            :show-header="false"
+            border
+          >
+            <el-table-column prop="name" label="知识点">
+              <template slot-scope="scope">
+                {{ scope.row.name }}({{ scope.row.code }})
+              </template>
+            </el-table-column>
+            <el-table-column
+              class-name="action-column"
+              label="操作"
+              width="40"
+              align="center"
+            >
+              <template slot-scope="scope">
+                <el-button
+                  type="text"
+                  class="btn-danger"
+                  icon="el-icon-error"
+                  @click="toDeleteDimension(scope.$index)"
+                >
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+        <el-form-item prop="degreeRequirement" label="目标分解详情:">
+          <el-input
+            v-model="modalForm.degreeRequirement"
+            placeholder="请输入目标分解详情"
+            type="textarea"
+            :autosize="{ minRows: 2, maxRows: 6 }"
+            :maxlength="999"
+            resize="none"
+            show-word-limit
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button type="primary" :disabled="isSubmit" @click="submit"
+          >确认</el-button
+        >
+        <el-button @click="cancel">取消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- SelectDimensionDialog -->
+    <select-dimension-dialog
+      ref="SelectDimensionDialog"
+      :course="{ teachCourseId: instance.teachCourseId }"
+      :selected-data="modalForm.dimensionIdList"
+      :disabled-data="instance.disabledDimensionIds"
+      @confirm="dimensionSelected"
+      @enforce-close="enforceClose"
+    ></select-dimension-dialog>
+  </div>
+</template>
+
+<script>
+import { updateCourseOutlineTarget } from "../../api";
+import SelectDimensionDialog from "../../../base/components/course-simple/SelectDimensionDialog.vue";
+
+const initModalForm = {
+  id: null,
+  teachCourseId: "",
+  targetName: "",
+  degreeRequirement: "",
+  dimensionIdList: [],
+};
+
+export default {
+  name: "modify-course-outline-target",
+  components: { SelectDimensionDialog },
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "课程目标";
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: { ...initModalForm },
+      dimensionList: [],
+      rules: {
+        targetName: [
+          {
+            required: true,
+            message: "请输入课程目标名称",
+            trigger: "change",
+          },
+          {
+            max: 30,
+            message: "课程目标名称不能超过30个字",
+            trigger: "change",
+          },
+        ],
+        dimensionIdList: [
+          {
+            validator: (rule, value, callback) => {
+              if (value && value.length) {
+                return callback();
+              }
+              return callback(new Error("请选择毕业要求指标点"));
+            },
+          },
+        ],
+        degreeRequirement: [
+          {
+            required: false,
+            max: 999,
+            message: "目标分解详情不能超过999个字",
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    initData(val) {
+      this.modalForm = this.$objAssign(initModalForm, val);
+      if (val.dimensionList) {
+        this.dimensionList = [...val.dimensionList];
+        this.updateDimensionIds();
+      } else {
+        this.dimensionList = [];
+        this.modalForm.dimensionIdList = [];
+      }
+    },
+    visibleChange() {
+      this.initData(this.instance);
+    },
+    enforceClose() {
+      this.modalIsShow = false;
+      this.$emit("enforce-close");
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    toSelectDimension() {
+      this.$refs.SelectDimensionDialog.open();
+    },
+    updateDimensionIds() {
+      this.modalForm.dimensionIdList = this.dimensionList.map(
+        (item) => item.id
+      );
+    },
+    dimensionSelected(dimensions) {
+      this.dimensionList = [...dimensions];
+      this.updateDimensionIds();
+      this.$refs.modalFormComp.validateField("dimensionIdList");
+    },
+    toDeleteDimension(index) {
+      this.dimensionList.splice(index, 1);
+      this.updateDimensionIds();
+      this.$refs.modalFormComp.validateField("dimensionIdList");
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const res = await updateCourseOutlineTarget(this.modalForm).catch(
+        () => {}
+      );
+      this.isSubmit = false;
+
+      if (!res) return;
+
+      this.$message.success(this.title + "成功!");
+      this.$emit("modified");
+      this.cancel();
+    },
+  },
+};
+</script>

+ 101 - 0
src/modules/target/components/course-outline/ModifyCourseOutlineTargetPredict.vue

@@ -0,0 +1,101 @@
+<template>
+  <el-dialog
+    :visible.sync="modalIsShow"
+    title="课程目标预期值"
+    top="10vh"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :key="modalForm.id"
+      :rules="rules"
+    >
+      <el-form-item prop="name" label="预期值:">
+        <el-input-number
+          v-model="modalForm.name"
+          :min="0.01"
+          :max="1"
+          :step="0.01"
+          step-strictly
+          :controls="false"
+        ></el-input-number>
+      </el-form-item>
+    </el-form>
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button @click="cancel">取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { updateCourseOutlineTargetPredict } from "../../api";
+
+const initModalForm = {
+  id: null,
+  name: "",
+};
+
+export default {
+  name: "modify-training-plan-requirement-predict",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: { ...initModalForm },
+      rules: {
+        name: [
+          {
+            required: true,
+            message: "请输入课程目标预期值",
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    visibleChange() {
+      this.modalForm = this.$objAssign(initModalForm, this.instance);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const data = await updateCourseOutlineTargetPredict(this.modalForm).catch(
+        () => {}
+      );
+      this.isSubmit = false;
+
+      if (!data) return;
+
+      this.$message.success("修改成功!");
+      this.$emit("modified");
+      this.cancel();
+    },
+  },
+};
+</script>

+ 1 - 1
src/modules/target/components/training-plan/DetailTrainingPlan.vue

@@ -57,7 +57,7 @@ export default {
   data() {
     return {
       modalIsShow: false,
-      curTab: "ProfessionalCourse",
+      curTab: "TrainingPlanBase",
       tabs: [
         {
           name: "基本信息",

+ 1 - 1
src/modules/target/components/training-plan/ModifyTrainingPlan.vue

@@ -14,7 +14,7 @@
       :model="modalForm"
       :key="modalForm.id"
       :rules="rules"
-      label-width="100px"
+      label-width="120px"
     >
       <el-form-item prop="name" label="培养方案名称:">
         <el-input

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

@@ -15,9 +15,9 @@
       :key="modalForm.id"
       :rules="rules"
     >
-      <el-form-item prop="name" label="毕业要求预期值:">
+      <el-form-item prop="expectValue" label="预期值:">
         <el-input-number
-          v-model="modalForm.name"
+          v-model="modalForm.expectValue"
           :min="0.01"
           :max="1"
           :step="0.01"
@@ -40,7 +40,7 @@ import { updateTrainingPlanRequirementPredict } from "../../api";
 
 const initModalForm = {
   id: null,
-  name: "",
+  expectValue: undefined,
 };
 
 export default {
@@ -59,7 +59,7 @@ export default {
       isSubmit: false,
       modalForm: { ...initModalForm },
       rules: {
-        name: [
+        expectValue: [
           {
             required: true,
             message: "请输入毕业要求预期值",

+ 2 - 2
src/modules/target/components/training-plan/ModifyTrainingPlanTarget.vue

@@ -3,7 +3,7 @@
     :visible.sync="modalIsShow"
     :title="title"
     top="10vh"
-    width="600px"
+    width="800px"
     :close-on-click-modal="false"
     :close-on-press-escape="false"
     append-to-body
@@ -14,7 +14,7 @@
       :model="modalForm"
       :key="modalForm.id"
       :rules="rules"
-      label-width="100px"
+      label-width="120px"
     >
       <el-form-item prop="name" label="培养目标名称:">
         <el-input

+ 1 - 1
src/modules/target/components/training-plan/TrainingPlanBase.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="training-plan-base part-box part-box-pad">
-    <el-descriptions title="培养方案" :column="1">
+    <el-descriptions title="培养方案" :column="1" size="medium">
       <el-descriptions-item label="培养方案名称">{{
         rowData.name
       }}</el-descriptions-item>

+ 0 - 1
src/modules/target/components/training-plan/TrainingPlanCourse.vue

@@ -50,7 +50,6 @@
 
     <!-- AddTrainingPlanCourse -->
     <add-training-plan-course
-      v-if="canEdit"
       ref="AddTrainingPlanCourse"
       :row-data="rowData"
       @modified="getList"

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

@@ -17,7 +17,7 @@
             {{ scope.row.courseName }}({{ scope.row.courseCode }})
           </template>
         </el-table-column>
-        <el-table-column lang="学分" width="60"></el-table-column>
+        <el-table-column label="学分" width="80"></el-table-column>
       </el-table-column>
       <el-table-column label="毕业要求" align="center">
         <template v-if="hasSubRequirements">
@@ -127,7 +127,7 @@ export default {
   methods: {
     async getList() {
       const res = await trainingPlanCourseMatrixDetail({
-        professionalId: this.rowData.id,
+        cultureProgramId: this.rowData.id,
       });
       const tableData = res || [];
       this.dataList = tableData.map((item, index) => {

+ 4 - 0
src/modules/target/components/training-plan/TrainingPlanMatrix.vue

@@ -51,6 +51,9 @@ export default {
       columns: [],
     };
   },
+  mounted() {
+    this.getList();
+  },
   methods: {
     async getList() {
       const datas = {
@@ -60,6 +63,7 @@ export default {
       if (!res || !res.length) return;
 
       this.columns = res[0].targetList.map((item) => item.name);
+      this.dataList = res;
     },
     async matrixChange() {
       const datas = this.dataList

+ 15 - 2
src/modules/target/components/training-plan/TrainingPlanTarget.vue

@@ -2,7 +2,7 @@
   <div class="training-plan-target">
     <div class="part-box part-box-pad">
       <el-form>
-        <el-form-item label="总体描述">
+        <el-form-item label="总体描述">
           <el-input
             v-model="modalForm.description"
             type="textarea"
@@ -12,6 +12,7 @@
             clearable
             maxlength="999"
             show-word-limit
+            @blur="descriptionChange"
           ></el-input>
         </el-form-item>
       </el-form>
@@ -72,12 +73,13 @@
 import {
   trainingPlanTargetListPage,
   deleteTrainingPlanTarget,
+  updateTrainingPlanDescription,
 } from "../../api";
 import ModifyTrainingPlanTarget from "./ModifyTrainingPlanTarget.vue";
 
 export default {
   name: "training-plan-target",
-  component: { ModifyTrainingPlanTarget },
+  components: { ModifyTrainingPlanTarget },
   props: {
     rowData: {
       type: Object,
@@ -91,8 +93,13 @@ export default {
       modalForm: {
         description: "",
       },
+      dataList: [],
+      curRow: {},
     };
   },
+  mounted() {
+    this.getList();
+  },
   methods: {
     async getList() {
       const datas = {
@@ -123,6 +130,12 @@ export default {
       this.$message.success("删除成功!");
       this.deletePageLastItem();
     },
+    async descriptionChange() {
+      await updateTrainingPlanDescription({
+        id: this.rowData.id,
+        description: this.modalForm.description,
+      });
+    },
   },
 };
 </script>

+ 216 - 0
src/modules/target/views/CourseOutlineManage.vue

@@ -0,0 +1,216 @@
+<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="专业:">
+            <professional-select
+              v-model="filter.professionalId"
+              placeholder="专业"
+              :org-id="userOrgId"
+            ></professional-select>
+          </el-form-item>
+          <el-form-item label="培养方案:">
+            <professional-select
+              v-model="filter.professionalId"
+              placeholder="培养方案"
+              :org-id="userOrgId"
+            ></professional-select>
+          </el-form-item>
+          <el-form-item label="课程:">
+            <course-select
+              v-model="filter.courseId"
+              placeholder="课程"
+            ></course-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 class="part-box-action">
+        <el-button
+          v-if="checkPrivilege('button', 'add')"
+          type="primary"
+          icon="el-icon-add"
+          @click="toAdd"
+          >新增</el-button
+        >
+      </div>
+    </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="outlineName" label="课程大纲"> </el-table-column>
+        <el-table-column prop="courseName" label="课程名称"> </el-table-column>
+        <el-table-column prop="credit" label="学分"> </el-table-column>
+        <el-table-column prop="evaluationMode" label="考核方式">
+          <span slot-scope="scope">
+            {{ scope.row.evaluationMode | evaluationModeFilter }}
+          </span>
+        </el-table-column>
+        <el-table-column prop="courseType" label="课程类别">
+          <span slot-scope="scope">
+            {{ scope.row.courseType | courseTypeFilter }}
+          </span>
+        </el-table-column>
+        <el-table-column prop="semesterName" label="修读学期">
+        </el-table-column>
+        <el-table-column prop="cultureProgramName" label="所属培养方案">
+        </el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          width="180"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <el-button
+              v-if="checkPrivilege('link', 'edit')"
+              class="btn-primary"
+              type="text"
+              @click="toEdit(scope.row)"
+              >编辑</el-button
+            >
+            <el-button
+              v-if="checkPrivilege('link', 'delete')"
+              class="btn-danger"
+              type="text"
+              @click="toDelete(scope.row)"
+              >删除</el-button
+            >
+            <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>
+    <!-- ModifyCourseOutline -->
+    <modify-course-outline
+      v-if="checkPrivilege('button', 'add')"
+      ref="ModifyCourseOutline"
+      :instance="curRow"
+      @modified="getList"
+    ></modify-course-outline>
+    <!-- DetailCourseOutline -->
+    <detail-course-outline
+      v-if="checkPrivilege('button', 'add')"
+      ref="DetailCourseOutline"
+      :row-data="curRow"
+      @modified="getList"
+    ></detail-course-outline>
+  </div>
+</template>
+
+<script>
+import { courseOutlineListPage, deleteCourseOutline } from "../api";
+import ModifyCourseOutline from "../components/course-outline/ModifyCourseOutline.vue";
+import DetailCourseOutline from "../components/course-outline/DetailCourseOutline.vue";
+
+export default {
+  name: "training-plan-manage",
+  components: { ModifyCourseOutline, DetailCourseOutline },
+  data() {
+    return {
+      filter: {
+        professionalId: "",
+        cultureProgramId: "",
+        courseId: "",
+        name: "",
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: [],
+      curRow: {},
+      userOrgId: this.$ls.get("orgId", ""),
+    };
+  },
+  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 courseOutlineListPage(datas);
+      this.dataList = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    search() {
+      this.toPage(1);
+    },
+    toAdd() {
+      this.curRow = {};
+      this.$refs.ModifyCourseOutline.open();
+    },
+    toEdit(row) {
+      this.curRow = row;
+      this.$refs.ModifyCourseOutline.open();
+    },
+    async toDelete(row) {
+      const confirm = await this.$confirm(
+        `确定要删除课程大纲【${row.name}】吗?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      await deleteCourseOutline(row.id);
+      this.$message.success("删除成功!");
+      this.deletePageLastItem();
+    },
+    toDetail(row) {
+      this.curRow = row;
+      this.$refs.DetailCourseOutline.open();
+    },
+  },
+};
+</script>

+ 3 - 3
src/modules/target/views/TrainingPlanManage.vue

@@ -92,7 +92,7 @@
               >删除</el-button
             >
             <el-button
-              v-if="checkPrivilege('link', 'detail')"
+              v-if="checkPrivilege('link', 'CultureProgramDetail')"
               class="btn-primary"
               type="text"
               @click="toDetail(scope.row)"
@@ -117,14 +117,14 @@
     </div>
     <!-- ModifyTrainingPlan -->
     <modify-training-plan
-      v-if="checkPrivilege('button', 'add')"
+      v-if="checkPrivilege('button', 'add') || checkPrivilege('link', 'edit')"
       ref="ModifyTrainingPlan"
       :instance="curRow"
       @modified="getList"
     ></modify-training-plan>
     <!-- DetailTrainingPlan -->
     <detail-training-plan
-      v-if="checkPrivilege('button', 'add')"
+      v-if="checkPrivilege('link', 'CultureProgramDetail')"
       ref="DetailTrainingPlan"
       :row-data="curRow"
       @modified="getList"

+ 8 - 0
src/plugins/filters.js

@@ -25,6 +25,8 @@ import {
   EXAM_NUMBER_STYLE,
   FLOW_TYPE,
   MARK_MODE_TYPE,
+  EVALUATION_MODE,
+  COURSE_TYPE,
 } from "../constants/enumerate";
 import { formatDate } from "../plugins/utils";
 
@@ -128,3 +130,9 @@ Vue.filter("examNumberStyleFilter", function (val) {
 Vue.filter("markModeTypeFilter", function (val) {
   return MARK_MODE_TYPE[val] || DEFAULT_FIELD;
 });
+Vue.filter("evaluationModeFilter", function (val) {
+  return EVALUATION_MODE[val] || DEFAULT_FIELD;
+});
+Vue.filter("courseTypeFilter", function (val) {
+  return COURSE_TYPE[val] || DEFAULT_FIELD;
+});

+ 2 - 0
src/router.js

@@ -14,6 +14,7 @@ import stmms from "./modules/stmms/router";
 import analysis from "./modules/analysis/router";
 import mark from "./modules/mark/router";
 import course from "./modules/course/router";
+import target from "./modules/target/router";
 // card part
 import card from "./modules/card/router";
 // admin
@@ -68,6 +69,7 @@ let router = new Router({
         ...analysis,
         ...mark,
         ...course,
+        ...target,
       ],
     },
     { ...login },