Browse Source

fix:修复了一些bug

DingXiaoYu 4 years ago
parent
commit
645cd97105
2 changed files with 646 additions and 861 deletions
  1. 36 222
      src/views/CoursePage/tabs/GroupTab.vue
  2. 610 639
      src/views/ManagePage/ManagePage.vue

+ 36 - 222
src/views/CoursePage/tabs/GroupTab.vue

@@ -22,7 +22,7 @@
       <el-table-column label="组名">
         <template #default="scope">
         <span
-                :style="groupData && scope.row['groupVO'].id===groupData['groupVO'].id ? 'color: #67C23A':''">
+            :style="groupData && scope.row['groupVO'].id===groupData['groupVO'].id ? 'color: #67C23A':''">
           {{ scope.row["groupVO"].name }}
         </span>
         </template>
@@ -84,15 +84,8 @@
 </template>
 
 <script>
-  import {ElMessage, ElMessageBox} from "element-plus";
+import {ElMessage, ElMessageBox} from "element-plus";
 
-<<<<<<< HEAD
-  export default {
-    name: "GroupTab",
-    props: {
-      courseId: {
-        required: true,
-=======
 export default {
   name: "GroupTab",
   props: {
@@ -117,50 +110,11 @@ export default {
         id: null,
         maxSize: null,
         maxNameLen: null,
->>>>>>> efe3831aac9edd6d113ed30d273ebeb3776bb381
       },
-      teacherId: {
-        required: true,
-      },
-    },
-    data() {
-      return {
-        groupTableData: [],
-        groupData: null,
-
-        isRuleExisted: false,
-        ruleFormDialog: false,
-        maxNameLen:10,
-        ruleForm: {
-          dialogTitle: "制定组队规则",
-          courseVO: null,
-          id: null,
-          maxSize: null,
-          maxNameLen: null,
+      ruleFormRule: {
+        maxSize: {
+          required: true, message: "请选择小组最大成员人数", trigger: "change",
         },
-<<<<<<< HEAD
-        ruleFormRule: {
-          maxSize: {
-            required: true, message: "请选择小组最大成员人数", trigger: "change",
-          },
-          maxNameLen: {
-            required: true, message: "请选择组名最大长度", trigger: "change",
-          }
-        },
-        addMemberRule: {
-          phone: [{required: true, message: "手机号不能为空"},
-            {
-              type: "number",
-              message: "手机号格式不正确",
-              trigger: "blur",
-              transform(value) {
-                var phonereg = 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/;
-                if (!phonereg.test(value)) {
-                  return false;
-                } else {
-                  return Number(value);
-                }
-=======
         maxNameLen: {
           required: true, message: "请选择组名最大长度", trigger: "change",
         }
@@ -237,16 +191,16 @@ export default {
             maxNameLen: this.ruleForm.maxNameLen,
           };
           this.$apis.createGroupRule(RuleVO)
-            .then(res => {
-              if (res.data.code) {
-                ElMessage.error(res.data.message);
-              } else {
-                this.isRuleExisted = true;
-                this.ruleFormDialog = false;
-                this.$refs.ruleFormRef.resetFields();
-                ElMessage.success("创建规则成功");
-              }
-            });
+              .then(res => {
+                if (res.data.code) {
+                  ElMessage.error(res.data.message);
+                } else {
+                  this.isRuleExisted = true;
+                  this.ruleFormDialog = false;
+                  this.$refs.ruleFormRef.resetFields();
+                  ElMessage.success("创建规则成功");
+                }
+              });
         }
       });
     },
@@ -271,17 +225,17 @@ export default {
             name: this.createGroupForm.name,
           };
           this.$apis.createGroup(GroupVO)
-            .then(res => {
-              if (res.data.code) {
-                ElMessage.error(res.data.message);
-              } else {
-                this.groupData = res.data.data;
-                this.groupTableData.push(res.data.data);
-                this.createGroupDialog = false;
-                this.$refs.createGroupFormRef.resetFields();
-                ElMessage.success("创建队伍成功");
-              }
-            });
+              .then(res => {
+                if (res.data.code) {
+                  ElMessage.error(res.data.message);
+                } else {
+                  this.groupData = res.data.data;
+                  this.groupTableData.push(res.data.data);
+                  this.createGroupDialog = false;
+                  this.$refs.createGroupFormRef.resetFields();
+                  ElMessage.success("创建队伍成功");
+                }
+              });
         }
       });
     },
@@ -306,162 +260,22 @@ export default {
             courseId: _this.courseId,
           };
           this.$apis.sendInvitation(groupMemberVO)
-            .then(res => {
-              if (res.data.code) {
-                ElMessage.error(res.data.message);
-              } else {
-                ElMessage.success("已发送邀请,请等候其同意。");
->>>>>>> efe3831aac9edd6d113ed30d273ebeb3776bb381
-              }
-            }],
-        },
-
-        createGroupDialog: false,
-        createGroupForm: {
-          dialogTitle: "队伍信息",
-          courseId: null,
-          name: null,
-        },
-
-        addMemberDialog: false,
-        addMemberForm: {
-          dialogTitle: "组员信息",
-          phone: null,
-        },
-      };
-    },
-    computed: {
-      isCreator() {
-        return Number(this.teacherId) === Number(this.$store.state.user.id);
-      },
-    },
-    mounted() {
-      this.init();
-    },
-    methods: {
-      async init() {
-        const _this = this;
-        const ruleRes = (await _this.$apis.findGroupRule(_this.courseId)).data;
-        _this.isRuleExisted = !ruleRes.code;
-        if (_this.isRuleExisted) {
-          _this.maxNameLen=ruleRes.data.maxNameLen;
-          const groupsRes = (await _this.$apis.findAllGroupsByCourse(_this.courseId)).data;
-          if (!groupsRes.code) {
-            _this.groupTableData = groupsRes.data;
-          }
-          const groupRes = (await _this.$apis.findGroup(_this.courseId)).data;
-          if (!groupRes.code) {
-            _this.groupData = groupRes.data;
-          }
-        }
-      },
-
-      beforeRuleFormClose() {
-        const _this = this;
-        _this.ruleFormDialog = false;
-        _this.$refs.ruleFormRef.resetFields();
-      },
-
-      handleCreateRuleConfirm() {
-        this.$refs.ruleFormRef.validate((valid) => {
-          if (valid) {
-            let RuleVO = {
-              courseVO: {id: this.courseId},
-              maxSize: this.ruleForm.maxSize,
-              maxNameLen: this.ruleForm.maxNameLen,
-            };
-            this.$apis.createGroupRule(RuleVO)
-                    .then(res => {
-                      if (res.data.code) {
-                        ElMessage.error(res.data.message);
-                      } else {
-                        this.isRuleExisted = true;
-                        this.ruleFormDialog = false;
-                        this.$refs.ruleFormRef.resetFields();
-                        ElMessage.success("创建规则成功");
-                      }
-                    });
-          }
-        });
-      },
-
-      beforeGroupFormClose() {
-        this.createGroupDialog = false;
-        this.$refs.createGroupFormRef.resetFields();
-      },
-
-      handleCreateGroupConfirm() {
-        if (this.createGroupForm.name.length===0){
-          return ;
-        }
-        if (this.createGroupForm.name.length>this.maxNameLen){
-          this.createGroupForm.name="";
-          ElMessage.error("创建队伍失败!队伍名称长度不能超过"+this.maxNameLen+"!");
+              .then(res => {
+                if (res.data.code) {
+                  ElMessage.error(res.data.message);
+                } else {
+                  ElMessage.success("已发送邀请,请等候其同意。");
+                }
+              });
         }
-        this.$refs.createGroupFormRef.validate((valid) => {
-          if (valid) {
-            let GroupVO = {
-              courseId: this.courseId,
-              name: this.createGroupForm.name,
-            };
-            this.$apis.createGroup(GroupVO)
-                    .then(res => {
-                      if (res.data.code) {
-                        ElMessage.error(res.data.message);
-                      } else {
-                        this.groupData = res.data.data;
-                        this.groupTableData.push(res.data.data);
-                        this.createGroupDialog = false;
-                        this.$refs.createGroupFormRef.resetFields();
-                        ElMessage.success("创建队伍成功");
-                      }
-                    });
-          }
-        });
-      },
-
-      beforeGroupMemberFormClose() {
-        this.addMemberDialog = false;
-        this.$refs.addMemberFormRef.resetFields();
-      },
-
-      handleAddMemberConfirm() {
-        const _this = this;
-        this.$refs.addMemberFormRef.validate(async (valid) => {
-          if (valid) {
-            const userIdRes = (await _this.$apis.findUserIdByPhone(_this.addMemberForm.phone)).data;
-            if (userIdRes.code) {
-              ElMessage.error(userIdRes.message);
-              return;
-            }
-            let groupMemberVO = {
-              userId: userIdRes.data,
-              groupId: _this.groupData["groupVO"].id,
-              courseId: _this.courseId,
-            };
-            this.$apis.sendInvitation(groupMemberVO)
-                    .then(res => {
-                      if (res.data.code) {
-                        ElMessage.error(res.data.message);
-                      } else {
-                        ElMessage.success("已发送邀请,请等候其同意。");
-                      }
-                    });
-          }
-        });
-
-      },
+      });
 
     },
