考试功能

sale
tianea 3 years ago
parent 9eeaf605d7
commit 4a94887b91

@ -18,7 +18,7 @@ public class JWTUtil {
private static final String ISSUER = "TIANZE"; private static final String ISSUER = "TIANZE";
public static final String USERNO = "userNo"; public static final String USERNO = "userNo";
public static final String USERTYPE= "userType"; public static final String USERTYPE= "userType";
public static final Long DATE = 30 * 24 * 3600 * 1000L; // 1个月 public static final Long DATE = 7* 24 * 3600 * 1000L; // 7天
/** /**
* @param userNo * @param userNo

@ -0,0 +1,34 @@
package com.tz.platform.competitiion.api;
import com.tz.platform.common.core.base.BaseController;
import com.tz.platform.common.core.base.Result;
import com.tz.platform.competitiion.api.biz.CompetitionMemberBiz;
import com.tz.platform.competitiion.api.dto.CompetitionMemberDTO;
import com.tz.platform.competitiion.api.dto.ExamPaperDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/auth/competition/member")
public class ApiCompetitionMemberController extends BaseController {
@Autowired
private CompetitionMemberBiz memberBiz;
@GetMapping(value = "paper")
public Result<ExamPaperDTO> getPaper(@RequestParam("compId")Long compId, @RequestParam("stageId") Integer stageId){
return memberBiz.getExamPaper(compId,stageId,getUserNo());
}
@GetMapping(value = "get")
public Result<CompetitionMemberDTO> get(@RequestParam("compId") Long compId,@RequestParam("stageId") Integer stageId){
return memberBiz.get(compId,stageId,getUserNo());
}
}

@ -0,0 +1,10 @@
package com.tz.platform.competitiion.api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/api/competition/ranking")
public class ApiCompetitionRankingController {
}

@ -0,0 +1,28 @@
package com.tz.platform.competitiion.api;
import com.tz.platform.common.core.base.Result;
import com.tz.platform.competitiion.api.biz.CompetitionTaskBiz;
import com.tz.platform.competitiion.api.dto.CompetitionTaskDTO;
import com.tz.platform.competitiion.api.dto.ListCompetitionTaskDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping(value = "auth/competition/task")
public class ApiCompetitionTaskController {
@Autowired
private CompetitionTaskBiz taskBiz;
@RequestMapping(value = "list")
public Result<ListCompetitionTaskDTO> list(@RequestParam("compId") Long compId){
return taskBiz.list(compId);
}
@RequestMapping(value = "get")
public Result<CompetitionTaskDTO> get(@RequestParam("compId") Long compId, @RequestParam("stageId") Integer stageId){
return taskBiz.get(compId,stageId);
}
}

@ -38,4 +38,5 @@ public class CompetitionExamController extends BaseController {
return examBiz.startExam(compId,stageId,getUserNo()); return examBiz.startExam(compId,stageId,getUserNo());
} }
} }

@ -6,6 +6,8 @@ import com.tz.platform.common.core.base.Result;
import com.tz.platform.competitiion.api.biz.CompetitionIndexBiz; import com.tz.platform.competitiion.api.biz.CompetitionIndexBiz;
import com.tz.platform.competitiion.api.dto.CompetitionDTO; import com.tz.platform.competitiion.api.dto.CompetitionDTO;
import com.tz.platform.competitiion.api.dto.IndexListCompetitionDTO; import com.tz.platform.competitiion.api.dto.IndexListCompetitionDTO;
import com.tz.platform.competitiion.api.dto.ListGroupDTO;
import com.tz.platform.competitiion.api.dto.ListRankingDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -21,7 +23,6 @@ public class CompetitionIndexControll extends BaseController {
return competitionIndexBiz.list(pageNo,type); return competitionIndexBiz.list(pageNo,type);
} }
@GetMapping(value = "get") @GetMapping(value = "get")
public Result<CompetitionDTO> get(@RequestParam("compId") Long compId){ public Result<CompetitionDTO> get(@RequestParam("compId") Long compId){
return competitionIndexBiz.get(compId); return competitionIndexBiz.get(compId);
@ -32,8 +33,18 @@ public class CompetitionIndexControll extends BaseController {
return competitionIndexBiz.position(getUserNo(),cmpId,stageId); return competitionIndexBiz.position(getUserNo(),cmpId,stageId);
} }
@GetMapping(value = "system") @GetMapping(value = "content")
public Result<String> getSystemInfo(){ public Result<String> getContent(@RequestParam("type") Integer type){
return Result.error("failed"); return Result.error("failed");
} }
@GetMapping(value = "sysRanking")
public Result<ListRankingDTO> sysRanking(@RequestParam("pageNO") Integer pageNo,@RequestParam("pageSize") Integer pageSize, @RequestParam("date") String date,@RequestParam("key") String key,@RequestParam("compId") Long compId, @RequestParam("stageId")Integer stageId){
return competitionIndexBiz.listRanKing(pageNo,pageSize,date,key,compId,stageId);
}
@GetMapping(value = "group")
public Result<ListGroupDTO> getGroup(@RequestParam("compId") Long compId,@RequestParam("stageId") Integer stageId){
return competitionIndexBiz.getGroup(compId);
}
} }

@ -9,10 +9,7 @@ import com.tz.platform.competitiion.api.dto.ExamDTO;
import com.tz.platform.competitiion.api.dto.SubmitResultDTO; import com.tz.platform.competitiion.api.dto.SubmitResultDTO;
import com.tz.platform.competitiion.api.vo.SubmitQuestionVO; import com.tz.platform.competitiion.api.vo.SubmitQuestionVO;
import com.tz.platform.competitiion.api.vo.SubmitVo; import com.tz.platform.competitiion.api.vo.SubmitVo;
import com.tz.platform.entity.CompetitionGroup; import com.tz.platform.entity.*;
import com.tz.platform.entity.CompetitionMember;
import com.tz.platform.entity.CompetitionTask;
import com.tz.platform.entity.ExamPaper;
import com.tz.platform.feign.exam.IFeignExam; import com.tz.platform.feign.exam.IFeignExam;
import com.tz.platform.feign.exam.qo.CacheQuestionQO; import com.tz.platform.feign.exam.qo.CacheQuestionQO;
import com.tz.platform.feign.exam.vo.QuestionVo; import com.tz.platform.feign.exam.vo.QuestionVo;
@ -23,6 +20,7 @@ import com.tz.platform.repository.CompetitionMemberDao;
import com.tz.platform.repository.CompetitionTaskDao; import com.tz.platform.repository.CompetitionTaskDao;
import com.tz.platform.repository.ExamPaperDao; import com.tz.platform.repository.ExamPaperDao;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -52,30 +50,50 @@ public class CompetitionExamBiz {
@Autowired @Autowired
private IFeignExam feignExam; private IFeignExam feignExam;
@Autowired
private RedisTemplate<String,Object> template;
public List<QuestionVo> getExamQuestion(Long compId,Integer stageId,Long userId){ public List<QuestionVo> getExamQuestion(Long compId,Integer stageId,Long userId){
UserVo currentUser = feignUser.getByUserNo(userId); UserVo currentUser = feignUser.getByUserNo(userId);
CompetitionTask task = competitionTaskDao.getByCompetitionIdAndStageId(compId,stageId); String key = "questionList_"+compId+"_"+stageId+"_"+currentUser.getLevelId();
List<CompetitionGroup> groupList = groupDao.findByCompetitionId(compId); Object questListObj = template.opsForValue().get(key);
//学生层次限制 List<QuestionVo> questionVos = null;
List<CompetitionGroup> limitList = groupList.stream().filter(g->g.getLimitType() == 1).collect(Collectors.toList()); if(questListObj!=null){
List<Long> ids = new ArrayList<>(); questionVos = ( List<QuestionVo>) questListObj;
task.getQuestionList().forEach(taskQuestion -> { }else{
if(taskQuestion.getGroupId().equals(0)){ CompetitionTask task = competitionTaskDao.getByCompetitionIdAndStageId(compId,stageId);
ids.addAll(taskQuestion.getQuestionIds()); List<CompetitionGroup> groupList = groupDao.findByCompetitionId(compId);
}else{ //学生层次限制
//不同学生层次不同案例题 List<CompetitionGroup> limitList = groupList.stream().filter(g->g.getLimitType() == 1).collect(Collectors.toList());
CompetitionGroup group = limitList.stream().filter(g->g.getId() .equals(taskQuestion.getGroupId())).findFirst().orElse(null); List<Long> ids = new ArrayList<>();
if(group!=null) { task.getQuestionList().forEach(taskQuestion -> {
GroupCat groupCat = group.getCatList().stream().filter(groupCat1 -> groupCat1.getId().equals(currentUser.getLevelId())).findFirst().orElse(null); if(taskQuestion.getGroupId().equals(0)){
if (groupCat != null) { ids.addAll(taskQuestion.getQuestionIds());
ids.addAll(taskQuestion.getQuestionIds()); }else{
//不同学生层次不同案例题
CompetitionGroup group = limitList.stream().filter(g->g.getId() .equals(taskQuestion.getGroupId())).findFirst().orElse(null);
if(group!=null) {
GroupCat groupCat = group.getCatList().stream().filter(groupCat1 -> groupCat1.getId().equals(currentUser.getLevelId())).findFirst().orElse(null);
if (groupCat != null) {
ids.addAll(taskQuestion.getQuestionIds());
}
} }
} }
});
CacheQuestionQO qo = new CacheQuestionQO();
qo.setIds(ids);
questionVos = feignExam.listQusetion(qo);
}
questionVos.forEach(questionVo -> {
if(questionVo.getType() == 0){
questionVo.setAnswerId(new ArrayList<>());
}else{
questionVo.getChildren().forEach(child->{
child.setAnswerId(new ArrayList<>());
});
} }
}); });
CacheQuestionQO qo = new CacheQuestionQO();
qo.setIds(ids);
List<QuestionVo> questionVos = feignExam.listQusetion(qo);
return questionVos; return questionVos;
} }
@ -88,18 +106,23 @@ public class CompetitionExamBiz {
@Transactional @Transactional
public Result<ExamDTO> startExam(Long compId, Integer stageId, Long userNo){ public Result<ExamDTO> startExam(Long compId, Integer stageId, Long userNo){
CompetitionMember member = competitionMemberDao.getByCompetitionIdAndStageIdAndUserId(compId,stageId,userNo); CompetitionMember member = competitionMemberDao.getByCompetitionIdAndStageIdAndUserId(compId,stageId,userNo);
CompetitionTask task = competitionTaskDao.getByCompetitionIdAndStageId(compId,stageId);
if(member == null){ if(member == null){
return Result.error("未报名该大赛或赛段"); return Result.error("未报名该大赛或赛段");
} }
if(task.getExamDuration() == null){
return Result.error("试卷设置错误");
}
if(member.getExamStartTime()!=null){ if(member.getExamStartTime()!=null){
ExamDTO dto = new ExamDTO(); ExamDTO dto = new ExamDTO();
dto.setStartTime(member.getExamStartTime()); dto.setStartTime(member.getExamStartTime());
dto.setEndTime(DateUtil.addHours(member.getExamStartTime(),1)); dto.setEndTime(DateUtil.addHours(member.getExamStartTime(),task.getExamDuration()));
return Result.success(dto); return Result.success(dto);
} }
Date examStartTime = new Date(); Date examStartTime = new Date();
Date examEndTime = DateUtil.addHours(examStartTime,1); Date examEndTime = DateUtil.addHours(examStartTime,task.getExamDuration());
int affect = competitionMemberDao.updateExamStartTime(userNo,stageId,compId,examStartTime); int affect = competitionMemberDao.updateExamStartTime(userNo,stageId,compId,examStartTime);
if(affect>0){ if(affect>0){
ExamDTO dto = new ExamDTO(); ExamDTO dto = new ExamDTO();
@ -131,7 +154,7 @@ public class CompetitionExamBiz {
SubmitResultDTO dto = new SubmitResultDTO(); SubmitResultDTO dto = new SubmitResultDTO();
List<QuestionVo> questionVoList = getExamQuestion(vo.getCompId(),vo.getStageId(),vo.getUserNo()); List<QuestionVo> questionVoList = getExamQuestion(vo.getCompId(),vo.getStageId(),vo.getUserNo());
Long score = computeScore(questionVoList,vo.getQList()); Double score = computeScore(questionVoList,vo.getQList());
competitionMemberDao.updateScore(vo.getUserNo(),vo.getStageId(),vo.getCompId(),score); competitionMemberDao.updateScore(vo.getUserNo(),vo.getStageId(),vo.getCompId(),score);
competitionMemberDao.updateExamEndTimeAndCostTime(vo.getUserNo(),vo.getStageId(),vo.getCompId(),now,costTime); competitionMemberDao.updateExamEndTimeAndCostTime(vo.getUserNo(),vo.getStageId(),vo.getCompId(),now,costTime);
ExamPaper paper = BeanUtils.copyProperties(vo,ExamPaper.class); ExamPaper paper = BeanUtils.copyProperties(vo,ExamPaper.class);
@ -142,8 +165,8 @@ public class CompetitionExamBiz {
} }
//计算得分 //计算得分
private Long computeScore(List<QuestionVo> questionVoList, List<SubmitQuestionVO> submitQuestionVOS){ private Double computeScore(List<QuestionVo> questionVoList, List<SubmitQuestionVO> submitQuestionVOS){
Long totalScore = 0L; Double totalScore = 0D;
for(int j = 0;j< submitQuestionVOS.size();j++) for(int j = 0;j< submitQuestionVOS.size();j++)
{ {
SubmitQuestionVO submitQuestionVO = submitQuestionVOS.get(j); SubmitQuestionVO submitQuestionVO = submitQuestionVOS.get(j);
@ -154,19 +177,6 @@ public class CompetitionExamBiz {
if(checkCorrect(q.getAnswerId(),submitQuestionVO.getIds())){ if(checkCorrect(q.getAnswerId(),submitQuestionVO.getIds())){
totalScore += q.getScore(); totalScore += q.getScore();
} }
// if(q.getAnswerId().size() == submitQuestionVO.getIds().size()){
// boolean crorrect = true;
// for(int i = 0 ;i <submitQuestionVO.getIds().size();i++){
// if(q.getAnswerId().indexOf(submitQuestionVO.getIds().get(i))<0){
// crorrect = false;
// break;
// }
// }
// if(crorrect){
// totalScore+= q.getScore();
// }
//
// }
}else{ }else{
//案例题 //案例题
SubQuestionVO subQuestionVO = q.getChildren().stream().filter(subQuestionVO1 -> subQuestionVO1.getId().intValue() == submitQuestionVO.getSubId()).findFirst().orElse(null); SubQuestionVO subQuestionVO = q.getChildren().stream().filter(subQuestionVO1 -> subQuestionVO1.getId().intValue() == submitQuestionVO.getSubId()).findFirst().orElse(null);
@ -182,7 +192,7 @@ public class CompetitionExamBiz {
} }
private boolean checkCorrect(List<Integer> answerId,List<Integer> checkList){ private boolean checkCorrect(List<Integer> answerId,List<Integer> checkList){
if(checkList ==null&&checkList.size() == 0) {return false;} if(checkList ==null||checkList.size() == 0) {return false;}
if(answerId.size() == checkList.size()){ if(answerId.size() == checkList.size()){
boolean correct = true; boolean correct = true;
for(int i = 0 ;i <checkList.size();i++){ for(int i = 0 ;i <checkList.size();i++){

@ -1,33 +1,30 @@
package com.tz.platform.competitiion.api.biz; package com.tz.platform.competitiion.api.biz;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.tz.platform.common.core.base.Result; import com.tz.platform.common.core.base.Result;
import com.tz.platform.common.core.tools.BeanUtils; import com.tz.platform.common.core.tools.BeanUtils;
import com.tz.platform.competitiion.api.dto.CompetitionDTO; import com.tz.platform.competitiion.api.dto.*;
import com.tz.platform.competitiion.api.dto.IndexCompetitionDTO; import com.tz.platform.competitiion.job.biz.RankingBiz;
import com.tz.platform.competitiion.api.dto.IndexListCompetitionDTO; import com.tz.platform.entity.*;
import com.tz.platform.entity.Competition;
import com.tz.platform.entity.CompetitionMember;
import com.tz.platform.entity.JueJinToken;
import com.tz.platform.feign.user.IFeignUser; import com.tz.platform.feign.user.IFeignUser;
import com.tz.platform.juejin.JueJinApi; import com.tz.platform.juejin.JueJinApi;
import com.tz.platform.repository.CompetitionDao; import com.tz.platform.repository.*;
import com.tz.platform.repository.CompetitionMemberDao;
import com.tz.platform.repository.CompetitionTaskDao;
import com.tz.platform.repository.JueJinTokenDao;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Component @Component
@Slf4j @Slf4j
@ -44,10 +41,19 @@ public class CompetitionIndexBiz {
@Autowired @Autowired
private CompetitionTaskDao competitionTaskDao; private CompetitionTaskDao competitionTaskDao;
@Autowired @Autowired
private IFeignUser feignUser; private IFeignUser feignUser;
@Autowired
private RankingDao rankingDao;
@Autowired
private CompetitionGroupDao groupDao;
@Autowired
private RedisTemplate<String,Object> template;
public Result<IndexListCompetitionDTO> list(int pageNo,int type){ public Result<IndexListCompetitionDTO> list(int pageNo,int type){
int pageSize = 20; int pageSize = 20;
pageNo = pageNo - 1; pageNo = pageNo - 1;
@ -55,6 +61,9 @@ public class CompetitionIndexBiz {
pageNo = 0; pageNo = 0;
} }
pageNo =pageNo* pageSize; pageNo =pageNo* pageSize;
String compListKey = "competition_list_"+type+"_"+pageNo;
Pageable pageable = PageRequest.of(pageNo,pageSize); Pageable pageable = PageRequest.of(pageNo,pageSize);
Page<Competition> competitionList = competitionDao.findAllByStatus(type,pageable); Page<Competition> competitionList = competitionDao.findAllByStatus(type,pageable);
IndexListCompetitionDTO dto = new IndexListCompetitionDTO(); IndexListCompetitionDTO dto = new IndexListCompetitionDTO();
@ -64,7 +73,15 @@ public class CompetitionIndexBiz {
} }
public Result<CompetitionDTO> get(Long compId){ public Result<CompetitionDTO> get(Long compId){
Competition competition = competitionDao.getById(compId); String compKey = "competition_"+compId;
Object compObj = template.opsForValue().get(compKey);
Competition competition = null;
if(compObj == null){
competition = competitionDao.getById(compId);
template.opsForValue().set(compKey,competition,5, TimeUnit.MINUTES);
}else{
competition = (Competition) compObj;
}
CompetitionDTO dto = BeanUtils.copyProperties(competition,CompetitionDTO.class); CompetitionDTO dto = BeanUtils.copyProperties(competition,CompetitionDTO.class);
return Result.success(dto); return Result.success(dto);
} }
@ -122,4 +139,46 @@ public class CompetitionIndexBiz {
return Result.error("获取数据失败"); return Result.error("获取数据失败");
} }
public Result<ListRankingDTO> listRanKing( Integer pageNo, Integer pageSize,String date,String key, Long compId, Integer stageId){
String redisKey = "system_ranking_"+compId+"_"+stageId+"_"+date;
Object rankListObj = template.opsForValue().get(redisKey);
List<Ranking> rankingList = null;
if(rankListObj == null){
if(StringUtils.isEmpty(date)){
Competition competition = competitionDao.getById(compId);
date = competition.getUpdateRankDate();
}
rankingList = rankingDao.findAllByCompIdAndStageIdAndUpdateTime(compId,stageId,date);
rankingList.sort(Comparator.comparingInt(Ranking::getPersonalRank));
template.opsForValue().set(redisKey,rankingList,1,TimeUnit.HOURS);
}else{
rankingList = ( List<Ranking>)rankListObj;
}
List<Ranking> onPage = filterRank(pageNo,pageSize,key,rankingList);
List<RankingDTO> rankingDTOList = BeanUtils.copyProperties(onPage,RankingDTO.class);
ListRankingDTO dto = new ListRankingDTO();
dto.setTotal(rankingList.size());
dto.setList(rankingDTOList);
return Result.success(dto);
}
private List<Ranking> filterRank(Integer pageNo,Integer pageSize,String key,List<Ranking> rankingList){
List<Ranking> tempList = rankingList.stream().filter(ranking -> ranking.getName().contains(key)||ranking.getSchool().contains(key)||ranking.getTeamName().contains(key)).collect(Collectors.toList());
int fromIndex = pageNo - 1;
if(fromIndex <0){
fromIndex = 0;
}
int toIndex = fromIndex+pageSize;
return tempList.subList(fromIndex,toIndex);
}
public Result<ListGroupDTO> getGroup(Long compId){
List<CompetitionGroup> group = groupDao.findByCompetitionId(compId);
List<GroupDTO> groupDTOList = BeanUtils.copyProperties(group,GroupDTO.class);
ListGroupDTO dto = new ListGroupDTO();
dto.setList(groupDTOList);
return Result.success(dto);
}
} }

@ -0,0 +1,108 @@
package com.tz.platform.competitiion.api.biz;
import com.tz.platform.common.core.base.Result;
import com.tz.platform.common.core.tools.BeanUtils;
import com.tz.platform.competitiion.api.dto.CompetitionMemberDTO;
import com.tz.platform.competitiion.api.dto.ExamPaperDTO;
import com.tz.platform.entity.CompetitionMember;
import com.tz.platform.entity.CompetitionTask;
import com.tz.platform.entity.ExamPaper;
import com.tz.platform.entity.JueJinToken;
import com.tz.platform.juejin.JueJinApi;
import com.tz.platform.juejin.bo.AccountInfo;
import com.tz.platform.repository.CompetitionMemberDao;
import com.tz.platform.repository.CompetitionTaskDao;
import com.tz.platform.repository.ExamPaperDao;
import com.tz.platform.repository.JueJinTokenDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.concurrent.TimeUnit;
@Component
public class CompetitionMemberBiz {
@Autowired
private CompetitionMemberDao memberDao;
@Autowired
private CompetitionTaskDao competitionTaskDao;
@Autowired
private JueJinTokenDao jueJinTokenDao;
@Autowired
private ExamPaperDao examPaperDao;
@Autowired
private RedisTemplate<String,Object> template;
public Result<ExamPaperDTO> getExamPaper(Long compId, Integer stageId,Long userNo){
ExamPaper paper = examPaperDao.getByUserNoAndCompIdAndStageId(userNo,compId,stageId);
if(paper!= null){
return Result.success(BeanUtils.copyProperties(paper,ExamPaperDTO.class));
}
return Result.error("failed");
}
public Result<CompetitionMemberDTO> get(Long compId,Integer stageId,Long userNo){
CompetitionMember member = memberDao.getByCompetitionIdAndStageIdAndUserId(compId,stageId,userNo);
if(member == null){
return Result.error("未参赛");
}
if(StringUtils.isEmpty(member.getAccountId())){
return initSystem(compId,stageId,userNo);
}
CompetitionMemberDTO dto= BeanUtils.copyProperties(member,CompetitionMemberDTO.class);
return Result.success(dto);
}
private Result<CompetitionMemberDTO> initSystem(Long compId,Integer stageId,Long userNo){
CompetitionMember member = memberDao.getByCompetitionIdAndStageIdAndUserId(compId,stageId,userNo);
if(member == null){
return Result.error("未报名参赛");
}
if(StringUtils.hasText(member.getAccountId())){
return Result.success(BeanUtils.copyProperties(member,CompetitionMemberDTO.class));
}
String competitionTaskKey = "competition_task_"+compId+"_"+stageId;
Object taskObj = template.opsForValue().get(competitionTaskKey);
CompetitionTask competitionTask = null;
if(taskObj == null){
competitionTask = competitionTaskDao.getByCompetitionIdAndStageId(compId,stageId);
template.opsForValue().set(competitionTaskKey,competitionTask,5, TimeUnit.MINUTES);
}else{
competitionTask = (CompetitionTask) taskObj;
}
//未开赛后不生成交易系统权限
if(competitionTask.getOperationStartTime().getTime()> System.currentTimeMillis()){
return Result.success(BeanUtils.copyProperties(member,CompetitionMemberDTO.class));
}
String juejinTokenKey = "juejin_token";
JueJinToken jueJinToken = null;
Object jtObj = template.opsForValue().get(juejinTokenKey);
if(jtObj == null){
jueJinToken =jueJinTokenDao.getById(1);
template.opsForValue().set(juejinTokenKey,jueJinToken,1, TimeUnit.DAYS);
}else{
jueJinToken = (JueJinToken) jtObj;
}
JueJinApi jueJinApi = new JueJinApi(jueJinToken.getToken());
Integer tradeType = 1;
if(competitionTask.getTradeType() != 1){
tradeType =4;
}
AccountInfo accountInfo = jueJinApi.createAccount(member.getName(),competitionTask.getInitCapital(),tradeType);
member.setAccountId(accountInfo.getAccount_id());
member.setAccountPwd(jueJinToken.getToken());
memberDao.save(member);
return Result.success( BeanUtils.copyProperties(member,CompetitionMemberDTO.class));
}
}

@ -0,0 +1,37 @@
package com.tz.platform.competitiion.api.biz;
import com.tz.platform.common.core.base.Result;
import com.tz.platform.common.core.tools.BeanUtils;
import com.tz.platform.competitiion.api.dto.CompetitionTaskDTO;
import com.tz.platform.competitiion.api.dto.ListCompetitionTaskDTO;
import com.tz.platform.entity.CompetitionTask;
import com.tz.platform.repository.CompetitionTaskDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class CompetitionTaskBiz {
@Autowired
private CompetitionTaskDao taskDao;
public Result<ListCompetitionTaskDTO> list(Long compId){
List<CompetitionTask> taskList = taskDao.findAllByCompetitionId(compId);
if(taskList == null || taskList.size() == 0){
return Result.error("无赛段数据");
}
List<CompetitionTaskDTO> rs =BeanUtils.copyProperties(taskList, CompetitionTaskDTO.class);
ListCompetitionTaskDTO dto = new ListCompetitionTaskDTO();
dto.setList(rs);
return Result.success(dto);
}
public Result<CompetitionTaskDTO> get(Long compId,Integer stageId){
CompetitionTask tak = taskDao.getByCompetitionIdAndStageId(compId,stageId);
if(tak==null){
return Result.error("赛段数据获取失败");
}
return Result.success(BeanUtils.copyProperties(tak,CompetitionTaskDTO.class));
}
}

@ -1,8 +1,9 @@
package com.tz.platform.competitiion.api.dto; package com.tz.platform.competitiion.api.dto;
import com.tz.platform.common.core.bo.CompetitionNews;
import com.tz.platform.common.core.bo.Rotation;
import com.tz.platform.common.core.bo.Stage; import com.tz.platform.common.core.bo.Stage;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -23,4 +24,11 @@ public class CompetitionDTO implements Serializable {
private Integer peopleCount; private Integer peopleCount;
private Integer teamCount; private Integer teamCount;
private List<Stage> stageList; private List<Stage> stageList;
private List<Rotation> bannerList;
private String summary;
private String rule;
private String prize;
private List<CompetitionNews> news;
private List<CompetitionNews> schoolNews;
} }

@ -0,0 +1,49 @@
package com.tz.platform.competitiion.api.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class CompetitionMemberDTO implements Serializable {
private Integer id;
private Long competitionId;
private Long userId;
private Integer stageId;
private String studentNo;
private String name;
private String school;
private Integer teamId;
private String teamName;
private String accountId;
private String accountPwd;
private String teacher;
private Double examScore;
private Double financeScore;
private Double combineScore;
private Integer personalRank;
private Integer teamRank;
private Date examStartTime;
private Date examEndTime;
private Double examCostTime;
private Integer levelId;
private Double initFounds;
private Double totalFounds;
private Double availableFounds;
private Double marketValue;
private Double currentRatio;
private Double highestRatio;
private Double overRatio;
private Double commission;
private Double totalRatio;
private Double baseRatio;
private Double yearRatio;
private Double maxDrawDown;
private String kammaRatio;
private String sharpRatio;
private Integer openCount;
private Integer closeCount;
private Double winRatio;
private Integer reportId;
}

@ -0,0 +1,21 @@
package com.tz.platform.competitiion.api.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class CompetitionTaskDTO implements Serializable {
private Integer id;
private Long competitionId;
private Integer stageId;
private Date operationStartTime;
private Date operationEndTime;
private Date examStartTime;
private Date examEndTime;
private Integer tradeType;
private Long initCapital;
private String operationLogo;
private String examLogo;
}

@ -0,0 +1,16 @@
package com.tz.platform.competitiion.api.dto;
import com.tz.platform.competitiion.api.vo.SubmitQuestionVO;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class ExamPaperDTO implements Serializable {
private String id;
private Long userNo;
private Long compId;
private Integer stageId;
private List<SubmitQuestionVO> qList;
}

@ -0,0 +1,16 @@
package com.tz.platform.competitiion.api.dto;
import com.tz.platform.common.core.bo.GroupCat;
import lombok.Data;
import java.util.List;
@Data
public class GroupDTO {
private Integer id;
private String name;
/**
* 1 2
*/
private Integer limitType;
private List<GroupCat> catList;
}

