feat(core): 新增 Feature Ticket 鉴权体系与任务执行接口

This commit is contained in:
2026-02-05 14:42:41 +08:00
parent 89fe1c2f66
commit 553eadfaa6
15 changed files with 794 additions and 4 deletions

View File

@@ -0,0 +1,104 @@
package com.yupi.springbootinit.controller;
import com.yupi.springbootinit.Interceptor.FeatureTicketInterceptor;
import com.yupi.springbootinit.annotation.RequireFeatureTicket;
import com.yupi.springbootinit.common.BaseResponse;
import com.yupi.springbootinit.common.ResultUtils;
import com.yupi.springbootinit.model.dto.ticket.FeatureTicketPayload;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 任务执行控制器(示例)
* 展示如何使用 @RequireFeatureTicket 注解保护接口
*
* @author ziin
*/
@RestController
@RequestMapping("/v1")
@Api(tags = "任务执行(示例)")
public class TaskExecuteController {
private static final Logger log = LoggerFactory.getLogger(TaskExecuteController.class);
/**
* 执行任务接口(受 Feature Ticket 保护)
*
* 调用此接口需要:
* 1. 请求头 X-Feature-Ticket: 有效的 Ticket
* 2. 请求头 X-Machine-Id: 与 Ticket 中一致的设备 ID
*/
@PostMapping("/execute-task")
@RequireFeatureTicket(featureCode = "CRAWL")
@ApiOperation(value = "执行任务", notes = "需要 Feature Ticket 校验,功能代码: CRAWL")
public BaseResponse<Map<String, Object>> executeTask(
@RequestBody Map<String, Object> taskParams,
HttpServletRequest request) {
// 从请求属性中获取已校验的 Ticket 载荷
FeatureTicketPayload payload = (FeatureTicketPayload) request.getAttribute(
FeatureTicketInterceptor.TICKET_PAYLOAD_ATTR);
log.info("执行任务,用户: {}, 租户: {}, 设备: {}",
payload.getUserId(), payload.getTenantId(), payload.getMachineId());
// 业务逻辑处理
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("taskId", System.currentTimeMillis());
result.put("tenantId", payload.getTenantId());
result.put("userId", payload.getUserId());
result.put("message", "任务已提交执行");
return ResultUtils.success(result);
}
/**
* 另一个受保护的接口示例(不限定功能代码)
*
* 只校验 Ticket 有效性和设备 ID不校验功能代码
*/
@PostMapping("/query-status")
@RequireFeatureTicket
@ApiOperation(value = "查询状态", notes = "需要 Feature Ticket 校验,不限定功能代码")
public BaseResponse<Map<String, Object>> queryStatus(HttpServletRequest request) {
FeatureTicketPayload payload = (FeatureTicketPayload) request.getAttribute(
FeatureTicketInterceptor.TICKET_PAYLOAD_ATTR);
Map<String, Object> result = new HashMap<>();
result.put("status", "running");
result.put("featureCode", payload.getFeatureCode());
result.put("tenantId", payload.getTenantId());
return ResultUtils.success(result);
}
/**
* 自定义请求头名称的示例
*/
@PostMapping("/custom-header-task")
@RequireFeatureTicket(
featureCode = "AI_CHAT",
ticketHeader = "Authorization-Ticket",
machineIdHeader = "Device-Id"
)
@ApiOperation(value = "自定义请求头任务", notes = "使用自定义请求头名称")
public BaseResponse<String> customHeaderTask(HttpServletRequest request) {
FeatureTicketPayload payload = (FeatureTicketPayload) request.getAttribute(
FeatureTicketInterceptor.TICKET_PAYLOAD_ATTR);
return ResultUtils.success("任务执行成功,用户: " + payload.getUserId());
}
}