✨作者主页:IT毕设梦工厂✨
个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。
☑文末获取源码☑
精彩专栏推荐⬇⬇⬇
Java项目
Python项目
安卓项目
微信小程序项目
一、前言
教育行业对教师工作量的准确统计和管理是衡量教学质量和教师绩效的重要环节。随着高等教育规模的不断扩大,教师的工作量统计工作也变得越来越复杂。据统计,中国高等教育在校生人数已超过4000万,教师数量也达到了数百万之多。在这种背景下,传统的手工统计方法不仅效率低下,而且容易出错,难以适应现代教育管理的需求。此外,教师工作量统计的准确性直接影响到教师的绩效评价、薪酬分配以及教学资源的合理配置。
现有的教学工作量统计方法多依赖于手工记录和Excel表格处理,这些方法存在诸多问题。例如,数据分散在不同的表格中,难以实现集中管理和实时更新;手工输入数据容易出错,且难以追踪错误来源;Excel表格在处理大量数据时性能受限,影响统计效率;此外,缺乏有效的数据分析工具,使得从统计数据中提取有价值的信息变得困难。这些问题不仅增加了教学管理部门的工作负担,也影响了教学资源的合理分配和教师的权益保障。
本课题旨在设计并实现一个学院教学工作量统计系统,以解决现有统计方法中存在的问题。系统将提供一个统一的平台,实现教师工作量的在线录入、管理和统计;支持数据的批量导入和导出,提高数据管理的效率;具备强大的数据处理和分析功能,帮助管理部门快速获取教师工作量的统计结果;并提供用户友好的操作界面,简化教师和管理人员的工作流程。通过本课题的研究,希望能够为学院提供一个便捷、准确、便捷的教学工作量统计解决方案。
在学院教学工作量统计系统中,管理人员角色负责教师账户的创建与管理、工作量信息的综合管理(包括增加、删除、修改、查询)以及数据的导出和年度工作量统计,确保教学工作量数据的准确性和系统的运行;教师角色则能够进行个人工作量信息的自我管理(包括增加、删除、修改、查询)并利用导入功能批量更新教学工作量数据,实现教学活动的准确记录和便捷管理。系统通过这些功能模块的整合,旨在为学院提供一个全局、便捷的教学工作量统计和管理平台。
本课题的研究具有重要的理论意义和实际意义。从理论角度来看,它为教学管理领域提供了新的研究思路,即通过信息技术手段优化教学工作量统计流程,有助于推动教育管理理论和实践的创新。从实际角度来看,该系统的应用将显著提高教学工作量统计的效率和准确性,减轻教学管理部门的工作负担,保障教师的权益,促进教学资源的合理配置。同时,系统的推广应用也将为其他教育机构提供借鉴,推动整个教育行业的信息化和现代化进程。
二、开发环境
- 开发语言:Java/Python
- 数据库:MySQL
- 系统架构:B/S
- 后端:SpringBoot/SSM/Django/Flask
- 前端:Vue
三、系统界面展示
- 学院教学工作量统计系统界面展示:
教师-教师工作量信息管理:
教师-导入教师工作量信息:
管理员-教师工作量信息管理:
管理员-导出教师工作量信息:
管理员-年度工作量统计:
管理员-教师管理:
四、部分代码设计
- 项目实战-代码参考:
@RestController
@Controller
@RequestMapping("/togzhi")
public class TogzhiController {
private static final Logger logger = LoggerFactory.getLogger(TogzhiController.class);
@Autowired
private TogzhiService togzhiService;
@Autowired
private TokenService tokenService;
@Autowired
private DictionaryService dictionaryService;
//级联表service
@Autowired
private JiaoshiService jiaoshiService;
/**
* 后端列表
*/
@RequestMapping("/page")
public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永不会进入");
else if("教师".equals(role))
params.put("jiaoshiId",request.getSession().getAttribute("userId"));
if(params.get("orderBy")==null || params.get("orderBy")==""){
params.put("orderBy","id");
}
PageUtils page = togzhiService.queryPage(params);
//字典表数据转换
List<TogzhiView> list =(List<TogzhiView>)page.getList();
for(TogzhiView c:list){
//修改对应字典表字段
dictionaryService.dictionaryConvert(c, request);
}
return R.ok().put("data", page);
}
/**
* 后端详情
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
TogzhiEntity togzhi = togzhiService.selectById(id);
if(togzhi !=null){
//entity转view
TogzhiView view = new TogzhiView();
BeanUtils.copyProperties( togzhi , view );//把实体数据重构到view中
//级联表
JiaoshiEntity jiaoshi = jiaoshiService.selectById(togzhi.getJiaoshiId());
if(jiaoshi != null){
BeanUtils.copyProperties( jiaoshi , view ,new String[]{ "id", "createTime", "insertTime", "updateTime"});//把级联的数据添加到view中,并排除id和创建时间字段
view.setJiaoshiId(jiaoshi.getId());
}
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 后端保存
*/
@RequestMapping("/save")
public R save(@RequestBody TogzhiEntity togzhi, HttpServletRequest request){
logger.debug("save方法:,,Controller:{},,togzhi:{}",this.getClass().getName(),togzhi.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永远不会进入");
else if("教师".equals(role))
togzhi.setJiaoshiId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));
Wrapper<TogzhiEntity> queryWrapper = new EntityWrapper<TogzhiEntity>()
.eq("jiaoshi_id", togzhi.getJiaoshiId())
.eq("togzhi_name", togzhi.getTogzhiName())
.eq("togzhi_types", togzhi.getTogzhiTypes())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
TogzhiEntity togzhiEntity = togzhiService.selectOne(queryWrapper);
if(togzhiEntity==null){
togzhi.setInsertTime(new Date());
togzhi.setCreateTime(new Date());
togzhiService.insert(togzhi);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
/**
* 后端修改
*/
@RequestMapping("/update")
public R update(@RequestBody TogzhiEntity togzhi, HttpServletRequest request){
logger.debug("update方法:,,Controller:{},,togzhi:{}",this.getClass().getName(),togzhi.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
// if(false)
// return R.error(511,"永远不会进入");
// else if("教师".equals(role))
// togzhi.setJiaoshiId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));
//根据字段查询是否有相同数据
Wrapper<TogzhiEntity> queryWrapper = new EntityWrapper<TogzhiEntity>()
.notIn("id",togzhi.getId())
.andNew()
.eq("jiaoshi_id", togzhi.getJiaoshiId())
.eq("togzhi_name", togzhi.getTogzhiName())
.eq("togzhi_types", togzhi.getTogzhiTypes())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
TogzhiEntity togzhiEntity = togzhiService.selectOne(queryWrapper);
if(togzhiEntity==null){
togzhiService.updateById(togzhi);//根据id更新
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Integer[] ids){
logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
togzhiService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
/**
* 批量上传
*/
@RequestMapping("/batchInsert")
public R save( String fileName){
logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);
try {
List<TogzhiEntity> togzhiList = new ArrayList<>();//上传的东西
Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段
Date date = new Date();
int lastIndexOf = fileName.lastIndexOf(".");
if(lastIndexOf == -1){
return R.error(511,"该文件没有后缀");
}else{
String suffix = fileName.substring(lastIndexOf);
if(!".xls".equals(suffix)){
return R.error(511,"只支持后缀为xls的excel文件");
}else{
URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径
File file = new File(resource.getFile());
if(!file.exists()){
return R.error(511,"找不到上传文件,请联系管理员");
}else{
List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件
dataList.remove(0);//删除第一行,因为第一行是提示
for(List<String> data:dataList){
//循环
TogzhiEntity togzhiEntity = new TogzhiEntity();
// togzhiEntity.setJiaoshiId(Integer.valueOf(data.get(0))); //教师 要改的
// togzhiEntity.setTogzhiName(data.get(0)); //通知标题 要改的
// togzhiEntity.setTogzhiTypes(Integer.valueOf(data.get(0))); //通知类型 要改的
// togzhiEntity.setInsertTime(date);//时间
// togzhiEntity.setTogzhiContent("");//照片
// togzhiEntity.setCreateTime(date);//时间
togzhiList.add(togzhiEntity);
//把要查询是否重复的字段放入map中
}
//查询是否重复
togzhiService.insertBatch(togzhiList);
return R.ok();
}
}
}
}catch (Exception e){
return R.error(511,"批量插入数据异常,请联系管理员");
}
}
}
@RestController
@Controller
@RequestMapping("/jiaoshi")
public class JiaoshiController {
private static final Logger logger = LoggerFactory.getLogger(JiaoshiController.class);
@Autowired
private JiaoshiService jiaoshiService;
@Autowired
private TokenService tokenService;
@Autowired
private DictionaryService dictionaryService;
//级联表service
/**
* 后端列表
*/
@RequestMapping("/page")
public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永不会进入");
else if("教师".equals(role))
params.put("jiaoshiId",request.getSession().getAttribute("userId"));
if(params.get("orderBy")==null || params.get("orderBy")==""){
params.put("orderBy","id");
}
PageUtils page = jiaoshiService.queryPage(params);
//字典表数据转换
List<JiaoshiView> list =(List<JiaoshiView>)page.getList();
for(JiaoshiView c:list){
//修改对应字典表字段
dictionaryService.dictionaryConvert(c, request);
}
return R.ok().put("data", page);
}
/**
* 后端详情
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
JiaoshiEntity jiaoshi = jiaoshiService.selectById(id);
if(jiaoshi !=null){
//entity转view
JiaoshiView view = new JiaoshiView();
BeanUtils.copyProperties( jiaoshi , view );//把实体数据重构到view中
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 后端保存
*/
@RequestMapping("/save")
public R save(@RequestBody JiaoshiEntity jiaoshi, HttpServletRequest request){
logger.debug("save方法:,,Controller:{},,jiaoshi:{}",this.getClass().getName(),jiaoshi.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永远不会进入");
Wrapper<JiaoshiEntity> queryWrapper = new EntityWrapper<JiaoshiEntity>()
.eq("username", jiaoshi.getUsername())
.or()
.eq("jiaoshi_phone", jiaoshi.getJiaoshiPhone())
.or()
.eq("jiaoshi_id_number", jiaoshi.getJiaoshiIdNumber())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
JiaoshiEntity jiaoshiEntity = jiaoshiService.selectOne(queryWrapper);
if(jiaoshiEntity==null){
jiaoshi.setCreateTime(new Date());
jiaoshi.setPassword("123456");
jiaoshiService.insert(jiaoshi);
return R.ok();
}else {
return R.error(511,"账户或者教师手机号或者教师身份证号已经被使用");
}
}
/**
* 后端修改
*/
@RequestMapping("/update")
public R update(@RequestBody JiaoshiEntity jiaoshi, HttpServletRequest request){
logger.debug("update方法:,,Controller:{},,jiaoshi:{}",this.getClass().getName(),jiaoshi.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
// if(false)
// return R.error(511,"永远不会进入");
//根据字段查询是否有相同数据
Wrapper<JiaoshiEntity> queryWrapper = new EntityWrapper<JiaoshiEntity>()
.notIn("id",jiaoshi.getId())
.andNew()
.eq("username", jiaoshi.getUsername())
.or()
.eq("jiaoshi_phone", jiaoshi.getJiaoshiPhone())
.or()
.eq("jiaoshi_id_number", jiaoshi.getJiaoshiIdNumber())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
JiaoshiEntity jiaoshiEntity = jiaoshiService.selectOne(queryWrapper);
if("".equals(jiaoshi.getJiaoshiPhoto()) || "null".equals(jiaoshi.getJiaoshiPhoto())){
jiaoshi.setJiaoshiPhoto(null);
}
if(jiaoshiEntity==null){
jiaoshiService.updateById(jiaoshi);//根据id更新
return R.ok();
}else {
return R.error(511,"账户或者教师手机号或者教师身份证号已经被使用");
}
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Integer[] ids){
logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
jiaoshiService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
/**
* 批量上传
*/
@RequestMapping("/batchInsert")
public R save( String fileName){
logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);
try {
List<JiaoshiEntity> jiaoshiList = new ArrayList<>();//上传的东西
Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段
Date date = new Date();
int lastIndexOf = fileName.lastIndexOf(".");
if(lastIndexOf == -1){
return R.error(511,"该文件没有后缀");
}else{
String suffix = fileName.substring(lastIndexOf);
if(!".xls".equals(suffix)){
return R.error(511,"只支持后缀为xls的excel文件");
}else{
URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径
File file = new File(resource.getFile());
if(!file.exists()){
return R.error(511,"找不到上传文件,请联系管理员");
}else{
List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件
dataList.remove(0);//删除第一行,因为第一行是提示
for(List<String> data:dataList){
//循环
JiaoshiEntity jiaoshiEntity = new JiaoshiEntity();
// jiaoshiEntity.setUsername(data.get(0)); //账户 要改的
// //jiaoshiEntity.setPassword("123456");//密码
// jiaoshiEntity.setJiaoshiName(data.get(0)); //教师姓名 要改的
// jiaoshiEntity.setJiaoshiPhone(data.get(0)); //教师手机号 要改的
// jiaoshiEntity.setJiaoshiIdNumber(data.get(0)); //教师身份证号 要改的
// jiaoshiEntity.setJiaoshiPhoto("");//照片
// jiaoshiEntity.setSexTypes(Integer.valueOf(data.get(0))); //性别 要改的
// jiaoshiEntity.setJiaoshiEmail(data.get(0)); //电子邮箱 要改的
// jiaoshiEntity.setCreateTime(date);//时间
jiaoshiList.add(jiaoshiEntity);
//把要查询是否重复的字段放入map中
//账户
if(seachFields.containsKey("username")){
List<String> username = seachFields.get("username");
username.add(data.get(0));//要改的
}else{
List<String> username = new ArrayList<>();
username.add(data.get(0));//要改的
seachFields.put("username",username);
}
//教师手机号
if(seachFields.containsKey("jiaoshiPhone")){
List<String> jiaoshiPhone = seachFields.get("jiaoshiPhone");
jiaoshiPhone.add(data.get(0));//要改的
}else{
List<String> jiaoshiPhone = new ArrayList<>();
jiaoshiPhone.add(data.get(0));//要改的
seachFields.put("jiaoshiPhone",jiaoshiPhone);
}
//教师身份证号
if(seachFields.containsKey("jiaoshiIdNumber")){
List<String> jiaoshiIdNumber = seachFields.get("jiaoshiIdNumber");
jiaoshiIdNumber.add(data.get(0));//要改的
}else{
List<String> jiaoshiIdNumber = new ArrayList<>();
jiaoshiIdNumber.add(data.get(0));//要改的
seachFields.put("jiaoshiIdNumber",jiaoshiIdNumber);
}
}
//查询是否重复
//账户
List<JiaoshiEntity> jiaoshiEntities_username = jiaoshiService.selectList(new EntityWrapper<JiaoshiEntity>().in("username", seachFields.get("username")));
if(jiaoshiEntities_username.size() >0 ){
ArrayList<String> repeatFields = new ArrayList<>();
for(JiaoshiEntity s:jiaoshiEntities_username){
repeatFields.add(s.getUsername());
}
return R.error(511,"数据库的该表中的 [账户] 字段已经存在 存在数据为:"+repeatFields.toString());
}
//教师手机号
List<JiaoshiEntity> jiaoshiEntities_jiaoshiPhone = jiaoshiService.selectList(new EntityWrapper<JiaoshiEntity>().in("jiaoshi_phone", seachFields.get("jiaoshiPhone")));
if(jiaoshiEntities_jiaoshiPhone.size() >0 ){
ArrayList<String> repeatFields = new ArrayList<>();
for(JiaoshiEntity s:jiaoshiEntities_jiaoshiPhone){
repeatFields.add(s.getJiaoshiPhone());
}
return R.error(511,"数据库的该表中的 [教师手机号] 字段已经存在 存在数据为:"+repeatFields.toString());
}
//教师身份证号
List<JiaoshiEntity> jiaoshiEntities_jiaoshiIdNumber = jiaoshiService.selectList(new EntityWrapper<JiaoshiEntity>().in("jiaoshi_id_number", seachFields.get("jiaoshiIdNumber")));
if(jiaoshiEntities_jiaoshiIdNumber.size() >0 ){
ArrayList<String> repeatFields = new ArrayList<>();
for(JiaoshiEntity s:jiaoshiEntities_jiaoshiIdNumber){
repeatFields.add(s.getJiaoshiIdNumber());
}
return R.error(511,"数据库的该表中的 [教师身份证号] 字段已经存在 存在数据为:"+repeatFields.toString());
}
jiaoshiService.insertBatch(jiaoshiList);
return R.ok();
}
}
}
}catch (Exception e){
return R.error(511,"批量插入数据异常,请联系管理员");
}
}
/**
* 登录
*/
@IgnoreAuth
@RequestMapping(value = "/login")
public R login(String username, String password, String captcha, HttpServletRequest request) {
JiaoshiEntity jiaoshi = jiaoshiService.selectOne(new EntityWrapper<JiaoshiEntity>().eq("username", username));
if(jiaoshi==null || !jiaoshi.getPassword().equals(password))
return R.error("账号或密码不正确");
// // 获取监听器中的字典表
// ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
// Map<String, Map<Integer, String>> dictionaryMap= (Map<String, Map<Integer, String>>) servletContext.getAttribute("dictionaryMap");
// Map<Integer, String> role_types = dictionaryMap.get("role_types");
// role_types.get(.getRoleTypes());
String token = tokenService.generateToken(jiaoshi.getId(),username, "jiaoshi", "教师");
R r = R.ok();
r.put("token", token);
r.put("role","教师");
r.put("username",jiaoshi.getJiaoshiName());
r.put("tableName","jiaoshi");
r.put("userId",jiaoshi.getId());
return r;
}
/**
* 注册
*/
@IgnoreAuth
@PostMapping(value = "/register")
public R register(@RequestBody JiaoshiEntity jiaoshi){
// ValidatorUtils.validateEntity(user);
Wrapper<JiaoshiEntity> queryWrapper = new EntityWrapper<JiaoshiEntity>()
.eq("username", jiaoshi.getUsername())
.or()
.eq("jiaoshi_phone", jiaoshi.getJiaoshiPhone())
.or()
.eq("jiaoshi_id_number", jiaoshi.getJiaoshiIdNumber())
;
JiaoshiEntity jiaoshiEntity = jiaoshiService.selectOne(queryWrapper);
if(jiaoshiEntity != null)
return R.error("账户或者教师手机号或者教师身份证号已经被使用");
jiaoshi.setCreateTime(new Date());
jiaoshiService.insert(jiaoshi);
return R.ok();
}
/**
* 重置密码
*/
@GetMapping(value = "/resetPassword")
public R resetPassword(Integer id){
JiaoshiEntity jiaoshi = new JiaoshiEntity();
jiaoshi.setPassword("123456");
jiaoshi.setId(id);
jiaoshiService.updateById(jiaoshi);
return R.ok();
}
/**
* 忘记密码
*/
@IgnoreAuth
@RequestMapping(value = "/resetPass")
public R resetPass(String username, HttpServletRequest request) {
JiaoshiEntity jiaoshi = jiaoshiService.selectOne(new EntityWrapper<JiaoshiEntity>().eq("username", username));
if(jiaoshi!=null){
jiaoshi.setPassword("123456");
boolean b = jiaoshiService.updateById(jiaoshi);
if(!b){
return R.error();
}
}else{
return R.error("账号不存在");
}
return R.ok();
}
/**
* 获取用户的session用户信息
*/
@RequestMapping("/session")
public R getCurrJiaoshi(HttpServletRequest request){
Integer id = (Integer)request.getSession().getAttribute("userId");
JiaoshiEntity jiaoshi = jiaoshiService.selectById(id);
if(jiaoshi !=null){
//entity转view
JiaoshiView view = new JiaoshiView();
BeanUtils.copyProperties( jiaoshi , view );//把实体数据重构到view中
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 退出
*/
@GetMapping(value = "logout")
public R logout(HttpServletRequest request) {
request.getSession().invalidate();
return R.ok("退出成功");
}
}
五、论文参考
- 计算机毕业设计选题推荐-学院教学工作量统计系统-论文参考:
六、系统视频
- 学院教学工作量统计系统-项目视频:
计算机毕业设计选题推荐-学院教学工作量统计系统-项目实战
结语
计算机毕业设计选题推荐-学院教学工作量统计系统-Java/Python项目实战
大家可以帮忙点赞、收藏、关注、评论啦~
源码获取:⬇⬇⬇