@ -0,0 +1,11 @@
package com.tz.platform.competitiion.api.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class ListCompetitionTaskDTO implements Serializable {
private List<CompetitionTaskDTO> list;
}

@ -0,0 +1,11 @@
package com.tz.platform.competitiion.api.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class ListGroupDTO implements Serializable {
List<GroupDTO> list;
}

@ -0,0 +1,12 @@
package com.tz.platform.competitiion.api.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class ListRankingDTO implements Serializable {
List<RankingDTO> list;
Integer total;
}

@ -0,0 +1,8 @@
package com.tz.platform.competitiion.api.dto;
import lombok.Data;
@Data
public class RankingDTO {
}

@ -6,5 +6,5 @@ import java.io.Serializable;
@Data @Data
public class SubmitResultDTO implements Serializable { public class SubmitResultDTO implements Serializable {
private Long score; private Double score;
} }

@ -54,7 +54,11 @@ public class CompetitionJob {
} }
} }
// @Scheduled(cron = "*/5 * * * * ?") /**
* 2
*/
@Scheduled(cron = "0 0 2 1 * ?")
// @Scheduled(cron = "10 * * * * ?")
public void fetchRanking(){ public void fetchRanking(){
String jobName = "rankingJob"; String jobName = "rankingJob";
boolean lock = lock(jobName,ms); boolean lock = lock(jobName,ms);
@ -74,7 +78,13 @@ public class CompetitionJob {
String jobName = "picJob"; String jobName = "picJob";
boolean lock = lock(jobName,ms); boolean lock = lock(jobName,ms);
if(lock){ if(lock){
try{
}catch (Exception ex){
}finally {
unLock(jobName);
}
} }
} }

@ -1,6 +1,5 @@
package com.tz.platform.competitiion.job.biz; package com.tz.platform.competitiion.job.biz;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.tz.platform.common.core.tools.DateUtil; import com.tz.platform.common.core.tools.DateUtil;
@ -12,8 +11,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.Date; import java.util.*;
import java.util.List; import java.util.stream.Collectors;
@Component @Component
@Slf4j @Slf4j
@ -35,18 +34,21 @@ public class RankingBiz {
@Autowired @Autowired
private RankingDao rankingDao; private RankingDao rankingDao;
public void fetchRanking(){ public void fetchRanking(){
JueJinToken jueJinToken = jueJinTokenDao.getById(1); JueJinToken jueJinToken = jueJinTokenDao.getById(1);
if(jueJinToken == null) {return;} if(jueJinToken == null) {return;}
JueJinApi jueJinApi = new JueJinApi(jueJinToken.getToken()); JueJinApi jueJinApi = new JueJinApi(jueJinToken.getToken());
List<Competition> competitionList = competitionDao.findAllByStatus(1); List<Competition> competitionList = competitionDao.findAllByStatus(1);
String endTime = DateUtil.format(new Date()); String endTime = DateUtil.format(new Date());
String now = DateUtil.format(new Date());
competitionList.forEach(competition -> { competitionList.forEach(competition -> {
try { try {
CompetitionTask currentTask = taskDao.getByCompetitionIdAndStageId(competition.getId(), competition.getCurrentStage()); CompetitionTask currentTask = taskDao.getByCompetitionIdAndStageId(competition.getId(), competition.getCurrentStage());
String startTime = DateUtil.format(currentTask.getOperationStartTime()); String startTime = DateUtil.format(currentTask.getOperationStartTime());
String baseRatio = jueJinApi.getBaseRatio(startTime, endTime); Double baseRatio = jueJinApi.getBaseRatio(startTime, endTime);
List<CompetitionMember> memberList = memberDao.findAllByCompetitionIdAndStageId(competition.getId(), competition.getCurrentStage()); List<CompetitionMember> memberList = memberDao.findAllByCompetitionIdAndStageId(competition.getId(), competition.getCurrentStage());
List<Ranking> rankingList = new ArrayList<>();
memberList.forEach(member -> { memberList.forEach(member -> {
if (StringUtils.hasText(member.getAccountId())) { if (StringUtils.hasText(member.getAccountId())) {
String jsonStr = jueJinApi.createReport(member.getAccountId(), endTime); String jsonStr = jueJinApi.createReport(member.getAccountId(), endTime);
@ -56,24 +58,180 @@ public class RankingBiz {
JSONObject jsonObject = JSONUtil.parseObj(jsonStr); JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
if(jsonObject.containsKey("report_id")){ if(jsonObject.containsKey("report_id")){
Integer reportId =jsonObject.getInt("report_id"); Integer reportId =jsonObject.getInt("report_id");
// JSONArray jsonArray = jsonObject.getJSONArray("indicator_durations"); // memberDao.updateReportId(member.getUserId(),currentTask.getStageId(),currentTask.getCompetitionId(),reportId);
member.setReportId(reportId);
String contentStr = jueJinApi.getReport(reportId.toString()); String contentStr = jueJinApi.getReport(reportId.toString());
Ranking ranking = new Ranking(); JSONObject rankingObj = JSONUtil.parseObj(contentStr);
ranking.setAccountId(member.getAccountId()); if(rankingObj.containsKey("data")){
// ranking.setTotalRatio(baseRatio); JSONObject dataObj = (JSONObject)rankingObj.getJSONArray("data").get(0);
rankingDao.save(ranking); JSONObject cashObj =dataObj.getJSONObject("cash");
//可用资金
Double available = cashObj.getDouble("available");
//累计手续费
Double cumCommission = cashObj.getDouble("cum_commission");
//浮动盈亏
Double fpnl = cashObj.getDouble("fpnl");
//收益
Double pnl = cashObj.getDouble("pnl");
//总资产
Double nav = cashObj.getDouble("nav");
JSONObject indicatorObj = dataObj.getJSONObject("indicator");
//累计收益率
Double pnlRatio = indicatorObj.getDouble("pnl_ratio");
//年化收益率
Double pnlRatioAnnual = indicatorObj.getDouble("pnl_ratio_annual");
//夏普比例
Double sharpRatio = indicatorObj.getDouble("sharp_ratio");
//卡玛比例
Double calmarRatio = indicatorObj.getDouble("calmar_ratio");
//最大回测
Double maxDrawdown = indicatorObj.getDouble("max_drawdown");
//开仓次数
Integer openCount = indicatorObj.getInt("open_count");
//平仓次数
Integer closeCount = indicatorObj.getInt("close_count");
//胜率
Double winRatio = indicatorObj.getDouble("win_ratio");
if(member.getHighestRatio() == null){
member.setHighestRatio(pnlRatio);
}
Double maxRatio = member.getHighestRatio();
if(pnlRatio>member.getHighestRatio()){
maxRatio = pnlRatio;
member.setHighestRatio(maxRatio);
}
Ranking ranking = new Ranking();
ranking.setUserNo(member.getId().longValue());
ranking.setCompId(competition.getId());
ranking.setName(member.getName());
ranking.setSchool(member.getSchool());
ranking.setTeamName(member.getTeamName());
ranking.setStageId(currentTask.getStageId());
ranking.setTeamId(member.getTeamId());
ranking.setId(now+"_"+member.getAccountId());
ranking.setAccountId(member.getAccountId());
ranking.setBaseRatio(baseRatio);
ranking.setPnlRatio(pnlRatio);
ranking.setProfitLoss(pnl - cumCommission);
ranking.setAvailable(available);
ranking.setCalmarRatio(calmarRatio);
ranking.setNav(nav);
ranking.setSharpRatio(sharpRatio);
ranking.setCloseCount(closeCount);
ranking.setOpenCount(openCount);
ranking.setCumCommission(cumCommission);
ranking.setFpnl(fpnl);
ranking.setMarketValue(nav-available);
ranking.setWinRatio(winRatio);
ranking.setUpdateTime(now);
ranking.setPnlRatioAnnual(pnlRatioAnnual);
ranking.setMaxDrawdown(maxDrawdown);
ranking.setLevelId(member.getLevelId());
ranking.setRegionId(member.getReportId());
double finaceScore = computeFinaceScore(currentTask,pnlRatio,baseRatio,maxRatio);
double combineScore = computeCombineScore(currentTask,member.getExamScore(),finaceScore);
member.setReportId(reportId);
member.setFinanceScore(finaceScore);
member.setCombineScore(combineScore);
member.setBaseRatio(baseRatio);
member.setAvailableFounds(available);
member.setTotalFounds(nav);
member.setCloseCount(closeCount);
member.setOpenCount(openCount);
member.setCommission(cumCommission);
member.setCurrentRatio(pnlRatio);
member.setKammaRatio(calmarRatio.toString());
member.setSharpRatio(sharpRatio.toString());
member.setYearRatio(pnlRatioAnnual);
member.setOverRatio(fpnl);
member.setMaxDrawDown(maxDrawdown);
member.setMarketValue(ranking.getMarketValue());
memberDao.save(member);
ranking.setFinanceScore(finaceScore);
ranking.setCombineScore(combineScore);
// rankingDao.save(ranking);
rankingList.add(ranking);
}
} }
} }
}); });
computeRanking(rankingList,currentTask);
competition.setUpdateRankDate(now);
competitionDao.save(competition);
}catch (Exception ex){ }catch (Exception ex){
log.error("排行榜数据获取失败:{}",competition.getId(),ex); log.error("排行榜数据获取失败:{}",competition.getId(),ex);
} }
}); });
} }
private Long computeCombineScore(CompetitionTask task){ /**
*
* @param rankingList
* @param task
*/
private void computeRanking(List<Ranking> rankingList ,CompetitionTask task){
Map<Integer,List<Ranking>> map = rankingList.stream().collect(Collectors.groupingBy(Ranking::getTeamId));
map.forEach((k,v)->{
Double teamRatio = v.stream().mapToDouble((r)-> {
Double t = r.getProfitLoss();
if(t == null){
return 0D;
}
return t;
}).sum();
Double teamCombineScore = v.stream().mapToDouble((r)-> {
Double t = r.getCombineScore();
if(t == null){
return 0D;
}
return t;
}).sum();
v.forEach(ranking -> {
ranking.setTeamRatio(teamRatio);
ranking.setTeamCombineScore(teamCombineScore);
});
});
rankingList.sort(Comparator.comparing(Ranking::getFinanceScore));
for(int i = 0;i<rankingList.size();i++){
rankingList.get(i).setPersonalRank(i+1);
}
rankingList.sort(Comparator.comparing(Ranking::getTeamCombineScore));
for(int i =0;i<rankingList.size();i++){
rankingList.get(i).setTeamRank(i+1);
}
rankingDao.saveAll(rankingList);
}
/**
*
* @param task
* @param examScore
* @param financeScore
* @return
*/
private double computeCombineScore(CompetitionTask task,double examScore,double financeScore){
double score = (examScore*task.getExamPower()+financeScore*task.getFinancePower())/100;
return score;
}
return 0L; /**
*
* @param task
* @param userRatio
* @param baseRatio
* @param maxUserRatio
* @return
*/
private double computeFinaceScore(CompetitionTask task,double userRatio,double baseRatio,double maxUserRatio){
double score = task.getFinanceBasePower() +(userRatio - baseRatio) /(maxUserRatio -baseRatio)* task.getFinanceProfitPower();
return score;
} }
} }

@ -54,9 +54,10 @@ public class PCGroupBiz {
} }
public Result<GroupDTO> get(Long cpId){ public Result<GroupDTO> get(Long cpId){
CompetitionGroup group = groupDao.getByCompetitionId(cpId); // CompetitionGroup group = groupDao.getByCompetitionId(cpId);
GroupDTO dto = new GroupDTO(); // GroupDTO dto = new GroupDTO();
BeanUtils.copyProperties(group,dto); // BeanUtils.copyProperties(group,dto);
return Result.success(dto); // return Result.success(dto);
return Result.error("接口未实现");
} }
} }

