parent
a138e16b40
commit
83c980dcae
@ -1,22 +0,0 @@
|
||||
package cn.teammodel.admin.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 管理员首页
|
||||
* @author winter
|
||||
* @create 2023-12-06 14:37
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("admin/index")
|
||||
public class IndexController {
|
||||
|
||||
|
||||
@RequestMapping("/")
|
||||
public String index(){
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package cn.teammodel.admin.service;
|
||||
|
||||
import cn.teammodel.model.vo.admin.IndexData;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-06 14:45
|
||||
*/
|
||||
public interface AdminAppraiseService {
|
||||
IndexData getIndexData(String period, String academicYearId);
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package cn.teammodel.admin.service.impl;
|
||||
|
||||
import cn.teammodel.admin.service.AdminAppraiseService;
|
||||
import cn.teammodel.common.PK;
|
||||
import cn.teammodel.dao.AppraiseRecordRepository;
|
||||
import cn.teammodel.dao.AppraiseRepository;
|
||||
import cn.teammodel.model.vo.admin.IndexData;
|
||||
import cn.teammodel.model.vo.appraise.RecordVo;
|
||||
import com.azure.spring.data.cosmos.core.CosmosTemplate;
|
||||
import com.azure.spring.data.cosmos.core.query.CosmosPageRequest;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.WeekFields;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-06 14:46
|
||||
*/
|
||||
@Service
|
||||
public class AdminAppraiseServiceImpl implements AdminAppraiseService {
|
||||
@Resource
|
||||
private CosmosTemplate cosmosTemplate;
|
||||
@Resource
|
||||
private AppraiseRepository appraiseRepository;
|
||||
@Resource
|
||||
private AppraiseRecordRepository appraiseRecordRepository;
|
||||
|
||||
@Override
|
||||
public IndexData getIndexData(String period, String academicYearId) {
|
||||
final IndexData indexData = new IndexData();
|
||||
int totalCount = 0;
|
||||
int criticalCount = 0;
|
||||
|
||||
//User loginUser = SecurityUtil.getLoginUser();
|
||||
String schoolId = "habook";
|
||||
|
||||
// slice 分段读取
|
||||
CosmosPageRequest pageRequest = new CosmosPageRequest(0, 10, null);
|
||||
Slice<RecordVo> slice;
|
||||
Map<Integer, Integer> countByWeek = new HashMap<>();
|
||||
|
||||
do {
|
||||
slice = appraiseRecordRepository.findAllByAcademicYearId(String.format(PK.PK_APPRAISE_RECORD, schoolId), academicYearId, pageRequest);
|
||||
List<RecordVo> content = slice.getContent();
|
||||
if (ObjectUtils.isEmpty(content)) {
|
||||
return indexData;
|
||||
}
|
||||
|
||||
// 分批次计算
|
||||
for (RecordVo item : content) {
|
||||
// 处理每周的评价数
|
||||
int weekNum = calculateWeekNum(item.getCreateTime());
|
||||
countByWeek.put(weekNum, countByWeek.getOrDefault(weekNum, 0) + 1);
|
||||
// 处理总评价数
|
||||
totalCount++;
|
||||
// 处理批评数
|
||||
if (!item.isPraise()) {
|
||||
criticalCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (slice.hasNext()) {
|
||||
pageRequest = (CosmosPageRequest) slice.nextPageable();
|
||||
}
|
||||
} while (slice.hasNext());
|
||||
|
||||
// 组装数据
|
||||
indexData.setCountByWeek(countByWeek);
|
||||
indexData.setTotalCount(totalCount);
|
||||
indexData.setCriticalCount(criticalCount);
|
||||
indexData.setPraiseCount(totalCount - criticalCount);
|
||||
return indexData;
|
||||
}
|
||||
|
||||
private int calculateWeekNum(LocalDateTime localDateTime) {
|
||||
// 获取周字段 todo: 时区或者周的计算
|
||||
WeekFields weekFields = WeekFields.of(Locale.getDefault());
|
||||
// 获取当前日期时间所在年的周数
|
||||
return localDateTime.get(weekFields.weekOfWeekBasedYear());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package cn.teammodel.controller.admin.controller;
|
||||
|
||||
import cn.teammodel.controller.admin.service.AdminAppraiseService;
|
||||
import cn.teammodel.common.R;
|
||||
import cn.teammodel.model.dto.admin.TimeRangeDto;
|
||||
import cn.teammodel.model.vo.admin.RankVo;
|
||||
import cn.teammodel.model.vo.appraise.RecordVo;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管理员首页
|
||||
* @author winter
|
||||
* @create 2023-12-06 14:37
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("admin/index")
|
||||
public class IndexController {
|
||||
@Resource
|
||||
private AdminAppraiseService adminAppraiseService;
|
||||
|
||||
|
||||
@GetMapping("/")
|
||||
public String index(){
|
||||
//IndexData indexData = adminAppraiseService.getIndexData("", "");
|
||||
return null;
|
||||
}
|
||||
|
||||
@PostMapping("latestRecord")
|
||||
@ApiOperation("查询最新评价(可通过时间范围分页)")
|
||||
public R<List<RecordVo>> latestRecord(@Valid @RequestBody TimeRangeDto timeRangeDto) {
|
||||
List<RecordVo> res = adminAppraiseService.conditionLatestRecord(timeRangeDto);
|
||||
return R.success(res);
|
||||
}
|
||||
|
||||
@PostMapping("classRank")
|
||||
@ApiOperation("班级评价活跃排行榜: Top10")
|
||||
public R<List<RankVo>> classRank(@Valid @RequestBody TimeRangeDto timeRangeDto) {
|
||||
List<RankVo> res = adminAppraiseService.classRank(timeRangeDto);
|
||||
return R.success(res);
|
||||
}
|
||||
@PostMapping("teacherRank")
|
||||
@ApiOperation("班级评价活跃排行榜: Top10")
|
||||
public R<List<RankVo>> teacherRank(@Valid @RequestBody TimeRangeDto timeRangeDto) {
|
||||
List<RankVo> res = adminAppraiseService.teacherRank(timeRangeDto);
|
||||
return R.success(res);
|
||||
}
|
||||
@PostMapping("appraiseNodeRank")
|
||||
@ApiOperation("班级评价活跃排行榜: Top10")
|
||||
public R<List<RankVo>> appraiseNodeRank(@Valid @RequestBody TimeRangeDto timeRangeDto) {
|
||||
List<RankVo> res = adminAppraiseService.appraiseNodeRank(timeRangeDto);
|
||||
return R.success(res);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package cn.teammodel.controller.admin.service;
|
||||
|
||||
import cn.teammodel.model.dto.admin.TimeRangeDto;
|
||||
import cn.teammodel.model.vo.admin.IndexData;
|
||||
import cn.teammodel.model.vo.admin.RankVo;
|
||||
import cn.teammodel.model.vo.appraise.RecordVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-06 14:45
|
||||
*/
|
||||
public interface AdminAppraiseService {
|
||||
IndexData getIndexData(String period, String academicYearId);
|
||||
|
||||
/**
|
||||
* 按时期分页获取最新的评价数据
|
||||
*/
|
||||
List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto);
|
||||
|
||||
List<RankVo> classRank(TimeRangeDto timeRangeDto);
|
||||
|
||||
List<RankVo> teacherRank(TimeRangeDto timeRangeDto);
|
||||
|
||||
List<RankVo> appraiseNodeRank(TimeRangeDto timeRangeDto);
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
package cn.teammodel.controller.admin.service.impl;
|
||||
|
||||
import cn.teammodel.controller.admin.service.AdminAppraiseService;
|
||||
import cn.teammodel.common.PK;
|
||||
import cn.teammodel.dao.AppraiseRecordRepository;
|
||||
import cn.teammodel.dao.AppraiseRepository;
|
||||
import cn.teammodel.dao.ClassRepository;
|
||||
import cn.teammodel.dao.TeacherRepository;
|
||||
import cn.teammodel.model.dto.admin.TimeRangeDto;
|
||||
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.Teacher;
|
||||
import cn.teammodel.model.vo.admin.IndexData;
|
||||
import cn.teammodel.model.vo.admin.RankVo;
|
||||
import cn.teammodel.model.vo.appraise.RecordVo;
|
||||
import cn.teammodel.security.utils.SecurityUtil;
|
||||
import com.azure.spring.data.cosmos.core.query.CosmosPageRequest;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.WeekFields;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-06 14:46
|
||||
*/
|
||||
@Service
|
||||
public class AdminAppraiseServiceImpl implements AdminAppraiseService {
|
||||
@Resource
|
||||
private ClassRepository classRepository;
|
||||
@Resource
|
||||
private TeacherRepository teacherRepository;
|
||||
@Resource
|
||||
private AppraiseRepository appraiseRepository;
|
||||
|
||||
@Resource
|
||||
private AppraiseRecordRepository appraiseRecordRepository;
|
||||
|
||||
@Override
|
||||
public IndexData getIndexData(String period, String academicYearId) {
|
||||
final IndexData indexData = new IndexData();
|
||||
int totalCount = 0;
|
||||
int criticalCount = 0;
|
||||
|
||||
User loginUser = SecurityUtil.getLoginUser();
|
||||
String schoolId = loginUser.getSchoolId();
|
||||
|
||||
// slice 分段读取
|
||||
CosmosPageRequest pageRequest = new CosmosPageRequest(0, 10, null);
|
||||
Slice<RecordVo> slice;
|
||||
Map<Integer, Integer> countByWeek = new HashMap<>();
|
||||
|
||||
do {
|
||||
slice = appraiseRecordRepository.findAllByAcademicYearId(String.format(PK.PK_APPRAISE_RECORD, schoolId), academicYearId, pageRequest);
|
||||
List<RecordVo> content = slice.getContent();
|
||||
if (ObjectUtils.isEmpty(content)) {
|
||||
return indexData;
|
||||
}
|
||||
|
||||
// 分批次计算
|
||||
for (RecordVo item : content) {
|
||||
// 处理每周的评价数
|
||||
int weekNum = calculateWeekNum(item.getCreateTime());
|
||||
countByWeek.put(weekNum, countByWeek.getOrDefault(weekNum, 0) + 1);
|
||||
// 处理总评价数
|
||||
totalCount++;
|
||||
// 处理批评数
|
||||
if (!item.isPraise()) {
|
||||
criticalCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (slice.hasNext()) {
|
||||
pageRequest = (CosmosPageRequest) slice.nextPageable();
|
||||
}
|
||||
} while (slice.hasNext());
|
||||
|
||||
// 组装数据
|
||||
indexData.setCountByWeek(countByWeek);
|
||||
indexData.setTotalCount(totalCount);
|
||||
indexData.setCriticalCount(criticalCount);
|
||||
indexData.setPraiseCount(totalCount - criticalCount);
|
||||
return indexData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto) {
|
||||
LocalDateTime startTime = timeRangeDto.getStartTime();
|
||||
LocalDateTime endTime = timeRangeDto.getEndTime();
|
||||
String academicYearId = timeRangeDto.getAcademicYearId();
|
||||
Integer current = timeRangeDto.getCurrent();
|
||||
Integer size = timeRangeDto.getSize();
|
||||
String schoolId = SecurityUtil.getLoginUser().getSchoolId();
|
||||
|
||||
final CosmosPageRequest pageRequest = new CosmosPageRequest(current, size, null);
|
||||
Page<RecordVo> page = appraiseRecordRepository.pageLatestRecords(
|
||||
String.format(PK.PK_APPRAISE_RECORD, schoolId),
|
||||
academicYearId,
|
||||
startTime.toString(),
|
||||
endTime.toString(),
|
||||
pageRequest);
|
||||
|
||||
return page.getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RankVo> classRank(TimeRangeDto timeRangeDto) {
|
||||
// todo 不要 page
|
||||
String startTime = timeRangeDto.getStartTime() == null ? null : timeRangeDto.getStartTime().toString();
|
||||
String endTime = timeRangeDto.getEndTime() == null ? null : timeRangeDto.getEndTime().toString();
|
||||
String academicYearId = timeRangeDto.getAcademicYearId();
|
||||
String schoolId = SecurityUtil.getLoginUser().getSchoolId();
|
||||
|
||||
List<RankVo> rankVoList = appraiseRecordRepository.classRank(
|
||||
String.format(PK.PK_APPRAISE_RECORD, schoolId),
|
||||
academicYearId,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
Set<String> classIdSet = rankVoList.stream().map(RankVo::getId).collect(Collectors.toSet());
|
||||
// 注意: 如果查询 in 的查询集在数据库中不存在,则在结果集也不会为 null.
|
||||
List<ClassInfo> classes = classRepository.findAllByCodeAndIdIn(String.format(PK.CLASS, schoolId), classIdSet);
|
||||
Map<String, String> idNameMap = classes.stream().collect(Collectors.toMap(ClassInfo::getId, ClassInfo::getName));
|
||||
rankVoList.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId())));
|
||||
return rankVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RankVo> teacherRank(TimeRangeDto timeRangeDto) {
|
||||
String startTime = timeRangeDto.getStartTime() == null ? null : timeRangeDto.getStartTime().toString();
|
||||
String endTime = timeRangeDto.getEndTime() == null ? null : timeRangeDto.getEndTime().toString();
|
||||
String academicYearId = timeRangeDto.getAcademicYearId();
|
||||
String schoolId = SecurityUtil.getLoginUser().getSchoolId();
|
||||
|
||||
List<RankVo> rankVoList = appraiseRecordRepository.teacherRank(
|
||||
String.format(PK.PK_APPRAISE_RECORD, schoolId),
|
||||
academicYearId,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
Set<String> teacherIdSet = rankVoList.stream().map(RankVo::getId).collect(Collectors.toSet());
|
||||
List<Teacher> teachers = teacherRepository.findAllByCodeAndIdIn(PK.COMMON_BASE, teacherIdSet);
|
||||
Map<String, String> idNameMap = teachers.stream().collect(Collectors.toMap(Teacher::getId, Teacher::getName));
|
||||
rankVoList.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId())));
|
||||
return rankVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RankVo> appraiseNodeRank(TimeRangeDto timeRangeDto) {
|
||||
String startTime = timeRangeDto.getStartTime() == null ? null : timeRangeDto.getStartTime().toString();
|
||||
String endTime = timeRangeDto.getEndTime() == null ? null : timeRangeDto.getEndTime().toString();
|
||||
String academicYearId = timeRangeDto.getAcademicYearId();
|
||||
String schoolId = SecurityUtil.getLoginUser().getSchoolId();
|
||||
|
||||
List<RankVo> rankVoList = appraiseRecordRepository.appraiseNodeRank(
|
||||
String.format(PK.PK_APPRAISE_RECORD, schoolId),
|
||||
academicYearId,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
|
||||
Set<String> appraiseNodeIdSet = rankVoList.stream().map(RankVo::getId).collect(Collectors.toSet());
|
||||
List<AppraiseTreeNode> appraises = appraiseRepository.findAllByCodeAndIdIn(PK.PK_APPRAISE, appraiseNodeIdSet);
|
||||
Map<String, String> idNameMap = appraises.stream().collect(Collectors.toMap(AppraiseTreeNode::getId, AppraiseTreeNode::getName));
|
||||
rankVoList.forEach(rankVo -> rankVo.setName(idNameMap.get(rankVo.getId())));
|
||||
return rankVoList;
|
||||
}
|
||||
|
||||
private int calculateWeekNum(LocalDateTime localDateTime) {
|
||||
// 获取周字段 todo: 时区或者周的计算
|
||||
WeekFields weekFields = WeekFields.of(Locale.getDefault());
|
||||
// 获取当前日期时间所在年的周数
|
||||
return localDateTime.get(weekFields.weekOfWeekBasedYear());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cn.teammodel.dao;
|
||||
|
||||
import cn.teammodel.model.entity.school.Teacher;
|
||||
import com.azure.spring.data.cosmos.repository.CosmosRepository;
|
||||
import com.azure.spring.data.cosmos.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-11-28 17:39
|
||||
*/
|
||||
@Repository
|
||||
public interface TeacherRepository extends CosmosRepository<Teacher, String> {
|
||||
@Query("select c.id, c.name from Teacher as c where c.code = @code and c.id in (@ids)")
|
||||
List<Teacher> findAllByCodeAndIdIn(String code, Collection<String> ids);
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package cn.teammodel.model.dto.admin;
|
||||
|
||||
import cn.teammodel.common.PageableRequest;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-06 19:03
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class TimeRangeDto extends PageableRequest {
|
||||
@JsonFormat(pattern = "yyyy-MM-ddTHH:mm:ss.fffffffZ")
|
||||
private LocalDateTime startTime;
|
||||
@JsonFormat(pattern = "yyyy-MM-ddTHH:mm:ss.fffffffZ")
|
||||
private LocalDateTime endTime;
|
||||
@NotNull
|
||||
// todo: 似乎不需要(如果不传时间那就需要)
|
||||
private String academicYearId;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package cn.teammodel.model.entity.school;
|
||||
|
||||
import cn.teammodel.model.entity.BaseItem;
|
||||
import com.azure.spring.data.cosmos.core.mapping.Container;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Container(containerName = "Teacher")
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Teacher extends BaseItem {
|
||||
private String name;
|
||||
private String picture;
|
||||
private int size;
|
||||
private String defaultSchool;
|
||||
private List<School> schools;
|
||||
private List<Area> areas;
|
||||
private List<LoginInfo> loginInfos;
|
||||
private long createTime;
|
||||
//private List<String> binds;
|
||||
private int lessonLimit;
|
||||
//private List<String> lessonShow;
|
||||
private String lang;
|
||||
private String pk;
|
||||
|
||||
@Data
|
||||
public static class School {
|
||||
private String schoolId;
|
||||
private String name;
|
||||
private String status;
|
||||
private long time;
|
||||
private String picture;
|
||||
private String areaId;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Area {
|
||||
private String areaId;
|
||||
private String name;
|
||||
private String status;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class LoginInfo {
|
||||
private long time;
|
||||
private String ip;
|
||||
private long expire;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cn.teammodel.model.vo.admin;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-06 20:17
|
||||
*/
|
||||
@Data
|
||||
public class RankVo {
|
||||
private String id;
|
||||
private String name;
|
||||
private Integer count;
|
||||
}
|
Loading…
Reference in new issue