feat: 下班!!!

11111
winter 1 year ago
parent 83c980dcae
commit 3477592027

@ -5,6 +5,7 @@ import cn.teammodel.common.R;
import cn.teammodel.manager.NotificationService; import cn.teammodel.manager.NotificationService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException; import org.springframework.web.bind.MissingPathVariableException;
@ -39,6 +40,13 @@ public class GlobalExceptionHandler {
return ObjectUtils.isNotEmpty(code) ? R.error(code, e.getMessage()) : R.error(e.getMessage()); return ObjectUtils.isNotEmpty(code) ? R.error(code, e.getMessage()) : R.error(e.getMessage());
} }
@ExceptionHandler(HttpMessageNotReadableException.class)
public R<?> handleHttpMsgNotReadableException(HttpMessageNotReadableException e, HttpServletRequest request)
{
log.error(e.getMessage(), e);
return R.error(ErrorCode.PARAMS_ERROR.getCode(), "参数格式有误");
}
/** /**
* *
*/ */

@ -1,9 +1,12 @@
package cn.teammodel.controller.admin.controller; package cn.teammodel.controller.admin.controller;
import cn.teammodel.controller.admin.service.AdminAppraiseService;
import cn.teammodel.common.R; import cn.teammodel.common.R;
import cn.teammodel.controller.admin.service.AdminAppraiseService;
import cn.teammodel.model.dto.admin.TimeRangeDto; import cn.teammodel.model.dto.admin.TimeRangeDto;
import cn.teammodel.model.vo.admin.IndexData;
import cn.teammodel.model.vo.admin.RankPo;
import cn.teammodel.model.vo.admin.RankVo; import cn.teammodel.model.vo.admin.RankVo;
import cn.teammodel.model.vo.admin.StudentRankVo;
import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.model.vo.appraise.RecordVo;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,10 +27,11 @@ public class IndexController {
private AdminAppraiseService adminAppraiseService; private AdminAppraiseService adminAppraiseService;
@GetMapping("/") @GetMapping("/{academicYearId}")
public String index(){ @ApiOperation("获取首页数据")
//IndexData indexData = adminAppraiseService.getIndexData("", ""); public R<IndexData> index(@PathVariable String academicYearId){
return null; IndexData indexData = adminAppraiseService.getIndexData(academicYearId);
return R.success(indexData);
} }
@PostMapping("latestRecord") @PostMapping("latestRecord")
@ -39,20 +43,26 @@ public class IndexController {
@PostMapping("classRank") @PostMapping("classRank")
@ApiOperation("班级评价活跃排行榜: Top10") @ApiOperation("班级评价活跃排行榜: Top10")
public R<List<RankVo>> classRank(@Valid @RequestBody TimeRangeDto timeRangeDto) { public R<List<RankPo>> classRank(@Valid @RequestBody TimeRangeDto timeRangeDto) {
List<RankVo> res = adminAppraiseService.classRank(timeRangeDto); List<RankPo> res = adminAppraiseService.classRank(timeRangeDto);
return R.success(res);
}
@PostMapping("studentRank")
@ApiOperation("学生评价活跃排行榜: Top10")
public R<List<StudentRankVo>> studentRank(@Valid @RequestBody TimeRangeDto timeRangeDto) {
List<StudentRankVo> res = adminAppraiseService.studentRank(timeRangeDto);
return R.success(res); return R.success(res);
} }
@PostMapping("teacherRank") @PostMapping("teacherRank")
@ApiOperation("班级评价活跃排行榜: Top10") @ApiOperation("老师评价活跃排行榜: Top10")
public R<List<RankVo>> teacherRank(@Valid @RequestBody TimeRangeDto timeRangeDto) { public R<List<RankVo>> teacherRank(@Valid @RequestBody TimeRangeDto timeRangeDto) {
List<RankVo> res = adminAppraiseService.teacherRank(timeRangeDto); List<RankVo> res = adminAppraiseService.teacherRank(timeRangeDto);
return R.success(res); return R.success(res);
} }
@PostMapping("appraiseNodeRank") @PostMapping("appraiseNodeRank")
@ApiOperation("班级评价活跃排行榜: Top10") @ApiOperation("评价指标活跃排行榜: Top10")
public R<List<RankVo>> appraiseNodeRank(@Valid @RequestBody TimeRangeDto timeRangeDto) { public R<List<RankPo>> appraiseNodeRank(@Valid @RequestBody TimeRangeDto timeRangeDto) {
List<RankVo> res = adminAppraiseService.appraiseNodeRank(timeRangeDto); List<RankPo> res = adminAppraiseService.appraiseNodeRank(timeRangeDto);
return R.success(res); return R.success(res);
} }

@ -2,7 +2,9 @@ package cn.teammodel.controller.admin.service;
import cn.teammodel.model.dto.admin.TimeRangeDto; import cn.teammodel.model.dto.admin.TimeRangeDto;
import cn.teammodel.model.vo.admin.IndexData; import cn.teammodel.model.vo.admin.IndexData;
import cn.teammodel.model.vo.admin.RankPo;
import cn.teammodel.model.vo.admin.RankVo; import cn.teammodel.model.vo.admin.RankVo;
import cn.teammodel.model.vo.admin.StudentRankVo;
import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.model.vo.appraise.RecordVo;
import java.util.List; import java.util.List;
@ -12,16 +14,18 @@ import java.util.List;
* @create 2023-12-06 14:45 * @create 2023-12-06 14:45
*/ */
public interface AdminAppraiseService { public interface AdminAppraiseService {
IndexData getIndexData(String period, String academicYearId); IndexData getIndexData(String academicYearId);
/** /**
* *
*/ */
List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto); List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto);
List<RankVo> classRank(TimeRangeDto timeRangeDto); List<RankPo> classRank(TimeRangeDto timeRangeDto);
List<RankVo> teacherRank(TimeRangeDto timeRangeDto); List<RankVo> teacherRank(TimeRangeDto timeRangeDto);
List<RankVo> appraiseNodeRank(TimeRangeDto timeRangeDto); List<RankPo> appraiseNodeRank(TimeRangeDto timeRangeDto);
List<StudentRankVo> studentRank(TimeRangeDto timeRangeDto);
} }