@ -19,6 +19,7 @@ public class TaskDTO implements Serializable {
private Integer tradeType; private Integer tradeType;
private Long initCapital; private Long initCapital;
private String operationLogo; private String operationLogo;
private String examLogo;
private Long financeBasePower; private Long financeBasePower;
private Long financeProfitPower; private Long financeProfitPower;
} }

@ -18,9 +18,11 @@ public class TaskVO implements Serializable {
private Date operationEndTime; private Date operationEndTime;
private Date examStartTime; private Date examStartTime;
private Date examEndTime; private Date examEndTime;
private Integer examDuration;
private Integer tradeType; private Integer tradeType;
private Long initCapital; private Long initCapital;
private String operationLogo; private String operationLogo;
private String examLogo;
private Long financeBasePower; private Long financeBasePower;
private Long financeProfitPower; private Long financeProfitPower;
private List<TaskQuestion> questionList; private List<TaskQuestion> questionList;

@ -0,0 +1,41 @@
package com.tz.platform.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class MyRedisConfig {
@Bean(name = "template")
public RedisTemplate<String, Object> template(RedisConnectionFactory factory) {
// 创建RedisTemplate<String, Object>对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
// 定义Jackson2JsonRedisSerializer序列化对象
Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域field,get和set,以及修饰符范围ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型类必须是非final修饰的final修饰的类比如String,Integer等会报异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
StringRedisSerializer stringSerial = new StringRedisSerializer();
// redis key 序列化方式使用stringSerial
template.setKeySerializer(stringSerial);
// redis value 序列化方式使用jackson
template.setValueSerializer(jacksonSeial);
// redis hash key 序列化方式使用stringSerial
template.setHashKeySerializer(stringSerial);
// redis hash value 序列化方式使用jackson
template.setHashValueSerializer(jacksonSeial);
template.afterPropertiesSet();
return template;
}
}

@ -29,6 +29,7 @@ public class Competition {
private Integer status; private Integer status;
private Integer peopleCount; private Integer peopleCount;
private Integer teamCount; private Integer teamCount;
private String updateRankDate;
private boolean enableSignup; private boolean enableSignup;
@Column(columnDefinition = "TIMESTAMP") @Column(columnDefinition = "TIMESTAMP")
private Date startTime; private Date startTime;

@ -24,31 +24,49 @@ public class CompetitionMember {
private String accountId; private String accountId;
private String accountPwd; private String accountPwd;
private String teacher; private String teacher;
private Long examScore; @Column(columnDefinition = "double(10,3) default '0.00'")
private Long financeScore; private Double examScore;
private Long combineScore; @Column(columnDefinition = "double(10,3) default '0.00'")
private Double financeScore;
@Column(columnDefinition = "double(10,3) default '0.00'")
private Double combineScore;
private Integer personalRank; private Integer personalRank;
private Integer teamRank; private Integer teamRank;
private Date examStartTime; private Date examStartTime;
private Date examEndTime; private Date examEndTime;
private Long examCostTime; private Double examCostTime;
private Integer levelId; private Integer levelId;
private Long initFounds; @Column(columnDefinition = "double(11,3) default '0.00'")
private Long totalFounds; private Double initFounds;
private Long availableFounds; @Column(columnDefinition = "double(11,3) default '0.00'")
private Long marketValue; private Double totalFounds;
private Long currentRatio; @Column(columnDefinition = "double(11,3) default '0.00'")
private Long highestRatio; private Double availableFounds;
private Long overRatio; @Column(columnDefinition = "double(11,3) default '0.00'")
private Long commission; private Double marketValue;
private Long totalRatio; @Column(columnDefinition = "double(11,3) default '0.00'")
private Long baseRatio; private Double currentRatio;
private Long yearRatio; @Column(columnDefinition = "double(11,3) default '0.00'")
private Long maxDrawDown; private Double highestRatio;
@Column(columnDefinition = "double(11,3) default '0.00'")
private Double overRatio;
@Column(columnDefinition = "double(11,3) default '0.00'")
private Double commission;
@Column(columnDefinition = "double(11,3) default '0.00'")
private Double totalRatio;
@Column(columnDefinition = "double(11,3) default '0.00'")
private Double baseRatio;
@Column(columnDefinition = "double(11,3) default '0.00'")
private Double yearRatio;
@Column(columnDefinition = "double(11,3) default '0.00'")
private Double maxDrawDown;
private String kammaRatio; private String kammaRatio;
private String sharpRatio; private String sharpRatio;
private Integer openCount; private Integer openCount;
private Integer closeCount; private Integer closeCount;
private Long winRatio; @Column(columnDefinition = "double(11,3) default '0.00'")
private Double winRatio;
private Integer reportId; private Integer reportId;
} }

@ -26,9 +26,11 @@ public class CompetitionTask {
private Date operationEndTime; private Date operationEndTime;
private Date examStartTime; private Date examStartTime;
private Date examEndTime; private Date examEndTime;
private Integer examDuration;
private Integer tradeType; private Integer tradeType;
private Long initCapital; private Long initCapital;
private String operationLogo; private String operationLogo;
private String examLogo;
private Long financeBasePower; private Long financeBasePower;
private Long financeProfitPower; private Long financeProfitPower;
@Type(type = "json") @Type(type = "json")

@ -6,13 +6,12 @@ import lombok.Data;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDef;
import javax.persistence.Column; import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.List; import java.util.List;
@Data @Data
@Entity @Entity
@Table(indexes={ @Index(columnList = "userNo,compId,stageId")})
@TypeDef(name = "json", typeClass = JsonStringType.class) @TypeDef(name = "json", typeClass = JsonStringType.class)
public class ExamPaper { public class ExamPaper {
@Id @Id
@ -20,7 +19,6 @@ public class ExamPaper {
private Long userNo; private Long userNo;
private Long compId; private Long compId;
private Integer stageId; private Integer stageId;
@Type(type = "json") @Type(type = "json")
@Column(columnDefinition = "json") @Column(columnDefinition = "json")
private List<SubmitQuestionVO> qList; private List<SubmitQuestionVO> qList;

@ -1,15 +1,14 @@
package com.tz.platform.entity; package com.tz.platform.entity;
import lombok.Data; import lombok.Data;
import org.springframework.stereotype.Indexed;
import javax.persistence.Entity; import javax.persistence.*;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date; import java.util.Date;
@Data @Data
@Entity @Entity
@Table(indexes = {@Index(columnList = "compId,stageId,updateTime")})
public class Ranking { public class Ranking {
@Id @Id
private String id; private String id;
@ -19,47 +18,47 @@ public class Ranking {
/** /**
* *
*/ */
private Long nav; private Double nav;
/** /**
* *
*/ */
private Long available; private Double available;
/** /**
* *
*/ */
private Long marketValue; private Double marketValue;
/** /**
* *
*/ */
private Long totalRatio; private Double profitLoss;
/** /**
* *
*/ */
private Long cumCommission; private Double cumCommission;
/** /**
* *
*/ */
private Long fpnl; private Double fpnl;
/** /**
* *
*/ */
private Long pnlRation; private Double pnlRatio;
/** /**
* *
*/ */
private Long baseRatio; private Double baseRatio;
/** /**
* *
*/ */
private Long teamRatio; private Double teamRatio;
/** /**
* *
@ -75,17 +74,17 @@ public class Ranking {
/** /**
* *
*/ */
private Long maxDrawdown; private Double maxDrawdown;
/** /**
* *
*/ */
private Long calmarRatio; private Double calmarRatio;
/** /**
* *
*/ */
private Long sharpRatio; private Double sharpRatio;
/** /**
* *
@ -100,12 +99,38 @@ public class Ranking {
/** /**
* *
*/ */
private Long pnlRatioAnnual; private Double pnlRatioAnnual;
/** /**
* *
*/ */
private Long winRatio; private Double winRatio;
private Long userNo;
private Long compId;
private Integer stageId;
private Integer teamId;
private String name;
private String teamName;
private String school;
private Integer levelId;
private Integer regionId;
/**
*
*/
private Double combineScore;
/**
*
*/
private Double teamCombineScore;
/**
*
*/
private Double financeScore;
/** /**
* *

@ -11,6 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -101,7 +102,7 @@ public class JueJinApi {
* *
* @return * @return
*/ */
public String getBaseRatio(String start,String end){ public Double getBaseRatio(String start,String end){
String url = baseUrl +"/ds-history-rpcgw/v3/data-history/benchmark-return?symbol=SHSE.000300&frequency=1d&start_time="+start+"&end_time="+end+"&adjust=0"; String url = baseUrl +"/ds-history-rpcgw/v3/data-history/benchmark-return?symbol=SHSE.000300&frequency=1d&start_time="+start+"&end_time="+end+"&adjust=0";
String content = HttpUtil.get(url,headers); String content = HttpUtil.get(url,headers);
@ -110,10 +111,12 @@ public class JueJinApi {
JSONArray jsonArray = jsonObject.getJSONArray("data"); JSONArray jsonArray = jsonObject.getJSONArray("data");
JSONObject ratioObj = (JSONObject) jsonArray.get(jsonArray.size()-1); JSONObject ratioObj = (JSONObject) jsonArray.get(jsonArray.size()-1);
logger.info("基准收益率:{}",ratioObj.get("ratio").toString()); logger.info("基准收益率:{}",ratioObj.get("ratio").toString());
return ratioObj.get("ratio").toString(); BigDecimal ratioDec = new BigDecimal(ratioObj.get("ratio").toString());
return ratioDec.doubleValue();
} }
return ""; return 0D;
} }
/** /**
@ -164,6 +167,16 @@ public class JueJinApi {
return content; return content;
} }
/**
*
* @return
*/
public String listReport(int pageNo,int pageSize){
String url =baseUrl+ "/api/v1/reports?page="+pageNo+"&size="+pageSize;
String content = HttpUtil.get(url,headers);
return content;
}
public String test(){ public String test(){
String url = "https://sim.sztzjy.com/sim?acc=2e41a913-9dc1-11ec-89b3-00163e0e6ad0"; String url = "https://sim.sztzjy.com/sim?acc=2e41a913-9dc1-11ec-89b3-00163e0e6ad0";
@ -190,7 +203,7 @@ public class JueJinApi {
// api.test(); // api.test();
// api.createReport(accountId,"report"+ System.currentTimeMillis()); // api.createReport(accountId,"report"+ System.currentTimeMillis());
// api.getCashInfo(accountId); // api.getCashInfo(accountId);
api.getReport("489327"); api.getReport("2794345");
// api.getStockInfo("SHSE.600547,SHSE.603160"); // api.getStockInfo("SHSE.600547,SHSE.603160");
// api.getProfit("2022-03-11","2022-03-15"); // api.getProfit("2022-03-11","2022-03-15");
// api.getHeavy(accountId,start,end); // api.getHeavy(accountId,start,end);

@ -9,6 +9,5 @@ import java.util.List;
@Repository @Repository
public interface CompetitionGroupDao extends JpaRepository<CompetitionGroup,Integer> { public interface CompetitionGroupDao extends JpaRepository<CompetitionGroup,Integer> {
List<CompetitionGroup> findByCompetitionId(Long competitionId); List<CompetitionGroup> findByCompetitionId(Long competitionId);
CompetitionGroup getByCompetitionId(Long competitionId);
int deleteAllByCompetitionIdAndIdNotIn(Long competition,List<Integer> ids); int deleteAllByCompetitionIdAndIdNotIn(Long competition,List<Integer> ids);
} }

@ -36,7 +36,7 @@ public interface CompetitionMemberDao extends JpaRepository<CompetitionMember,In
@Modifying @Modifying
@Query(value = "update competition_member set exam_score=:score where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true) @Query(value = "update competition_member set exam_score=:score where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true)
int updateScore(@Param("userNo") Long userNo,@Param("stageId") Integer stageId,@Param("compId") Long comId, @Param("score") Long score); int updateScore(@Param("userNo") Long userNo,@Param("stageId") Integer stageId,@Param("compId") Long comId, @Param("score") Double score);
@Modifying @Modifying
@Query(value = "update competition_member set exam_start_time=:startTime where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true) @Query(value = "update competition_member set exam_start_time=:startTime where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true)
@ -46,4 +46,11 @@ public interface CompetitionMemberDao extends JpaRepository<CompetitionMember,In
@Query(value = "update competition_member set exam_end_time=:endTime,exam_cost_time=:costTime where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true) @Query(value = "update competition_member set exam_end_time=:endTime,exam_cost_time=:costTime where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true)
int updateExamEndTimeAndCostTime(@Param("userNo") Long userNo,@Param("stageId") Integer stageId,@Param("compId") Long comId, @Param("endTime") Date endTime, @Param("costTime") Long costTime); int updateExamEndTimeAndCostTime(@Param("userNo") Long userNo,@Param("stageId") Integer stageId,@Param("compId") Long comId, @Param("endTime") Date endTime, @Param("costTime") Long costTime);
@Query(value = "update competition_member set report_id=:reportId where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true)
int updateReportId(@Param("userNo") Long userNo,@Param("stageId") Integer stageId,@Param("compId") Long comId, @Param("reportId") Integer reportId);
@Modifying
@Query(value = "update competition_member set highest_ratio=:ratio where user_id=:userNo and stage_id=:stageId and competition_id=:compId",nativeQuery = true)
int updateHighestRatio(@Param("userNo") Long userNo,@Param("stageId") Integer stageId,@Param("compId") Long comId, @Param("ratio") Double ratio);
} }

@ -3,6 +3,7 @@ package com.tz.platform.repository;
import com.tz.platform.entity.CompetitionTask; import com.tz.platform.entity.CompetitionTask;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import springfox.documentation.annotations.Cacheable;
import java.util.List; import java.util.List;
@ -10,5 +11,8 @@ import java.util.List;
public interface CompetitionTaskDao extends JpaRepository<CompetitionTask,Integer> { public interface CompetitionTaskDao extends JpaRepository<CompetitionTask,Integer> {
CompetitionTask getById(Integer id); CompetitionTask getById(Integer id);
List<CompetitionTask> findAllByCompetitionId(Long competitionId); List<CompetitionTask> findAllByCompetitionId(Long competitionId);
CompetitionTask getByCompetitionIdAndStageId(Long cmpId,Integer stageId); CompetitionTask getByCompetitionIdAndStageId(Long cmpId,Integer stageId);
} }

@ -6,4 +6,5 @@ import org.springframework.stereotype.Repository;
@Repository @Repository
public interface ExamPaperDao extends JpaRepository<ExamPaper,String> { public interface ExamPaperDao extends JpaRepository<ExamPaper,String> {
ExamPaper getByUserNoAndCompIdAndStageId(Long userNo,Long compId,Integer stageId);
} }

@ -4,6 +4,9 @@ import com.tz.platform.entity.Ranking;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
@Repository @Repository
public interface RankingDao extends JpaRepository<Ranking,String> { public interface RankingDao extends JpaRepository<Ranking,String> {
List<Ranking> findAllByCompIdAndStageIdAndUpdateTime(Long compId,Integer stageId,String updateTime);
} }

@ -12,7 +12,6 @@ import java.util.Date;
@Entity @Entity
public class LoginLog { public class LoginLog {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
private String username; private String username;
private Date loginDate; private Date loginDate;
@ -20,4 +19,5 @@ public class LoginLog {
private String clientType; private String clientType;
private String location; private String location;
private Integer loginStatus; private Integer loginStatus;
private String lastTime;
} }

@ -39,6 +39,10 @@ public class User implements Serializable {
private Integer regionId; private Integer regionId;
private Integer levelId; private Integer levelId;
private String email;
private Boolean complete;
@JsonIgnore @JsonIgnore
private String mobileSalt; private String mobileSalt;

@ -2,8 +2,19 @@ package com.tz.platform.repository;
import com.tz.platform.entity.LoginLog; import com.tz.platform.entity.LoginLog;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository @Repository
public interface LoginLogDao extends JpaRepository<LoginLog,Long> { public interface LoginLogDao extends JpaRepository<LoginLog,Long> {
@Transactional
@Modifying
@Query(value = "update login_log set login_status = 2 where id=:userNo ",nativeQuery = true)
int updateLoginOut(@Param("userNo") Long userNo);
LoginLog getById(Long id);
} }

@ -6,10 +6,7 @@ import com.tz.platform.user.api.biz.ApiUserLoginBiz;
import com.tz.platform.user.api.bo.UserLoginPasswordBO; import com.tz.platform.user.api.bo.UserLoginPasswordBO;
import com.tz.platform.user.api.dto.UserLoginDTO; import com.tz.platform.user.api.dto.UserLoginDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/user/login") @RequestMapping("/api/user/login")
@ -22,4 +19,9 @@ public class UserLoginController extends BaseController {
public Result<UserLoginDTO> loginPassword(@RequestBody UserLoginPasswordBO userLoginPasswordBO){ public Result<UserLoginDTO> loginPassword(@RequestBody UserLoginPasswordBO userLoginPasswordBO){
return apiUserLoginBiz.loginPassword(userLoginPasswordBO); return apiUserLoginBiz.loginPassword(userLoginPasswordBO);
} }
@GetMapping(path = "out")
public Result<String> loginOut(){
return apiUserLoginBiz.loginOut(getUserNo());
}
} }

@ -3,6 +3,7 @@ package com.tz.platform.user.api.biz;
import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.crypto.digest.DigestUtil;
import com.tz.platform.common.core.base.Result; import com.tz.platform.common.core.base.Result;
import com.tz.platform.common.core.enmus.LoginStatusEnum; import com.tz.platform.common.core.enmus.LoginStatusEnum;
import com.tz.platform.common.core.tools.DateUtil;
import com.tz.platform.common.core.tools.JWTUtil; import com.tz.platform.common.core.tools.JWTUtil;
import com.tz.platform.entity.LoginLog; import com.tz.platform.entity.LoginLog;
import com.tz.platform.entity.User; import com.tz.platform.entity.User;
@ -15,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestParam;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Date; import java.util.Date;
@ -64,7 +66,7 @@ public class ApiUserLoginBiz {
return Result.error("账号或者密码不正确"); return Result.error("账号或者密码不正确");
} }
// 登录日志 // 登录日志
loginLog(LoginStatusEnum.SUCCESS, userLoginPasswordBO.getIp(),user.getUsername(), userLoginPasswordBO.getClient()); LoginLog loginLog = loginLog(LoginStatusEnum.SUCCESS, userLoginPasswordBO.getIp(),user.getUsername(), userLoginPasswordBO.getClient(),user.getId());
UserLoginDTO dto = new UserLoginDTO(); UserLoginDTO dto = new UserLoginDTO();
dto.setUserNo(user.getId()); dto.setUserNo(user.getId());
@ -72,22 +74,42 @@ public class ApiUserLoginBiz {
dto.setName(user.getName()); dto.setName(user.getName());
dto.setSchool(user.getSchool()); dto.setSchool(user.getSchool());
dto.setLevelId(user.getLevelId()); dto.setLevelId(user.getLevelId());
dto.setEmail(user.getEmail());
dto.setMobile(user.getMobile());
dto.setIp(loginLog.getIp());
dto.setComplete(user.getComplete());
dto.setLocation(loginLog.getLocation());
dto.setLastLoginTime(loginLog.getLastTime());
dto.setToken(JWTUtil.create(user.getId(),user.getUserType(), JWTUtil.DATE)); dto.setToken(JWTUtil.create(user.getId(),user.getUserType(), JWTUtil.DATE));
// 登录成功,存入缓存,单点登录使用 // 登录成功,存入缓存,单点登录使用
// redisTemplate.opsForValue().set(dto.getUserNo().toString(), dto.getToken(), 1, TimeUnit.DAYS); // template.opsForValue().set(dto.getUserNo().toString(),dto,1,TimeUnit.DAYS);
template.opsForValue().set(dto.getUserNo().toString(),dto,1,TimeUnit.DAYS);
return Result.success(dto); return Result.success(dto);
} }
private void loginLog(LoginStatusEnum loginStatusEnum, String ip,String username,String clientType){ private LoginLog loginLog(LoginStatusEnum loginStatusEnum, String ip,String username,String clientType,Long userNo){
LoginLog loginLog = new LoginLog(); LoginLog loginLog = loginLogDao.getById(userNo);
String lastTime = "";
if(loginLog == null){
loginLog = new LoginLog();
}else{
lastTime = loginLog.getLastTime();
}
loginLog.setId(userNo);
loginLog.setIp(ip); loginLog.setIp(ip);
loginLog.setUsername(username); loginLog.setUsername(username);
loginLog.setLoginDate(new Date()); loginLog.setLoginDate(new Date());
loginLog.setClientType(clientType); loginLog.setClientType(clientType);
loginLog.setLoginStatus(loginStatusEnum.getCode()); loginLog.setLoginStatus(loginStatusEnum.getCode());
loginLog.setLastTime(DateUtil.getDateTime(new Date()));
loginLog.setLocation( IPSeeker.getInstance().getAddress(ip)); loginLog.setLocation( IPSeeker.getInstance().getAddress(ip));
loginLogDao.save(loginLog); loginLogDao.save(loginLog);
loginLog.setLastTime(lastTime);
return loginLog;
}
public Result<String> loginOut(Long userNo){
loginLogDao.updateLoginOut(userNo);
return Result.success("success");
} }
} }

@ -30,6 +30,17 @@ public class UserLoginDTO implements Serializable {
private String name; private String name;
private Integer levelId; private Integer levelId;
private String email;
private String mobile;
private String location;
private String ip;
private String lastLoginTime;
private Boolean complete;
/** /**
* token1 * token1
*/ */

@ -5,6 +5,7 @@ import com.tz.platform.common.core.base.Result;
import com.tz.platform.repository.UserDao; import com.tz.platform.repository.UserDao;
import com.tz.platform.user.auth.biz.AuthUserInfoBiz; import com.tz.platform.user.auth.biz.AuthUserInfoBiz;
import com.tz.platform.user.auth.dto.AuthUserInfoDTO; import com.tz.platform.user.auth.dto.AuthUserInfoDTO;
import com.tz.platform.user.auth.vo.EditUserVO;
import com.tz.platform.user.auth.vo.UserInfoVo; import com.tz.platform.user.auth.vo.UserInfoVo;
import jdk.nashorn.internal.objects.annotations.Getter; import jdk.nashorn.internal.objects.annotations.Getter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -25,4 +26,9 @@ public class UserInfoController extends BaseController {
public Result<AuthUserInfoDTO> info(@RequestBody UserInfoVo userInfoVo){ public Result<AuthUserInfoDTO> info(@RequestBody UserInfoVo userInfoVo){
return authUserInfoBiz.info(userInfoVo.getUserNo()); return authUserInfoBiz.info(userInfoVo.getUserNo());
} }
@PostMapping(path = "complete")
public Result<Boolean> complete(@RequestBody EditUserVO vo){
return authUserInfoBiz.complete(vo);
}
} }

@ -1,13 +1,18 @@
package com.tz.platform.user.auth.biz; package com.tz.platform.user.auth.biz;
import cn.hutool.crypto.digest.DigestUtil;
import com.tz.platform.common.core.base.Result; import com.tz.platform.common.core.base.Result;
import com.tz.platform.common.core.config.SystemUtil;
import com.tz.platform.common.core.tools.StrUtil;
import com.tz.platform.entity.User; import com.tz.platform.entity.User;
import com.tz.platform.repository.UserDao; import com.tz.platform.repository.UserDao;
import com.tz.platform.user.auth.dto.AuthUserInfoDTO; import com.tz.platform.user.auth.dto.AuthUserInfoDTO;
import com.tz.platform.user.auth.vo.EditUserVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component @Component
@Slf4j @Slf4j
@ -23,4 +28,31 @@ public class AuthUserInfoBiz {
BeanUtils.copyProperties(user,authUserInfoDTO); BeanUtils.copyProperties(user,authUserInfoDTO);
return Result.success(authUserInfoDTO); return Result.success(authUserInfoDTO);
} }
public Result<Boolean> complete(EditUserVO vo){
if(StringUtils.isEmpty(vo.getEmail())){
return Result.error("邮箱不能为空");
}
if(StringUtils.isEmpty(vo.getMobile())){
return Result.error("手机不能为空");
}
User user = userDao.getById(vo.getUserNo());
if(user ==null){
return Result.error("用户不存在");
}
user.setEmail(vo.getEmail());
user.setMobile(vo.getMobile());
if(StringUtils.hasText(vo.getPassword())){
if(vo.getPassword().length()<6){
return Result.error("密码长度不能小于6位");
}
user.setMobileSalt(StrUtil.get32UUID());
user.setMobilePsw(DigestUtil.sha1Hex(user.getMobileSalt() + vo.getPassword()));
}
user.setComplete(true);
userDao.save(user);
return Result.success(user.getComplete());
}
} }

@ -0,0 +1,11 @@
package com.tz.platform.user.auth.vo;
import lombok.Data;
@Data
public class EditUserVO {
private Long userNo;
private String mobile;
private String email;
private String password;
}
Loading…
Cancel
Save