Explorar o código

feat: ProjectLongCard

mjh %!s(int64=4) %!d(string=hai) anos
pai
achega
a8ae71db3e
Modificáronse 3 ficheiros con 272 adicións e 155 borrados
  1. 45 26
      src/api/project.js
  2. 83 0
      src/components/project/ProjectLongCard.vue
  3. 144 129
      src/views/CoursePage/CourseDetail.vue

+ 45 - 26
src/api/project.js

@@ -1,45 +1,64 @@
 import {axios} from "@/requests/axios.config";
+
 const prefix = "/project";
 
-function findAllProjects(){
-    return axios.get(`${prefix}/findAll`);
+function findAllProjects() {
+  return axios.get(`${prefix}/findAll`);
+}
+
+function findCourseProjects() {
+  return axios.get(`${prefix}/findCourse`);
+}
+
+function findNonCourseProjects() {
+  return axios.get(`${prefix}/findNonCourse`);
 }
 
-function findCourseProjects(){
-    return axios.get(`${prefix}/findCourse`);
+function findProjectById(id) {
+  return axios.get(`${prefix}/findById`, {
+    params: {
+      id,
+    }
+  });
 }
 
-function findNonCourseProjects(){
-    return axios.get(`${prefix}/findNonCourse`);
+function findProjectsByCourse(courseId) {
+  return axios.get(`${prefix}/findByCourse`, {
+    params: {
+      courseId,
+    }
+  });
 }
 
-function  findProjectById(id){
-    return axios.get(`${prefix}/findById`,{
-        params: {
-            id,
-        }
-    });
+function createProject(data) {
+  return axios.post(`${prefix}`, data);
 }
 
-function  findProjectsByCourse(courseId){
-    return axios.get(`${prefix}/findByCourse`,{
-        params: {
-            courseId,
-        }
-    });
+function findProjectMembers(id) {
+  return axios.get(`${prefix}/findMembers`, {
+    params: {
+      id,
+    }
+  });
 }
 
-function createProject(data){
-    return axios.post(`${prefix}`,data);
+function updateCourseProjectState(id) {
+  return axios.put(`${prefix}/updateState`, null, {
+    params: {
+      id,
+    }
+  });
 }
 
 const projectAPIs = {
-    findAllProjects,
-    findCourseProjects,
-    findNonCourseProjects,
-    findProjectById,
-    findProjectsByCourse,
-    createProject,
+  findAllProjects,
+  findCourseProjects,
+  findNonCourseProjects,
+  findProjectById,
+  findProjectMembers,
+  findProjectsByCourse,
+  createProject,
+  updateCourseProjectState,
 };
 
 export default projectAPIs;

+ 83 - 0
src/components/project/ProjectLongCard.vue

@@ -0,0 +1,83 @@
+<template>
+  <el-card class="project-long-card" shadow="hover">
+    <div style="display:flex;justify-content: space-between;align-items: center">
+      <div v-if="project.name">
+        <span>名称:{{ project.name }}</span>
+      </div>
+      <div v-else>
+        <span>项目ID:{{ project.id }}</span>
+      </div>
+      <div v-if="project.name">
+        <span>成员:
+          <span v-for="item in members" :key="'project'+project.id+'member'+item.id"
+                class="project-long-card-member">{{ item.username }}
+          </span>
+        </span>
+      </div>
+      <el-button v-if="isTeacher" size="small" type="primary"
+                 @click="$emit('switch')">
+        设为{{ isPublic ? '私有' : '公共' }}
+      </el-button>
+      <el-button v-if="isPublic&&!isTeacher" size="small" type="primary"
+                 @click="$emit('fork')">
+        Fork
+      </el-button>
+    </div>
+    <el-divider v-if="project.name"/>
+    <div v-if="project.name">描述:{{ project.description }}</div>
+    <div v-if="project.name">链接:{{ project.gitRemoteUrl }}</div>
+  </el-card>
+</template>
+
+<script>
+
+export default {
+  name: "ProjectLongCard",
+  props: {
+    project: {
+      type: Object,
+      required: true,
+    },
+    isPublic: {
+      type: Boolean,
+      default: false,
+    },
+    isTeacher: {
+      type: Boolean,
+      default: false,
+    }
+  },
+  emits: ["switch"],
+  data() {
+    return {
+      members: [],
+    };
+  },
+  async mounted() {
+    const _this = this;
+    const res = (await _this.$apis.findProjectMembers(_this.project.id)).data;
+    if (!res.code) {
+      _this.members = res.data;
+    }
+  },
+};
+</script>
+
+<style scoped>
+.project-long-card {
+  margin-bottom: 10px;
+}
+
+.el-divider {
+  margin: 2px;
+}
+
+.project-long-card-member {
+  cursor: pointer;
+  margin-right: 5px;
+}
+
+.project-long-card-member:hover {
+  color: #409EFF;
+}
+</style>

+ 144 - 129
src/views/CoursePage/CourseDetail.vue

@@ -54,6 +54,7 @@
             <el-radio-button label="group" @click="switchTab('group')">团队</el-radio-button>
             <el-radio-button label="comment" @click="switchTab('comment')">评论</el-radio-button>
           </el-radio-group>
+          <!--教师视角-->
           <div v-if="isCreator">
             <el-popover v-if="tabName==='task'" trigger="hover">
               <div style="display: flex;justify-content: space-around;">
@@ -118,14 +119,12 @@
               新建项目
             </el-button>
           </div>
-          <!--组队-->
+          <!--学生视角-->
           <div v-if="isCourseSelected">
-            <div v-if="tabName==='group'">
-              <el-button v-if="tabName==='group'&&isRuleExisted!==null"
-                         plain type="primary" :disabled="isGroupExisted" @click="CreateTeam">
-                {{ isGroupExisted ? '队伍已创建' : '创建队伍' }}
-              </el-button>
-            </div>
+            <el-button v-if="tabName==='group'&&isRuleExisted!==null"
+                       plain type="primary" :disabled="isGroupExisted" @click="createGroupDialog=true">
+              {{ isGroupExisted ? '队伍已创建' : '创建队伍' }}
+            </el-button>
           </div>
         </div>
         <!--tab内容-->
@@ -267,20 +266,30 @@
             </div>
           </div>
           <div v-else-if="tabName==='project'">
-            <el-tabs v-if="projects!==null" v-model="projectTabName" type="border-card">
-              <el-tab-pane label="公开项目" name="public">
-                <div v-if="projects.public.length===0">
-                  当前没有公开项目
-                </div>
-                <div v-else>
-                  {{ projects.public }}
+            <el-tabs v-model="projectTabName" type="border-card">
+              <el-tab-pane label="公共项目" name="public">
+                <div v-if="projects!==null">
+                  <div v-if="projects.public.length===0">
+                    当前没有公共项目
+                  </div>
+                  <div v-else>
+                    <project-long-card v-for="item in projects.public" :key="'project'+item.id"
+                                       :project="item" is-public :is-teacher="isCreator"
+                                       @switch="handleProjectSwitch(item.id)"/>
+                  </div>
                 </div>
               </el-tab-pane>
               <el-tab-pane label="私有项目" name="private">
-                <div v-if="projects.private.length===0">
-                  当前没有私有项目
+                <div v-if="projects!==null">
+                  <div v-if="projects.private.length===0">
+                    当前没有私有项目
+                  </div>
+                  <div v-else>
+                    <project-long-card v-for="item in projects.private" :key="'project'+item.id"
+                                       :project="item" :is-teacher="isCreator"
+                                       @switch="handleProjectSwitch(item.id)"/>
+                  </div>
                 </div>
-                <div v-else>{{ projects.private }}</div>
               </el-tab-pane>
             </el-tabs>
           </div>
@@ -314,10 +323,12 @@
     <el-dialog v-model="ruleFormDialog" :before-close="beforeRuleFormClose" :title="ruleForm.dialogTitle">
       <el-form ref="ruleFormRef" :model="ruleForm" :rules="ruleFormRule" label-position="right" label-width="150px">
         <el-form-item label="小组最大人数" prop="maxSize">
-          <el-input v-model="ruleForm.maxSize" type="number" min="1" max="5" placeholder="输入小组最大人数(1~5)" maxlength="1" onkeypress='return( /[1-5]/.test(String.fromCharCode(event.keyCode)))'></el-input>
+          <el-input v-model="ruleForm.maxSize" type="number" min="1" max="5" placeholder="输入小组最大人数(1~5)" maxlength="1"
+                    onkeypress='return( /[1-5]/.test(String.fromCharCode(event.keyCode)))'></el-input>
         </el-form-item>
         <el-form-item label="组名最大长度" prop="maxNameLen">
-          <el-input v-model="ruleForm.maxNameLen" type="number" min="1" max="9" placeholder="输入组名最大长度(1~9)" maxlength="1" onkeypress='return( /[1-9]/.test(String.fromCharCode(event.keyCode)))'></el-input>
+          <el-input v-model="ruleForm.maxNameLen" type="number" min="1" max="9" placeholder="输入组名最大长度(1~9)"
+                    maxlength="1" onkeypress='return( /[1-9]/.test(String.fromCharCode(event.keyCode)))'></el-input>
         </el-form-item>
       </el-form>
       <div style="margin: auto;width: fit-content">
@@ -328,17 +339,17 @@
     <!--新建项目-->
     <el-dialog v-model="projectDialogVisible" title="新建项目"
                :before-close="handleProjectFormCancel">
-      <el-form :model="projectForm" ref="projectFormRef">
+      <el-form :model="projectForm" ref="projectFormRef" label-position="right">
         <el-form-item label="项目名称" prop="name">
           <el-input v-model="projectForm.name" placeholder="请输入项目名称"/>
         </el-form-item>
         <el-form-item label="项目描述" prop="description">
           <el-input v-model="projectForm.description" placeholder="请输入项目描述"/>
         </el-form-item>
-        <el-form-item label="是否公" prop="isPublic">
+        <el-form-item label="是否公" prop="isPublic">
           <el-select v-model="projectForm.isPublic">
-            <el-option label="公开" :value="true" />
-            <el-option label="私有" :value="false" />
+            <el-option label="公共" :value="true"/>
+            <el-option label="私有" :value="false"/>
           </el-select>
         </el-form-item>
       </el-form>
@@ -349,15 +360,14 @@
       </template>
     </el-dialog>
     <!--组队信息-->
-    <el-dialog v-model="createGroupDialog" :before-close="beforeGroupFormClose" :title="createTeamForm.dialogTitle">
-    <el-form ref="createGroupFormRef" :model="createTeamForm" label-position="right" label-width="150px">
-      <el-form-item label="组名" prop="name">
-        <el-input v-model="createTeamForm.name" placeholder="输入组名" maxlength="5"></el-input>
-      </el-form-item>
-    </el-form>
+    <el-dialog v-model="createGroupDialog" :before-close="beforeGroupFormClose" :title="createGroupForm.dialogTitle">
+      <el-form ref="createGroupFormRef" :model="createGroupForm" label-position="right">
+        <el-form-item label="组名" prop="name">
+          <el-input v-model="createGroupForm.name" placeholder="输入组名" maxlength="5"></el-input>
+        </el-form-item>
+      </el-form>
       <div style="margin: auto;width: fit-content">
-        <el-button plain type="primary" @click="createTeam">确认</el-button>
-        <el-button plain type="danger" @click="beforeGroupFormClose">我再想想</el-button>
+        <el-button plain type="primary" @click="createGroup">确认</el-button>
       </div>
     </el-dialog>
   </div>
@@ -368,12 +378,14 @@ import NoticeItem from "./components/NoticeItem";
 import FileEntry from "./components/FileEntry";
 import {ElMessageBox, ElMessage} from "element-plus";
 import variables from "@/utils/variables";
+import ProjectLongCard from "@/components/project/ProjectLongCard";
 
 export default {
   name: "CourseDetail",
   components: {
     NoticeItem,
     FileEntry,
+    ProjectLongCard,
   },
   data() {
     const themeColor = {
@@ -410,13 +422,10 @@ export default {
         }
       },
       announcementList: [],
-      // group
+      // groupRule
       isRuleExisted: null,
-      isGroupExisted: null,
       ruleFormDialog: false,
       createGroupDialog: false,
-      maxSize: null,
-      maxNameLen: null,
       ruleForm: {
         dialogTitle: "制定组队规则",
         courseVO: null,
@@ -432,7 +441,9 @@ export default {
           required: true, message: "请选择组名最大长度", trigger: "change",
         }
       },
-      createTeamForm: {
+      // group
+      isGroupExisted: null,
+      createGroupForm: {
         dialogTitle: "队伍信息",
         courseId: null,
         name: null,
@@ -656,12 +667,6 @@ export default {
       this.ruleFormDialog = true;
     },
 
-    createTeam() {
-      this.createGroupDialog = true;
-      this.getRule();
-    },
-
-
 
     beforeFormClose() {
       ElMessageBox.confirm("是否确认退出?退出后将不保存表格信息。", "提示", {
@@ -676,86 +681,6 @@ export default {
         });
     },
 
-    // group
-    beforeRuleFormClose() {
-      ElMessageBox.confirm("是否确认退出?退出后将不保存组队规则信息。", "提示", {
-        confirmButtonText: "确认退出",
-        cancelButtonText: "我再想想",
-        type: "warning",
-        center: true,
-      })
-        .then(() => {
-          this.ruleFormDialog = false;
-          this.$refs.ruleFormRef.resetFields();
-        });
-    },
-    createRule() {
-      this.$refs.ruleFormRef.validate((valid) => {
-        if (valid) {
-          let RuleVO = {
-            courseVO: {id: this.courseInfo.id},
-            maxSize: this.ruleForm.maxSize,
-            maxNameLen: this.ruleForm.maxNameLen,
-          };
-          console.log(RuleVO);
-          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("创建规则成功");
-              }
-            });
-        }
-      });
-    },
-    getRule() {
-      this.$apis.findGroupRule(this.courseInfo.id)
-          .then(res =>{
-            this.maxSize=res.data.data.maxSize;
-            console.log(this.maxSize);
-            this.maxNameLen=res.data.data.maxNameLen;
-            console.log(this.maxNameLen);
-          });
-    },
-
-    beforeGroupFormClose() {
-      ElMessageBox.confirm("是否确认退出?退出后将不保存队伍信息。", "提示", {
-        confirmButtonText: "确认退出",
-        cancelButtonText: "我再想想",
-        type: "warning",
-        center: true,
-      })
-          .then(() => {
-            this.createGroupDialog = false;
-            this.$refs.createGroupFormRef.resetFields();
-          });
-    },
-    createTeam() {
-      this.$refs.createGroupFormRef.validate((valid) => {
-        if (valid) {
-          let GroupVO = {
-            courseId: this.courseInfo.id,
-            name: this.createTeamForm.name,
-          };
-          console.log(GroupVO);
-          this.$apis.createGroup(GroupVO)
-              .then(res => {
-                if (res.data.code) {
-                  ElMessage.error(res.data.message);
-                } else {
-                  this.isGroupExisted = true;
-                  this.createGroupDialog = false;
-                  this.$refs.createGroupFormRef.resetFields();
-                  ElMessage.success("创建队伍成功");
-                }
-              });
-        }
-      });
-    },
     // announcement
     handlePublishAnnouncement() {
       const _this = this;
@@ -1026,30 +951,120 @@ export default {
           }
         });
     },
+
     // project
-    handleProjectFormCancel(){
+    handleProjectFormCancel() {
       const _this = this;
       _this.projectDialogVisible = false;
       _this.$refs.projectFormRef.resetFields();
     },
-    async handleProjectFormConfirm(){
+
+    async handleProjectFormConfirm() {
       const _this = this;
       const res = (await _this.$apis.createProject({
         courseId: _this.courseInfo.id,
         ..._this.projectForm,
       })).data;
-      if(res.code){
+      if (res.code) {
         ElMessage.error(res.message);
-      }else{
-        if(_this.projectForm.isPublic){
+      } else {
+        if (_this.projectForm.isPublic) {
           _this.projects.public.push(res.data);
-        }else{
+        } else {
           _this.projects.private.push(res.data);
         }
         _this.projectDialogVisible = false;
         _this.$refs.projectFormRef.resetFields();
       }
-    }
+    },
+
+    async handleProjectSwitch(id) {
+      const _this = this;
+      const res = (await _this.$apis.updateCourseProjectState(id)).data;
+      if (!res.code) {
+        if (res.data) {
+          removeProject(_this.projects.private, _this.projects.public);
+        } else {
+          removeProject(_this.projects.public, _this.projects.private);
+        }
+      }
+
+      function removeProject(array1, array2) {
+        for (const index in array1) {
+          if (array1[index].id === id) {
+            array2.push(array1[index]);
+            array1.splice(index, 1);
+            return;
+          }
+        }
+      }
+    },
+
+    // group
+    beforeRuleFormClose() {
+      ElMessageBox.confirm("是否确认退出?退出后将不保存组队规则信息。", "提示", {
+        confirmButtonText: "确认退出",
+        cancelButtonText: "我再想想",
+        type: "warning",
+        center: true,
+      })
+        .then(() => {
+          this.ruleFormDialog = false;
+          this.$refs.ruleFormRef.resetFields();
+        });
+    },
+
+    createRule() {
+      this.$refs.ruleFormRef.validate((valid) => {
+        if (valid) {
+          let RuleVO = {
+            courseVO: {id: this.courseInfo.id},
+            maxSize: this.ruleForm.maxSize,
+            maxNameLen: this.ruleForm.maxNameLen,
+          };
+          console.log(RuleVO);
+          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();
+    },
+
+    createGroup() {
+      this.$refs.createGroupFormRef.validate((valid) => {
+        if (valid) {
+          let GroupVO = {
+            courseId: this.courseInfo.id,
+            name: this.createGroupForm.name,
+          };
+          this.$apis.createGroup(GroupVO)
+            .then(res => {
+              if (res.data.code) {
+                ElMessage.error(res.data.message);
+              } else {
+                this.isGroupExisted = true;
+                this.createGroupDialog = false;
+                this.$refs.createGroupFormRef.resetFields();
+                ElMessage.success("创建队伍成功");
+              }
+            });
+        }
+      });
+    },
+
   },
 };
 </script>