前言
项目地址
本项目是为开发一套容器化的开发、运行、测试环境,用以支持Web开发、程序设计等课程的实验教学。
任务
教师端建立组织,得到组织邀请码,并可以设置课程时间、发布作业、发布通知等操作。
学生端可以根据邀请码搜索并加入组织,并添加了通知模块。
教师组织模块
<el-tab-pane label="组织中心" name="1">
<el-dialog v-model="createCurrFormVisible" title="添加组织" width="30%">
<el-form>
<el-form-item label="课程名字" label-width="100px">
<el-input v-model="createCurrForm.name" autocomplete="off" />
</el-form-item>
<el-form-item label="课序号" label-width="100px">
<el-input v-model="createCurrForm.courseId" autocomplete="off" />
</el-form-item>
<el-form-item label="课称介绍" label-width="100px">
<el-input v-model="createCurrForm.des" autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="createCurrFormVisible = false">取消</el-button>
<el-button type="primary" @click="ConfirmAddCurr">确认</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="updateCurrFormVisible" title="修改信息" width="30%">
<el-form>
<el-form-item label="课程名字" label-width="100px">
<el-input v-model="updateCurrForm.name" autocomplete="off" />
</el-form-item>
<el-form-item label="课序号" label-width="100px">
<el-input v-model="updateCurrForm.courseId" autocomplete="off" />
</el-form-item>
<el-form-item label="课称介绍" label-width="100px">
<el-input v-model="updateCurrForm.des" autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="updateCurrFormVisible = false">取消</el-button>
<el-button type="primary" @click="ConfirmUpdateCurr">确认</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="releaseHWFormVisible" title="发布作业" width="30%">
<el-form>
<el-form-item label="作业内容" label-width="100px">
<el-input v-model="releaseHWForm.content" autocomplete="off" />
</el-form-item>
<el-form-item label="截止日期" label-width="100px">
<el-date-picker v-model="releaseHWForm.ddl" type="date" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="releaseHWFormVisible = false">取消</el-button>
<el-button type="primary" @click="ConfirmReleaseHW">确认</el-button>
</span>
</template>
</el-dialog>
<el-button @click="AddCurriculum">添加组织</el-button>
<el-collapse>
<el-collapse-item v-for="(curriculum, currIdx) in curriculumData"
:title="curriculum.title + '(课序号:' + curriculum.data[0].courseId + ')'" :name="curriculum.id">
<el-row>
<el-col :span="2">
<span>邀请码:{{ curriculum.data[0].code }}</span>
</el-col>
<!-- <el-col :span="3">
<el-button @click="ImportBatchStudent">批次导入学生</el-button>
</el-col>
<el-col :span="3">
<el-button @click="ImportOneStudent">导入单个学生</el-button>
</el-col> -->
<!-- <el-col :span="18" /> -->
<el-col :span="1">
<el-button @click="DeleteCurr(currIdx)">删除组织</el-button>
</el-col>
<el-col :span="1"></el-col>
<el-col :span="1">
<el-button @click="UpdateCurrInfo(currIdx)">修改信息</el-button>
</el-col>
</el-row>
<el-table :data="curriculum.data" style="width: 100%">
<el-table-column label="时间" width="430">
<el-date-picker v-model="curriculum.data[0].time" type="datetimerange" range-separator="To"
start-placeholder="开始日期" end-placeholder="结束日期" />
</el-table-column>
<el-table-column label="具体描述" width="580">
<el-input v-model="curriculum.data[0].description" :rows="2" type="textarea" placeholder="请输入..." />
</el-table-column>
<el-table-column fixed="right" label="操作" width="200">
<el-button type="text" size="large" @click="releaseHW(curriculum)">发布作业</el-button>
<el-button type="text" size="large" @click="releaseNotice(curriculum)">发布通知</el-button>
</el-table-column>
</el-table>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<script lang="ts">
//组织中心
interface StudentDataI {
name: string,
email: string,
message: string,
score: number
}
interface CurriculumDataIf {
title: string,
id: string,
data: [{
time: any,
description: string,
code: string,
courseId: string
}],
student: StudentDataI[]
}
const curriculumData = ref<CurriculumDataIf[]>([]);
const createCurrFormVisible = ref(false);
const createCurrForm = reactive({
name: '',
courseId: '',
des: ''
})
const updateCurrFormVisible = ref(false);
const updateCurrForm = reactive({
name: '',
courseId: '',
des: '',
idx: -1
})
const releaseHWFormVisible = ref(false);
const releaseHWForm = reactive({
content: '',
ddl: new Date(),
curr:{}
})
const AddCurriculum = () => {
createCurrForm.name = '';
createCurrForm.courseId = '';
createCurrForm.des = '';
createCurrFormVisible.value = true;
}
const ConfirmAddCurr = () => {
let param = new FormData();
param.append('name', createCurrForm.name);
param.append('desc', createCurrForm.des);
param.append('courseId', createCurrForm.courseId);
request('/weblab/organization/createOrg', param)
.then(res => {
let createData = res.data;
let code = '';
let getMessageParam = new FormData();
getMessageParam.append('orgId', createData.pkg);
request('/weblab/organization/getOrgMessageById', param)
.then(res => {
code = res.data.pkg.code;
})
.catch(error => {
console.log(error);
})
curriculumData.value!.push({
title: createCurrForm.name,
id: `${createData.pkg}`,
student: [
{
name: '张三',
email: '123@126.com',
message: '这是张三同学这是张三同学这是张三同学这是张三同学这是张三同学',
score: 0,
}
],
data: [{
time: ['Wed May 18 2022 00:00:00 GMT+0800 (香港标准时间)', 'Wed May 18 2022 01:01:02 GMT+0800 (香港标准时间)'],
code: code,
courseId: createCurrForm.courseId,
description: createCurrForm.des
}]
})
createCurrFormVisible.value = false;
})
.catch(error => {
console.log(error)
})
}
const DeleteCurr = (currIdx: number) => {
ElMessageBox.confirm('将删除该组织,继续?', 'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
})
.then(() => {
curriculumData.value.splice(currIdx, 1);
})
.catch(() => {
})
}
const UpdateCurrInfo = (currIdx: number) => {
updateCurrForm.name = '';
updateCurrForm.courseId = '';
updateCurrForm.des = '';
updateCurrForm.idx = currIdx;
updateCurrFormVisible.value = true;
}
const ConfirmUpdateCurr = () => {
let param = new FormData();
const currData = curriculumData.value[updateCurrForm.idx];
param.append('id', currData.id);
param.append('name', updateCurrForm.name);
param.append('desc', updateCurrForm.des);
param.append('courseId', updateCurrForm.courseId);
request('/weblab/organization/updateOrg', param)
.then(res => {
currData.title = updateCurrForm.name;
currData.data[0].courseId = updateCurrForm.courseId;
currData.data[0].description = updateCurrForm.des;
})
updateCurrFormVisible.value = false;
}
const ImportBatchStudent = () => {
}
const ImportOneStudent = () => {
}
const releaseHW = (curr: CurriculumDataIf) => {
releaseHWForm.content='';
releaseHWForm.curr=curr;
releaseHWFormVisible.value = true;
}
const ConfirmReleaseHW = () => {
releaseHWFormVisible.value = false;
const date=releaseHWForm.ddl;
console.log(date.getFullYear() ,date.getMonth()+1,date.getDate())
}
const releaseNotice = (curr: CurriculumDataIf) => {
ElMessageBox.prompt('输入通知内容', '发布通知', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
})
.then(({ value }) => {
ElMessage({
type: 'success',
message: `通知发布成功!`,
})
})
.catch(() => {
})
}
</script>
教师查看作业模块
<el-tab-pane label="课程作业" name="2">
<el-collapse>
<el-collapse-item v-for="(curriculum, cuuIdx) in curriculumData"
:title="curriculum.title + '(课序号:' + curriculum.data[0].courseId + ')'" :name="curriculum.id">
<el-collapse>
<el-table :data="curriculum.student" style="width: 100%">
<el-table-column prop="name" label="Name" width="150" />
<el-table-column prop="email" label="Email" width="180" />
<el-table-column prop="message" label="Message" width="180" />
<el-table-column prop="score" label="Score" width="200">
<template #default="scope">
<el-rate v-model="scope.row.score" :texts="['oops', 'disappointed', 'normal', 'good', 'great']"
show-text @change="onScoreChange(scope.row)" />
</template>
</el-table-column>
<el-table-column fixed="right" prop="Homework" label="Homework" width="170">
<el-button type="text" size="small" @click="DownloadHomework">gitee地址</el-button>
</el-table-column>
</el-table>
</el-collapse>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
学生组织模块
<el-main v-show="activeIndex == '5'">
<el-header>
<el-row :gutter="20">
<el-col :span="3">
<el-input v-model="invitationCode" placeholder="组织邀请码" :style="{width:'200px'} "/>
</el-col>
<el-col :span="6">
<el-button text @click="addOrganization()">添加组织</el-button>
</el-col>
<el-col :span="6" />
<el-col :span="6" />
</el-row>
</el-header>
<el-main>
<el-table :data="organizationData" border style="width: 100%">
<el-table-column prop="lesson" label="课程" width="510px" />
<el-table-column prop="class" label="班级" width="510px" />
<el-table-column width="110px">
<template #default="scope">
<el-button text size="small" @click="deleteOrganization(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-main>
</el-main>
任务和项目模块
<el-main v-show="activeIndex == '2'">
<el-tabs v-model="activeProjectTabName" class="demo-tabs" @tab-click="handleProjectTabClick">
<el-tab-pane label="课程任务" name="1">
<el-main>
<el-dialog v-model="choseProjectFormVisible" title="选择项目" width="30%">
<el-form>
<el-form-item label="项目名称" label-width="100px">
<el-cascader
v-model="choseProject"
placeholder="项目搜索"
:options="projectData"
filterable
:props="choseProjectProps"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="choseProjectFormVisible = false">取消</el-button>
<el-button type="primary" @click="submitProject">确认</el-button>
</span>
</template>
</el-dialog>
<el-table :data="homeworkTableData" border style="width: 100%">
<el-table-column prop="lesson" label="课程" width="180" />
<el-table-column prop="date" label="截止日期" sortable width="180">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-icon>
<timer />
</el-icon>
<span style="margin-left: 10px">{{ scope.row.date }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="mission" label="任务简介" />
<el-table-column prop="finish" label="任务进度" width="100"/>
<el-table-column fixed="right" width="200">
<template #default="scope">
<el-button text size="small" @click="checkDetail(scope.row.missionDetail)">查看详情</el-button>
<el-button text size="small" @click="choseProjectFormVisible=true">提交作业</el-button>
</template>
</el-table-column>
</el-table>
</el-main>
</el-tab-pane>
<el-tab-pane label="课程通知" name="2">
<el-table :data="noticeTableData" border style="width: 100%">
<el-table-column prop="className" label="课程" width="180" />
<el-table-column prop="date" label="发布日期" sortable width="180">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-icon>
<timer />
</el-icon>
<span style="margin-left: 10px">{{ scope.row.date }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="detail" label="通知内容" />
<el-table-column fixed="right" width="180">
<template #default="scope">
<el-button text size="small" @click="checkDetail(scope.row.detail)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="我的项目" name="3">
<div v-show="!showDetail">
<el-header>
<el-button @click="addProject()">
添加<el-icon class="el-icon--right">
<Plus />
</el-icon>
</el-button>
<el-button @click="deleteProject()">
删除<el-icon class="el-icon--right">
<Delete />
</el-icon>
</el-button>
<el-button @click="downloadProject()">
下载<el-icon class="el-icon--right">
<Bottom />
</el-icon>
</el-button>
</el-header>
<el-main>
<el-dialog v-model="createProjectFormVisible" title="添加项目" width="30%">
<el-form :model="createProjectForm">
<el-form-item label="项目名称" label-width="100px">
<el-input v-model="createProjectForm.name" autocomplete="off" />
</el-form-item>
<el-form-item label="项目简介" label-width="100px">
<el-input type="textarea" v-model="createProjectForm.description" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="createProjectFormVisible = false">取消</el-button>
<el-button type="primary" @click="confirmAddProject">确认</el-button>
</span>
</template>
</el-dialog>
<el-table ref="projectTableRef" :data="projectData" border style="width: 100%"
@selection-change="handleProjectSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="projectName" label="项目名字" width="180">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-icon>
<folder />
</el-icon>
<span style="margin-left: 10px">{{ scope.row.projectName }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="date" label="上次更新" width="180" />
<el-table-column prop="introduction" label="项目简介" />
<el-table-column fixed="right" width="220">
<template #default="scope">
<el-button text size="small" @click="showProjectDetail(scope.row)">项目详情</el-button>
<el-button text size="small" @click="editProject(scope.raw)">编辑项目</el-button>
</template>
</el-table-column>
</el-table>
</el-main>
</div>
<div v-show="showDetail">
<el-main>
<el-page-header content="项目详情" @back="closeProjectDetail" />
<el-container>
<el-main>
<el-table :data="selectedProjectDetail?.files" style="width: 100%">
<el-table-column prop="name" label="文件夹名字" width="180">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-icon>
<folder />
</el-icon>
<el-button type="text" style="margin-left: 10px">{{ scope.row.name }}</el-button>
</div>
</template>
</el-table-column>
<el-table-column prop="date" label="上次更新" width="180" />
<el-table-column prop="introduction" label="简介" />
<el-table-column fixed="right" width="120">
<template #default="scope">
<el-button text size="small" @click="deleteProjecFolder(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-main>
<el-divider />
<h6>项目输出日志</h6>
<div class="demo-radius">
<el-input type="textarea" class="example-demonstration">{{selectedProjectDetail?.outputlog}}</el-input>
</div>
</el-main>
</el-main>
<el-aside width="300px">
<el-row>
<el-col :span="2">
<el-divider direction="vertical" style="height: 800px" />
</el-col>
<el-col :span="22">
<el-form label-width="120px">
<el-form-item size="large" label="项目介绍">
</el-form-item>
<el-input type="textarea" class="example-demonstration">{{selectedProjectDetail?.introduction}}</el-input>
</el-form>
</el-col>
</el-row>
</el-aside>
</el-container>
</el-main>
</div>
</el-tab-pane>
</el-tabs>
</el-main>
//项目中心
//课程任务
const choseProjectFormVisible = ref(false);
const choseProjectProps={
label:'projectName',
value:'projectName'
}
const choseProject=ref('');
const homeworkTableData = ref<hwDataIF[]>([
{
lesson: '项目实训',
mission: '任务简介',
date: '2022-05-15',
missionDetail: '用vue3+springboot完成一个简单的前后端分离项目',
finish:'已完成'
},
{
lesson: '项目实训',
mission: '任务简介',
date: '2022-06-15',
missionDetail: '用vue3+springboot完成一个简单的前后端分离项目',
finish:'未完成'
},
])
//查看作业详情
const checkDetail = (detail: string) => {
ElMessageBox.alert(detail, '详情', {
confirmButtonText: 'OK',
})
}
//提交项目
const submitProject=()=>{
choseProjectFormVisible.value = false
console.log(choseProject.value)
}
//课程通知
interface noticetDataIF {
className: string,
date: string,
detail: string
}
const noticeTableData=ref<noticetDataIF[]>([
{
className:'项目实训',
date:'2022-5-24',
detail:'请同学们与6-30前提交作业'
}
]);
//我的项目
const showDetail = ref(false);
const activeProjectTabName = ref('1');
const createProjectFormVisible = ref(false);
const createProjectForm = reactive({
name: '',
description: ''
})
const projectTableRef = ref<InstanceType<typeof ElTable>>()
const selectedProject = ref<projectDataIF[]>();
const selectedProjectDetail = ref<projectDetailIF>();
//任务数据
interface hwDataIF {
lesson: string,
mission: string,
date: string,
missionDetail: string,
finish:string
}
//项目数据
//项目详情内容
interface projectFilesIF {
name: string,
date: string,
introduction: string
}
interface projectDetailIF {
outputlog: string,
introduction: string,
files: projectFilesIF[]
}
interface projectDataIF {
projectName: string,
introduction: string,
date: string,
detail: projectDetailIF
}
const projectData = ref<projectDataIF[]>([
{
projectName: '项目实训',
introduction: '项目实训简介',
date: '2022-05-15',
detail: {
outputlog: '输出日志',
introduction: '项目介绍',
files: [
{
name: 'src',
introduction: 'src',
date: '2022-05-15',
},
{
name: 'views',
introduction: 'views',
date: '2022-05-15',
},
]
}
},
{
projectName: 'web',
introduction: 'web简介',
date: '2022-05-15',
detail: {
outputlog: '输出日志',
introduction: '项目介绍',
files: [
{
name: 'src',
introduction: 'src',
date: '2022-05-15',
},
{
name: 'views',
introduction: 'views',
date: '2022-05-15',
},
]
}
},
])
//编辑项目
const editProject = (data: projectDataIF) => {
activeIndex.value = '4'
}
//查看项目详情
const showProjectDetail = (data: projectDataIF) => {
const idx = projectData.value.findIndex(item => item == data);
selectedProjectDetail.value = projectData.value[idx].detail;
showDetail.value = true;
}
const closeProjectDetail = () => {
showDetail.value = false;
}
//删除项目内容
const deleteProjecFolder = (index: number) => {
ElMessageBox.confirm('将删除该文件,继续?', 'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
})
.then(() => {
selectedProjectDetail.value?.files.splice(index, 1);
})
}
//添加项目
const addProject = () => {
createProjectFormVisible.value = true;
}
const confirmAddProject = () => {
createProjectFormVisible.value = false;
projectData.value.push({
projectName: createProjectForm.name,
introduction: createProjectForm.description,
date: getFormDate(),
detail: {
outputlog: '',
introduction: '',
files: []
}
})
}
//删除项目
const deleteProject = () => {
ElMessageBox.confirm('将删除选中的项目,继续?', 'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
})
.then(() => {
projectData.value = projectData.value.filter((x) => !selectedProject.value!.some((item) => x.projectName === item.projectName));
projectTableRef.value!.clearSelection();
})
}
//下载项目
const downloadProject = () => {
projectTableRef.value!.clearSelection();
}