实习日志
本文最后更新于:2025年4月29日 下午
Jiliason
计算试卷通过率、平均成绩
// 通过率
double pass = (stuReport.getFinishTask() * 1.00 / total) * 100;
// 保留两位小数
BigDecimal bigDecimal = new BigDecimal(pass);
pass = bigDecimal.setScale(2, RoundingMode.HALF_UP).doubleValue(); // HALF_UP表示四舍五入
busStu.setScenePassingRate(pass + "%");
RoundingMode
可以选择其他的舍值方式,例如去尾,等等。
// 试卷通过率
int Count = 0;
int oneCount = 0;
double scoreSum = 0;
Long userId = busStu.getUserId();
List<BusPaperDetail> busPaperDetails = busPaperDetailMapper.selectList(new LambdaQueryWrapper<BusPaperDetail>().eq(BusPaperDetail::getUserId, userId));
for (BusPaperDetail busPaperDetail : busPaperDetails) {
String score = busPaperDetail.getScore();
scoreSum += Double.parseDouble(score);
int result = Integer.parseInt(busPaperDetail.getResult());
if (result == 1) {
oneCount++;
}
Count++;
}
if (oneCount == 0)
{
busStu.setPaperPassingRate("0%");
} else {
BigDecimal paperPass = new BigDecimal(oneCount).divide(new BigDecimal(Count), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
busStu.setPaperPassingRate(paperPass + "%");
}
// 试卷平均成绩
if (Count == 0)
{
busStu.setPaperAverageScores(0);
} else {
BigDecimal average = new BigDecimal(scoreSum).divide(new BigDecimal(Count), 2, RoundingMode.HALF_UP);
// PaperAverage转为int类型
int PaperAverage = average.intValue();
busStu.setPaperAverageScores(PaperAverage);
}
优化版:
// 试卷通过率 试卷平均成绩
int Count = 0;
int oneCount = 0;
double scoreSum = 0;
Long userId = busStu.getUserId();
List<BusPaperDetail> busPaperDetails = busPaperDetailMapper.selectList(new LambdaQueryWrapper<BusPaperDetail>().eq(BusPaperDetail::getUserId, userId));
for (BusPaperDetail busPaperDetail : busPaperDetails) {
String score = busPaperDetail.getScore();
scoreSum += Double.parseDouble(score);
int result = Integer.parseInt(busPaperDetail.getResult());
if (result == 1) {
oneCount++;
}
Count++;
}
busStu.setPaperPassingRate(oneCount == 0 ? "0%" : new BigDecimal(oneCount).divide(new BigDecimal(Count), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)) + "%");
busStu.setPaperAverageScores(Count == 0 ? 0 : new BigDecimal(scoreSum).divide(new BigDecimal(Count), 2, RoundingMode.HALF_UP).intValue());
使用工号登录
对Spring Security的loadUserByUsername
进行改写
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
String[] split = username.split(",");
String type = split[0];
String name = split[1];
SysUser user;
if (type.equals("username")) {
user = userService.selectUserByUserName(name);
} else {
user = userService.selectUserByJobId(name);
}
if (StringUtils.isNull(user))
{
log.info("登录用户:{} 不存在.", name);
throw new ServiceException("登录用户:" + name + " 不存在");
}
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
log.info("登录用户:{} 已被删除.", name);
throw new ServiceException("对不起,您的账号:" + name + " 已被删除");
}
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
log.info("登录用户:{} 已被停用.", name);
throw new ServiceException("对不起,您的账号:" + name + " 已停用");
}
passwordService.validate(user);
return createLoginUser(user);
}
通过时间统计登录人数
<select id="selectCountByTime" resultType="java.lang.Integer">
SELECT COUNT(DISTINCT user_name)
FROM sys_logininfor
<where>
<if test="startTime != null and startTime != ''"><!-- 开始时间检索 -->
and date_format(login_time,'%y%m%d') >= date_format(#{startTime},'%y%m%d')
</if>
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
and date_format(login_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
</if>
AND status <> 1
AND msg <> '退出成功'
</where>
</select>
DISTINCT 列名:去除该列重复的值
controller
public List<Map<String,Integer>> getLoginCount(String startTime, String endTime) {
List<Map<String, Integer>> counts = new ArrayList<>();
Map<String, Integer> countMap = new HashMap<>();
LocalDate startDate = LocalDate.parse(startTime);
LocalDate endDate = LocalDate.parse(endTime);
List<LocalDate> dates = new ArrayList<>();
LocalDate currentDate = startDate;
while (!currentDate.isAfter(endDate)) {
dates.add(currentDate);
currentDate = currentDate.plusDays(1);
}
dates.sort(Comparator.naturalOrder()); // 将日期按升序排序
for (LocalDate date : dates) {
int count = logininforService.selectCountByTime(date.toString(), date.toString());
countMap.put(date.toString(), count);
}
counts.add(countMap);
return counts;
}
bug修复
学员报表分页总条数错误
试卷报表中:首次考试与末次考试分页有误
8.23期
- 下发任务,查看(场景、课程、试卷)内容
查看详情 | 请求地址 | 请求方式 | 参数 |
---|---|---|---|
试卷 | /bus/paper/query | GET | id |
场景 | /bus/course/queryCourse | GET | id |
课程 | /bus/scene/selectSceneById | POST | id |
- 下发任务给学员,人员范围做成筛选框
下发任务时,在人员范围的显示栏上,加上部门、岗位的显示,然后是人员明细,如为全选的情况,则显示“全部”
任务下发时,做成筛选框,无条件时展示所有用户,有筛选条件时展示符合条件的用户
勾选人员时需要可以按照部门勾选
请求地址 | 请求方式 | 参数 |
---|---|---|
/system/user/allUserInfo |
- 视频快进
在bus_user_task
新增允许快进的学员字段(is_speed)
在学员播放时,调用bus_user_task
进行判断
前端:在新建任务时,只有选择了视频
isSpeed:(0-禁止 | 1-允许)
- 开通学员评价和学习记录的功能
对课程的评价,可以导出每个学员的评价
按照课程分类,看到每个学员对该课程的评价
请求地址 | 请求方式 | 参数 | |
---|---|---|---|
评论 | /bus/course/commentCourse | GET | BusComment |
/bus/course/queryComment | BusComment |
学习记录
点击==课时完成==时,调用插入学习记录
请求地址 | 请求方式 | 参数 | |
---|---|---|---|
插入学习记录 | bus/study/insert | POST | BusStudyInfo |
查看学习记录 | /bus/study/list | GET | 无 |
@RequestBody
示例代码:
@PostMapping("save")
public Result save(@RequestBody SkuInfoVo skuInfoVo) {
skuInfoService.saveSkuInfo(skuInfoVo);
return Result.ok(null);
}
@RequestBody:主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);
GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
在后端的同一个接收方法里,**@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()**可以有多个。
实习日志
https://junyyds.top/2023/06/30/实习日志/