qiangdanxitong/backend/src/main/java/com/designhub/service/TaskApprovalService.java
Your Name 07ce2e5613 feat: 管理员享受所有角色权限
- 管理员可以代审核所有任务(主任务和子任务组)
- 管理员可以发起任务(不受部门类型限制)
- isAdminUser同时检查isAdmin字段和角色
2026-01-04 08:36:33 +08:00

785 lines
36 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.designhub.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.designhub.dto.PipelineTaskDTO;
import com.designhub.dto.TaskApprovalDTO;
import com.designhub.dto.TaskUpdateDTO;
import com.designhub.entity.*;
import com.designhub.exception.BusinessException;
import com.designhub.mapper.*;
import com.designhub.common.ResultCode;
import com.designhub.entity.Brand;
import com.designhub.entity.Category;
import com.designhub.entity.Platform;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* 任务审核服务
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class TaskApprovalService {
private final TaskMapper taskMapper;
private final TaskApprovalLogMapper approvalLogMapper;
private final DepartmentMapper departmentMapper;
private final UserMapper userMapper;
private final BrandMapper brandMapper;
private final CategoryMapper categoryMapper;
private final PlatformMapper platformMapper;
private final NotificationService notificationService;
private final TeamScorePoolService teamScorePoolService;
private final TaskService taskService;
private final ConfigService configService;
private final ObjectMapper objectMapper;
private final DingTalkService dingTalkService;
/**
* 需求部门负责人审核通过
*/
@Transactional(rollbackFor = Exception.class)
public void approveDemandLevel(Long taskId, Long approverId, TaskApprovalDTO dto) {
// 1. 验证任务和权限
Task task = getTaskForApproval(taskId, "pending_demand_approval");
validateApprover(task, approverId, "demand_leader");
// 2. 应用任务修改(如果有)
if (dto.getTaskUpdates() != null) {
applyTaskUpdates(task, dto.getTaskUpdates());
logApproval(taskId, approverId, 1, "modify", dto.getComment());
}
// 3. 根据发布类型决定是否需要接单部门负责人审核
String releaseType = task.getReleaseType();
boolean needReceivingApproval = "default".equals(releaseType);
if (needReceivingApproval) {
// default模式:需要接单部门负责人审核
Long receivingLeaderId = determineReceivingLeader(task);
if (receivingLeaderId == null) {
throw new BusinessException(ResultCode.PARAM_ERROR, "无法确定接单部门负责人,请在系统设置中为接单部门配置负责人");
}
// 更新任务状态为待接单部门审核
task.setApprovalStatus("pending_receiving_approval");
task.setDemandApprovalTime(LocalDateTime.now());
task.setCurrentApproverId(receivingLeaderId);
task.setCurrentApproverRole("receiving_leader");
taskMapper.updateById(task);
// 记录审核日志
logApproval(taskId, approverId, 1, "approve", dto.getComment());
// 发送通知给接单部门负责人
User receivingLeader = userMapper.selectById(receivingLeaderId);
if (receivingLeader != null) {
notificationService.sendNotification(
receivingLeaderId,
"新任务待审核",
String.format("任务【%s】需要您审核并分配设计师", task.getTitle()),
"task_approval",
taskId
);
}
log.info("需求部门负责人审核通过,任务ID:{},审核人:{},等待接单部门负责人审核", taskId, approverId);
} else {
// recruitment或assigned模式:不需要接单部门负责人审核,直接发布
task.setDemandApprovalTime(LocalDateTime.now());
// 判断是否为流水线任务
if (task.getIsPipeline() != null && task.getIsPipeline() == 1) {
// 流水线任务:拆分子任务
splitIntoPipelineSubTasks(task);
// splitIntoPipelineSubTasks方法会根据releaseType设置任务状态
} else {
// 普通任务处理
if ("assigned".equals(releaseType) && task.getReceiverId() != null) {
// assigned模式:如果指定了接收人,直接分配给该设计师
User receiver = userMapper.selectById(task.getReceiverId());
if (receiver != null && receiver.getDeptId() != null) {
task.setReceiverDeptId(receiver.getDeptId());
task.setStatus("in_progress");
task.setStartTime(LocalDateTime.now());
task.setActualStartTime(LocalDateTime.now());
// 重新计算截止时间
if (task.getEstimatedHours() != null) {
int hours = task.getEstimatedHours().intValue();
if (hours > 0) {
task.setDeadline(LocalDateTime.now().plusHours(hours));
}
}
// 发送通知给被指定的设计师
notificationService.sendNotification(
task.getReceiverId(),
"新任务分配",
String.format("任务【%s】已分配给您", task.getTitle()),
"task_assigned",
taskId
);
log.info("assigned模式任务已直接分配给设计师:taskId={}, receiverId={}", taskId, task.getReceiverId());
} else {
throw new BusinessException(ResultCode.PARAM_ERROR, "指定的接收人不存在或部门信息不完整");
}
} else {
// recruitment模式:发布到任务大厅
task.setStatus("pending");
}
}
// 更新审核状态为已通过
task.setApprovalStatus("approved");
task.setCurrentApproverId(null);
task.setCurrentApproverRole(null);
taskMapper.updateById(task);
// 扣除部门积分
try {
teamScorePoolService.deductScore(task.getPublisherDeptId(), task.getScore());
} catch (Exception e) {
log.error("扣除部门积分失败", e);
throw new BusinessException(ResultCode.ERROR, "扣除部门积分失败:" + e.getMessage());
}
// 记录审核日志
logApproval(taskId, approverId, 1, "approve", dto.getComment());
log.info("需求部门负责人审核通过,任务ID:{},审核人:{},发布类型:{},已直接发布", taskId, approverId, releaseType);
}
}
/**
* 需求部门负责人驳回
*/
@Transactional(rollbackFor = Exception.class)
public void rejectByDemandLeader(Long taskId, Long approverId, String reason) {
Task task = getTaskForApproval(taskId, "pending_demand_approval");
validateApprover(task, approverId, "demand_leader");
task.setApprovalStatus("rejected_by_demand");
task.setStatus("draft");
task.setCurrentApproverId(null);
task.setCurrentApproverRole(null);
taskMapper.updateById(task);
logApproval(taskId, approverId, 1, "reject", reason);
// 通知发起人
notificationService.sendNotification(
task.getPublisherId(),
"任务已被驳回",
String.format("您的任务【%s】被需求部门负责人驳回,原因:%s", task.getTitle(), reason),
"task_reject",
taskId
);
// 如果任务有指定的处理人,发送群通知告知驳回
if (task.getReceiverId() != null) {
try {
com.designhub.entity.User receiver = userMapper.selectById(task.getReceiverId());
if (receiver != null) {
String title = "任务已驳回";
StringBuilder content = new StringBuilder();
content.append("-------------------------------- \n");
content.append(" 【 任 务 已 驳 回 】 \n");
content.append("-------------------------------- \n\n");
content.append("任务名称:").append(task.getTitle()).append(" \n");
content.append("任务编号:").append(task.getTaskNo()).append(" \n");
content.append("原处理人:").append(receiver.getRealName()).append(" \n");
content.append("驳回原因:").append(reason).append(" \n");
content.append(" \n");
content.append("--------------------------------");
java.util.List<String> atMobiles = receiver.getPhone() != null ?
java.util.Arrays.asList(receiver.getPhone()) : null;
dingTalkService.sendRobotMessage(title, content.toString(), atMobiles);
}
} catch (Exception e) {
log.error("发送任务驳回群通知失败", e);
}
}
log.info("需求部门负责人驳回任务,任务ID:{},审核人:{}", taskId, approverId);
}
/**
* 接单部门负责人审核通过
* @param taskId 任务ID
* @param approverId 审核人ID
* @param dto 审核数据(包含备注和任务修改)
* @param assignedReceiverId 指定的接收人ID(可选)
*/
@Transactional(rollbackFor = Exception.class)
public void approveReceivingLevel(Long taskId, Long approverId, TaskApprovalDTO dto, Long assignedReceiverId) {
Task task = getTaskForApproval(taskId, "pending_receiving_approval");
validateApprover(task, approverId, "receiving_leader");
// 应用任务修改(如果有)
if (dto.getTaskUpdates() != null) {
applyTaskUpdates(task, dto.getTaskUpdates());
logApproval(taskId, approverId, 2, "modify", dto.getComment());
}
// 如果指定了接收人,验证接收人是否存在并设置
if (assignedReceiverId != null) {
com.designhub.entity.User receiver = userMapper.selectById(assignedReceiverId);
if (receiver == null) {
throw new BusinessException(ResultCode.PARAM_ERROR, "指定的接收人不存在");
}
task.setReceiverId(assignedReceiverId);
task.setReceiverDeptId(receiver.getDeptId());
task.setReleaseType("assigned"); // 设置为指定模式
log.info("任务【{}】已指定给设计师【{}】", task.getTitle(), receiver.getRealName());
}
// 判断是否为流水线任务
if (task.getIsPipeline() != null && task.getIsPipeline() == 1) {
// 流水线任务:拆分子任务
splitIntoPipelineSubTasks(task);
} else {
// 普通任务:根据是否指定接收人设置状态
if (assignedReceiverId != null) {
task.setStatus("in_progress"); // 指定接单直接进入进行中状态
LocalDateTime now = LocalDateTime.now();
task.setStartTime(now);
task.setActualStartTime(now);
// 重新计算deadline:从指定接单时间开始计算
if (task.getEstimatedHours() != null) {
int hours = task.getEstimatedHours().intValue();
if (hours > 0) {
task.setDeadline(now.plusHours(hours));
log.info("任务deadline已重新计算:从指定接单时间 {} 开始,预估 {} 小时,截止时间 {}",
now, hours, task.getDeadline());
}
}
} else {
task.setStatus("pending"); // 未指定则发布到大厅
}
}
// 更新审核状态
task.setApprovalStatus("approved");
task.setReceivingApprovalTime(LocalDateTime.now());
task.setCurrentApproverId(null);
task.setCurrentApproverRole(null);
taskMapper.updateById(task);
// 扣除部门积分
try {
teamScorePoolService.deductScore(task.getPublisherDeptId(), task.getScore());
} catch (Exception e) {
log.error("扣除部门积分失败", e);
throw new BusinessException(ResultCode.ERROR, "扣除部门积分失败:" + e.getMessage());
}
// 记录审核日志
String logComment = dto.getComment();
if (assignedReceiverId != null) {
com.designhub.entity.User receiver = userMapper.selectById(assignedReceiverId);
logComment = (logComment != null ? logComment + ";" : "") +
"已指定给设计师:" + (receiver != null ? receiver.getRealName() : assignedReceiverId);
}
logApproval(taskId, approverId, 2, "approve", logComment);
// 发送钉钉群通知
if (assignedReceiverId != null) {
// 指定了设计师,发送群通知并@该设计师
log.info("任务【{}】已指定给设计师,准备发送钉钉群通知", task.getTitle());
try {
com.designhub.entity.User receiver = userMapper.selectById(assignedReceiverId);
String receiverName = receiver != null ? receiver.getRealName() : "未知";
String receiverPhone = receiver != null ? receiver.getPhone() : null;
String title = "任务已指派";
StringBuilder content = new StringBuilder();
content.append("-------------------------------- \n");
content.append(" 【 任 务 已 指 派 】 \n");
content.append("-------------------------------- \n\n");
content.append("任务名称:").append(task.getTitle()).append(" \n");
content.append("任务编号:").append(task.getTaskNo()).append(" \n");
content.append("任务积分:").append(task.getScore()).append(" 分 \n");
content.append("指派给:").append(receiverName).append(" \n");
if (task.getEstimatedHours() != null) {
content.append("预估工时:").append(task.getEstimatedHours().intValue()).append(" 小时 \n");
}
if (task.getPublisherName() != null && !task.getPublisherName().isEmpty()) {
content.append("发起人:").append(task.getPublisherName()).append(" \n");
}
content.append(" \n");
content.append("-------------------------------- \n");
content.append("请尽快处理!qd.yydd.ai \n");
content.append("--------------------------------");
// 发送群通知并@指定的设计师
java.util.List<String> atMobiles = receiverPhone != null ?
java.util.Arrays.asList(receiverPhone) : null;
dingTalkService.sendRobotMessage(title, content.toString(), atMobiles);
log.info("任务指派群通知已发送,@手机号: {}", receiverPhone);
} catch (Exception e) {
log.error("发送任务指派群通知失败", e);
}
} else {
log.info("任务【{}】已发布到任务大厅,准备发送钉钉群通知", task.getTitle());
// 任务发布到大厅,发送钉钉群机器人通知
// 注意:钉钉Markdown换行需要两个空格+换行符
try {
String title = "新任务发布";
StringBuilder content = new StringBuilder();
content.append("-------------------------------- \n");
content.append(" 【 新 任 务 发 布 】 \n");
content.append("-------------------------------- \n\n");
// 基本信息
content.append("任务名称:").append(task.getTitle()).append(" \n");
content.append("任务编号:").append(task.getTaskNo()).append(" \n");
content.append("任务积分:").append(task.getScore()).append(" 分 \n");
// 数量信息
if (task.getQuantity() != null && task.getQuantity() > 0) {
content.append("任务数量:").append(task.getQuantity()).append(" 个 \n");
}
// 任务需求类型
if (task.getTaskTypeIds() != null && !task.getTaskTypeIds().isEmpty()) {
StringBuilder typeNames = new StringBuilder();
String[] typeIds = task.getTaskTypeIds().split(",");
for (String typeIdStr : typeIds) {
try {
Long typeId = Long.parseLong(typeIdStr.trim());
DemandType demandType = configService.getDemandTypeById(typeId);
if (demandType != null) {
if (typeNames.length() > 0) {
typeNames.append("、");
}
typeNames.append(demandType.getName());
}
} catch (NumberFormatException e) {
log.warn("解析任务类型ID失败:{}", typeIdStr);
}
}
if (typeNames.length() > 0) {
content.append("需求类型:").append(typeNames.toString()).append(" \n");
}
}
content.append(" \n");
// 任务详情
if (task.getBrandName() != null && !task.getBrandName().isEmpty()) {
content.append("品牌:").append(task.getBrandName()).append(" \n");
}
if (task.getCategoryName() != null && !task.getCategoryName().isEmpty()) {
content.append("类目:").append(task.getCategoryName()).append(" \n");
}
if (task.getPlatformName() != null && !task.getPlatformName().isEmpty()) {
content.append("平台:").append(task.getPlatformName()).append(" \n");
}
if (task.getSpuInfo() != null && !task.getSpuInfo().isEmpty()) {
content.append("SPU:").append(task.getSpuInfo()).append(" \n");
}
if (task.getTaskSubType() != null && !task.getTaskSubType().isEmpty()) {
content.append("子类型:").append(task.getTaskSubType()).append(" \n");
}
// 时间信息
if (task.getEstimatedHours() != null) {
content.append("预估工时:").append(task.getEstimatedHours().intValue()).append(" 小时(接单后开始计时) \n");
}
content.append(" \n");
// 发起人信息
if (task.getPublisherName() != null && !task.getPublisherName().isEmpty()) {
content.append("发起人:").append(task.getPublisherName()).append(" \n");
}
if (task.getPublisherDeptName() != null && !task.getPublisherDeptName().isEmpty()) {
content.append("发起部门:").append(task.getPublisherDeptName()).append(" \n");
}
content.append(" \n");
content.append("-------------------------------- \n");
content.append("前往抢单:qd.yydd.ai \n");
content.append("--------------------------------");
log.info("准备调用钉钉机器人发送消息,title={}", title);
boolean success = dingTalkService.sendRobotMessage(title, content.toString());
if (success) {
log.info("任务【{}】钉钉群通知发送成功", task.getTitle());
} else {
log.warn("任务【{}】钉钉群通知发送失败(返回false)", task.getTitle());
}
} catch (Exception e) {
log.error("发送钉钉群通知异常:taskId={}, error={}", taskId, e.getMessage(), e);
// 通知发送失败不影响主流程
}
}
log.info("接单部门负责人审核通过,任务ID:{},审核人:{},指定接收人:{}",
taskId, approverId, assignedReceiverId);
}
/**
* 接单部门负责人审核通过(重载方法,保持向后兼容)
*/
@Transactional(rollbackFor = Exception.class)
public void approveReceivingLevel(Long taskId, Long approverId, TaskApprovalDTO dto) {
approveReceivingLevel(taskId, approverId, dto, null);
}
/**
* 接单部门负责人驳回
*/
@Transactional(rollbackFor = Exception.class)
public void rejectByReceivingLeader(Long taskId, Long approverId, String reason) {
Task task = getTaskForApproval(taskId, "pending_receiving_approval");
validateApprover(task, approverId, "receiving_leader");
// 退回给需求部门负责人
Department demandDept = departmentMapper.selectById(task.getPublisherDeptId());
if (demandDept == null || demandDept.getLeaderId() == null) {
throw new BusinessException(ResultCode.PARAM_ERROR, "需求部门负责人不存在");
}
task.setApprovalStatus("rejected_by_receiving");
task.setStatus("draft");
task.setCurrentApproverId(demandDept.getLeaderId());
task.setCurrentApproverRole("demand_leader");
taskMapper.updateById(task);
logApproval(taskId, approverId, 2, "reject", reason);
// 通知需求部门负责人
notificationService.sendNotification(
demandDept.getLeaderId(),
"任务已被驳回",
String.format("任务【%s】被接单部门负责人驳回,原因:%s", task.getTitle(), reason),
"task_reject",
taskId
);
// 如果任务有指定的处理人,发送群通知告知驳回
if (task.getReceiverId() != null) {
try {
com.designhub.entity.User receiver = userMapper.selectById(task.getReceiverId());
if (receiver != null) {
String title = "任务已驳回";
StringBuilder content = new StringBuilder();
content.append("-------------------------------- \n");
content.append(" 【 任 务 已 驳 回 】 \n");
content.append("-------------------------------- \n\n");
content.append("任务名称:").append(task.getTitle()).append(" \n");
content.append("任务编号:").append(task.getTaskNo()).append(" \n");
content.append("原处理人:").append(receiver.getRealName()).append(" \n");
content.append("驳回原因:").append(reason).append(" \n");
content.append(" \n");
content.append("--------------------------------");
java.util.List<String> atMobiles = receiver.getPhone() != null ?
java.util.Arrays.asList(receiver.getPhone()) : null;
dingTalkService.sendRobotMessage(title, content.toString(), atMobiles);
}
} catch (Exception e) {
log.error("发送任务驳回群通知失败", e);
}
}
log.info("接单部门负责人驳回任务,任务ID:{},审核人:{}", taskId, approverId);
}
/**
* 获取待审核任务列表
* 管理员可以看到所有待审核任务
*/
public List<Task> getPendingApprovalTasks(Long userId) {
// 检查用户是否是管理员
User user = userMapper.selectById(userId);
boolean isAdmin = user != null && Integer.valueOf(1).equals(user.getIsAdmin());
LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
wrapper.in(Task::getApprovalStatus, "pending_demand_approval", "pending_receiving_approval");
// 非管理员只能看到分配给自己的待审核任务
if (!isAdmin) {
wrapper.eq(Task::getCurrentApproverId, userId);
}
wrapper.orderByDesc(Task::getCreateTime);
List<Task> tasks = taskMapper.selectList(wrapper);
// 填充关联信息
for (Task task : tasks) {
// 填充发起人姓名
if (task.getPublisherId() != null) {
User publisher = userMapper.selectById(task.getPublisherId());
if (publisher != null) {
task.setPublisherName(publisher.getUsername());
}
}
// 填充发起部门名称
if (task.getPublisherDeptId() != null) {
Department dept = departmentMapper.selectById(task.getPublisherDeptId());
if (dept != null) {
task.setPublisherDeptName(dept.getDeptName());
}
}
// 填充品牌名称
if (task.getBrandId() != null) {
Brand brand = brandMapper.selectById(task.getBrandId());
if (brand != null) {
// Brand实体类中name字段映射到brand_name,使用getName()
task.setBrandName(brand.getName());
} else {
log.warn("任务 {} 品牌ID {} 不存在", task.getId(), task.getBrandId());
}
}
// 填充类目名称
if (task.getCategoryId() != null) {
Category category = categoryMapper.selectById(task.getCategoryId());
if (category != null) {
// Category实体类中name字段映射到category_name,使用getName()
task.setCategoryName(category.getName());
} else {
log.warn("任务 {} 类目ID {} 不存在", task.getId(), task.getCategoryId());
}
}
// 填充平台名称
if (task.getPlatformId() != null) {
Platform platform = platformMapper.selectById(task.getPlatformId());
if (platform != null) {
// Platform实体类中name字段映射到platform_name,使用getName()
task.setPlatformName(platform.getName());
} else {
log.warn("任务 {} 平台ID {} 不存在", task.getId(), task.getPlatformId());
}
}
// 填充当前审核人姓名
if (task.getCurrentApproverId() != null) {
User approver = userMapper.selectById(task.getCurrentApproverId());
if (approver != null) {
task.setCurrentApproverName(approver.getRealName() != null ? approver.getRealName() : approver.getUsername());
}
}
}
return tasks;
}
/**
* 获取任务并验证审核状态
*/
private Task getTaskForApproval(Long taskId, String expectedStatus) {
Task task = taskMapper.selectById(taskId);
if (task == null) {
throw new BusinessException(ResultCode.NOT_FOUND, "任务不存在");
}
if (!expectedStatus.equals(task.getApprovalStatus())) {
throw new BusinessException(ResultCode.TASK_STATUS_ERROR,
"任务当前状态不允许此操作,当前状态:" + task.getApprovalStatus());
}
return task;
}
/**
* 验证审核人权限
* 管理员可以代审核所有任务
*/
private void validateApprover(Task task, Long approverId, String expectedRole) {
// 检查是否是管理员,管理员可以代审核所有任务
User approver = userMapper.selectById(approverId);
if (approver != null && Integer.valueOf(1).equals(approver.getIsAdmin())) {
log.info("管理员 {} 代审核任务 {}", approver.getRealName(), task.getId());
return; // 管理员绕过权限验证
}
if (!approverId.equals(task.getCurrentApproverId())) {
throw new BusinessException(ResultCode.FORBIDDEN, "您无权审核此任务");
}
if (!expectedRole.equals(task.getCurrentApproverRole())) {
throw new BusinessException(ResultCode.FORBIDDEN, "审核角色不匹配");
}
}
/**
* 确定接单部门负责人
*/
private Long determineReceivingLeader(Task task) {
// 根据任务类型的allowedDeptIds确定接单部门
// 简化版本:取第一个任务类型的第一个允许部门
String taskTypeIds = task.getTaskTypeIds();
if (taskTypeIds == null || taskTypeIds.isEmpty()) {
return null;
}
String[] typeIdArray = taskTypeIds.split(",");
for (String typeIdStr : typeIdArray) {
try {
Long typeId = Long.parseLong(typeIdStr.trim());
DemandType demandType = configService.getDemandTypeById(typeId);
if (demandType != null && demandType.getAllowedDeptIds() != null) {
String[] deptIds = demandType.getAllowedDeptIds().split(",");
if (deptIds.length > 0) {
Long deptId = Long.parseLong(deptIds[0].trim());
Department dept = departmentMapper.selectById(deptId);
if (dept != null && dept.getLeaderId() != null) {
return dept.getLeaderId();
}
}
}
} catch (Exception e) {
log.error("解析任务类型或部门ID失败", e);
}
}
return null;
}
/**
* 应用任务更新
*/
private void applyTaskUpdates(Task task, TaskUpdateDTO updates) {
if (updates.getTitle() != null) {
task.setTitle(updates.getTitle());
}
if (updates.getTaskSubType() != null) {
task.setTaskSubType(updates.getTaskSubType());
}
if (updates.getBrandId() != null) {
task.setBrandId(updates.getBrandId());
}
if (updates.getPlatformId() != null) {
task.setPlatformId(updates.getPlatformId());
}
if (updates.getCategoryId() != null) {
task.setCategoryId(updates.getCategoryId());
}
if (updates.getSpuInfo() != null) {
task.setSpuInfo(updates.getSpuInfo());
}
if (updates.getRemark() != null) {
task.setRemark(updates.getRemark());
}
if (updates.getAttachmentUrl() != null) {
task.setAttachmentUrl(updates.getAttachmentUrl());
}
// 如果修改了任务类型和数量,需要重新计算积分
if (updates.getTaskTypes() != null && !updates.getTaskTypes().isEmpty()) {
String taskTypeIds = updates.getTaskTypes().stream()
.map(t -> String.valueOf(t.getTaskTypeId()))
.collect(Collectors.joining(","));
task.setTaskTypeIds(taskTypeIds);
// 如果只有一个任务类型,更新quantity字段
if (updates.getTaskTypes().size() == 1) {
task.setQuantity(updates.getTaskTypes().get(0).getQuantity());
}
// 重新计算积分
int totalScore = taskService.calculateTotalScore(updates.getTaskTypes());
task.setScore(totalScore);
}
}
/**
* 拆分为流水线子任务
*/
private void splitIntoPipelineSubTasks(Task task) {
try {
// 构建流水线任务DTO
PipelineTaskDTO dto = new PipelineTaskDTO();
dto.setTitle(task.getTitle());
dto.setTaskSubType(task.getTaskSubType());
dto.setBrandId(task.getBrandId());
dto.setPlatformId(task.getPlatformId());
dto.setCategoryId(task.getCategoryId());
dto.setSpuInfo(task.getSpuInfo());
dto.setRemark(task.getRemark());
dto.setAttachmentUrl(task.getAttachmentUrl());
dto.setPipelineMode(task.getPipelineMode());
dto.setReleaseType(task.getReleaseType()); // 传递发布类型
// 解析任务类型
String[] taskTypeIds = task.getTaskTypeIds().split(",");
List<PipelineTaskDTO.TaskItemDTO> items = new java.util.ArrayList<>();
// 简化版本:所有任务类型使用相同的数量(task.quantity)
int quantity = task.getQuantity() != null ? task.getQuantity() : 1;
for (String taskTypeIdStr : taskTypeIds) {
PipelineTaskDTO.TaskItemDTO item = new PipelineTaskDTO.TaskItemDTO();
item.setTaskTypeId(Long.parseLong(taskTypeIdStr.trim()));
item.setQuantity(quantity);
items.add(item);
}
dto.setItems(items);
// 调用TaskService创建流水线子任务
taskService.createPipelineTaskItems(task, dto);
// 根据发布类型设置主任务状态
if ("recruitment".equals(task.getReleaseType())) {
// recruitment模式:发布到任务大厅
task.setStatus("pending");
} else if ("assigned".equals(task.getReleaseType()) && task.getReceiverId() != null) {
// assigned模式:如果指定了接收人,状态已经是in_progress(在approveDemandLevel中已设置)
// 这里不需要再次设置
} else {
// default模式或其他模式:流水线任务的主任务状态设置为pending
// 子任务会根据is_locked字段控制可见性
task.setStatus("pending");
}
} catch (Exception e) {
log.error("拆分流水线任务失败", e);
throw new BusinessException(ResultCode.ERROR, "拆分流水线任务失败:" + e.getMessage());
}
}
/**
* 记录审核日志
*/
private void logApproval(Long taskId, Long approverId, Integer level, String action, String comment) {
try {
User approver = userMapper.selectById(approverId);
TaskApprovalLog log = new TaskApprovalLog();
log.setTaskId(taskId);
log.setApprovalLevel(level);
log.setApproverId(approverId);
log.setApproverName(approver != null ? approver.getRealName() : null);
log.setAction(action);
log.setComment(comment);
log.setCreateTime(LocalDateTime.now());
approvalLogMapper.insert(log);
} catch (Exception e) {
this.log.error("记录审核日志失败", e);
}
}
}