@ -1,18 +1,18 @@
package cn.teammodel.controller.admin.service.impl; package cn.teammodel.controller.admin.service.impl;
import cn.teammodel.controller.admin.service.AdminAppraiseService; import cn.hutool.core.lang.Pair;
import cn.teammodel.common.PK; import cn.teammodel.common.PK;
import cn.teammodel.dao.AppraiseRecordRepository; import cn.teammodel.controller.admin.service.AdminAppraiseService;
import cn.teammodel.dao.AppraiseRepository; import cn.teammodel.dao.*;
import cn.teammodel.dao.ClassRepository;
import cn.teammodel.dao.TeacherRepository;
import cn.teammodel.model.dto.admin.TimeRangeDto; import cn.teammodel.model.dto.admin.TimeRangeDto;
import cn.teammodel.model.entity.User; import cn.teammodel.model.entity.User;
import cn.teammodel.model.entity.appraise.AppraiseTreeNode;
import cn.teammodel.model.entity.school.ClassInfo; import cn.teammodel.model.entity.school.ClassInfo;
import cn.teammodel.model.entity.school.Student;
import cn.teammodel.model.entity.school.Teacher; import cn.teammodel.model.entity.school.Teacher;
import cn.teammodel.model.vo.admin.IndexData; import cn.teammodel.model.vo.admin.IndexData;
import cn.teammodel.model.vo.admin.RankPo;
import cn.teammodel.model.vo.admin.RankVo; import cn.teammodel.model.vo.admin.RankVo;
import cn.teammodel.model.vo.admin.StudentRankVo;
import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.model.vo.appraise.RecordVo;
import cn.teammodel.security.utils.SecurityUtil; import cn.teammodel.security.utils.SecurityUtil;
import com.azure.spring.data.cosmos.core.query.CosmosPageRequest; import com.azure.spring.data.cosmos.core.query.CosmosPageRequest;
@ -22,7 +22,9 @@ import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.WeekFields; import java.time.temporal.WeekFields;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -38,22 +40,25 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
@Resource @Resource
private TeacherRepository teacherRepository; private TeacherRepository teacherRepository;
@Resource @Resource
private StudentRepository studentRepository;
@Resource
private AppraiseRepository appraiseRepository; private AppraiseRepository appraiseRepository;
@Resource @Resource
private AppraiseRecordRepository appraiseRecordRepository; private AppraiseRecordRepository appraiseRecordRepository;
@Override @Override
public IndexData getIndexData(String period, String academicYearId) { public IndexData getIndexData(String academicYearId) {
final IndexData indexData = new IndexData(); final IndexData indexData = new IndexData();
int totalCount = 0; int totalCount = 0;
int criticalCount = 0; int criticalCount = 0;
Set<String> creatorIdSet = new HashSet<>();
User loginUser = SecurityUtil.getLoginUser(); User loginUser = SecurityUtil.getLoginUser();
String schoolId = loginUser.getSchoolId(); String schoolId = loginUser.getSchoolId();
// slice 分段读取 // slice 分段读取
CosmosPageRequest pageRequest = new CosmosPageRequest(0, 10, null); CosmosPageRequest pageRequest = new CosmosPageRequest(0, 100, null);
Slice<RecordVo> slice; Slice<RecordVo> slice;
Map<Integer, Integer> countByWeek = new HashMap<>(); Map<Integer, Integer> countByWeek = new HashMap<>();
@ -75,6 +80,8 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
if (!item.isPraise()) { if (!item.isPraise()) {
criticalCount++; criticalCount++;
} }
// 处理已评价老师总数
creatorIdSet.add(item.getCreatorId());
} }
if (slice.hasNext()) { if (slice.hasNext()) {
@ -87,13 +94,14 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
indexData.setTotalCount(totalCount); indexData.setTotalCount(totalCount);
indexData.setCriticalCount(criticalCount); indexData.setCriticalCount(criticalCount);
indexData.setPraiseCount(totalCount - criticalCount); indexData.setPraiseCount(totalCount - criticalCount);
indexData.setTeacherCount(creatorIdSet.size());
return indexData; return indexData;
} }
@Override @Override
public List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto) { public List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto) {
LocalDateTime startTime = timeRangeDto.getStartTime(); Long startTime = timeRangeDto.getStartTime();
LocalDateTime endTime = timeRangeDto.getEndTime(); Long endTime = timeRangeDto.getEndTime();
String academicYearId = timeRangeDto.getAcademicYearId(); String academicYearId = timeRangeDto.getAcademicYearId();
Integer current = timeRangeDto.getCurrent(); Integer current = timeRangeDto.getCurrent();
Integer size = timeRangeDto.getSize(); Integer size = timeRangeDto.getSize();
@ -103,77 +111,170 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
Page<RecordVo> page = appraiseRecordRepository.pageLatestRecords( Page<RecordVo> page = appraiseRecordRepository.pageLatestRecords(
String.format(PK.PK_APPRAISE_RECORD, schoolId), String.format(PK.PK_APPRAISE_RECORD, schoolId),
academicYearId, academicYearId,
startTime.toString(), startTime,
endTime.toString(), endTime,
pageRequest); pageRequest);
return page.getContent(); return page.getContent();
} }
@Override @Override
public List<RankVo> classRank(TimeRangeDto timeRangeDto) { public List<RankPo> classRank(TimeRangeDto timeRangeDto) {
// todo 不要 page // todo 不要 page| 批评和表扬数量
String startTime = timeRangeDto.getStartTime() == null ? null : timeRangeDto.getStartTime().toString(); Long startTime = timeRangeDto.getStartTime();
String endTime = timeRangeDto.getEndTime() == null ? null : timeRangeDto.getEndTime().toString(); Long endTime = timeRangeDto.getEndTime();
String academicYearId = timeRangeDto.getAcademicYearId(); String academicYearId = timeRangeDto.getAcademicYearId();
String schoolId = SecurityUtil.getLoginUser().getSchoolId(); String schoolId = SecurityUtil.getLoginUser().getSchoolId();
List<RankVo> rankVoList = appraiseRecordRepository.classRank( List<RankPo> rankPoList = appraiseRecordRepository.classRank(
String.format(PK.PK_APPRAISE_RECORD, schoolId), String.format(PK.PK_APPRAISE_RECORD, schoolId),
academicYearId, academicYearId,
startTime, startTime,
endTime endTime
); );
Set<String> classIdSet = rankVoList.stream().map(RankVo::getId).collect(Collectors.toSet()); if (ObjectUtils.isEmpty(rankPoList)) return null;
Set<String> classIdSet = rankPoList.stream().map(RankPo::getId).collect(Collectors.toSet());
// 注意: 如果查询 in 的查询集在数据库中不存在,则在结果集也不会为 null. // 注意: 如果查询 in 的查询集在数据库中不存在,则在结果集也不会为 null.
if (ObjectUtils.isEmpty(classIdSet)) return rankPoList;
List<ClassInfo> classes = classRepository.findAllByCodeAndIdIn(String.format(PK.CLASS, schoolId), classIdSet); List<ClassInfo> classes = classRepository.findAllByCodeAndIdIn(String.format(PK.CLASS, schoolId), classIdSet);
Map<String, String> idNameMap = classes.stream().collect(Collectors.toMap(ClassInfo::getId, ClassInfo::getName)); Map<String, String> idNameMap = classes.stream().collect(Collectors.toMap(ClassInfo::getId, ClassInfo::getName));
rankVoList.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId()))); rankPoList.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId())));
return rankVoList; return rankPoList;
} }
@Override @Override
public List<RankVo> teacherRank(TimeRangeDto timeRangeDto) { public List<RankVo> teacherRank(TimeRangeDto timeRangeDto) {
String startTime = timeRangeDto.getStartTime() == null ? null : timeRangeDto.getStartTime().toString(); Long startTime = timeRangeDto.getStartTime();
String endTime = timeRangeDto.getEndTime() == null ? null : timeRangeDto.getEndTime().toString(); Long endTime = timeRangeDto.getEndTime();
String academicYearId = timeRangeDto.getAcademicYearId(); String academicYearId = timeRangeDto.getAcademicYearId();
String schoolId = SecurityUtil.getLoginUser().getSchoolId(); String schoolId = SecurityUtil.getLoginUser().getSchoolId();
List<RankVo> rankVoList = appraiseRecordRepository.teacherRank( List<RankPo> rankPoList = appraiseRecordRepository.teacherRank(
String.format(PK.PK_APPRAISE_RECORD, schoolId), String.format(PK.PK_APPRAISE_RECORD, schoolId),
academicYearId, academicYearId,
startTime, startTime,
endTime endTime
); );
Set<String> teacherIdSet = rankVoList.stream().map(RankVo::getId).collect(Collectors.toSet()); // 根据 id 分组
Map<String, List<RankPo>> idRankPoMap = rankPoList.stream().collect(Collectors.groupingBy(RankPo::getId));
final List<RankVo> rankVos = new ArrayList<>();
idRankPoMap.forEach((id, list) -> {
RankVo rankVo = new RankVo();
int praiseCount = 0;
int criticalCount = 0;
rankVo.setId(id);
for (RankPo po : list) {
if (po.getIsPraise()) {
praiseCount += po.getCount();
} else {
criticalCount += po.getCount();
}
}
rankVo.setPraiseCount(praiseCount);
rankVo.setCriticalCount(criticalCount);
rankVo.setTotalCount(praiseCount + criticalCount);
rankVos.add(rankVo);
});
// 排序
List<RankVo> res = rankVos.stream()
.sorted(Comparator.comparing(RankVo::getTotalCount).reversed())
.collect(Collectors.toList());
// 设置 name
if (ObjectUtils.isEmpty(res)) return null;
Set<String> teacherIdSet = res.stream().map(RankVo::getId).collect(Collectors.toSet());
if (ObjectUtils.isEmpty(teacherIdSet)) return res;
List<Teacher> teachers = teacherRepository.findAllByCodeAndIdIn(PK.COMMON_BASE, teacherIdSet); List<Teacher> teachers = teacherRepository.findAllByCodeAndIdIn(PK.COMMON_BASE, teacherIdSet);
Map<String, String> idNameMap = teachers.stream().collect(Collectors.toMap(Teacher::getId, Teacher::getName)); Map<String, String> idNameMap = teachers.stream().collect(Collectors.toMap(Teacher::getId, Teacher::getName));
rankVoList.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId()))); res.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId())));
return rankVoList; return res;
} }
@Override @Override
public List<RankVo> appraiseNodeRank(TimeRangeDto timeRangeDto) { public List<RankPo> appraiseNodeRank(TimeRangeDto timeRangeDto) {
String startTime = timeRangeDto.getStartTime() == null ? null : timeRangeDto.getStartTime().toString(); Long startTime = timeRangeDto.getStartTime();
String endTime = timeRangeDto.getEndTime() == null ? null : timeRangeDto.getEndTime().toString(); Long endTime = timeRangeDto.getEndTime();
String academicYearId = timeRangeDto.getAcademicYearId(); String academicYearId = timeRangeDto.getAcademicYearId();
String schoolId = SecurityUtil.getLoginUser().getSchoolId(); String schoolId = SecurityUtil.getLoginUser().getSchoolId();
List<RankVo> rankVoList = appraiseRecordRepository.appraiseNodeRank( List<RankPo> rankPoList = appraiseRecordRepository.appraiseNodeRank(
String.format(PK.PK_APPRAISE_RECORD, schoolId), String.format(PK.PK_APPRAISE_RECORD, schoolId),
academicYearId, academicYearId,
startTime, startTime,
endTime endTime
); );
Set<String> appraiseNodeIdSet = rankVoList.stream().map(RankVo::getId).collect(Collectors.toSet()); if (rankPoList == null) return null;
List<AppraiseTreeNode> appraises = appraiseRepository.findAllByCodeAndIdIn(PK.PK_APPRAISE, appraiseNodeIdSet); rankPoList = rankPoList.stream()
Map<String, String> idNameMap = appraises.stream().collect(Collectors.toMap(AppraiseTreeNode::getId, AppraiseTreeNode::getName)); .sorted(Comparator.comparing(RankPo::getCount).reversed())
rankVoList.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId()))); .collect(Collectors.toList());
return rankVoList;
return rankPoList;
}
@Override
public List<StudentRankVo> studentRank(TimeRangeDto timeRangeDto) {
Long startTime = timeRangeDto.getStartTime();
Long endTime = timeRangeDto.getEndTime();
String academicYearId = timeRangeDto.getAcademicYearId();
String schoolId = SecurityUtil.getLoginUser().getSchoolId();
List<RankPo> rankPoList = appraiseRecordRepository.studentRank(
String.format(PK.PK_APPRAISE_RECORD, schoolId),
academicYearId,
startTime,
endTime
);
// 根据 id 分组
Map<String, List<RankPo>> idRankPoMap = rankPoList.stream().collect(Collectors.groupingBy(RankPo::getId));
final List<StudentRankVo> rankVos = new ArrayList<>();
idRankPoMap.forEach((id, list) -> {
StudentRankVo rankVo = new StudentRankVo();
int praiseCount = 0;
int criticalCount = 0;
rankVo.setId(id);
for (RankPo po : list) {
if (po.getIsPraise()) {
praiseCount += po.getCount();
} else {
criticalCount += po.getCount();
}
}
rankVo.setPraiseCount(praiseCount);
rankVo.setCriticalCount(criticalCount);
rankVo.setTotalCount(praiseCount + criticalCount);
rankVos.add(rankVo);
});
// 排序
List<StudentRankVo> res = rankVos.stream()
.sorted(Comparator.comparing(StudentRankVo::getTotalCount).reversed())
.collect(Collectors.toList());
// 设置 student name
if (ObjectUtils.isEmpty(res)) return null;
Set<String> studentIdSet = res.stream().map(StudentRankVo::getId).collect(Collectors.toSet());
if (ObjectUtils.isEmpty(studentIdSet)) return res;
List<Student> students = studentRepository.findAllByCodeAndIdIn(String.format(PK.STUDENT, schoolId), studentIdSet);
// 提取 Student 中的 name 和 classId
Map<String, Pair<String, String>> idNameMap = students.stream().collect(Collectors.toMap(Student::getId, item -> new Pair<>(item.getName(), item.getClassId())));
res.forEach(rankVo -> {
rankVo.setName(idNameMap.get(rankVo.getId()).getKey());
rankVo.setClassName(idNameMap.get(rankVo.getId()).getValue());
});
// 设置 class name
Set<String> classIds = students.stream().map(Student::getClassId).collect(Collectors.toSet());
List<ClassInfo> classes = classRepository.findAllByCodeAndIdIn(String.format(PK.CLASS, schoolId), classIds);
Map<String, String> idClassNameMap = classes.stream().collect(Collectors.toMap(ClassInfo::getId, ClassInfo::getName));
res.forEach(rankVo -> rankVo.setClassName(idClassNameMap.getOrDefault(rankVo.getClassName(), null)));
return res;
} }
private int calculateWeekNum(LocalDateTime localDateTime) { private int calculateWeekNum(Long timeStamp) {
// second 时间戳转 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timeStamp), ZoneOffset.UTC);
// 获取周字段 todo: 时区或者周的计算 // 获取周字段 todo: 时区或者周的计算
WeekFields weekFields = WeekFields.of(Locale.getDefault()); WeekFields weekFields = WeekFields.of(Locale.getDefault());
// 获取当前日期时间所在年的周数 // 获取当前日期时间所在年的周数

@ -1,7 +1,7 @@
package cn.teammodel.dao; package cn.teammodel.dao;
import cn.teammodel.model.entity.appraise.AppraiseRecord; import cn.teammodel.model.entity.appraise.AppraiseRecord;
import cn.teammodel.model.vo.admin.RankVo; import cn.teammodel.model.vo.admin.RankPo;
import cn.teammodel.model.vo.appraise.AppraiseRecordVo; import cn.teammodel.model.vo.appraise.AppraiseRecordVo;
import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.model.vo.appraise.RecordVo;
import com.azure.spring.data.cosmos.repository.CosmosRepository; import com.azure.spring.data.cosmos.repository.CosmosRepository;
@ -60,20 +60,20 @@ public interface AppraiseRecordRepository extends CosmosRepository<AppraiseRecor
int countRecords(Boolean praise, String academicYearId, String code); int countRecords(Boolean praise, String academicYearId, String code);
@Query("select n.createTime, n.appraiseNode.isPraise from Student as c join n in c.nodes where c.code = @code and c.academicYearId = @academicYearId") @Query("select n.createTime, n.appraiseNode.isPraise, n.creatorId from Student as c join n in c.nodes where c.code = @code and c.academicYearId = @academicYearId")
Slice<RecordVo> findAllByAcademicYearId(String code, String academicYearId, Pageable pageable); Slice<RecordVo> findAllByAcademicYearId(String code, String academicYearId, Pageable pageable);
/** /**
* , * ,
*/ */
// todo: 调整一下数据结构 // todo: 调整一下数据结构
@Query("select c.id as recordId, c.name, c.avatar, c.targetId, c.targetType, n as info from Student as c join n in c.nodes where " + @Query("select c.id as recordId, c.name as targetName, c.avatar, c.className, c.targetId, c.targetType, n.creator, n.createTime, n.appraiseNode.name as appraiseName, n.appraiseNode.isPraise from Student as c join n in c.nodes where " +
"c.code = @code and" + "c.code = @code and " +
"c.academicYearId = @academicYearId and" + "c.academicYearId = @academicYearId and " +
"(IS_NULL(@startTime) or c.createTime >= @startTime) and" + "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
"(IS_NULL(@endTime) or c.createTime <= @endTime)" + "(IS_NULL(@endTime) or n.createTime <= @endTime) " +
"order by c.createTime desc") "order by c.createTime desc")
Page<RecordVo> pageLatestRecords(String code, String academicYearId, String startTime, String endTime, Pageable pageable); Page<RecordVo> pageLatestRecords(String code, String academicYearId, Long startTime, Long endTime, Pageable pageable);
@Query("select c.classId as id, count(1) as count from Student as c join n in c.nodes where( " + @Query("select c.classId as id, count(1) as count from Student as c join n in c.nodes where( " +
@ -82,21 +82,36 @@ public interface AppraiseRecordRepository extends CosmosRepository<AppraiseRecor
"(IS_NULL(@startTime) or n.createTime >= @startTime) and " + "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
"(IS_NULL(@endTime) or n.createTime <= @endTime) " + "(IS_NULL(@endTime) or n.createTime <= @endTime) " +
"group by c.classId") "group by c.classId")
List<RankVo> classRank(String code, String academicYearId, String startTime, String endTime); List<RankPo> classRank(String code, String academicYearId, Long startTime, Long endTime);
@Query("select n.creatorId as id, n.appraiseNode.isPraise, count(1) as count from Student as c join n in c.nodes where " +
"(c.academicYearId = @academicYearId) and " +
"(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
"(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
"(c.code = @code) " +
"group by n.creatorId, n.appraiseNode.isPraise")
List<RankPo> teacherRank(String code, String academicYearId, Long startTime, Long endTime);
@Query("select n.creatorId as id, count(1) as count from Student as c join n in c.nodes where " + @Query("select n.appraiseNode.name as name, count(1) as count from Student as c join n in c.nodes where " +
"(c.academicYearId = @academicYearId) and " + "(c.academicYearId = @academicYearId) and " +
"(IS_NULL(@startTime) or n.createTime >= @startTime) and " + "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
"(IS_NULL(@endTime) or n.createTime <= @endTime) and " + "(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
"(c.code = @code) " + "(c.code = @code) " +
"group by n.creatorId") "group by n.appraiseNode.name")
List<RankVo> teacherRank(String code, String academicYearId, String startTime, String endTime); List<RankPo> appraiseNodeRank(String code, String academicYearId, Long startTime, Long endTime);
@Query("select n.appraiseNode.id as id, count(1) as count from Student as c join n in c.nodes where " + /**
* ,
*/
@Query("select c.targetId as id, n.appraiseNode.isPraise, count(1) as count from Student as c join n in c.nodes where " +
"(c.academicYearId = @academicYearId) and " + "(c.academicYearId = @academicYearId) and " +
"(IS_NULL(@startTime) or n.createTime >= @startTime) and " + "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
"(IS_NULL(@endTime) or n.createTime <= @endTime) and " + "(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
"(c.targetType = 'student') and " +
"(c.code = @code) " + "(c.code = @code) " +
"group by n.appraiseNode.id") "group by c.targetId, n.appraiseNode.isPraise")
List<RankVo> appraiseNodeRank(String code, String academicYearId, String startTime, String endTime); List<RankPo> studentRank(String code, String academicYearId, Long startTime, Long endTime);
@Query("select * from Student as c where c.code = @code")
List<AppraiseRecord> findByCode(String code);
} }

