feat: 新增部分管理员接口以及提升稳定性

11111
winter 1 year ago
parent 3477592027
commit 79db32c215

@ -39,16 +39,17 @@
</dependency> </dependency>
<!-- cosmos --> <!-- cosmos -->
<dependency> <!-- <dependency>-->
<groupId>com.azure.spring</groupId> <!-- <groupId>com.azure.spring</groupId>-->
<artifactId>spring-cloud-azure-starter</artifactId> <!-- <artifactId>spring-cloud-azure-starter</artifactId>-->
</dependency> <!-- </dependency>-->
<!-- knife4j --> <!-- knife4j -->
<dependency> <dependency>
<groupId>com.github.xiaoymin</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId> <artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version> <version>3.0.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.azure.spring</groupId> <groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-data-cosmos</artifactId> <artifactId>spring-cloud-azure-starter-data-cosmos</artifactId>
@ -73,11 +74,12 @@
<!-- 修改后的jjwt --> <!-- 修改后的jjwt -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>jsonwebtoken</groupId>
<artifactId>jjwt</artifactId> <artifactId>habook-jjwt</artifactId>
<version>0.9.1</version> <version>0.0.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
@ -92,6 +94,7 @@
</dependency> </dependency>
</dependencies> </dependencies>
<!-- 私服 -->
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
@ -104,6 +107,25 @@
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<repositories>
<repository>
<id>gitea</id>
<url>http://163.228.224.105:3000/api/packages/winteach/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitea</id>
<url>http://163.228.224.105:3000/api/packages/winteach/maven</url>
</repository>
<snapshotRepository>
<id>gitea</id>
<url>http://163.228.224.105:3000/api/packages/winteach/maven</url>
</snapshotRepository>
</distributionManagement>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>

@ -0,0 +1,18 @@
package cn.teammodel.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
/**
* @author winter
* @create 2023-12-08 17:30
*/
@Data
@AllArgsConstructor
public class PageVo<T> {
private Integer totalPages;
private Long totalItems;
private List<T> content;
}

@ -1,5 +1,6 @@
package cn.teammodel.controller.admin.controller; package cn.teammodel.controller.admin.controller;
import cn.teammodel.common.PageVo;
import cn.teammodel.common.R; import cn.teammodel.common.R;
import cn.teammodel.controller.admin.service.AdminAppraiseService; import cn.teammodel.controller.admin.service.AdminAppraiseService;
import cn.teammodel.model.dto.admin.TimeRangeDto; import cn.teammodel.model.dto.admin.TimeRangeDto;
@ -27,17 +28,17 @@ public class IndexController {
private AdminAppraiseService adminAppraiseService; private AdminAppraiseService adminAppraiseService;
@GetMapping("/{academicYearId}") @GetMapping("/{periodId}")
@ApiOperation("获取首页数据") @ApiOperation("获取首页数据")
public R<IndexData> index(@PathVariable String academicYearId){ public R<IndexData> index(@PathVariable String periodId){
IndexData indexData = adminAppraiseService.getIndexData(academicYearId); IndexData indexData = adminAppraiseService.getIndexData(periodId);
return R.success(indexData); return R.success(indexData);
} }
@PostMapping("latestRecord") @PostMapping("latestRecord")
@ApiOperation("查询最新评价(可通过时间范围分页)") @ApiOperation("查询最新评价(可通过时间范围分页)")
public R<List<RecordVo>> latestRecord(@Valid @RequestBody TimeRangeDto timeRangeDto) { public R<PageVo<RecordVo>> latestRecord(@Valid @RequestBody TimeRangeDto timeRangeDto) {
List<RecordVo> res = adminAppraiseService.conditionLatestRecord(timeRangeDto); PageVo<RecordVo> res = adminAppraiseService.conditionLatestRecord(timeRangeDto);
return R.success(res); return R.success(res);
} }

@ -1,5 +1,6 @@
package cn.teammodel.controller.admin.service; package cn.teammodel.controller.admin.service;
import cn.teammodel.common.PageVo;
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.RankPo;
@ -14,12 +15,12 @@ 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 academicYearId); IndexData getIndexData(String periodId);
/** /**
* *
*/ */
List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto); PageVo<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto);
List<RankPo> classRank(TimeRangeDto timeRangeDto); List<RankPo> classRank(TimeRangeDto timeRangeDto);

