作业及管理系统(二)
害,开场白都不知道说什么了,就放上总篇和第一篇的链接吧,然后直接上代码和干货,本篇开始前端代码及后端代码将会一起讲解
基于springcloud+vue+element开发的作业及课程管理系统
话不多说,直接开干,如果遇到没有注释的方法,一般都是方法名就表示了这个方法干了什么东西
系统之学生模块
1.登录
系统中大部分表单都采用了element-ui的表单验证规则,可以自行添加每一个input的输入验证。
验证规则的前端代码:
rules: {
nickName: [{required: true, message: '请输入用户名', trigger: 'blur'}],
password: [{required: true, message: '请输入密码', trigger: 'blur'}]
},
html中调用验证规则只需要加上vue的绑定语法就可以调用,但是规则中的规则名一定要对应prop对象名
:rules="rules"
<el-form :model="ruleForm" :rules="rules"
status-icon
ref="ruleForm"
label-position="left"
label-width="0px"
class="demo-ruleForm login-page">
<h3 class="title">Python课程辅助学习系统-学生</h3>
<el-form-item prop="nickName">
<el-input type="text"
v-model="ruleForm.nickName"
auto-complete="off"
placeholder="用户名"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password"
v-model="ruleForm.password"
auto-complete="off"
placeholder="密码"
></el-input>
</el-form-item>
<el-checkbox
v-model="checked"
class="rememberme"
>记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button type="primary" style="width:100%;" @click="handleSubmit" >登录</el-button>
<el-button type="text" @click="changeOther(1)">切换到教师登录</el-button>
</el-form-item>
</el-form>
前端中的代码都是边学边做,一些是ctrl cv过来的,因此变量名不是特别规范,可能对象id对象名和应该对应的操作名对不上,但是不影响使用。
重点!!!!
在写这篇文章的时候,需要复盘代码以及截图,然后发现了一个致命的问题,一个以前都没有报过的错误!!!
Mybatis的参数注入问题。mybatis的xml文件中读取不到java传入的参数,提示这个参数没有被声明。一般这个问题都是由单词拼写错误造成的,但是!今天眼睛都看瞎了都没有看到哪里拼写错误了。最后问了一下公司架构师,他跟我说:加上下面的代码
HomeworkVo showStatus(@Param("homeworkId") String homeworkId, String uid)
看到啥不同了吗,加上@Param注解,并给value赋值。他说,尚不明确这个value的机制,但是不添加这个注解容易报错,报错的概率大概是买**中奖的概率,但是他就是会报错,加上!加上!
然而奇怪的是,homeworkId报错,但是uid居然没有报错,这就是命?
2.课程界面
这里应该是有一个路由控制,跳转到相应的课程号中去的,但是由于能力有限,只能写一个if-else标签,控制一下当前页面展示效果了:
可以看到这里的url是没有变得,变得只是标签的是否显示:
<div v-else-if="isDetail==1">
<el-page-header @back="goBack" content="课程详情页面" ></el-page-header>
<h2 style="text-align: center;">{{courseDetail.name}}</h2>
<h4 style="text-align: center;">创建时间:{{courseDetail.createTime}} 任课教师:{{courseDetail.teacher}}</h4>
<div v-html="courseDetail.courseContext"></div>
<el-button type="button" @click="open">点击加入此课程</el-button>
</div>
可以看到这里用了一个isDetail的参数控制,这里原本上应该是配置一个动态路由的,但是由于偷懒不想学习就用这个方式了,见谅见谅
下方有个加入课程的按钮,点击以后就会自动加入课程,教师可以看到谁加入了课程,以及该课程下的作业提交情况。(教师部分放在后面几期展示)
加入课程最重要的一点是要注意添加相应的作业提交状态,不然课程提交了,作业没有提交,gg了。
这个地方点击下载是可以下载附件的,url上传到oss服务器中,并将读取url存到数据库里。当然,这个url也只能坚持三分钟。(真oss,就是快!)
附件这里用的是element表格,但是这个长度不知道是哪里设置的不对,硬是窄窄的,那就没办法了,随他吧。
具体的后台代码无非就是CRUD
作业提交部分
作业提交这里是个小难点,放下代码详细说明一下:
<el-upload
class="upload-demo"
action="http://localhost:9502/student/homework/uploadHomework"
:on-success="upSuccess"
multiple
:data="updata"
:limit="1"
:file-list="fileList">
<el-button
type="text"
size="mini"
@click="upHomework(scope.$index, scope.row)">提交</el-button>
</el-upload>
这里使用了elment-ui的upload组件,并且把上传按钮嵌入进了button,原本是一个比较大的框。这里的action是文件上传的地址,:data属性是上传时携带的对象(数据)
/**
* 提交作业
* @param file
* @param upDataVo
* @return
*/
@RequestMapping(value = "/uploadHomework",produces = "application/json;charset=utf-8")
@ResponseBody
public Result uploadHomework(@RequestParam("file") MultipartFile file, UpDataVo upDataVo){
System.out.println(file.getOriginalFilename());
return homeworkService.uplodHomework(file,upDataVo.getHomeworkId(),upDataVo.getUid());
}
因为是文件传递,在前端传递文件的时候,header里面的传参方式为
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLYbfTklDepmyG3OA
可以看出不是传统的application/json;charset=utf-8
这样就会导致文件可以正常接收,但是参数不会正常传递(因为是post请求,使用了实体传参)。
所以在后端接受的时候要指定接收参数形式为application/json,这样既可正常接收文件,也可以接受实体参数。
搜索作业里面使用了模糊搜索,效率比较低,但是演示是够了,当时测试十万数据时居然出现了一次慢查询,但是后面平均在五秒左右,可能是电脑当时运行效率太低了。
SELECT ph.id as homeworkId,ph.name as homeworkName,pt.name as teacherName,pc.name as courseName,ph.createtime as createTime,ph.context as context
FROM pd_homework_status as phs,pd_homework as ph,pd_teacher as pt,pd_course as pc
WHERE
phs.uid=#{uid} AND ph.id=phs.homeworkid AND ph.teacherid=pt.uid AND ph.courseid=pc.courseid AND pc.isdelete=0
AND concat(ph.`name`,pc.name,pt.`name`) LIKE "%"#{keywords}"%"
注意这里"%"#{keywords}"%"的写法,mysql中是’%keywords%’,如果直接在xml中这样写,就会转换成keword = %‘keword’%,他会无法识别百分号,一定要用双括号框起来。
信息修改,密码修改,取消选课都是很基础的CRUD,这里就不做具体的展示了
在个人中心里,有一个模块式论坛管理,这里可以发布自己的帖子,引入了富文本编辑器,使用的是quill-editor,自己修改了一下。但是没有提供图片上传功能,因为那个三分钟bug没有解决,我就删除了这个功能,只提供简单的代码块和大部分文字的支持。(大部分还是支持的,就是没有图片感觉文章有点素)
最后因为数据量大,原因入的是page-helper分页的,但是好像业务逻辑上面有点不同步,数据处理的部分有点多,所以就自己写了一个分页,当时测试的时候一万条数据一下没有影响,数据上了五万开始慢下来。
/**
* @author wangyb
*/
@Data
public class PageResult {
int nowPage;
int total;
int pageSize;
int thisSize;
List<Object> pageEntity;
public Result pageRes(PageResult pr){
HandleResult hr=new HandleResult();
return hr.outResultWithData("0","success",pr);
}
public List<Object> pageStarter(int pageNum,int pageSize,List<Object> o){
if(null!=o&&!o.isEmpty()){
return pageReturn(pageNum,pageSize,o);
}
return null;
}
public List<Object> pageReturn(int pageNum, int pageSize, List<Object> o){
this.nowPage=pageNum;
if(pageNum<1)
return null;
List<Object> temp=new ArrayList<>();
this.pageSize=pageSize;
if(o.size()%pageSize>0){
this.total=o.size()/pageSize+1;
}else{
this.total=o.size()/pageSize;
}
if(pageNum>this.total)
return null;
for(int i=(pageNum-1)*pageSize;i<=pageNum*pageSize-1;i++){
if(i==o.size()){
break;
}
temp.add(o.get(i));
}
this.pageEntity=temp;
this.thisSize=temp.size();
return temp;
}
}
学生篇大部分就是这样子,如果后面还有什么需要修改的,或者又错误的,我会及时更正。如果大佬们在阅读的时候有发现那里不正确或者讲的不太好的地方,欢迎留言批评指正!