|
|
@@ -2,6 +2,7 @@ package com.huimv.employment.controller.mcp;
|
|
2
|
2
|
|
|
3
|
3
|
import com.huimv.employment.common.web.R;
|
|
4
|
4
|
import com.huimv.employment.service.draft.McpDraftService;
|
|
|
5
|
+import com.huimv.employment.service.draft.dto.McpDraftCalculateRequest;
|
|
5
|
6
|
import com.huimv.employment.service.draft.dto.McpDraftCalculateResponse;
|
|
6
|
7
|
import com.huimv.employment.service.draft.dto.McpDraftGenerateRequest;
|
|
7
|
8
|
import com.huimv.employment.service.draft.dto.McpDraftGenerateResponse;
|
|
|
@@ -19,25 +20,22 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|
19
|
20
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
20
|
21
|
import org.springframework.web.bind.annotation.PutMapping;
|
|
21
|
22
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
22
|
|
-import org.springframework.web.bind.annotation.RequestHeader;
|
|
23
|
23
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
24
|
+import org.springframework.web.bind.annotation.RequestParam;
|
|
24
|
25
|
import org.springframework.web.bind.annotation.RestController;
|
|
25
|
26
|
|
|
26
|
27
|
/**
|
|
27
|
28
|
* MCP 草稿接口(交互规则 v2 §6.3)。
|
|
28
|
29
|
* <p>
|
|
29
|
|
- * 通过 {@code X-Session-Id} + {@code X-Agent-Id} 自动关联会话与草稿,Agent 无需传递 draft_id。
|
|
|
30
|
+ * 通过请求体/查询参数 {@code session_id}(= conversation_no)自动关联会话与草稿,Agent 无需传递 draft_id。
|
|
30
|
31
|
* 鉴权见 {@code fe.internal.ai-key} 与 {@link com.huimv.employment.security.McpAuthFilter}。
|
|
31
|
32
|
* </p>
|
|
32
|
33
|
*/
|
|
33
|
34
|
@RestController
|
|
34
|
35
|
@RequestMapping("/api/mcp/draft")
|
|
35
|
|
-@Tag(name = "MCP-草稿", description = "智能体草稿 generate/update/info,需 X-Fe-Ai-Key + X-Session-Id")
|
|
|
36
|
+@Tag(name = "MCP-草稿", description = "智能体草稿 generate/update/info,需 X-Fe-Ai-Key + session_id")
|
|
36
|
37
|
public class McpDraftController {
|
|
37
|
38
|
|
|
38
|
|
- public static final String HEADER_SESSION_ID = "X-Session-Id";
|
|
39
|
|
- public static final String HEADER_AGENT_ID = "X-Agent-Id";
|
|
40
|
|
-
|
|
41
|
39
|
private final McpDraftService mcpDraftService;
|
|
42
|
40
|
|
|
43
|
41
|
public McpDraftController(McpDraftService mcpDraftService) {
|
|
|
@@ -48,40 +46,32 @@ public class McpDraftController {
|
|
48
|
46
|
@Operation(summary = "生成初始草稿结构",
|
|
49
|
47
|
description = "后端生成含 Schema、默认值与 missing_fields 的草稿骨架。同会话已有 pending 草稿时幂等返回。",
|
|
50
|
48
|
parameters = {
|
|
51
|
|
- @Parameter(name = HEADER_SESSION_ID, in = ParameterIn.HEADER, required = true,
|
|
52
|
|
- description = "会话标识,与 AI chat session_id / conversation_no 一致"),
|
|
53
|
|
- @Parameter(name = HEADER_AGENT_ID, in = ParameterIn.HEADER,
|
|
54
|
|
- description = "智能体标识,默认 default"),
|
|
55
|
49
|
@Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER,
|
|
56
|
50
|
description = "内网服务密钥")
|
|
57
|
51
|
})
|
|
58
|
|
- public R<McpDraftGenerateResponse> generate(
|
|
59
|
|
- @RequestHeader(HEADER_SESSION_ID) String sessionId,
|
|
60
|
|
- @Validated @RequestBody McpDraftGenerateRequest request) {
|
|
61
|
|
- return R.ok(mcpDraftService.generate(sessionId, request));
|
|
|
52
|
+ public R<McpDraftGenerateResponse> generate(@Validated @RequestBody McpDraftGenerateRequest request) {
|
|
|
53
|
+ return R.ok(mcpDraftService.generate(request.getSessionId(), request));
|
|
62
|
54
|
}
|
|
63
|
55
|
|
|
64
|
56
|
@PutMapping("/update")
|
|
65
|
57
|
@Operation(summary = "更新草稿数据",
|
|
66
|
58
|
description = "根据用户回答或画像预填字段;不可编辑时返回 status=ban。",
|
|
67
|
59
|
parameters = {
|
|
68
|
|
- @Parameter(name = HEADER_SESSION_ID, in = ParameterIn.HEADER, required = true),
|
|
69
|
60
|
@Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
|
|
70
|
61
|
})
|
|
71
|
|
- public R<McpDraftUpdateResponse> update(
|
|
72
|
|
- @RequestHeader(HEADER_SESSION_ID) String sessionId,
|
|
73
|
|
- @Validated @RequestBody McpDraftUpdateRequest request) {
|
|
74
|
|
- return R.ok(mcpDraftService.update(sessionId, request));
|
|
|
62
|
+ public R<McpDraftUpdateResponse> update(@Validated @RequestBody McpDraftUpdateRequest request) {
|
|
|
63
|
+ return R.ok(mcpDraftService.update(request.getSessionId(), request));
|
|
75
|
64
|
}
|
|
76
|
65
|
|
|
77
|
66
|
@GetMapping("/info")
|
|
78
|
67
|
@Operation(summary = "获取草稿详情与状态",
|
|
79
|
68
|
description = "返回 status(incomplete/ready/submitted)、data、editable、missing_fields。",
|
|
80
|
69
|
parameters = {
|
|
81
|
|
- @Parameter(name = HEADER_SESSION_ID, in = ParameterIn.HEADER, required = true),
|
|
|
70
|
+ @Parameter(name = "session_id", in = ParameterIn.QUERY, required = true,
|
|
|
71
|
+ description = "会话标识,与 AI chat session_id / conversation_no 一致"),
|
|
82
|
72
|
@Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
|
|
83
|
73
|
})
|
|
84
|
|
- public R<McpDraftInfoResponse> info(@RequestHeader(HEADER_SESSION_ID) String sessionId) {
|
|
|
74
|
+ public R<McpDraftInfoResponse> info(@RequestParam("session_id") String sessionId) {
|
|
85
|
75
|
return R.ok(mcpDraftService.getInfo(sessionId));
|
|
86
|
76
|
}
|
|
87
|
77
|
|
|
|
@@ -89,23 +79,19 @@ public class McpDraftController {
|
|
89
|
79
|
@Operation(summary = "成本测算",
|
|
90
|
80
|
description = "草稿 status=ready 后调用,返回 SCHEME_A/SCHEME_B 多套合规方案。",
|
|
91
|
81
|
parameters = {
|
|
92
|
|
- @Parameter(name = HEADER_SESSION_ID, in = ParameterIn.HEADER, required = true),
|
|
93
|
82
|
@Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
|
|
94
|
83
|
})
|
|
95
|
|
- public R<McpDraftCalculateResponse> calculate(@RequestHeader(HEADER_SESSION_ID) String sessionId) {
|
|
96
|
|
- return R.ok(mcpDraftService.calculate(sessionId));
|
|
|
84
|
+ public R<McpDraftCalculateResponse> calculate(@Validated @RequestBody McpDraftCalculateRequest request) {
|
|
|
85
|
+ return R.ok(mcpDraftService.calculate(request.getSessionId()));
|
|
97
|
86
|
}
|
|
98
|
87
|
|
|
99
|
88
|
@PostMapping("/submit")
|
|
100
|
89
|
@Operation(summary = "确认并提交草稿",
|
|
101
|
90
|
description = "用户选定方案后转化为正式订单,需先调用 calculate。",
|
|
102
|
91
|
parameters = {
|
|
103
|
|
- @Parameter(name = HEADER_SESSION_ID, in = ParameterIn.HEADER, required = true),
|
|
104
|
92
|
@Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
|
|
105
|
93
|
})
|
|
106
|
|
- public R<McpDraftSubmitResponse> submit(
|
|
107
|
|
- @RequestHeader(HEADER_SESSION_ID) String sessionId,
|
|
108
|
|
- @Validated @RequestBody McpDraftSubmitRequest request) {
|
|
109
|
|
- return R.ok(mcpDraftService.submit(sessionId, request));
|
|
|
94
|
+ public R<McpDraftSubmitResponse> submit(@Validated @RequestBody McpDraftSubmitRequest request) {
|
|
|
95
|
+ return R.ok(mcpDraftService.submit(request.getSessionId(), request));
|
|
110
|
96
|
}
|
|
111
|
97
|
}
|