@ -1,12 +1,16 @@
package cn.teammodel.controller.admin.service.impl; package cn.teammodel.controller.admin.service.impl;
import cn.hutool.core.lang.Pair; import cn.hutool.core.lang.Pair;
import cn.teammodel.common.ErrorCode;
import cn.teammodel.common.PK; import cn.teammodel.common.PK;
import cn.teammodel.common.PageVo;
import cn.teammodel.config.exception.ServiceException;
import cn.teammodel.controller.admin.service.AdminAppraiseService; import cn.teammodel.controller.admin.service.AdminAppraiseService;
import cn.teammodel.dao.*; import cn.teammodel.dao.*;
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.school.ClassInfo; import cn.teammodel.model.entity.school.ClassInfo;
import cn.teammodel.model.entity.school.School;
import cn.teammodel.model.entity.school.Student; 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;
@ -15,26 +19,30 @@ import cn.teammodel.model.vo.admin.RankVo;
import cn.teammodel.model.vo.admin.StudentRankVo; 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 cn.teammodel.utils.SchoolDateUtil;
import com.azure.spring.data.cosmos.core.query.CosmosPageRequest; import com.azure.spring.data.cosmos.core.query.CosmosPageRequest;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice; 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.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.WeekFields;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.teammodel.utils.SchoolDateUtil.calculateWeekNum;
/** /**
* @author winter * @author winter
* @create 2023-12-06 14:46 * @create 2023-12-06 14:46
*/ */
@Service @Service
public class AdminAppraiseServiceImpl implements AdminAppraiseService { public class AdminAppraiseServiceImpl implements AdminAppraiseService {
@Resource
private SchoolRepository schoolRepository;
@Resource @Resource
private ClassRepository classRepository; private ClassRepository classRepository;
@Resource @Resource
@ -48,19 +56,32 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
private AppraiseRecordRepository appraiseRecordRepository; private AppraiseRecordRepository appraiseRecordRepository;
@Override @Override
public IndexData getIndexData(String academicYearId) { public IndexData getIndexData(String periodId) {
final int SLICE_SIZE = 100;
if (StringUtils.isBlank(periodId)) {
throw new ServiceException(ErrorCode.PARAMS_ERROR.getCode(), "不能为空");
}
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<>(); Set<String> creatorIdSet = new HashSet<>();
User loginUser = SecurityUtil.getLoginUser(); User loginUser = SecurityUtil.getLoginUser();
String schoolId = loginUser.getSchoolId(); String schoolId = loginUser.getSchoolId();
// 获取学期起止时间
List<School.Semester> semesters = schoolRepository.findSemestersById(schoolId, periodId);
SchoolDateUtil.semesterModel semesterModel = SchoolDateUtil.getSemesterByNow(semesters, LocalDate.now());
String academicYearId = semesterModel.getAcademicYearId();
LocalDateTime startDatetime = semesterModel.getStartDatetime();
LocalDateTime endDatetime = semesterModel.getEndDatetime();
if (startDatetime == null || endDatetime == null) throw new ServiceException(ErrorCode.PARAMS_ERROR);
long totalWeek = calculateWeekNum(startDatetime, endDatetime, null);
// slice 分段读取 // slice 分段读取
CosmosPageRequest pageRequest = new CosmosPageRequest(0, 100, null); CosmosPageRequest pageRequest = new CosmosPageRequest(0, SLICE_SIZE, null);
Slice<RecordVo> slice; Slice<RecordVo> slice;
Map<Integer, Integer> countByWeek = new HashMap<>(); Map<Long, Integer> countByWeek = SchoolDateUtil.createEmptyWeekMap(totalWeek);
do { do {
slice = appraiseRecordRepository.findAllByAcademicYearId(String.format(PK.PK_APPRAISE_RECORD, schoolId), academicYearId, pageRequest); slice = appraiseRecordRepository.findAllByAcademicYearId(String.format(PK.PK_APPRAISE_RECORD, schoolId), academicYearId, pageRequest);
@ -72,7 +93,7 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
// 分批次计算 // 分批次计算
for (RecordVo item : content) { for (RecordVo item : content) {
// 处理每周的评价数 // 处理每周的评价数
int weekNum = calculateWeekNum(item.getCreateTime()); long weekNum = calculateWeekNum(startDatetime, endDatetime, item.getCreateTime());
countByWeek.put(weekNum, countByWeek.getOrDefault(weekNum, 0) + 1); countByWeek.put(weekNum, countByWeek.getOrDefault(weekNum, 0) + 1);
// 处理总评价数 // 处理总评价数
totalCount++; totalCount++;
@ -99,7 +120,7 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
} }
@Override @Override
public List<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto) { public PageVo<RecordVo> conditionLatestRecord(TimeRangeDto timeRangeDto) {
Long startTime = timeRangeDto.getStartTime(); Long startTime = timeRangeDto.getStartTime();
Long endTime = timeRangeDto.getEndTime(); Long endTime = timeRangeDto.getEndTime();
String academicYearId = timeRangeDto.getAcademicYearId(); String academicYearId = timeRangeDto.getAcademicYearId();
@ -115,7 +136,7 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
endTime, endTime,
pageRequest); pageRequest);
return page.getContent(); return new PageVo<>(page.getTotalPages(), page.getTotalElements(), page.getContent());
} }
@Override @Override
@ -272,13 +293,4 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService {
return res; return res;
} }
private int calculateWeekNum(Long timeStamp) {
// second 时间戳转 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timeStamp), ZoneOffset.UTC);
// 获取周字段 todo: 时区或者周的计算
WeekFields weekFields = WeekFields.of(Locale.getDefault());
// 获取当前日期时间所在年的周数
return localDateTime.get(weekFields.weekOfWeekBasedYear());
}
} }