-<<<<<<< HEAD
-  };
-=======
 
   },
 };
->>>>>>> efe3831aac9edd6d113ed30d273ebeb3776bb381
 </script>
 
 <style scoped>
-  @import "tabs.css";
-</style>
+@import "tabs.css";
+</style>

+ 610 - 639
src/views/ManagePage/ManagePage.vue

@@ -2,7 +2,6 @@
   <el-row id="manage-page-body">
     <el-col :span="3">
       <el-card style="position: fixed;">
-<<<<<<< HEAD
         <el-menu default-active="1" @select="handleSelect">
           <el-menu-item index="0">
             <el-icon>
@@ -29,34 +28,6 @@
             <span style="padding-left: 20px">全部题目</span>
           </el-menu-item>
         </el-menu>
-=======
-      <el-menu default-active="1" @select="handleSelect">
-        <el-menu-item index="0">
-          <el-icon>
-            <Back/>
-          </el-icon>
-          <span style="padding-left: 20px">返回首页</span>
-        </el-menu-item>
-        <el-menu-item index="1">
-          <el-icon>
-            <Document/>
-          </el-icon>
-          <span style="padding-left: 20px">全部课程</span>
-        </el-menu-item>
-        <el-menu-item index="2">
-          <el-icon>
-            <DocumentChecked/>
-          </el-icon>
-          <span style="padding-left: 20px">全部测试</span>
-        </el-menu-item>
-        <el-menu-item index="3">
-          <el-icon>
-            <DocumentChecked/>
-          </el-icon>
-          <span style="padding-left: 20px">全部题目</span>
-        </el-menu-item>
-      </el-menu>
->>>>>>> efe3831aac9edd6d113ed30d273ebeb3776bb381
       </el-card>
     </el-col>
     <el-col :span="1"/>
@@ -70,10 +41,10 @@
             <div class="course-type-selector">
               <el-select v-model="courseType" class="m-2" placeholder="课程类型">
                 <el-option
-                        v-for="item in courseTypeOptions"
-                        :key="item.value"
-                        :label="item.label"
-                        :value="item.value"
+                    v-for="item in courseTypeOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
                 />
               </el-select>
               <el-button class="ml-16" plain type="primary"
@@ -182,9 +153,9 @@
           <el-table-column label="操作" width="200">
             <template #default="scope">
               <el-button
-                      type="primary"
-                      size="mini"
-                      @click="checkDetails(scope.row.id)"
+                  type="primary"
+                  size="mini"
+                  @click="checkDetails(scope.row.id)"
               >
                 详情
               </el-button>
@@ -192,12 +163,12 @@
           </el-table-column>
         </el-table>
         <el-pagination
-                background
-                layout="prev, pager, next"
-                :current-page="problemPageInfo.page"
-                :page-size="problemPageInfo.limit"
-                :total="problemPageInfo.total"
-                @current-change="changePage"
+            background
+            layout="prev, pager, next"
+            :current-page="problemPageInfo.page"
+            :page-size="problemPageInfo.limit"
+            :total="problemPageInfo.total"
+            @current-change="changePage"
         />
       </el-card>
     </el-col>
@@ -253,16 +224,16 @@
         </el-form-item>
         <el-form-item label="课程图片">
           <el-upload
-                  :before-upload="beforeUpload"
-                  :file-list="form.fileList"
-                  :http-request="httpRequest"
-                  :limit="1"
-                  :on-change="handleChange"
-                  :on-exceed="handleExceed"
-                  :on-remove="handleChange"
-                  action=""
-                  class="upload-demo"
-                  list-type="picture">
+              :before-upload="beforeUpload"
+              :file-list="form.fileList"
+              :http-request="httpRequest"
+              :limit="1"
+              :on-change="handleChange"
+              :on-exceed="handleExceed"
+              :on-remove="handleChange"
+              action=""
+              class="upload-demo"
+              list-type="picture">
             <el-button plain size="small" type="primary">点击上传</el-button>
           </el-upload>
         </el-form-item>
@@ -286,20 +257,20 @@
         <el-form-item label="测试种类" prop="type">
           <el-select v-model="examForm.examType" class="m-2" placeholder="请选择种类">
             <el-option
