fix: 修复任务大厅导出功能数据不完整的问题

问题:导出功能只导出主任务,但前端任务大厅显示的是子任务
修复:按子任务行导出,与前端显示一致
- 查询可接单的子任务(task_item表status=pending)
- 每个子任务导出一行数据
- 包含子任务的任务编号、积分、数量等信息

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Your Name 2026-01-31 15:12:43 +08:00
parent f9a689dc1e
commit 01f0e3e3dc

View File

@ -42,44 +42,90 @@ public class ExportService {
/**
* 导出任务大厅数据
* 🔥 修复:按子任务行导出,与前端任务大厅显示一致
* 前端显示的是每个可接单的子任务,导出也应该按子任务行导出
*/
public void exportTaskHall(HttpServletResponse response, String status, Long publisherDeptId,
Long receiverDeptId, Long brandId, Long categoryId, Long platformId) throws IOException {
log.info("开始导出任务大厅数据: status={}, publisherDeptId={}, receiverDeptId={}, brandId={}, categoryId={}, platformId={}",
status, publisherDeptId, receiverDeptId, brandId, categoryId, platformId);
// 构建查询条件
LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Task::getDeleted, 0);
queryWrapper.eq(Task::getApprovalStatus, "approved"); // 只导出已审批的任务
String effectiveStatus = (status != null && !status.isEmpty()) ? status : "pending";
if (status != null && !status.isEmpty()) {
queryWrapper.eq(Task::getStatus, status);
} else {
// 默认导出待接单任务
queryWrapper.eq(Task::getStatus, "pending");
}
if (publisherDeptId != null) {
queryWrapper.eq(Task::getPublisherDeptId, publisherDeptId);
}
// 🔥 查询可接单的子任务(这是前端任务大厅实际显示的数据)
LambdaQueryWrapper<TaskItem> itemQueryWrapper = new LambdaQueryWrapper<>();
itemQueryWrapper.eq(TaskItem::getStatus, effectiveStatus);
if (receiverDeptId != null) {
queryWrapper.eq(Task::getReceiverDeptId, receiverDeptId);
itemQueryWrapper.eq(TaskItem::getReceiverDeptId, receiverDeptId);
}
if (brandId != null) {
queryWrapper.eq(Task::getBrandId, brandId);
}
if (categoryId != null) {
queryWrapper.eq(Task::getCategoryId, categoryId);
}
if (platformId != null) {
queryWrapper.eq(Task::getPlatformId, platformId);
itemQueryWrapper.orderByDesc(TaskItem::getCreateTime);
List<TaskItem> pendingItems = taskItemMapper.selectList(itemQueryWrapper);
log.info("查询到 {} 条可接单子任务", pendingItems.size());
// 🔥 获取子任务对应的主任务信息
List<Long> taskIds = pendingItems.stream()
.map(TaskItem::getTaskId)
.distinct()
.toList();
Map<Long, Task> taskMap = new HashMap<>();
if (!taskIds.isEmpty()) {
List<Task> parentTasks = taskMapper.selectBatchIds(taskIds);
for (Task t : parentTasks) {
taskMap.put(t.getId(), t);
}
}
queryWrapper.orderByDesc(Task::getCreateTime);
// 🔥 过滤:应用筛选条件到主任务
List<TaskItem> filteredItems = pendingItems.stream()
.filter(item -> {
Task task = taskMap.get(item.getTaskId());
if (task == null) return false;
if (publisherDeptId != null && !publisherDeptId.equals(task.getPublisherDeptId())) return false;
if (brandId != null && !brandId.equals(task.getBrandId())) return false;
if (categoryId != null && !categoryId.equals(task.getCategoryId())) return false;
if (platformId != null && !platformId.equals(task.getPlatformId())) return false;
return true;
})
.toList();
List<Task> tasks = taskMapper.selectList(queryWrapper);
log.info("查询到 {} 条任务", tasks.size());
log.info("过滤后 {} 条子任务", filteredItems.size());
// 🔥 将子任务转换为虚拟Task对象用于导出(保持现有导出格式兼容)
List<Task> tasks = new ArrayList<>();
for (TaskItem item : filteredItems) {
Task parentTask = taskMap.get(item.getTaskId());
if (parentTask == null) continue;
// 创建虚拟Task对象,包含子任务信息
Task virtualTask = new Task();
virtualTask.setId(parentTask.getId());
virtualTask.setTaskNo(item.getItemNo() != null ? item.getItemNo() : parentTask.getTaskNo());
virtualTask.setTitle(parentTask.getTitle());
virtualTask.setTaskTypeId(item.getTaskTypeId() != null ? item.getTaskTypeId() : parentTask.getTaskTypeId());
virtualTask.setTaskSubType(parentTask.getTaskSubType());
virtualTask.setBrandId(parentTask.getBrandId());
virtualTask.setCategoryId(parentTask.getCategoryId());
virtualTask.setPlatformId(parentTask.getPlatformId());
virtualTask.setSpuInfo(parentTask.getSpuInfo());
virtualTask.setScore(item.getTotalScore() != null ? item.getTotalScore() : parentTask.getScore());
virtualTask.setEstimatedHours(item.getEstimatedHours() != null ? item.getEstimatedHours() : parentTask.getEstimatedHours());
virtualTask.setQuantity(item.getQuantity() != null ? item.getQuantity() : parentTask.getQuantity());
virtualTask.setPublisherId(parentTask.getPublisherId());
virtualTask.setPublisherDeptId(parentTask.getPublisherDeptId());
virtualTask.setReceiverId(item.getReceiverId());
virtualTask.setReceiverDeptId(item.getReceiverDeptId());
virtualTask.setStatus(item.getStatus());
virtualTask.setReleaseType(parentTask.getReleaseType());
virtualTask.setIsUrgent(parentTask.getIsUrgent());
virtualTask.setIsPipeline(1);
virtualTask.setCreateTime(item.getCreateTime() != null ? item.getCreateTime() : parentTask.getCreateTime());
virtualTask.setDeadline(item.getDeadline() != null ? item.getDeadline() : parentTask.getDeadline());
tasks.add(virtualTask);
}
log.info("转换后共 {} 条任务用于导出", tasks.size());
// 预加载关联数据
Map<Long, String> taskTypeMap = loadTaskTypeMap();
@ -90,18 +136,18 @@ public class ExportService {
Map<Long, String> userMap = loadUserMap();
Map<Long, String> deptMap = loadDeptMap();
// 预加载所有相关任务的子任务明细
List<Long> taskIds = tasks.stream().map(Task::getId).toList();
// 🔥 为每个虚拟Task创建对应的子任务映射(每个Task对应一个子任务)
Map<Long, List<TaskItem>> taskItemsMap = new HashMap<>();
if (!taskIds.isEmpty()) {
List<TaskItem> allItems = taskItemMapper.selectList(
new LambdaQueryWrapper<TaskItem>()
.in(TaskItem::getTaskId, taskIds)
.orderBy(true, true, TaskItem::getGroupNo)
);
for (TaskItem item : allItems) {
taskItemsMap.computeIfAbsent(item.getTaskId(), k -> new ArrayList<>()).add(item);
}
// 使用子任务的ID作为虚拟Task的唯一标识(避免同一主任务多个子任务冲突)
Map<Long, TaskItem> virtualTaskToItemMap = new HashMap<>();
for (int i = 0; i < tasks.size(); i++) {
Task virtualTask = tasks.get(i);
TaskItem correspondingItem = filteredItems.get(i);
// 使用负数ID区分虚拟Task(避免与真实TaskID冲突)
Long virtualId = -(correspondingItem.getId());
virtualTask.setId(virtualId);
taskItemsMap.put(virtualId, List.of(correspondingItem));
virtualTaskToItemMap.put(virtualId, correspondingItem);
}
// 🔥 第一遍遍历:收集所有出现的任务类型名称(用于动态列)