@ -67,7 +67,7 @@ public interface AppraiseRecordRepository extends CosmosRepository<AppraiseRecor
* , * ,
*/ */
// todo: 调整一下数据结构 // todo: 调整一下数据结构
@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 " + @Query("select c.id as recordId, c.name as targetName, c.avatar, c.className, n.id as recordNodeId, 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 n.createTime >= @startTime) and " + "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +

@ -21,4 +21,6 @@ public interface SchoolRepository extends CosmosRepository<School, String> {
List<School.Period> findPeriodById(@Param("schoolId") String schoolId, @Param("periodId") String periodId); List<School.Period> findPeriodById(@Param("schoolId") String schoolId, @Param("periodId") String periodId);
@Query("select value p.semesters from School as s join p in s.period where s.id = @schoolId and s.code = 'Base' and p.id = @periodId") @Query("select value p.semesters from School as s join p in s.period where s.id = @schoolId and s.code = 'Base' and p.id = @periodId")
List<School.Semester> findSemestersById(@Param("schoolId") String schoolId, @Param("periodId") String periodId); List<School.Semester> findSemestersById(@Param("schoolId") String schoolId, @Param("periodId") String periodId);
School findSchoolByIdAndCode(String schoolId, String code);
} }

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

@ -9,12 +9,14 @@ import lombok.Data;
*/ */
@Data @Data
public class RecordVo { public class RecordVo {
private String recordId; private String recordId; // 文档 id
private String targetName; private String recordNodeId; // 文档中的评价记录 id
private String targetName; // 评价对象的名字
private String avatar; private String avatar;
private String className;
private String appraiseName; private String appraiseName;
private String targetId; private String targetId; // 评价对象 id
private String targetType; private String targetType; // 评价对象类型
private String creatorId; private String creatorId;
private String creator; private String creator;
private Long createTime; private Long createTime;

@ -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(Instant.now().getEpochSecond()); newNode.setCreateTime(Instant.now().toEpochMilli());
originNodes.add(newNode); originNodes.add(newNode);
return buildTree(appraiseRepository.save(appraise)); return buildTree(appraiseRepository.save(appraise));
@ -277,7 +277,7 @@ public class EvaluationServiceImpl implements EvaluationService {
List<School.Semester> semesters = period.getSemesters(); List<School.Semester> semesters = period.getSemesters();
// 获取当前学年学期组合 ID // 获取当前学年学期组合 ID
String academicYearId = SchoolDateUtil.generateAcademicId(semesters, LocalDate.now()); String academicYearId = SchoolDateUtil.calculateAcademicYearId(semesters, LocalDate.now());
// 查询是否存在记录 // 查询是否存在记录
AppraiseRecord record = appraiseRecordRepository.findAppraiseRecordByTargetIdAndClassIdAndAcademicYearIdAndCode( AppraiseRecord record = appraiseRecordRepository.findAppraiseRecordByTargetIdAndClassIdAndAcademicYearIdAndCode(
@ -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(Instant.now().getEpochSecond()); item.setCreateTime(Instant.now().toEpochMilli());
// 处理学校与学生的差异 // 处理学校与学生的差异
if (targetType.equals(TARGET_CLASS)){ if (targetType.equals(TARGET_CLASS)){
item.setSpread(spread); item.setSpread(spread);
@ -345,7 +345,7 @@ public class EvaluationServiceImpl implements EvaluationService {
String schoolId = loginUser.getSchoolId(); String schoolId = loginUser.getSchoolId();
List<School.Semester> semesters = schoolRepository.findSemestersById(schoolId, periodId); List<School.Semester> semesters = schoolRepository.findSemestersById(schoolId, periodId);
String academicYearId = SchoolDateUtil.generateAcademicId(semesters, LocalDate.now()); String academicYearId = SchoolDateUtil.calculateAcademicYearId(semesters, LocalDate.now());
// 分页 // 分页
Sort sort = Sort.by("createTime").descending(); Sort sort = Sort.by("createTime").descending();
final CosmosPageRequest pageRequest = new CosmosPageRequest(findVoteRecordDto.getCurrent(), findVoteRecordDto.getSize(), null, sort); final CosmosPageRequest pageRequest = new CosmosPageRequest(findVoteRecordDto.getCurrent(), findVoteRecordDto.getSize(), null, sort);

@ -3,11 +3,18 @@ package cn.teammodel.utils;
import cn.teammodel.common.CommonConstant; import cn.teammodel.common.CommonConstant;
import cn.teammodel.config.exception.ServiceException; import cn.teammodel.config.exception.ServiceException;
import cn.teammodel.model.entity.school.School; import cn.teammodel.model.entity.school.School;
import org.apache.commons.lang3.tuple.Pair; import lombok.AllArgsConstructor;
import lombok.Data;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* ,, * ,,
@ -41,7 +48,7 @@ public class SchoolDateUtil {
* : -> 2024.1.1, 2023,,semesters * : -> 2024.1.1, 2023,,semesters
* </p> * </p>
*/ */
public static Pair<String, LocalDate> getSemesterByNow(List<School.Semester> semesters, LocalDate date) { public static semesterModel getSemesterByNow(List<School.Semester> semesters, LocalDate date) {
if (semesters == null || semesters.isEmpty() || date == null) { if (semesters == null || semesters.isEmpty() || date == null) {
throw new ServiceException("semesters and date must not be null or empty."); throw new ServiceException("semesters and date must not be null or empty.");
} }
@ -53,6 +60,8 @@ public class SchoolDateUtil {
int size = semesters.size(); int size = semesters.size();
// 拿到最晚开学的日期,将年份 - 1后,与头节点组成可跨年区间 // 拿到最晚开学的日期,将年份 - 1后,与头节点组成可跨年区间
School.Semester lastSemester = semesters.get(size - 1); School.Semester lastSemester = semesters.get(size - 1);
School.Semester firstSemester = semesters.get(0);
// 动态替换
LocalDate lastSemesterStart = LocalDate.of(date.getYear() - 1, lastSemester.getMonth(), lastSemester.getDay()); LocalDate lastSemesterStart = LocalDate.of(date.getYear() - 1, lastSemester.getMonth(), lastSemester.getDay());
String lastSemesterId = lastSemester.getId(); String lastSemesterId = lastSemester.getId();
for (School.Semester semester : semesters) { for (School.Semester semester : semesters) {
@ -60,25 +69,71 @@ public class SchoolDateUtil {
// 2022.9.1 - 2023.3.1, 2023.3.1 - 2023.9.1, 2023.9.1 - 2024.3.1 // 2022.9.1 - 2023.3.1, 2023.3.1 - 2023.9.1, 2023.9.1 - 2024.3.1
LocalDate curSemesterStart = LocalDate.of(date.getYear(), semester.getMonth(), semester.getDay()); LocalDate curSemesterStart = LocalDate.of(date.getYear(), semester.getMonth(), semester.getDay());
if (date.isEqual(lastSemesterStart) || date.isAfter(lastSemesterStart) && date.isBefore(curSemesterStart)) { if (date.isEqual(lastSemesterStart) || date.isAfter(lastSemesterStart) && date.isBefore(curSemesterStart)) {
return Pair.of(lastSemesterId, lastSemesterStart); String academicYearId = generateCurAcademicId(lastSemesterStart.getYear(), lastSemesterId);
return new semesterModel(academicYearId, lastSemesterId, lastSemesterStart.atStartOfDay(), semester.getId(), curSemesterStart.atStartOfDay());
} }
lastSemesterStart = curSemesterStart; lastSemesterStart = curSemesterStart;
lastSemesterId = semester.getId(); lastSemesterId = semester.getId();
} }
// 剩下的时间段, 学年应该就是最后一个学年 // 剩下的时间段, 学年应该就是最后一个学年. 学期末就应该是下一年(year + 1)的第一个节点
return Pair.of(lastSemester.getId(), LocalDate.of(date.getYear(), lastSemester.getMonth(), lastSemester.getDay())); String academicYearId = generateCurAcademicId(date.getYear(), lastSemester.getId());
return new semesterModel(
academicYearId,
lastSemester.getId(),
LocalDate.of(date.getYear(), lastSemester.getMonth(), lastSemester.getDay()).atStartOfDay(),
firstSemester.getId(),
LocalDate.of(date.getYear() + 1, firstSemester.getMonth(), firstSemester.getDay()).atStartOfDay()
);
} }
/** /**
* ID -> ( id: -semesterId -> 2023-{semesterId}) * ID -> ( id: -semesterId -> 2023-{semesterId})
*/ */
public static String generateAcademicId(List<School.Semester> semesters, LocalDate date) { private static String generateCurAcademicId(int academicYear, String semesterId) {
Pair<String, LocalDate> pair = getSemesterByNow(semesters, date); return academicYear + CommonConstant.DASH + semesterId;
String semesterId = pair.getLeft();
LocalDate academicYear = pair.getRight();
return academicYear.getYear() + CommonConstant.DASH + semesterId;
} }
public static String calculateAcademicYearId(List<School.Semester> semesters, LocalDate date) {
return getSemesterByNow(semesters, date).getAcademicYearId();
}
/**
* <br/>
* timeStamp null,
*/
public static long calculateWeekNum(LocalDateTime startDateTime, LocalDateTime endDateTime, Long timeStamp) {
if (timeStamp == null) {
return ChronoUnit.WEEKS.between(startDateTime, endDateTime) + 1;
} else {
LocalDateTime curDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeStamp), ZoneOffset.UTC);
// 如果传参没在学期范围内, 返回 -1
if (curDateTime.isBefore(startDateTime) || curDateTime.isAfter(endDateTime)) {
return -1;
}
return ChronoUnit.WEEKS.between(startDateTime, curDateTime) + 1;
}
}
/**
* Map
*/
public static Map<Long, Integer> createEmptyWeekMap(long totalWeek) {
Map<Long, Integer> initialMap = new HashMap<>();
for (long i = 1; i <= totalWeek; i++) {
initialMap.put(i, 0);
}
return initialMap;
}
@Data
@AllArgsConstructor
public static class semesterModel {
private String academicYearId;
private String startSemesterId;
private LocalDateTime startDatetime;
private String endSemesterId;
private LocalDateTime endDatetime;
}
} }

@ -10,24 +10,25 @@ 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.AppraiseRecord;
import cn.teammodel.model.entity.appraise.AppraiseRecordItem;
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.RankPo; import cn.teammodel.model.vo.admin.RankPo;
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;
import com.azure.cosmos.models.PartitionKey; import com.azure.cosmos.models.PartitionKey;
import com.azure.spring.data.cosmos.core.CosmosTemplate; import com.azure.spring.data.cosmos.core.CosmosTemplate;
import com.azure.spring.data.cosmos.core.query.CosmosPageRequest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Slice;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.WeekFields; import java.time.temporal.WeekFields;
import java.util.*; import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
@SpringBootTest @SpringBootTest
class TeamModelExtensionApplicationTests { class TeamModelExtensionApplicationTests {
@ -150,24 +151,24 @@ class TeamModelExtensionApplicationTests {
@Test @Test
public void testSlice() { public void testSlice() {
CosmosPageRequest pageRequest = new CosmosPageRequest(0, 10, null); // CosmosPageRequest pageRequest = new CosmosPageRequest(0, 10, null);
Slice<RecordVo> slice; // Slice<RecordVo> slice;
Map<Integer, Integer> countByWeek = new HashMap<>(); // Map<Integer, Integer> countByWeek = new HashMap<>();
//
do { // do {
slice = appraiseRecordRepository.findAllByAcademicYearId("AppraiseRecord-habook", "2023-71fbd0bd-9a46-0490-f6b3-7d16cba4c017", pageRequest); // slice = appraiseRecordRepository.findAllByAcademicYearId("AppraiseRecord-habook", "2023-71fbd0bd-9a46-0490-f6b3-7d16cba4c017", pageRequest);
//
slice.getContent().forEach(item -> { // slice.getContent().forEach(item -> {
int weekNum = calculateWeekNum(item.getCreateTime()); // int weekNum = calculateWeekNum(item.getCreateTime());
countByWeek.put(weekNum, countByWeek.getOrDefault(weekNum, 0) + 1); // countByWeek.put(weekNum, countByWeek.getOrDefault(weekNum, 0) + 1);
}); // });
//
if (slice.hasNext()) { // if (slice.hasNext()) {
pageRequest = (CosmosPageRequest) slice.nextPageable(); // pageRequest = (CosmosPageRequest) slice.nextPageable();
} // }
} while (slice.hasNext()); // } while (slice.hasNext());
//
countByWeek.forEach((item, count) -> System.out.println(item + ": " + count)); // countByWeek.forEach((item, count) -> System.out.println(item + ": " + count));
} }
private int calculateWeekNum(LocalDateTime localDateTime) { private int calculateWeekNum(LocalDateTime localDateTime) {
@ -188,17 +189,19 @@ class TeamModelExtensionApplicationTests {
@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, "habook"));
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(); Long createTime = node.getCreateTime();
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); int length = String.valueOf(createTime).length();
// // 解析字符串 // 让所有十位的时间戳转为十三位
// LocalDateTime dateTime = LocalDateTime.parse(createTime, formatter); if (length == 10) {
// node.setTime(String.valueOf(dateTime.toEpochSecond(ZoneOffset.UTC))); createTime = createTime * 1000L;
// } }
node.setCreateTime(createTime);
}
cosmosTemplate.upsert(appraiseRecord); cosmosTemplate.upsert(appraiseRecord);
System.out.println("更新完毕"); System.out.println("更新完毕");
} }

@ -4,6 +4,7 @@ import cn.teammodel.model.entity.appraise.Appraise;
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.service.impl.EvaluationServiceImpl; import cn.teammodel.service.impl.EvaluationServiceImpl;
import cn.teammodel.utils.SchoolDateUtil;
import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest; import com.dingtalk.api.request.OapiRobotSendRequest;
@ -12,7 +13,10 @@ import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -145,9 +149,17 @@ public class TestWithoutSpring {
new School.Semester("2", "下学期", 0, 5, 1) new School.Semester("2", "下学期", 0, 5, 1)
); );
LocalDate currentDate = LocalDate.of(2024, 1, 1); LocalDate currentDate = LocalDate.of(2024, 11, 1);
//String currentSemester = SchoolDateUtil.getSemesterByNow(semesters, currentDate); String id = SchoolDateUtil.calculateAcademicYearId(semesters, currentDate);
//System.out.println(currentSemester); System.out.println(id);
}
@Test
public void testWeek() {
LocalDateTime start = LocalDateTime.ofInstant(Instant.ofEpochSecond(1690819200L), ZoneOffset.UTC);
LocalDateTime end = LocalDateTime.ofInstant(Instant.ofEpochSecond(1708099200L), ZoneOffset.UTC);
long l = SchoolDateUtil.calculateWeekNum(start, end, null);
System.out.println(l);
} }
} }

Loading…
Cancel
Save