-                    v-for="item in examCategoryOptions"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
+                v-for="item in examCategoryOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
             />
           </el-select>
         </el-form-item>
         <el-form-item v-if="isCoder" label="所属课程" prop="course">
           <el-select v-model="examForm.course" class="m-2" placeholder="请选择课程">
             <el-option
-                    v-for="item in courseOptions"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
+                v-for="item in courseOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
             />
           </el-select>
         </el-form-item>
@@ -325,9 +296,9 @@
         <el-form-item v-if="$store.state.problem.cart.length">
           <el-collapse accordion>
             <el-collapse-item
-                    v-for="problem in $store.state.problem.cart"
-                    :key="problem.id"
-                    :name="problem.id"
+                v-for="problem in $store.state.problem.cart"
+                :key="problem.id"
+                :name="problem.id"
             >
               <template #title>
                 <span>{{ problem.name }}</span>
@@ -337,9 +308,9 @@
               <span class="problem-description">{{ problem.description }}</span>
               <div class="remove-button">
                 <el-button
-                        type="danger"
-                        size="mini"
-                        @click="$store.commit('removeProblem', problem)"
+                    type="danger"
+                    size="mini"
+                    @click="$store.commit('removeProblem', problem)"
                 >移除该题
                 </el-button
                 >
@@ -386,25 +357,25 @@
         <el-table-column label="操作" width="200">
           <template #default="scope">
             <el-button
-                    type="primary"
-                    size="mini"
-                    @click="checkDetails"
+                type="primary"
+                size="mini"
+                @click="checkDetails"
             >详情
             </el-button
             >
             <el-button
-                    v-if="removeEnable(scope.row)"
-                    type="danger"
-                    size="mini"
-                    @click="$store.commit('removeProblem', scope.row)"
+                v-if="removeEnable(scope.row)"
+                type="danger"
+                size="mini"
+                @click="$store.commit('removeProblem', scope.row)"
             >移出试题清单
             </el-button
             >
             <el-button
-                    v-else-if="addEnable(scope.row)"
-                    type="success"
-                    size="mini"
-                    @click="$store.commit('addProblem', scope.row)"
+                v-else-if="addEnable(scope.row)"
+                type="success"
+                size="mini"
+                @click="$store.commit('addProblem', scope.row)"
             >加入试题清单
             </el-button
             >
@@ -412,20 +383,20 @@
         </el-table-column>
       </el-table>
       <el-pagination
-              background
-              layout="prev, pager, next"
-              :total="problemPageInfo.total"
-              @current-change="changePage"
+          background
+          layout="prev, pager, next"
+          :total="problemPageInfo.total"
+          @current-change="changePage"
       />
     </el-dialog>
 
     <el-dialog v-model="uploadFileDialog" :width="1000">
       <el-form
-              ref="form"
-              :model="uploadFileForm"
-              label-width="80px"
-              :rules="uploadFileRules"
-              class="fill-card"
+          ref="form"
+          :model="uploadFileForm"
+          label-width="80px"
+          :rules="uploadFileRules"
+          class="fill-card"
       >
         <el-form-item label="题目名称" prop="name">
           <el-input v-model="uploadFileForm.name"></el-input>
@@ -433,29 +404,29 @@
         <el-form-item label="题目类型" prop="type">
           <el-select v-model="uploadFileForm.type" placeholder="请选择" value="">
             <el-option
-                    v-for="item in problemTypeOptions"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
+                v-for="item in problemTypeOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
             ></el-option>
           </el-select>
         </el-form-item>
         <el-form-item label="题目描述" prop="description">
           <el-input
-                  v-model="uploadFileForm.description"
-                  type="textarea"
-                  :rows="3"
+              v-model="uploadFileForm.description"
+              type="textarea"
+              :rows="3"
           ></el-input>
         </el-form-item>
         <el-form-item label="题目文件" prop="file">
           <el-upload
-                  ref="file"
-                  action=""
-                  :auto-upload="false"
-                  :limit="1"
-                  accept=".zip"
-                  :on-change="onFileChange"
-                  :on-remove="onFileChange"
+              ref="file"
+              action=""
+              :auto-upload="false"
+              :limit="1"
+              accept=".zip"
+              :on-change="onFileChange"
+              :on-remove="onFileChange"
           >
             <el-button size="small" type="primary">选取</el-button>
           </el-upload>
@@ -464,10 +435,10 @@
           <div class="form-button">
             <el-button type="danger" plain @click="resetForm">重置</el-button>
             <el-button
-                    type="primary"
-                    :loading="loading"
-                    :disabled="!uploadFiles.length"
-                    @click="submitProblem"
+                type="primary"
+                :loading="loading"
+                :disabled="!uploadFiles.length"
+                @click="submitProblem"
             >上传
             </el-button
             >
@@ -480,568 +451,568 @@
 </template>
 
 <script>
-  import CourseCard from "@/components/CourseCard";
-  import {ElMessage, ElMessageBox} from "element-plus";
-  import {Back, Document} from "@element-plus/icons-vue";
-  import TestCard from "@/components/TestCard";
-  import {debounce} from "@/utils/debounce";
-  import {formatTimestamp, problemTypeOptions, problemTypeToTagContent} from "@/utils/coder-utils";
-  import PageHeader from "@/components/PageHeader";
+import CourseCard from "@/components/CourseCard";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {Back, Document} from "@element-plus/icons-vue";
+import TestCard from "@/components/TestCard";
+import {debounce} from "@/utils/debounce";
+import {formatTimestamp, problemTypeOptions, problemTypeToTagContent} from "@/utils/coder-utils";
+import PageHeader from "@/components/PageHeader";
 