@ -6,6 +6,7 @@ import com.azure.spring.data.cosmos.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
import java.util.Set;
@Repository @Repository
public interface StudentRepository extends CosmosRepository<Student, String> { public interface StudentRepository extends CosmosRepository<Student, String> {
@ -14,4 +15,7 @@ public interface StudentRepository extends CosmosRepository<Student, String> {
@Query("select c.pk, c.code, c.id, c.name, c.gender, c.schoolId, c.periodId, c.year, c.createTime, c.picture, c.mail, c.mobile, c.country, c.classId, c.no, c.groupId, c.groupName, c.guardians, c.irs, c.salt from Student as c where c.id = @id and c.code = @code") @Query("select c.pk, c.code, c.id, c.name, c.gender, c.schoolId, c.periodId, c.year, c.createTime, c.picture, c.mail, c.mobile, c.country, c.classId, c.no, c.groupId, c.groupName, c.guardians, c.irs, c.salt from Student as c where c.id = @id and c.code = @code")
List<Student> findByIdAndCode(String id, String code); List<Student> findByIdAndCode(String id, String code);
@Query("select c.id, c.name, c.classId from Student as c where c.code = @code and c.id in (@ids)")
List<Student> findAllByCodeAndIdIn(String code, Set<String> ids);
} }

@ -1,12 +1,10 @@
package cn.teammodel.model.dto.admin; package cn.teammodel.model.dto.admin;
import cn.teammodel.common.PageableRequest; import cn.teammodel.common.PageableRequest;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/** /**
* @author winter * @author winter
@ -15,10 +13,8 @@ import java.time.LocalDateTime;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
public class TimeRangeDto extends PageableRequest { public class TimeRangeDto extends PageableRequest {
@JsonFormat(pattern = "yyyy-MM-ddTHH:mm:ss.fffffffZ") private Long startTime;
private LocalDateTime startTime; private Long endTime;
@JsonFormat(pattern = "yyyy-MM-ddTHH:mm:ss.fffffffZ")
private LocalDateTime endTime;
@NotNull @NotNull
// todo: 似乎不需要(如果不传时间那就需要) // todo: 似乎不需要(如果不传时间那就需要)
private String academicYearId; private String academicYearId;

@ -1,11 +1,8 @@
package cn.teammodel.model.entity.appraise; package cn.teammodel.model.entity.appraise;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime;
/** /**
* *
* @author winter * @author winter
@ -24,6 +21,5 @@ public class AppraiseRecordItem {
private Boolean pushParent; private Boolean pushParent;
String creator; String creator;
String creatorId; String creatorId;
@JsonFormat(pattern = "yyyy-MM-ddTHH:mm:ss") private Long createTime;
private LocalDateTime createTime;
} }

@ -1,11 +1,9 @@
package cn.teammodel.model.entity.appraise; package cn.teammodel.model.entity.appraise;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@Data @Data
@ -17,8 +15,7 @@ public class AppraiseTreeNode {
String logo; String logo;
String creator; String creator;
String creatorId; String creatorId;
@JsonFormat(pattern = "yyyy-MM-ddTHH:mm:ss") Long createTime;
LocalDateTime createTime;
/** /**
* *
*/ */

@ -13,5 +13,6 @@ public class IndexData {
private Integer totalCount; private Integer totalCount;
private Integer praiseCount; private Integer praiseCount;
private Integer criticalCount; private Integer criticalCount;
private Integer teacherCount;
private Map<Integer, Integer> countByWeek; private Map<Integer, Integer> countByWeek;
} }

