暂存提交
This commit is contained in:
+83
-7
@@ -2,10 +2,14 @@ package com.baiyue.firstleg.controller;
|
||||
|
||||
import com.baiyue.common.audit.BusinessAudit;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.AssignRequest;
|
||||
import com.baiyue.firstleg.dto.FulfillmentTaskQuery;
|
||||
import com.baiyue.firstleg.entity.AssignmentHistoryEntity;
|
||||
import com.baiyue.firstleg.entity.FulfillmentTaskEntity;
|
||||
import com.baiyue.firstleg.service.FulfillmentTaskService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -13,7 +17,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -22,11 +30,11 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 平台端头程履约任务指派接口,在目标租户内完成任务指派或改派并记录指派历史。
|
||||
* 平台端头程履约任务接口,在目标租户内提供任务查询、分配和分配历史查询。
|
||||
*/
|
||||
@Tag(
|
||||
name = "Platform first-leg assignment / 平台头程指派",
|
||||
description = "Platform APIs for assigning tenant-scoped first-leg fulfillment tasks. / 平台端按租户指派头程履约任务的接口。"
|
||||
name = "平台头程履约任务",
|
||||
description = "平台端按目标租户查询和分配头程履约任务。"
|
||||
)
|
||||
@RestController
|
||||
@RequestMapping("/api/platform/v1/first-leg/tasks")
|
||||
@@ -52,6 +60,7 @@ public class PlatformFulfillmentAssignmentController {
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "409", description = "Task is closed or concurrently updated / 任务已关闭或发生并发更新")
|
||||
})
|
||||
@PostMapping("/{taskId}/assignment")
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:assignment:assign')")
|
||||
public ApiResponse<Void> assign(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -72,17 +81,84 @@ public class PlatformFulfillmentAssignmentController {
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询履约任务列表", description = "在指定租户内按条件分页查询头程履约任务。")
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无查询权限")
|
||||
})
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:task:list')")
|
||||
public ApiResponse<PageResult<FulfillmentTaskEntity>> page(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam long tenantId,
|
||||
@Valid FulfillmentTaskQuery query) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
return ApiResponse.success(service.page(tenantId, query));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询履约任务详情", description = "查询指定租户内的头程履约任务详情。")
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无查看权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "任务不存在")
|
||||
})
|
||||
@GetMapping("/{taskId}")
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:task:view')")
|
||||
public ApiResponse<FulfillmentTaskEntity> detail(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam long tenantId,
|
||||
@PathVariable long taskId) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
return ApiResponse.success(service.detail(tenantId, taskId));
|
||||
}
|
||||
|
||||
@Operation(summary = "按订单查询履约任务", description = "使用订单逻辑ID查询指定租户内唯一的履约任务。")
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无查看权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "任务不存在")
|
||||
})
|
||||
@GetMapping("/by-order/{orderId}")
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:task:view')")
|
||||
public ApiResponse<FulfillmentTaskEntity> byOrder(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam long tenantId,
|
||||
@PathVariable long orderId) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
return ApiResponse.success(service.byOrder(tenantId, orderId));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询分配历史", description = "分页查询指定履约任务不可变的分配历史。")
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无历史查看权限"),
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "任务不存在")
|
||||
})
|
||||
@GetMapping("/{taskId}/assignment-history")
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:assignment:history')")
|
||||
public ApiResponse<PageResult<AssignmentHistoryEntity>> assignmentHistory(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam long tenantId,
|
||||
@PathVariable long taskId,
|
||||
@RequestParam(defaultValue = "1") @Min(1) long page,
|
||||
@RequestParam(defaultValue = "20") @Min(1) @Max(200) long size) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
return ApiResponse.success(service.assignmentHistory(tenantId, taskId, page, size));
|
||||
}
|
||||
|
||||
private static void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN,
|
||||
"Platform application required / 仅允许平台端访问");
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
}
|
||||
|
||||
private static void requireTenant(long tenantId) {
|
||||
if (tenantId <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST,
|
||||
"Target tenant is required / 必须指定有效目标租户");
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "必须指定有效目标租户");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.baiyue.firstleg.repository;
|
||||
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.firstleg.dto.FulfillmentTaskQuery;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baiyue.firstleg.entity.AssignmentHistoryEntity;
|
||||
import com.baiyue.firstleg.entity.FulfillmentTaskEntity;
|
||||
import com.baiyue.firstleg.mapper.AssignmentHistoryMapper;
|
||||
import com.baiyue.firstleg.mapper.FulfillmentTaskMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 头程履约任务仓储,按租户查询和更新任务,并持久化每次指派历史。
|
||||
@@ -26,6 +30,31 @@ public class FulfillmentTaskRepository {
|
||||
.eq(FulfillmentTaskEntity::getId, taskId));
|
||||
}
|
||||
|
||||
public FulfillmentTaskEntity findByOrder(long tenantId, long orderId) {
|
||||
return tasks.selectOne(new LambdaQueryWrapper<FulfillmentTaskEntity>()
|
||||
.eq(FulfillmentTaskEntity::getTenantId, tenantId)
|
||||
.eq(FulfillmentTaskEntity::getOrderId, orderId));
|
||||
}
|
||||
|
||||
public PageResult<FulfillmentTaskEntity> page(long tenantId, FulfillmentTaskQuery query) {
|
||||
LambdaQueryWrapper<FulfillmentTaskEntity> wrapper = new LambdaQueryWrapper<FulfillmentTaskEntity>()
|
||||
.eq(FulfillmentTaskEntity::getTenantId, tenantId)
|
||||
.eq(StringUtils.hasText(query.status()), FulfillmentTaskEntity::getStatus, query.status())
|
||||
.eq(query.assigneeId() != null, FulfillmentTaskEntity::getAssigneeId, query.assigneeId())
|
||||
.like(StringUtils.hasText(query.keyword()), FulfillmentTaskEntity::getOrderNo, query.keyword())
|
||||
.orderByDesc(FulfillmentTaskEntity::getCreatedAt);
|
||||
return PageResult.from(tasks.selectPage(new Page<>(query.page(), query.size()), wrapper));
|
||||
}
|
||||
|
||||
public PageResult<AssignmentHistoryEntity> pageHistory(
|
||||
long tenantId, long taskId, long page, long size) {
|
||||
LambdaQueryWrapper<AssignmentHistoryEntity> wrapper = new LambdaQueryWrapper<AssignmentHistoryEntity>()
|
||||
.eq(AssignmentHistoryEntity::getTenantId, tenantId)
|
||||
.eq(AssignmentHistoryEntity::getTaskId, taskId)
|
||||
.orderByDesc(AssignmentHistoryEntity::getCreatedAt);
|
||||
return PageResult.from(histories.selectPage(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
public boolean update(FulfillmentTaskEntity task) {
|
||||
return tasks.updateById(task) == 1;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.baiyue.firstleg.service;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.firstleg.dto.FulfillmentTaskQuery;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.entity.AssignmentHistoryEntity;
|
||||
import com.baiyue.firstleg.entity.FulfillmentTaskEntity;
|
||||
@@ -23,11 +25,7 @@ public class FulfillmentTaskService {
|
||||
@Transactional
|
||||
public void assign(long tenantId, long operatorId, long taskId,
|
||||
long assigneeId, String assigneeName, String reason) {
|
||||
FulfillmentTaskEntity task = repository.findOwned(tenantId, taskId);
|
||||
if (task == null) {
|
||||
throw new BizException(ResultCode.NOT_FOUND,
|
||||
"Fulfillment task not found / 头程履约任务不存在");
|
||||
}
|
||||
FulfillmentTaskEntity task = requireTask(tenantId, taskId);
|
||||
if ("COMPLETED".equals(task.getStatus()) || "CANCELLED".equals(task.getStatus())) {
|
||||
throw new BizException(ResultCode.CONFLICT,
|
||||
"Closed task cannot be assigned / 已关闭任务不能再次指派");
|
||||
@@ -55,4 +53,38 @@ public class FulfillmentTaskService {
|
||||
history.setCreatedAt(LocalDateTime.now());
|
||||
repository.insertHistory(history);
|
||||
}
|
||||
|
||||
public PageResult<FulfillmentTaskEntity> page(long tenantId, FulfillmentTaskQuery query) {
|
||||
return repository.page(tenantId, query);
|
||||
}
|
||||
|
||||
public FulfillmentTaskEntity detail(long tenantId, long taskId) {
|
||||
return requireTask(tenantId, taskId);
|
||||
}
|
||||
|
||||
public FulfillmentTaskEntity byOrder(long tenantId, long orderId) {
|
||||
FulfillmentTaskEntity task = repository.findByOrder(tenantId, orderId);
|
||||
if (task == null) {
|
||||
throw notFound();
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
public PageResult<AssignmentHistoryEntity> assignmentHistory(
|
||||
long tenantId, long taskId, long page, long size) {
|
||||
requireTask(tenantId, taskId);
|
||||
return repository.pageHistory(tenantId, taskId, page, size);
|
||||
}
|
||||
|
||||
private FulfillmentTaskEntity requireTask(long tenantId, long taskId) {
|
||||
FulfillmentTaskEntity task = repository.findOwned(tenantId, taskId);
|
||||
if (task == null) {
|
||||
throw notFound();
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
private BizException notFound() {
|
||||
return new BizException(ResultCode.NOT_FOUND, "头程履约任务不存在");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ CREATE TABLE IF NOT EXISTS fl_fulfillment_task (
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_task_tenant_order (tenant_id, order_id),
|
||||
KEY idx_task_tenant_created (tenant_id, created_at),
|
||||
KEY idx_task_assignee_status (tenant_id, assignee_id, status, created_at)
|
||||
) ENGINE=InnoDB COMMENT='头程履约任务表:接收订单事件后形成独立履约任务,管理指派、执行和完成状态';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user