-  export default {
-    name: "ManagePage",
-    components: {
-      PageHeader,
-      TestCard,
-      Document,
-      Back,
-      CourseCard,
-    },
-    data() {
-      const validateName = async (rule, value, callback) => {
-        const res = await this.$apis.checkCourseNameUnique(this.form.id === null ? -1 : this.form.id, value);
-        const isNameUnique = res.data.data;
-        if (value === "") {
-          callback(new Error("请输入课程名称"));
-        } else if (!isNameUnique) {
-          callback(new Error("课程名称重复"));
-        } else {
-          callback();
-        }
-      };
-      const validateTime = (rule, value, callback) => {
-        if (this.form.courseTime[0] === null || this.form.courseTime[1] === null) {
-          callback(new Error("请选择课程始末时间"));
-        } else {
-          callback();
-        }
-      };
-      const validateCode = async (rule, value, callback) => {
-        const res = await this.$apis.checkCourseCodeUnique(this.form.id === null ? -1 : this.form.id, value);
-        const isCodeUnique = res.data.data;
-        if (value === "") {
-          callback(new Error("请输入课程邀请码"));
-        } else if (!isCodeUnique) {
-          callback(new Error("课程邀请码重复"));
-        } else {
-          callback();
-        }
-      };
-      const validatePrice = (rule, value, callback) => {
-        let regs = /^(\d+)(\.\d+)?$/;
-        if (regs.test(value)) {
-          callback();
-        } else {
-          callback(new Error("请正确输入课程价格"));
-        }
-      };
-      return {
-        activeIndex: "1",
-        activeTestPaneName: "eval",
-        dialogVisible: false,
-        dialogExamVisible: false,
-        dialogTitle: "新增课程",
-        dialogExamTitle: "新增测试",
-        form: {
-          id: null,
-          name: "",
-          year: "",
-          season: "",
-          description: "",
-          courseTime: [
-            null,
-            null,
-          ],
-          invitationCode: "",
-          price: "0",//input均会将Number类型转化成为字符串类型
-          moocUrl: null,
-          fileList: [],
-          imageUrl: null,
-          coderLink: false,
-          evalLink: false,
+export default {
+  name: "ManagePage",
+  components: {
+    PageHeader,
+    TestCard,
+    Document,
+    Back,
+    CourseCard,
+  },
+  data() {
+    const validateName = async (rule, value, callback) => {
+      const res = await this.$apis.checkCourseNameUnique(this.form.id === null ? -1 : this.form.id, value);
+      const isNameUnique = res.data.data;
+      if (value === "") {
+        callback(new Error("请输入课程名称"));
+      } else if (!isNameUnique) {
+        callback(new Error("课程名称重复"));
+      } else {
+        callback();
+      }
+    };
+    const validateTime = (rule, value, callback) => {
+      if (this.form.courseTime[0] === null || this.form.courseTime[1] === null) {
+        callback(new Error("请选择课程始末时间"));
+      } else {
+        callback();
+      }
+    };
+    const validateCode = async (rule, value, callback) => {
+      const res = await this.$apis.checkCourseCodeUnique(this.form.id === null ? -1 : this.form.id, value);
+      const isCodeUnique = res.data.data;
+      if (value === "") {
+        callback(new Error("请输入课程邀请码"));
+      } else if (!isCodeUnique) {
+        callback(new Error("课程邀请码重复"));
+      } else {
+        callback();
+      }
+    };
+    const validatePrice = (rule, value, callback) => {
+      let regs = /^(\d+)(\.\d+)?$/;
+      if (regs.test(value)) {
+        callback();
+      } else {
+        callback(new Error("请正确输入课程价格"));
+      }
+    };
+    return {
+      activeIndex: "1",
+      activeTestPaneName: "eval",
+      dialogVisible: false,
+      dialogExamVisible: false,
+      dialogTitle: "新增课程",
+      dialogExamTitle: "新增测试",
+      form: {
+        id: null,
+        name: "",
+        year: "",
+        season: "",
+        description: "",
+        courseTime: [
+          null,
+          null,
+        ],
+        invitationCode: "",
+        price: "0",//input均会将Number类型转化成为字符串类型
+        moocUrl: null,
+        fileList: [],
+        imageUrl: null,
+        coderLink: false,
+        evalLink: false,
+      },
+      examForm: {
+        examType: "coder",
+        course: "",
+        name: "",
+        range: [],
+        isCodeAnalysisNeeded: false,
+        isConsoleOutputShownForStu: false
+      },
+      formRules: {
+        name: {
+          required: true, validator: validateName, trigger: "blur",
         },
-        examForm: {
-          examType: "coder",
-          course: "",
-          name: "",
-          range: [],
-          isCodeAnalysisNeeded: false,
-          isConsoleOutputShownForStu: false
+        year: {
+          required: true, message: "请选择年份", trigger: "blur",
         },
-        formRules: {
-          name: {
-            required: true, validator: validateName, trigger: "blur",
-          },
-          year: {
-            required: true, message: "请选择年份", trigger: "blur",
-          },
-          season: {
-            required: true, message: "请选择季节", trigger: "blur",
-          },
-          description: {
-            required: true, message: "请输入课程简介", trigger: "blur",
-          },
-          time: {
-            required: true, validator: validateTime, trigger: "blur",
-          },
-          invitationCode: {
-            required: true, validator: validateCode, trigger: "blur",
-          },
-          price: {
-            required: true, validator: validatePrice, trigger: "blur",
-          },
+        season: {
+          required: true, message: "请选择季节", trigger: "blur",
         },
-        examFormRules: {
-          // type: {
-          //   required: true, message: "请选择测试种类",
-          // },
-          name: {
-            required: true, message: "请输入测试名称", trigger: "blur",
-          },
-          course: {
-            required: true, message: "请选择测试名称",
-          },
-          range: {
-            required: true, message: "请选择测试时间段", trigger: "blur",
-          }
+        description: {
+          required: true, message: "请输入课程简介", trigger: "blur",
         },
-        coderCourses: [],
-        courseOptions: [],
-
-        switchDisabled: false,
-        switchExamDisabled: false,
-        //
-        myCourseList: [],
-        courseType: "all",
-        courseTypeOptions: [
-          {value: "all", label: "全部课程"},
-          {value: "pending", label: "未开始"},
-          {value: "start", label: "正在进行"},
-          {value: "end", label: "已结束"},
-        ],
-        evalExamList: [],
-        coderExamList: [],
-        examType: "all",
-        examTypeOptions: [
-          {value: "all", label: "全部测试"},
-          {value: "pending", label: "未开始"},
-          {value: "start", label: "正在进行"},
-          {value: "end", label: "已结束"},
-        ],
-        examCategoryOptions: [
-          {value: "eval", label: "评测题"},
-          {value: "coder", label: "代码题"},
-        ],
-        dialogProblemVisible: false,
-        dialogProblemPage: 1,
-        dialogProblemLimit: 10,
-        dialogProblemTypeStr: "",
-        dialogProblemName: "",
-        problemList: [],
-        problemPageInfo: {},
-
-        //上传Coder代码题
-        uploadFileDialog: false,
-        uploadFileForm: {
-          name: "",
-          type: "",
-          description: ""
+        time: {
+          required: true, validator: validateTime, trigger: "blur",
         },
-        uploadFileRules: {
-          name: [{required: true, message: "请输入题目名称", trigger: "blur"}],
-          type: [{required: true, message: "请选择题目类型", trigger: "blur"}],
-          description: [
-            {required: true, message: "请输入题目描述", trigger: "blur"}
-          ]
+        invitationCode: {
+          required: true, validator: validateCode, trigger: "blur",
+        },
+        price: {
+          required: true, validator: validatePrice, trigger: "blur",
         },
-        uploadFiles: [],
-        loading: false,
-      };
-    },
-    computed: {
-      filterCourses: function () {
-        if (this.courseType === "all") return this.myCourseList;
-        if (this.courseType === "pending") return this.myCourseList.filter(i => this.state(i) === "NOT_STARTED");
-        if (this.courseType === "start") return this.myCourseList.filter(i => this.state(i) === "RUNNING");
-        if (this.courseType === "end") return this.myCourseList.filter(i => this.state(i) === "FINISHED");
-        else return this.myCourseList;
       },
-      isCoder() {
-        return this.examForm.examType === "coder";
+      examFormRules: {
+        // type: {
+        //   required: true, message: "请选择测试种类",
+        // },
+        name: {
+          required: true, message: "请输入测试名称", trigger: "blur",
+        },
+        course: {
+          required: true, message: "请选择测试名称",
+        },
+        range: {
+          required: true, message: "请选择测试时间段", trigger: "blur",
+        }
       },
-      problemTypeOptions() {
-        return problemTypeOptions(true);
-      }
+      coderCourses: [],
+      courseOptions: [],
+
+      switchDisabled: false,
+      switchExamDisabled: false,
+      //
+      myCourseList: [],
+      courseType: "all",
+      courseTypeOptions: [
+        {value: "all", label: "全部课程"},
+        {value: "pending", label: "未开始"},
+        {value: "start", label: "正在进行"},
+        {value: "end", label: "已结束"},
+      ],
+      evalExamList: [],
+      coderExamList: [],
+      examType: "all",
+      examTypeOptions: [
+        {value: "all", label: "全部测试"},
+        {value: "pending", label: "未开始"},
+        {value: "start", label: "正在进行"},
+        {value: "end", label: "已结束"},
+      ],
+      examCategoryOptions: [
+        {value: "eval", label: "评测题"},
+        {value: "coder", label: "代码题"},
+      ],
+      dialogProblemVisible: false,
+      dialogProblemPage: 1,
+      dialogProblemLimit: 10,
+      dialogProblemTypeStr: "",
+      dialogProblemName: "",
+      problemList: [],
+      problemPageInfo: {},
+
+      //上传Coder代码题
+      uploadFileDialog: false,
+      uploadFileForm: {
+        name: "",
+        type: "",
+        description: ""
+      },
+      uploadFileRules: {
+        name: [{required: true, message: "请输入题目名称", trigger: "blur"}],
+        type: [{required: true, message: "请选择题目类型", trigger: "blur"}],
+        description: [
+          {required: true, message: "请输入题目描述", trigger: "blur"}
+        ]
+      },
+      uploadFiles: [],
+      loading: false,
+    };
+  },
+  computed: {
+    filterCourses: function () {
+      if (this.courseType === "all") return this.myCourseList;
+      if (this.courseType === "pending") return this.myCourseList.filter(i => this.state(i) === "NOT_STARTED");
+      if (this.courseType === "start") return this.myCourseList.filter(i => this.state(i) === "RUNNING");
+      if (this.courseType === "end") return this.myCourseList.filter(i => this.state(i) === "FINISHED");
+      else return this.myCourseList;
     },
-    mounted() {
-      this.$apis.getTeacherCourses().then(res => {
-        this.myCourseList = res.data.data;
-      });
-      this.$apis.getTeacherEvalExamsGroupByCourse().then(res => {
-        this.evalExamList = res.data.data;
-      });
-      this.$apis.getTeacherCoderExamsGroupByCourse().then(res => {
-        this.coderExamList = res.data.data;
-      });
-      this.fetchProblemData();
+    isCoder() {
+      return this.examForm.examType === "coder";
     },
-    watch: {
-      //TODO 防抖!
-      dialogProblemName() {
-        debounce(this.fetchProblemData, 500);
+    problemTypeOptions() {
+      return problemTypeOptions(true);
+    }
+  },
+  mounted() {
+    this.$apis.getTeacherCourses().then(res => {
+      this.myCourseList = res.data.data;
+    });
+    this.$apis.getTeacherEvalExamsGroupByCourse().then(res => {
+      this.evalExamList = res.data.data;
+    });
+    this.$apis.getTeacherCoderExamsGroupByCourse().then(res => {
+      this.coderExamList = res.data.data;
+    });
+    this.fetchProblemData();
+  },
+  watch: {
+    //TODO 防抖!
+    dialogProblemName() {
+      debounce(this.fetchProblemData, 500);
+    }
+  },
+  methods: {
+    formatTimestamp,
+    problemTypeToTagContent,
+    state(courseVO) {
+      const now = new Date();
+      if (new Date(courseVO.endTime) < now) {
+        return "FINISHED";
+      } else if (new Date(courseVO.startTime) > now) {
+        return "NOT_STARTED";
+      } else {
+        return "RUNNING";
       }
     },
-    methods: {
-      formatTimestamp,
-      problemTypeToTagContent,
-      state(courseVO) {
-        const now = new Date();
-        if (new Date(courseVO.endTime) < now) {
-          return "FINISHED";
-        } else if (new Date(courseVO.startTime) > now) {
-          return "NOT_STARTED";
-        } else {
-          return "RUNNING";
-        }
-      },
-      handleSelect(index) {
-        if (index === "0") {
-          this.$router.push("portal");
-        }
-        if (index === "1") {
-          document.getElementById("app").scrollIntoView({behavior: "smooth"});
-        }
-        if (index === "2") {
-          document.querySelector("#manage-page-divider").scrollIntoView({behavior: "smooth"});
-        }
-        if (index === "3") {
-          document.querySelector("#manage-page-divider-3").scrollIntoView({behavior: "smooth"});
-        }
-        this.activeIndex = index;
-      },
-      handleFormConfirm() {
-        const _this = this;
-        _this.$refs.formRef.validate((valid) => {
-          if (valid) {
-            if (_this.form.id === null) {
-              // 首先创建课程
-              // 之后上传课程图片
-              _this.$apis.createCourse({
-                name: _this.form.name,
-                teacher: {
-                  id: _this.$store.state.user.id,
-                },
-                semester: _this.form.year + _this.form.season,
-                imageUrl: null,
-                description: _this.form.description,
-                startTime: _this.form.courseTime[0],
-                endTime: _this.form.courseTime[1],
-                invitationCode: _this.form.invitationCode,
-                moocUrl: _this.form.moocUrl,
-                createdTime: new Date(),
-                price: Number(_this.form.price),
-                coderId: _this.form.coderLink ? -1 : null,
-                evalId: _this.form.evalLink ? -1 : null,
-              }).then(async (res) => {
-                const createdCourse = res.data.data;
-                if (createdCourse) {
-                  if (_this.form.fileList.length !== 0 && this.form.fileList[0].raw) {
-                    const imageUrl = (await _this.$apis.uploadCourseImage(createdCourse.name, this.form.fileList[0].raw)).data.data;
-                    if (imageUrl) {
-                      createdCourse.imageUrl = imageUrl;
-                    }
+    handleSelect(index) {
+      if (index === "0") {
+        this.$router.push("portal");
+      }
+      if (index === "1") {
+        document.getElementById("app").scrollIntoView({behavior: "smooth"});
+      }
+      if (index === "2") {
+        document.querySelector("#manage-page-divider").scrollIntoView({behavior: "smooth"});
+      }
+      if (index === "3") {
+        document.querySelector("#manage-page-divider-3").scrollIntoView({behavior: "smooth"});
+      }
+      this.activeIndex = index;
+    },
+    handleFormConfirm() {
+      const _this = this;
+      _this.$refs.formRef.validate((valid) => {
+        if (valid) {
+          if (_this.form.id === null) {
+            // 首先创建课程
+            // 之后上传课程图片
+            _this.$apis.createCourse({
+              name: _this.form.name,
+              teacher: {
+                id: _this.$store.state.user.id,
+              },
+              semester: _this.form.year + _this.form.season,
+              imageUrl: null,
+              description: _this.form.description,
+              startTime: _this.form.courseTime[0],
+              endTime: _this.form.courseTime[1],
+              invitationCode: _this.form.invitationCode,
+              moocUrl: _this.form.moocUrl,
+              createdTime: new Date(),
+              price: Number(_this.form.price),
+              coderId: _this.form.coderLink ? -1 : null,
+              evalId: _this.form.evalLink ? -1 : null,
+            }).then(async (res) => {
+              const createdCourse = res.data.data;
+              if (createdCourse) {
+                if (_this.form.fileList.length !== 0 && this.form.fileList[0].raw) {
+                  const imageUrl = (await _this.$apis.uploadCourseImage(createdCourse.name, this.form.fileList[0].raw)).data.data;
+                  if (imageUrl) {
+                    createdCourse.imageUrl = imageUrl;
                   }
-                  _this.myCourseList.push(createdCourse);
-                  _this.dialogVisible = false;
-                  _this.clearForm();
-                  ElMessage.success("新建课程成功");
-                } else {
-                  console.log(res);
                 }
-              });
-            } else {
-              // 首先更新课程
-              // 之后更新课程图片
-              _this.$apis.updateCourse({
-                id: _this.form.id,
-                name: _this.form.name,
-                semester: _this.form.year + _this.form.season,
-                imageUrl: _this.form.imageUrl,
-                description: _this.form.description,
-                startTime: _this.form.courseTime[0],
-                endTime: _this.form.courseTime[1],
-                invitationCode: _this.form.invitationCode,
-                moocUrl: _this.form.moocUrl,
-                price: Number(_this.form.price),
-              }).then(async (res) => {
-                const updatedCourse = res.data.data;
-                if (updatedCourse) {
-                  if (_this.form.fileList.length !== 0 && this.form.fileList[0].raw) {
-                    const imageUrl = (await _this.$apis.uploadCourseImage(updatedCourse.name, this.form.fileList[0].raw)).data.data;
-                    if (imageUrl) {
-                      updatedCourse.imageUrl = imageUrl;
-                    }
+                _this.myCourseList.push(createdCourse);
+                _this.dialogVisible = false;
+                _this.clearForm();
+                ElMessage.success("新建课程成功");
+              } else {
+                console.log(res);
+              }
+            });
+          } else {
+            // 首先更新课程
+            // 之后更新课程图片
+            _this.$apis.updateCourse({
+              id: _this.form.id,
+              name: _this.form.name,
+              semester: _this.form.year + _this.form.season,
+              imageUrl: _this.form.imageUrl,
+              description: _this.form.description,
+              startTime: _this.form.courseTime[0],
+              endTime: _this.form.courseTime[1],
+              invitationCode: _this.form.invitationCode,
+              moocUrl: _this.form.moocUrl,
+              price: Number(_this.form.price),
+            }).then(async (res) => {
+              const updatedCourse = res.data.data;
+              if (updatedCourse) {
+                if (_this.form.fileList.length !== 0 && this.form.fileList[0].raw) {
+                  const imageUrl = (await _this.$apis.uploadCourseImage(updatedCourse.name, this.form.fileList[0].raw)).data.data;
+                  if (imageUrl) {
+                    updatedCourse.imageUrl = imageUrl;
                   }
-                  for (let i = 0; i < _this.myCourseList.length; i++) {
-                    if (_this.myCourseList[i].id === _this.form.id) {
-                      _this.myCourseList[i] = updatedCourse;
-                    }
+                }
+                for (let i = 0; i < _this.myCourseList.length; i++) {
+                  if (_this.myCourseList[i].id === _this.form.id) {
+                    _this.myCourseList[i] = updatedCourse;
                   }
-                  _this.$refs["courseCard" + _this.form.id][0].$props.courseVO = updatedCourse;
-                  _this.dialogVisible = false;
-                  _this.clearForm();
-                  ElMessage.success("更新课程成功");
                 }
-              });
-            }
-          }
-        });
-      },
-      handleFormCancel(done) {
-        ElMessageBox.confirm("是否确认退出?退出后将不保存表格信息。", "提示", {
-          confirmButtonText: "确认退出",
-          cancelButtonText: "我再想想",
-          type: "warning",
-          center: true,
-        })
-                .then(() => {
-                  this.dialogVisible = false;
-                  this.clearForm();
-                  // Zhurui修改,关闭dialog
-                  done();
-                })
-                .catch((err) => {
-                  console.log(err);
-                });
-      },
-      handleExamCreate() {
-        const form = this.$refs.examFormRef;
-        form.validate((valid) => {
-          if (valid) {
-            console.log("validate 成功");
-            this.createCoderExam();
-          } else {
-            console.log("validate 失败了");
-            return false;
+                _this.$refs["courseCard" + _this.form.id][0].$props.courseVO = updatedCourse;
+                _this.dialogVisible = false;
+                _this.clearForm();
+                ElMessage.success("更新课程成功");
+              }
+            });
           }
-        });
-      },
-      createCoderExam() {
-        //创建Coder考试
-        this.$apis.createCoderExam({
-          course: this.examForm.course,
-          name: this.examForm.name,
-          startAt: this.examForm.range[0].getTime() / 1000,
-          endAt: this.examForm.range[1].getTime() / 1000,
-          problems: this.$store.state.problem.cart.map((item) => item.id),
-          isConsoleOutputShownForStu: this.examForm.isConsoleOutputShownForStu
-        }).then(_res => {
-          this.$store.commit("clearProblem");
-          ElMessage.success("创建测试成功!");
-          this.dialogExamVisible = false;
-        }).catch(_err => {
-          console.log(_err);
-          ElMessage.warning("创建测试失败!");
-        });
-      },
-      handleExamFormCancel(done) {
-        //关闭dialog的提示
-        ElMessageBox.confirm("是否确认退出?退出后将不保存表格信息。", "提示", {
-          confirmButtonText: "确认退出",
-          cancelButtonText: "我再想想",
-          type: "warning",
-          center: true,
-        })
-                .then(() => {
-                  this.dialogExamVisible = false;
-                  // this.clearForm();
-                  //TODO 清除表格信息
-                  done();
-                })
-                .catch((err) => {
-                  console.log(err);
-                });
-      },
-      showProblemDialog() { //打开弹框,获取初始数据
-        this.fetchProblemData();
-        this.dialogProblemVisible = true;
-      },
-      // handleProblemChange(){
-      //   debounce(fetchProblemData,1000);
-      // },
-      checkDetails(problemId) {
-        this.$router.push(`/problem/${problemId}`);
-      },
-      fetchProblemData(page = 1) { // 按需获得Coder题目
-        this.$apis.retrievePageProblem(page, this.dialogProblemLimit, this.dialogProblemTypeStr, this.dialogProblemName)
-                .then(_res => {
-                  this.problemPageInfo = _res.data.page;
-                  this.problemList = _res.data.res;
-                }).catch(err => {
-          console.log(err);
-        });
-      },
-      removeEnable(problem) { //是否可以移除题目
-        return this.$store.state.problem.cart.length && this.$store.state.problem.cart
-                .map((item) => item.id)
-                .includes(problem.id);
-      },
-      addEnable(problem) { //是否可以添加题目
-        return this.$store.getters.isTeacher && problem.modifiedAt;
-      },
-      changePage(val) {
-        this.fetchProblemData(val);
-      },
-      clearForm() {
-        this.form = {
-          id: null,
-          name: "",
-          year: "",
-          season: "",
-          description: "",
-          courseTime: [null, null],
-          invitationCode: "",
-          price: "0",//input均会将Number类型转化成为字符串类型
-          moocUrl: null,
-          fileList: [],
-          imageUrl: null,
-          coderLink: false,
-          evalLink: false,
-        };
-      },
-      // el-upload相关的方法
-      handleChange(file, fileList) {
-        this.form.fileList = fileList;
-      },
-      handleExceed(files, fileList) {
-        ElMessage.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
-      },
-      httpRequest(event) {
-      },
-      beforeUpload(file) {
-        const isJPG = file.type === "image/jpeg";
-        const isLt10M = file.size / 1024 / 1024 < 3;
-        const isPNG = file.type === "image/png";
-        if (!(isJPG || isPNG)) {
-          ElMessage.error("上传头像图片只能是 JPG/PNG 格式!");
-        }
-        if (!isLt10M) {
-          ElMessage.error("上传图片大小不能超过 3MB!");
         }
-        return (isJPG || isPNG) && isLt10M;
-      },
-      // update & delete
-      beforeUpdateCourse(item) {
-        this.form.id = item.id;
-        this.form.name = item.name;
-        this.form.year = Number(item.semester.substring(0, 4));
-        this.form.season = item.semester[4];
-        this.form.description = item.description;
-        this.form.courseTime[0] = new Date(item.startTime);
-        this.form.courseTime[1] = new Date(item.endTime);
-        this.form.invitationCode = item.invitationCode;
-        this.form.price = String(item.price);
-        this.form.moocUrl = item.moocUrl;
-        this.form.fileList = item.imageUrl === null ? [] : [{
-          name: item.name + "-image.jpg",
-          url: item.imageUrl
-        }];
-        this.form.imageUrl = item.imageUrl;
-        this.form.coderLink = item.coderId !== null;
-        this.form.evalLink = item.evalId !== null;
-        this.dialogTitle = "修改课程";
-        this.switchDisabled = true;
-        this.dialogVisible = true;
-      },
-      deleteCourse(item) {
-        if (item.state === "EXAMPLE") {
-          ElMessage.error("无法删除示例课程");
+      });
+    },
+    handleFormCancel(done) {
+      ElMessageBox.confirm("是否确认退出?退出后将不保存表格信息。", "提示", {
+        confirmButtonText: "确认退出",
+        cancelButtonText: "我再想想",
+        type: "warning",
+        center: true,
+      })
+          .then(() => {
+            this.dialogVisible = false;
+            this.clearForm();
+            // Zhurui修改,关闭dialog
+            done();
+          })
+          .catch((err) => {
+            console.log(err);
+          });
+    },
+    handleExamCreate() {
+      const form = this.$refs.examFormRef;
+      form.validate((valid) => {
+        if (valid) {
+          console.log("validate 成功");
+          this.createCoderExam();
         } else {
-          ElMessageBox.confirm(
-                  "确定删除课程",
-                  "Warning",
-                  {
-                    confirmButtonText: "立即删除",
-                    cancelButtonText: "让我想想",
-                    type: "warning",
-                    center: true,
-                  }
-          )
-                  .then(() => {
-                    this.$apis.deleteCourse(item.id)
-                            .then(res => {
-                              for (let i = 0; i < this.myCourseList.length; i++) {
-                                if (this.myCourseList[i].id === item.id) {
-                                  this.myCourseList.splice(i, 1);
-                                }
-                              }
-                              ElMessage.success(res.data.data);
-                            });
-                  })
-                  .catch(() => {
-                    ElMessage({
-                      type: "info",
-                      message: "取消删除",
-                    });
-                  });
+          console.log("validate 失败了");
+          return false;
         }
-      },
-      handleProblemCreate() {
-        alert("创建Coder题目");
-      },
-      uploadFile() {
-        this.uploadFileDialog = true;
-      },
-      onFileChange(fileList) {
-        console.log(fileList);
-        this.uploadFiles.push(fileList);
-      },
-      resetForm() {
-        const form = this.$refs.form;
-        form.resetFields();
-        const file = this.$refs.file;
-        file.clearFiles();
-        this.uploadFiles = [];
-      },
-      submitProblem() {
-        const form = this.$refs.form;
-        form.validate((valid) => {
-          if (valid) {
-            this.uploadProblem();
-          } else {
-            return false;
-          }
-        });
-      },
-      uploadProblem() {
-        this.loading = true;
-        const body = new FormData();
-        const meta = new Blob([JSON.stringify(this.uploadFileForm)], {
-          type: "application/json",
-        });
-        body.append("meta", meta);
-        body.append("data", this.uploadFiles[0].raw);
-        this.$apis.createCoderProblem(body)
-                .then((data) => {
-                  ElMessage.success("创建Coder代码题成功");
-                  this.loading = false;
-                  this.uploadFileDialog = false;
-                  // this.problemList.push()
-                  // this.$nuxt.$router.push("/problem/" + data.res?.id);
-                })
-                .catch((err) => {
-                  this.$message.error({
-                    message: errorMessage(err),
-                    center: true
+      });
+    },
+    createCoderExam() {
+      //创建Coder考试
+      this.$apis.createCoderExam({
+        course: this.examForm.course,
+        name: this.examForm.name,
+        startAt: this.examForm.range[0].getTime() / 1000,
+        endAt: this.examForm.range[1].getTime() / 1000,
+        problems: this.$store.state.problem.cart.map((item) => item.id),
+        isConsoleOutputShownForStu: this.examForm.isConsoleOutputShownForStu
+      }).then(_res => {
+        this.$store.commit("clearProblem");
+        ElMessage.success("创建测试成功!");
+        this.dialogExamVisible = false;
+      }).catch(_err => {
+        console.log(_err);
+        ElMessage.warning("创建测试失败!");
+      });
+    },
+    handleExamFormCancel(done) {
+      //关闭dialog的提示
+      ElMessageBox.confirm("是否确认退出?退出后将不保存表格信息。", "提示", {
+        confirmButtonText: "确认退出",
+        cancelButtonText: "我再想想",
+        type: "warning",
+        center: true,
+      })
+          .then(() => {
+            this.dialogExamVisible = false;
+            // this.clearForm();
+            //TODO 清除表格信息
+            done();
+          })
+          .catch((err) => {
+            console.log(err);
+          });
+    },
+    showProblemDialog() { //打开弹框,获取初始数据
+      this.fetchProblemData();
+      this.dialogProblemVisible = true;
+    },
+    // handleProblemChange(){
+    //   debounce(fetchProblemData,1000);
+    // },
+    checkDetails(problemId) {
+      this.$router.push(`/problem/${problemId}`);
+    },
+    fetchProblemData(page = 1) { // 按需获得Coder题目
+      this.$apis.retrievePageProblem(page, this.dialogProblemLimit, this.dialogProblemTypeStr, this.dialogProblemName)
+          .then(_res => {
+            this.problemPageInfo = _res.data.page;
+            this.problemList = _res.data.res;
+          }).catch(err => {
+        console.log(err);
+      });
+    },
+    removeEnable(problem) { //是否可以移除题目
+      return this.$store.state.problem.cart.length && this.$store.state.problem.cart
+          .map((item) => item.id)
+          .includes(problem.id);
+    },
+    addEnable(problem) { //是否可以添加题目
+      return this.$store.getters.isTeacher && problem.modifiedAt;
+    },
+    changePage(val) {
+      this.fetchProblemData(val);
+    },
+    clearForm() {
+      this.form = {
+        id: null,
+        name: "",
+        year: "",
+        season: "",
+        description: "",
+        courseTime: [null, null],
+        invitationCode: "",
+        price: "0",//input均会将Number类型转化成为字符串类型
+        moocUrl: null,
+        fileList: [],
+        imageUrl: null,
+        coderLink: false,
+        evalLink: false,
+      };
+    },
+    // el-upload相关的方法
+    handleChange(file, fileList) {
+      this.form.fileList = fileList;
+    },
+    handleExceed(files, fileList) {
+      ElMessage.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
+    },
+    httpRequest(event) {
+    },
+    beforeUpload(file) {
+      const isJPG = file.type === "image/jpeg";
+      const isLt10M = file.size / 1024 / 1024 < 3;
+      const isPNG = file.type === "image/png";
+      if (!(isJPG || isPNG)) {
+        ElMessage.error("上传头像图片只能是 JPG/PNG 格式!");
+      }
+      if (!isLt10M) {
+        ElMessage.error("上传图片大小不能超过 3MB!");
+      }
+      return (isJPG || isPNG) && isLt10M;
+    },
+    // update & delete
+    beforeUpdateCourse(item) {
+      this.form.id = item.id;
+      this.form.name = item.name;
+      this.form.year = Number(item.semester.substring(0, 4));
+      this.form.season = item.semester[4];
+      this.form.description = item.description;
+      this.form.courseTime[0] = new Date(item.startTime);
+      this.form.courseTime[1] = new Date(item.endTime);
+      this.form.invitationCode = item.invitationCode;
+      this.form.price = String(item.price);
+      this.form.moocUrl = item.moocUrl;
+      this.form.fileList = item.imageUrl === null ? [] : [{
+        name: item.name + "-image.jpg",
+        url: item.imageUrl
+      }];
+      this.form.imageUrl = item.imageUrl;
+      this.form.coderLink = item.coderId !== null;
+      this.form.evalLink = item.evalId !== null;
+      this.dialogTitle = "修改课程";
+      this.switchDisabled = true;
+      this.dialogVisible = true;
+    },
+    deleteCourse(item) {
+      if (item.state === "EXAMPLE") {
+        ElMessage.error("无法删除示例课程");
+      } else {
+        ElMessageBox.confirm(
+            "确定删除课程",
+            "Warning",
+            {
+              confirmButtonText: "立即删除",
+              cancelButtonText: "让我想想",
+              type: "warning",
+              center: true,
+            }
+        )
+            .then(() => {
+              this.$apis.deleteCourse(item.id)
+                  .then(res => {
+                    for (let i = 0; i < this.myCourseList.length; i++) {
+                      if (this.myCourseList[i].id === item.id) {
+                        this.myCourseList.splice(i, 1);
+                      }
+                    }
+                    ElMessage.success(res.data.data);
                   });
-                  this.loading = false;
-                });
+            })
+            .catch(() => {
+              ElMessage({
+                type: "info",
+                message: "取消删除",
+              });
+            });
       }
     },
+    handleProblemCreate() {
+      alert("创建Coder题目");
+    },
+    uploadFile() {
+      this.uploadFileDialog = true;
+    },
+    onFileChange(fileList) {
+      console.log(fileList);
+      this.uploadFiles.push(fileList);
+    },
+    resetForm() {
+      const form = this.$refs.form;
+      form.resetFields();
+      const file = this.$refs.file;
+      file.clearFiles();
+      this.uploadFiles = [];
+    },
+    submitProblem() {
+      const form = this.$refs.form;
+      form.validate((valid) => {
+        if (valid) {
+          this.uploadProblem();
+        } else {
+          return false;
+        }
+      });
+    },
+    uploadProblem() {
+      this.loading = true;
+      const body = new FormData();
+      const meta = new Blob([JSON.stringify(this.uploadFileForm)], {
+        type: "application/json",
+      });
+      body.append("meta", meta);
+      body.append("data", this.uploadFiles[0].raw);
+      this.$apis.createCoderProblem(body)
+          .then((data) => {
+            ElMessage.success("创建Coder代码题成功");
+            this.loading = false;
+            this.uploadFileDialog = false;
+            // this.problemList.push()
+            // this.$nuxt.$router.push("/problem/" + data.res?.id);
+          })
+          .catch((err) => {
+            this.$message.error({
+              message: errorMessage(err),
+              center: true
+            });
+            this.loading = false;
+          });
+    }
+  },
 
-  };
+};
 </script>
 
 <style scoped>
-  @import "managePage.css";
+@import "managePage.css";
 </style>