Merge remote-tracking branch 'origin/master_develop' into master_develop
This commit is contained in:
commit
9b5c24c49c
@ -173,8 +173,37 @@ public class JudgesManagementServiceImpl implements IJudgesManagementService {
|
|||||||
Long currentTenantId = SecurityUtil.getCurrentTenantId();
|
Long currentTenantId = SecurityUtil.getCurrentTenantId();
|
||||||
Long judgeTenantId = getJudgeTenantId();
|
Long judgeTenantId = getJudgeTenantId();
|
||||||
|
|
||||||
|
// 查询当前租户和平台评委租户的 judge 角色 ID
|
||||||
|
Set<Long> judgeRoleIds = new HashSet<>();
|
||||||
|
for (Long tid : List.of(currentTenantId, judgeTenantId)) {
|
||||||
|
if (tid == null) continue;
|
||||||
|
LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
|
||||||
|
roleWrapper.eq(SysRole::getCode, "judge");
|
||||||
|
roleWrapper.eq(SysRole::getTenantId, tid);
|
||||||
|
SysRole role = sysRoleMapper.selectOne(roleWrapper);
|
||||||
|
if (role != null) {
|
||||||
|
judgeRoleIds.add(role.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询拥有 judge 角色的用户 ID
|
||||||
|
Set<Long> judgeUserIds = new HashSet<>();
|
||||||
|
if (!judgeRoleIds.isEmpty()) {
|
||||||
|
LambdaQueryWrapper<SysUserRole> urWrapper = new LambdaQueryWrapper<>();
|
||||||
|
urWrapper.in(SysUserRole::getRoleId, judgeRoleIds);
|
||||||
|
List<SysUserRole> userRoles = sysUserRoleMapper.selectList(urWrapper);
|
||||||
|
for (SysUserRole ur : userRoles) {
|
||||||
|
judgeUserIds.add(ur.getUserId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (judgeUserIds.isEmpty()) {
|
||||||
|
return new PageResult<>(Collections.emptyList(), 0L, page, pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
|
||||||
// 查询当前租户评委 + 平台评委
|
// 只查询拥有 judge 角色且属于当前租户或平台评委租户的用户
|
||||||
|
wrapper.in(SysUser::getId, judgeUserIds);
|
||||||
wrapper.in(SysUser::getTenantId, List.of(currentTenantId, judgeTenantId));
|
wrapper.in(SysUser::getTenantId, List.of(currentTenantId, judgeTenantId));
|
||||||
|
|
||||||
if (keyword != null && !keyword.isBlank()) {
|
if (keyword != null && !keyword.isBlank()) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.competition.modules.biz.review.controller;
|
|||||||
import com.competition.common.result.Result;
|
import com.competition.common.result.Result;
|
||||||
import com.competition.common.util.SecurityUtil;
|
import com.competition.common.util.SecurityUtil;
|
||||||
import com.competition.modules.biz.review.dto.CreatePresetCommentDto;
|
import com.competition.modules.biz.review.dto.CreatePresetCommentDto;
|
||||||
|
import com.competition.modules.biz.review.dto.SyncPresetCommentsDto;
|
||||||
import com.competition.modules.biz.review.entity.BizPresetComment;
|
import com.competition.modules.biz.review.entity.BizPresetComment;
|
||||||
import com.competition.modules.biz.review.service.IPresetCommentService;
|
import com.competition.modules.biz.review.service.IPresetCommentService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -65,11 +66,10 @@ public class PresetCommentController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@PostMapping("/batch-delete")
|
@PostMapping("/batch-delete")
|
||||||
@Operation(summary = "批量删除预设评语")
|
@Operation(summary = "批量删除预设评语")
|
||||||
public Result<Void> batchDelete(@RequestBody Map<String, Object> body) {
|
public Result<Void> batchDelete(@RequestBody Map<String, List<Long>> body) {
|
||||||
List<Long> ids = (List<Long>) body.get("ids");
|
List<Long> ids = body.get("ids");
|
||||||
Long judgeId = SecurityUtil.getCurrentUserId();
|
Long judgeId = SecurityUtil.getCurrentUserId();
|
||||||
presetCommentService.batchDelete(ids, judgeId);
|
presetCommentService.batchDelete(ids, judgeId);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
@ -77,12 +77,9 @@ public class PresetCommentController {
|
|||||||
|
|
||||||
@PostMapping("/sync")
|
@PostMapping("/sync")
|
||||||
@Operation(summary = "同步评语到其他赛事")
|
@Operation(summary = "同步评语到其他赛事")
|
||||||
public Result<Map<String, Object>> syncComments(@RequestBody Map<String, Object> body) {
|
public Result<Map<String, Object>> syncComments(@Valid @RequestBody SyncPresetCommentsDto dto) {
|
||||||
Long sourceContestId = Long.valueOf(body.get("sourceContestId").toString());
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
List<Long> targetContestIds = (List<Long>) body.get("targetContestIds");
|
|
||||||
Long judgeId = SecurityUtil.getCurrentUserId();
|
Long judgeId = SecurityUtil.getCurrentUserId();
|
||||||
return Result.success(presetCommentService.syncComments(sourceContestId, targetContestIds, judgeId));
|
return Result.success(presetCommentService.syncComments(dto.getSourceContestId(), dto.getTargetContestIds(), judgeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/{id}/use")
|
@PostMapping("/{id}/use")
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.competition.modules.biz.review.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "同步预设评语DTO")
|
||||||
|
public class SyncPresetCommentsDto {
|
||||||
|
|
||||||
|
@NotNull(message = "源赛事ID不能为空")
|
||||||
|
@Schema(description = "源赛事ID")
|
||||||
|
private Long sourceContestId;
|
||||||
|
|
||||||
|
@NotEmpty(message = "目标赛事列表不能为空")
|
||||||
|
@Schema(description = "目标赛事ID列表")
|
||||||
|
private List<Long> targetContestIds;
|
||||||
|
}
|
||||||
@ -9,7 +9,9 @@ import com.competition.modules.biz.review.entity.BizContestWorkJudgeAssignment;
|
|||||||
import com.competition.modules.biz.review.mapper.ContestJudgeMapper;
|
import com.competition.modules.biz.review.mapper.ContestJudgeMapper;
|
||||||
import com.competition.modules.biz.review.mapper.ContestWorkJudgeAssignmentMapper;
|
import com.competition.modules.biz.review.mapper.ContestWorkJudgeAssignmentMapper;
|
||||||
import com.competition.modules.biz.review.service.IContestJudgeService;
|
import com.competition.modules.biz.review.service.IContestJudgeService;
|
||||||
|
import com.competition.modules.sys.entity.SysTenant;
|
||||||
import com.competition.modules.sys.entity.SysUser;
|
import com.competition.modules.sys.entity.SysUser;
|
||||||
|
import com.competition.modules.sys.mapper.SysTenantMapper;
|
||||||
import com.competition.modules.sys.mapper.SysUserMapper;
|
import com.competition.modules.sys.mapper.SysUserMapper;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -27,6 +29,7 @@ public class ContestJudgeServiceImpl extends ServiceImpl<ContestJudgeMapper, Biz
|
|||||||
private final ContestJudgeMapper contestJudgeMapper;
|
private final ContestJudgeMapper contestJudgeMapper;
|
||||||
private final ContestWorkJudgeAssignmentMapper assignmentMapper;
|
private final ContestWorkJudgeAssignmentMapper assignmentMapper;
|
||||||
private final SysUserMapper sysUserMapper;
|
private final SysUserMapper sysUserMapper;
|
||||||
|
private final SysTenantMapper sysTenantMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BizContestJudge createJudge(Long contestId, Long judgeId, String specialty, BigDecimal weight, String description) {
|
public BizContestJudge createJudge(Long contestId, Long judgeId, String specialty, BigDecimal weight, String description) {
|
||||||
@ -57,6 +60,10 @@ public class ContestJudgeServiceImpl extends ServiceImpl<ContestJudgeMapper, Biz
|
|||||||
public List<Map<String, Object>> findByContest(Long contestId) {
|
public List<Map<String, Object>> findByContest(Long contestId) {
|
||||||
log.info("查询赛事评委列表,赛事ID:{}", contestId);
|
log.info("查询赛事评委列表,赛事ID:{}", contestId);
|
||||||
|
|
||||||
|
// 获取平台评委租户 ID
|
||||||
|
Long judgeTenantId = getJudgeTenantId();
|
||||||
|
|
||||||
|
// 1. 查询已显式分配的评委
|
||||||
LambdaQueryWrapper<BizContestJudge> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<BizContestJudge> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.eq(BizContestJudge::getContestId, contestId);
|
wrapper.eq(BizContestJudge::getContestId, contestId);
|
||||||
wrapper.eq(BizContestJudge::getValidState, 1);
|
wrapper.eq(BizContestJudge::getValidState, 1);
|
||||||
@ -64,11 +71,32 @@ public class ContestJudgeServiceImpl extends ServiceImpl<ContestJudgeMapper, Biz
|
|||||||
|
|
||||||
List<BizContestJudge> judges = contestJudgeMapper.selectList(wrapper);
|
List<BizContestJudge> judges = contestJudgeMapper.selectList(wrapper);
|
||||||
|
|
||||||
|
// 收集所有需要查询的用户 ID(已分配评委)
|
||||||
|
Set<Long> assignedJudgeIds = judges.stream().map(BizContestJudge::getJudgeId).collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 2. 查询平台评委(自动对所有赛事可用)
|
||||||
|
List<SysUser> platformJudges = new ArrayList<>();
|
||||||
|
if (judgeTenantId != null) {
|
||||||
|
LambdaQueryWrapper<SysUser> platformWrapper = new LambdaQueryWrapper<>();
|
||||||
|
platformWrapper.eq(SysUser::getTenantId, judgeTenantId);
|
||||||
|
platformWrapper.eq(SysUser::getStatus, "enabled");
|
||||||
|
platformJudges = sysUserMapper.selectList(platformWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 平台评委中去掉已显式分配的(避免重复)
|
||||||
|
Set<Long> platformOnlyIds = platformJudges.stream()
|
||||||
|
.map(SysUser::getId)
|
||||||
|
.filter(id -> !assignedJudgeIds.contains(id))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 合并所有需要查询的用户 ID
|
||||||
|
Set<Long> allUserIds = new HashSet<>(assignedJudgeIds);
|
||||||
|
allUserIds.addAll(platformOnlyIds);
|
||||||
|
|
||||||
// 批量查询用户信息
|
// 批量查询用户信息
|
||||||
Set<Long> userIds = judges.stream().map(BizContestJudge::getJudgeId).collect(Collectors.toSet());
|
|
||||||
Map<Long, SysUser> userMap = new HashMap<>();
|
Map<Long, SysUser> userMap = new HashMap<>();
|
||||||
if (!userIds.isEmpty()) {
|
if (!allUserIds.isEmpty()) {
|
||||||
List<SysUser> users = sysUserMapper.selectBatchIds(userIds);
|
List<SysUser> users = sysUserMapper.selectBatchIds(allUserIds);
|
||||||
for (SysUser user : users) {
|
for (SysUser user : users) {
|
||||||
userMap.put(user.getId(), user);
|
userMap.put(user.getId(), user);
|
||||||
}
|
}
|
||||||
@ -76,14 +104,17 @@ public class ContestJudgeServiceImpl extends ServiceImpl<ContestJudgeMapper, Biz
|
|||||||
|
|
||||||
// 批量查询每个评委在该赛事下的已分配作品数
|
// 批量查询每个评委在该赛事下的已分配作品数
|
||||||
Map<Long, Long> assignedCountMap = new HashMap<>();
|
Map<Long, Long> assignedCountMap = new HashMap<>();
|
||||||
for (BizContestJudge j : judges) {
|
for (Long judgeId : allUserIds) {
|
||||||
LambdaQueryWrapper<BizContestWorkJudgeAssignment> assignWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<BizContestWorkJudgeAssignment> assignWrapper = new LambdaQueryWrapper<>();
|
||||||
assignWrapper.eq(BizContestWorkJudgeAssignment::getContestId, contestId);
|
assignWrapper.eq(BizContestWorkJudgeAssignment::getContestId, contestId);
|
||||||
assignWrapper.eq(BizContestWorkJudgeAssignment::getJudgeId, j.getJudgeId());
|
assignWrapper.eq(BizContestWorkJudgeAssignment::getJudgeId, judgeId);
|
||||||
assignedCountMap.put(j.getJudgeId(), assignmentMapper.selectCount(assignWrapper));
|
assignedCountMap.put(judgeId, assignmentMapper.selectCount(assignWrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
return judges.stream().map(j -> {
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
|
|
||||||
|
// 构建已显式分配的评委数据
|
||||||
|
for (BizContestJudge j : judges) {
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("id", j.getId());
|
map.put("id", j.getId());
|
||||||
map.put("contestId", j.getContestId());
|
map.put("contestId", j.getContestId());
|
||||||
@ -98,9 +129,50 @@ public class ContestJudgeServiceImpl extends ServiceImpl<ContestJudgeMapper, Biz
|
|||||||
if (user != null) {
|
if (user != null) {
|
||||||
map.put("judgeName", user.getNickname());
|
map.put("judgeName", user.getNickname());
|
||||||
map.put("judgeUsername", user.getUsername());
|
map.put("judgeUsername", user.getUsername());
|
||||||
|
map.put("tenantId", user.getTenantId());
|
||||||
|
map.put("status", user.getStatus());
|
||||||
|
map.put("organization", user.getOrganization());
|
||||||
|
map.put("isPlatform", judgeTenantId != null && judgeTenantId.equals(user.getTenantId()));
|
||||||
|
} else {
|
||||||
|
map.put("isPlatform", false);
|
||||||
}
|
}
|
||||||
return map;
|
result.add(map);
|
||||||
}).collect(Collectors.toList());
|
}
|
||||||
|
|
||||||
|
// 追加未显式分配的平台评委
|
||||||
|
for (SysUser platformJudge : platformJudges) {
|
||||||
|
if (assignedJudgeIds.contains(platformJudge.getId())) {
|
||||||
|
continue; // 已在显式分配列表中,跳过
|
||||||
|
}
|
||||||
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
map.put("id", null);
|
||||||
|
map.put("contestId", contestId);
|
||||||
|
map.put("judgeId", platformJudge.getId());
|
||||||
|
map.put("specialty", null);
|
||||||
|
map.put("weight", null);
|
||||||
|
map.put("description", null);
|
||||||
|
map.put("createTime", null);
|
||||||
|
map.put("assignedCount", assignedCountMap.getOrDefault(platformJudge.getId(), 0L));
|
||||||
|
map.put("judgeName", platformJudge.getNickname());
|
||||||
|
map.put("judgeUsername", platformJudge.getUsername());
|
||||||
|
map.put("tenantId", platformJudge.getTenantId());
|
||||||
|
map.put("status", platformJudge.getStatus());
|
||||||
|
map.put("organization", platformJudge.getOrganization());
|
||||||
|
map.put("isPlatform", true);
|
||||||
|
result.add(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台评委租户 ID
|
||||||
|
*/
|
||||||
|
private Long getJudgeTenantId() {
|
||||||
|
LambdaQueryWrapper<SysTenant> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(SysTenant::getCode, "judge");
|
||||||
|
SysTenant tenant = sysTenantMapper.selectOne(wrapper);
|
||||||
|
return tenant != null ? tenant.getId() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
import com.competition.common.enums.ErrorCode;
|
import com.competition.common.enums.ErrorCode;
|
||||||
import com.competition.common.exception.BusinessException;
|
import com.competition.common.exception.BusinessException;
|
||||||
import com.competition.modules.biz.review.dto.CreatePresetCommentDto;
|
import com.competition.modules.biz.review.dto.CreatePresetCommentDto;
|
||||||
|
import com.competition.modules.biz.contest.entity.BizContest;
|
||||||
|
import com.competition.modules.biz.contest.mapper.ContestMapper;
|
||||||
import com.competition.modules.biz.review.entity.BizContestJudge;
|
import com.competition.modules.biz.review.entity.BizContestJudge;
|
||||||
import com.competition.modules.biz.review.entity.BizPresetComment;
|
import com.competition.modules.biz.review.entity.BizPresetComment;
|
||||||
import com.competition.modules.biz.review.mapper.ContestJudgeMapper;
|
import com.competition.modules.biz.review.mapper.ContestJudgeMapper;
|
||||||
@ -25,6 +27,7 @@ public class PresetCommentServiceImpl extends ServiceImpl<PresetCommentMapper, B
|
|||||||
|
|
||||||
private final PresetCommentMapper presetCommentMapper;
|
private final PresetCommentMapper presetCommentMapper;
|
||||||
private final ContestJudgeMapper contestJudgeMapper;
|
private final ContestJudgeMapper contestJudgeMapper;
|
||||||
|
private final ContestMapper contestMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BizPresetComment createComment(CreatePresetCommentDto dto, Long judgeId) {
|
public BizPresetComment createComment(CreatePresetCommentDto dto, Long judgeId) {
|
||||||
@ -162,7 +165,14 @@ public class PresetCommentServiceImpl extends ServiceImpl<PresetCommentMapper, B
|
|||||||
|
|
||||||
return judgeRecords.stream().map(j -> {
|
return judgeRecords.stream().map(j -> {
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("contestId", j.getContestId());
|
map.put("id", j.getContestId());
|
||||||
|
// 查询赛事详情获取名称和状态
|
||||||
|
BizContest contest = contestMapper.selectById(j.getContestId());
|
||||||
|
if (contest != null) {
|
||||||
|
map.put("contestName", contest.getContestName());
|
||||||
|
map.put("contestState", contest.getContestState());
|
||||||
|
map.put("status", contest.getStatus());
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
@ -201,9 +211,8 @@ public class PresetCommentServiceImpl extends ServiceImpl<PresetCommentMapper, B
|
|||||||
log.info("预设评语同步完成,新建数量:{}", created);
|
log.info("预设评语同步完成,新建数量:{}", created);
|
||||||
|
|
||||||
Map<String, Object> result = new LinkedHashMap<>();
|
Map<String, Object> result = new LinkedHashMap<>();
|
||||||
result.put("sourceCount", sourceComments.size());
|
result.put("message", "同步成功");
|
||||||
result.put("targetContests", targetContestIds.size());
|
result.put("count", created);
|
||||||
result.put("createdCount", created);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -607,13 +607,23 @@ const handleViewWork = (record: ContestWork) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 单个分配评委
|
// 单个分配评委
|
||||||
const handleAssignJudge = (record: ContestWork) => {
|
const handleAssignJudge = async (record: ContestWork) => {
|
||||||
currentAssignWork.value = record
|
currentAssignWork.value = record
|
||||||
isBatchAssign.value = false
|
isBatchAssign.value = false
|
||||||
selectedJudgeKeys.value = []
|
selectedJudgeKeys.value = []
|
||||||
selectedJudgeRows.value = []
|
selectedJudgeRows.value = []
|
||||||
assignModalVisible.value = true
|
assignModalVisible.value = true
|
||||||
fetchJudgeList()
|
await fetchJudgeList()
|
||||||
|
|
||||||
|
// 回显已分配的评委
|
||||||
|
if (record.assignments && record.assignments.length > 0) {
|
||||||
|
const assignedJudgeUserIds = record.assignments.map((a) => a.judgeId)
|
||||||
|
const matchedJudges = judgeList.value.filter((judge) =>
|
||||||
|
assignedJudgeUserIds.includes(judge.judgeId)
|
||||||
|
)
|
||||||
|
selectedJudgeKeys.value = matchedJudges.map((j) => j.id)
|
||||||
|
selectedJudgeRows.value = matchedJudges
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量分配评委
|
// 批量分配评委
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user