@ -0,0 +1,17 @@
package cn.teammodel.model.vo.admin;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* @author winter
* @create 2023-12-06 20:17
*/
@Data
public class RankPo {
private String id;
private String name;
@JsonProperty("isPraise")
private Boolean isPraise;
private Integer count;
}

@ -10,5 +10,7 @@ import lombok.Data;
public class RankVo { public class RankVo {
private String id; private String id;
private String name; private String name;
private Integer count; private Integer praiseCount;
private Integer criticalCount;
private Integer totalCount;
} }

@ -0,0 +1,14 @@
package cn.teammodel.model.vo.admin;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author winter
* @create 2023-12-07 17:14
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class StudentRankVo extends RankVo{
private String className;
}

@ -1,11 +1,8 @@
package cn.teammodel.model.vo.appraise; package cn.teammodel.model.vo.appraise;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime;
/** /**
* @author winter * @author winter
* @create 2023-12-06 17:43 * @create 2023-12-06 17:43
@ -13,12 +10,14 @@ import java.time.LocalDateTime;
@Data @Data
public class RecordVo { public class RecordVo {
private String recordId; private String recordId;
private String name; private String targetName;
private String avatar; private String avatar;
private String appraiseName;
private String targetId; private String targetId;
private String targetType; private String targetType;
@JsonFormat(pattern = "yyyy-MM-ddTHH:mm:ss") private String creatorId;
private LocalDateTime createTime; private String creator;
private Long createTime;
@JsonProperty("isPraise") @JsonProperty("isPraise")
private boolean isPraise; private boolean isPraise;
} }

@ -29,8 +29,8 @@ import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -180,7 +180,7 @@ public class EvaluationServiceImpl implements EvaluationService {
newNode.setId(UUID.randomUUID().toString()); newNode.setId(UUID.randomUUID().toString());
newNode.setCreatorId(loginUser.getId()); newNode.setCreatorId(loginUser.getId());
newNode.setCreator(loginUser.getName()); newNode.setCreator(loginUser.getName());
newNode.setCreateTime(LocalDateTime.now()); newNode.setCreateTime(Instant.now().getEpochSecond());
originNodes.add(newNode); originNodes.add(newNode);
return buildTree(appraiseRepository.save(appraise)); return buildTree(appraiseRepository.save(appraise));
@ -293,7 +293,7 @@ public class EvaluationServiceImpl implements EvaluationService {
item.setAppraiseNode(appraiseTreeNode); item.setAppraiseNode(appraiseTreeNode);
item.setCreator(loginUser.getName()); item.setCreator(loginUser.getName());
item.setCreatorId(loginUser.getId()); item.setCreatorId(loginUser.getId());
item.setCreateTime(LocalDateTime.now()); item.setCreateTime(Instant.now().getEpochSecond());
// 处理学校与学生的差异 // 处理学校与学生的差异
if (targetType.equals(TARGET_CLASS)){ if (targetType.equals(TARGET_CLASS)){
item.setSpread(spread); item.setSpread(spread);

@ -1,5 +1,6 @@
package cn.teammodel; package cn.teammodel;
import cn.teammodel.common.PK;
import cn.teammodel.controller.admin.service.AdminAppraiseService; import cn.teammodel.controller.admin.service.AdminAppraiseService;
import cn.teammodel.dao.AppraiseRecordRepository; import cn.teammodel.dao.AppraiseRecordRepository;
import cn.teammodel.dao.AppraiseRepository; import cn.teammodel.dao.AppraiseRepository;
@ -8,9 +9,10 @@ import cn.teammodel.dao.StudentRepository;
import cn.teammodel.manager.DingAlertNotifier; import cn.teammodel.manager.DingAlertNotifier;
import cn.teammodel.model.dto.admin.TimeRangeDto; import cn.teammodel.model.dto.admin.TimeRangeDto;
import cn.teammodel.model.entity.appraise.Appraise; import cn.teammodel.model.entity.appraise.Appraise;
import cn.teammodel.model.entity.appraise.AppraiseRecord;
import cn.teammodel.model.entity.appraise.AppraiseTreeNode; import cn.teammodel.model.entity.appraise.AppraiseTreeNode;
import cn.teammodel.model.entity.school.School; import cn.teammodel.model.entity.school.School;
import cn.teammodel.model.vo.admin.RankVo; import cn.teammodel.model.vo.admin.RankPo;
import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.model.vo.appraise.RecordVo;
import cn.teammodel.service.EvaluationService; import cn.teammodel.service.EvaluationService;
import cn.teammodel.service.impl.EvaluationServiceImpl; import cn.teammodel.service.impl.EvaluationServiceImpl;
@ -179,31 +181,31 @@ class TeamModelExtensionApplicationTests {
public void testIndexData() { public void testIndexData() {
TimeRangeDto timeRangeDto = new TimeRangeDto(); TimeRangeDto timeRangeDto = new TimeRangeDto();
timeRangeDto.setAcademicYearId("2023-71fbd0bd-9a46-0490-f6b3-7d16cba4c017"); timeRangeDto.setAcademicYearId("2023-71fbd0bd-9a46-0490-f6b3-7d16cba4c017");
List<RankVo> list = adminAppraiseService.appraiseNodeRank(timeRangeDto); List<RankPo> list = adminAppraiseService.appraiseNodeRank(timeRangeDto);
System.out.println(list); System.out.println(list);
} }
// @Test @Test
// public void batchUpdateTimeFormat() { public void batchUpdateTimeFormat() {
// // 批量更改所有 appraiseRecord 的时间格式为标准的 utf // 批量更改所有 appraiseRecord 的时间格式为标准的 utf
// List<AppraiseRecord> appraiseRecords = appraiseRecordRepository.findByCode(String.format(PK.PK_APPRAISE_RECORD, "hbcn")); List<AppraiseRecord> appraiseRecords = appraiseRecordRepository.findByCode(String.format(PK.PK_APPRAISE_RECORD, "hbcn"));
// for (AppraiseRecord appraiseRecord : appraiseRecords) { for (AppraiseRecord appraiseRecord : appraiseRecords) {
// List<AppraiseRecordItem> nodes = appraiseRecord.getNodes(); // List<AppraiseRecordItem> nodes = appraiseRecord.getNodes();
// // 处理 node 中的时间 // // 处理 node 中的时间
// for (AppraiseRecordItem node : nodes) { // for (AppraiseRecordItem node : nodes) {
// String createTime = node.getTime(); // String createTime = node.getTime();
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
// // 解析字符串 // // 解析字符串
// LocalDateTime dateTime = LocalDateTime.parse(createTime, formatter); // LocalDateTime dateTime = LocalDateTime.parse(createTime, formatter);
// node.setTime(dateTime.toString()); // node.setTime(String.valueOf(dateTime.toEpochSecond(ZoneOffset.UTC)));
// } // }
// cosmosTemplate.upsert(appraiseRecord); cosmosTemplate.upsert(appraiseRecord);
// System.out.println("更新完毕"); System.out.println("更新完毕");
// } }
// }
@Test
public void batchUpdateTimeFormat() {
} }
// @Test
// public void batchUpdateTimeFormat() {
//
// }
} }

Loading…
Cancel
Save