Kaynağa Gözat

增加与ai大模型对话

wwh 2 hafta önce
ebeveyn
işleme
1f667bcc0f

+ 16 - 10
huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mcp/McpDraftController.java

@@ -27,13 +27,14 @@ import org.springframework.web.bind.annotation.RestController;
27 27
 /**
28 28
  * MCP 草稿接口(交互规则 v2 §6.3)。
29 29
  * <p>
30
- * 通过请求体/查询参数 {@code session_id}(= conversation_no)自动关联会话与草稿,Agent 无需传递 draft_id。
30
+ * generate 通过 session_id 创建/复用草稿并返回 draft_id;
31
+ * update/info/calculate/submit 须同时传入 session_id 与 draft_id。
31 32
  * 鉴权见 {@code fe.internal.ai-key} 与 {@link com.huimv.employment.security.McpAuthFilter}。
32 33
  * </p>
33 34
  */
34 35
 @RestController
35 36
 @RequestMapping("/api/mcp/draft")
36
-@Tag(name = "MCP-草稿", description = "智能体草稿 generate/update/info,需 X-Fe-Ai-Key + session_id")
37
+@Tag(name = "MCP-草稿", description = "智能体草稿 generate/update/info/calculate/submit,需 X-Fe-Ai-Key + session_id;后四者另需 draft_id")
37 38
 public class McpDraftController {
38 39
 
39 40
     private final McpDraftService mcpDraftService;
@@ -44,7 +45,8 @@ public class McpDraftController {
44 45
 
45 46
     @PostMapping("/generate")
46 47
     @Operation(summary = "生成初始草稿结构",
47
-            description = "后端生成含 Schema、默认值与 missing_fields 的草稿骨架。同会话已有 pending 草稿时幂等返回。",
48
+            description = "后端生成含 Schema、默认值与 missing_fields 的草稿骨架,返回 draft_id。"
49
+                    + "同会话已有 pending 草稿时幂等返回。",
48 50
             parameters = {
49 51
                     @Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER,
50 52
                             description = "内网服务密钥")
@@ -55,7 +57,7 @@ public class McpDraftController {
55 57
 
56 58
     @PutMapping("/update")
57 59
     @Operation(summary = "更新草稿数据",
58
-            description = "根据用户回答或画像预填字段;不可编辑时返回 status=ban。",
60
+            description = "根据用户回答或画像预填字段;须传 draft_id;不可编辑时返回 status=ban。",
59 61
             parameters = {
60 62
                     @Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
61 63
             })
@@ -65,31 +67,35 @@ public class McpDraftController {
65 67
 
66 68
     @GetMapping("/info")
67 69
     @Operation(summary = "获取草稿详情与状态",
68
-            description = "返回 status(incomplete/ready/submitted)、data、editable、missing_fields。",
70
+            description = "返回 draft_id、status(incomplete/ready/submitted)、data、editable、missing_fields。",
69 71
             parameters = {
70 72
                     @Parameter(name = "session_id", in = ParameterIn.QUERY, required = true,
71 73
                             description = "会话标识,与 AI chat session_id / conversation_no 一致"),
74
+                    @Parameter(name = "draft_id", in = ParameterIn.QUERY, required = true,
75
+                            description = "草稿 ID(generate 返回)"),
72 76
                     @Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
73 77
             })
74
-    public R<McpDraftInfoResponse> info(@RequestParam("session_id") String sessionId) {
75
-        return R.ok(mcpDraftService.getInfo(sessionId));
78
+    public R<McpDraftInfoResponse> info(@RequestParam("session_id") String sessionId,
79
+                                        @RequestParam("draft_id") Long draftId) {
80
+        return R.ok(mcpDraftService.getInfo(sessionId, draftId));
76 81
     }
77 82
 
78 83
     @PostMapping("/calculate")
79 84
     @Operation(summary = "成本测算",
80
-            description = "当前会话草稿就绪后调用。"
85
+            description = "须传 draft_id;草稿就绪后测算。"
81 86
                     + "按 fe_service_plan(status=active,排除 current)及 fe_service_plan_fee_rule 预置规则测算,"
82 87
                     + "返回成本方案列表(如 SCHEME_A / SCHEME_B),并落库 fe_draft_cost_snapshot。",
83 88
             parameters = {
84 89
                     @Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
85 90
             })
86 91
     public R<McpDraftCalculateResponse> calculate(@Validated @RequestBody McpDraftCalculateRequest request) {
87
-        return R.ok(mcpDraftService.calculate(request.getSessionId()));
92
+        return R.ok(mcpDraftService.calculate(request.getSessionId(), request.getDraftId()));
88 93
     }
89 94
 
90 95
     @PostMapping("/submit")
91 96
     @Operation(summary = "确认并提交草稿",
92
-            description = "用户选定方案后转化为正式订单,并创建登记批次、立刻生成小程序码(fe_registration_batch.qr_code_url)。需先调用 calculate。",
97
+            description = "须传 draft_id;用户选定方案后转化为正式订单,并创建登记批次、立刻生成小程序码。"
98
+                    + "需先调用 calculate。",
93 99
             parameters = {
94 100
                     @Parameter(name = "X-Fe-Ai-Key", in = ParameterIn.HEADER)
95 101
             })

+ 3 - 1
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/DraftService.java

@@ -168,7 +168,9 @@ public class DraftService {
168 168
         List<DraftCostCalculationEngine.CalculatedScheme> schemes = draftCostCalculationEngine.calculate(draft);
169 169
         persistCostSnapshots(draft, schemes);
170 170
         updateDraftEstimates(draft, schemes, LocalDateTime.now());
171
-        return draftCostCalculationEngine.toApiResponse(schemes);
171
+        McpDraftCalculateResponse response = draftCostCalculationEngine.toApiResponse(schemes);
172
+        response.setDraftId(draft.getId());
173
+        return response;
172 174
     }
173 175
 
174 176
     /**

+ 42 - 33
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/McpDraftService.java

@@ -48,7 +48,7 @@ import java.util.UUID;
48 48
 
49 49
 /**
50 50
  * MCP 草稿接口业务(对齐交互规则 v2 §6.3)。
51
- * <p>通过 {@code X-Session-Id}(= conversation_no)自动关联会话与草稿,Agent 无需传递 draft_id。</p>
51
+ * <p>通过 session_id 关联会话;update/info/calculate/submit 须传入 draft_id,并校验草稿归属当前会话。</p>
52 52
  */
53 53
 @Service
54 54
 public class McpDraftService {
@@ -134,9 +134,9 @@ public class McpDraftService {
134 134
     @Transactional(rollbackFor = Exception.class)
135 135
     public McpDraftUpdateResponse update(String sessionId, McpDraftUpdateRequest request) {
136 136
         FeConversation conversation = conversationService.requireBySessionId(sessionId);
137
-        FeEmploymentDraft draft = requirePendingDraft(conversation.getId());
137
+        FeEmploymentDraft draft = requireDraftInConversation(conversation.getId(), request.getDraftId());
138 138
         if (!isDbEditable(draft)) {
139
-            return banResponse();
139
+            return banResponse(draft.getId());
140 140
         }
141 141
         try {
142 142
             LocalDateTime now = LocalDateTime.now();
@@ -145,38 +145,39 @@ public class McpDraftService {
145 145
             feEmploymentDraftMapper.updateById(draft);
146 146
             syncFieldMetadata(draft.getId(), updatedKeys, draft, now, SOURCE_AI_INFERRED);
147 147
             recalculateMissingFields(draft, now);
148
-            return successResponse();
148
+            return successResponse(draft.getId());
149 149
         } catch (BizException ex) {
150
-            log.debug("MCP 草稿更新失败 sessionId={}: {}", sessionId, ex.getMessage());
150
+            log.debug("MCP 草稿更新失败 sessionId={} draftId={}: {}",
151
+                    sessionId, request.getDraftId(), ex.getMessage());
151 152
             McpDraftUpdateResponse response = new McpDraftUpdateResponse();
153
+            response.setDraftId(request.getDraftId());
152 154
             response.setStatus(MCP_UPDATE_FAIL);
153 155
             return response;
154 156
         }
155 157
     }
156 158
 
157
-    public McpDraftInfoResponse getInfo(String sessionId) {
159
+    public McpDraftInfoResponse getInfo(String sessionId, Long draftId) {
158 160
         FeConversation conversation = conversationService.requireBySessionId(sessionId);
159
-        FeEmploymentDraft draft = findLatestDraft(conversation.getId());
160
-        if (draft == null) {
161
-            throw new BizException(ErrorCode.NOT_FOUND, "当前会话暂无草稿,请先调用 generate");
162
-        }
161
+        FeEmploymentDraft draft = requireDraftInConversation(conversation.getId(), draftId);
163 162
         return toInfoResponse(draft);
164 163
     }
165 164
 
166 165
     @Transactional(rollbackFor = Exception.class)
167
-    public McpDraftCalculateResponse calculate(String sessionId) {
166
+    public McpDraftCalculateResponse calculate(String sessionId, Long draftId) {
168 167
         FeConversation conversation = conversationService.requireBySessionId(sessionId);
169
-        FeEmploymentDraft draft = requireReadyDraft(conversation.getId());
168
+        FeEmploymentDraft draft = requireReadyDraft(conversation.getId(), draftId);
170 169
         List<DraftCostCalculationEngine.CalculatedScheme> schemes = draftCostCalculationEngine.calculate(draft);
171 170
         persistCostSnapshots(draft, schemes);
172 171
         updateDraftEstimates(draft, schemes, LocalDateTime.now());
173
-        return draftCostCalculationEngine.toApiResponse(schemes);
172
+        McpDraftCalculateResponse response = draftCostCalculationEngine.toApiResponse(schemes);
173
+        response.setDraftId(draft.getId());
174
+        return response;
174 175
     }
175 176
 
176 177
     @Transactional(rollbackFor = Exception.class)
177 178
     public McpDraftSubmitResponse submit(String sessionId, McpDraftSubmitRequest request) {
178 179
         FeConversation conversation = conversationService.requireBySessionId(sessionId);
179
-        FeEmploymentDraft draft = requireReadyDraft(conversation.getId());
180
+        FeEmploymentDraft draft = requireReadyDraft(conversation.getId(), request.getDraftId());
180 181
         String schemeCode = request.getSelectedSchemeCode().trim().toUpperCase();
181 182
         if (!draftCostCalculationEngine.isAllowedSchemeCode(schemeCode)) {
182 183
             throw new BizException(ErrorCode.BAD_REQUEST, "不支持的方案编码:" + request.getSelectedSchemeCode());
@@ -210,14 +211,34 @@ public class McpDraftService {
210 211
         FeRegistrationBatch batch = registrationBatchService.createForOrder(order, draft, now);
211 212
 
212 213
         McpDraftSubmitResponse response = new McpDraftSubmitResponse();
214
+        response.setDraftId(draft.getId());
213 215
         response.setStatus(SUBMIT_SUCCESS);
214 216
         response.setOrderId(order.getOrderNo());
215 217
         response.setBatchId(batch.getBatchNo());
216 218
         return response;
217 219
     }
218 220
 
219
-    private FeEmploymentDraft requireReadyDraft(Long conversationId) {
220
-        FeEmploymentDraft draft = requirePendingDraft(conversationId);
221
+    private FeEmploymentDraft requireDraftInConversation(Long conversationId, Long draftId) {
222
+        if (draftId == null) {
223
+            throw new BizException(ErrorCode.BAD_REQUEST, "draft_id 不能为空");
224
+        }
225
+        FeEmploymentDraft draft = feEmploymentDraftMapper.selectById(draftId);
226
+        if (draft == null || !conversationId.equals(draft.getConversationId())) {
227
+            throw new BizException(ErrorCode.NOT_FOUND, "草稿不存在或不属于当前会话");
228
+        }
229
+        return draft;
230
+    }
231
+
232
+    private FeEmploymentDraft requirePendingDraft(Long conversationId, Long draftId) {
233
+        FeEmploymentDraft draft = requireDraftInConversation(conversationId, draftId);
234
+        if (!DB_STATUS_PENDING.equals(draft.getStatus())) {
235
+            throw new BizException(ErrorCode.BAD_REQUEST, "草稿已提交,不可继续操作");
236
+        }
237
+        return draft;
238
+    }
239
+
240
+    private FeEmploymentDraft requireReadyDraft(Long conversationId, Long draftId) {
241
+        FeEmploymentDraft draft = requirePendingDraft(conversationId, draftId);
221 242
         List<String> missing = parseMissingFields(draft.getMissingFields());
222 243
         if (!missing.isEmpty()) {
223 244
             throw new BizException(ErrorCode.BAD_REQUEST,
@@ -371,21 +392,6 @@ public class McpDraftService {
371 392
                 .last("LIMIT 1"));
372 393
     }
373 394
 
374
-    private FeEmploymentDraft findLatestDraft(Long conversationId) {
375
-        return feEmploymentDraftMapper.selectOne(new LambdaQueryWrapper<FeEmploymentDraft>()
376
-                .eq(FeEmploymentDraft::getConversationId, conversationId)
377
-                .orderByDesc(FeEmploymentDraft::getCreateTime)
378
-                .last("LIMIT 1"));
379
-    }
380
-
381
-    private FeEmploymentDraft requirePendingDraft(Long conversationId) {
382
-        FeEmploymentDraft draft = findPendingDraft(conversationId);
383
-        if (draft == null) {
384
-            throw new BizException(ErrorCode.NOT_FOUND, "当前会话暂无待完善草稿,请先调用 generate");
385
-        }
386
-        return draft;
387
-    }
388
-
389 395
     private Set<String> applyMcpFields(FeEmploymentDraft draft, Map<String, Object> fields) {
390 396
         if (fields == null || fields.isEmpty()) {
391 397
             throw new BizException(ErrorCode.BAD_REQUEST, "fields 不能为空");
@@ -510,6 +516,7 @@ public class McpDraftService {
510 516
         List<String> missing = parseMissingFields(draft.getMissingFields());
511 517
         boolean editable = isDbEditable(draft);
512 518
         McpDraftInfoResponse response = new McpDraftInfoResponse();
519
+        response.setDraftId(draft.getId());
513 520
         response.setData(toDataMap(draft));
514 521
         response.setMissingFields(missing);
515 522
         response.setEditable(editable);
@@ -552,14 +559,16 @@ public class McpDraftService {
552 559
         return DB_STATUS_PENDING.equals(draft.getStatus());
553 560
     }
554 561
 
555
-    private McpDraftUpdateResponse successResponse() {
562
+    private McpDraftUpdateResponse successResponse(Long draftId) {
556 563
         McpDraftUpdateResponse response = new McpDraftUpdateResponse();
564
+        response.setDraftId(draftId);
557 565
         response.setStatus(MCP_UPDATE_SUCCESS);
558 566
         return response;
559 567
     }
560 568
 
561
-    private McpDraftUpdateResponse banResponse() {
569
+    private McpDraftUpdateResponse banResponse(Long draftId) {
562 570
         McpDraftUpdateResponse response = new McpDraftUpdateResponse();
571
+        response.setDraftId(draftId);
563 572
         response.setStatus(MCP_UPDATE_BAN);
564 573
         return response;
565 574
     }

+ 14 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftCalculateRequest.java

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
4 4
 import io.swagger.v3.oas.annotations.media.Schema;
5 5
 
6 6
 import javax.validation.constraints.NotBlank;
7
+import javax.validation.constraints.NotNull;
7 8
 
8 9
 @Schema(description = "MCP 成本测算请求")
9 10
 public class McpDraftCalculateRequest {
@@ -14,6 +15,11 @@ public class McpDraftCalculateRequest {
14 15
             example = "a1b2c3d4e5f6", requiredMode = Schema.RequiredMode.REQUIRED)
15 16
     private String sessionId;
16 17
 
18
+    @NotNull(message = "draft_id 不能为空")
19
+    @JsonProperty("draft_id")
20
+    @Schema(description = "草稿 ID(generate 返回)", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
21
+    private Long draftId;
22
+
17 23
     public String getSessionId() {
18 24
         return sessionId;
19 25
     }
@@ -21,4 +27,12 @@ public class McpDraftCalculateRequest {
21 27
     public void setSessionId(String sessionId) {
22 28
         this.sessionId = sessionId;
23 29
     }
30
+
31
+    public Long getDraftId() {
32
+        return draftId;
33
+    }
34
+
35
+    public void setDraftId(Long draftId) {
36
+        this.draftId = draftId;
37
+    }
24 38
 }

+ 13 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftCalculateResponse.java

@@ -1,5 +1,6 @@
1 1
 package com.huimv.employment.service.draft.dto;
2 2
 
3
+import com.fasterxml.jackson.annotation.JsonProperty;
3 4
 import io.swagger.v3.oas.annotations.media.Schema;
4 5
 
5 6
 import java.util.ArrayList;
@@ -8,9 +9,21 @@ import java.util.List;
8 9
 @Schema(description = "MCP 成本测算响应(v2 §6.3.4)")
9 10
 public class McpDraftCalculateResponse {
10 11
 
12
+    @JsonProperty("draft_id")
13
+    @Schema(description = "草稿 ID")
14
+    private Long draftId;
15
+
11 16
     @Schema(description = "合规方案列表")
12 17
     private List<McpDraftSchemeResponse> schemes = new ArrayList<>();
13 18
 
19
+    public Long getDraftId() {
20
+        return draftId;
21
+    }
22
+
23
+    public void setDraftId(Long draftId) {
24
+        this.draftId = draftId;
25
+    }
26
+
14 27
     public List<McpDraftSchemeResponse> getSchemes() {
15 28
         return schemes;
16 29
     }

+ 2 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftGenerateResponse.java

@@ -1,5 +1,6 @@
1 1
 package com.huimv.employment.service.draft.dto;
2 2
 
3
+import com.fasterxml.jackson.annotation.JsonProperty;
3 4
 import io.swagger.v3.oas.annotations.media.Schema;
4 5
 
5 6
 import java.util.List;
@@ -7,6 +8,7 @@ import java.util.List;
7 8
 @Schema(description = "MCP 生成初始草稿响应")
8 9
 public class McpDraftGenerateResponse {
9 10
 
11
+    @JsonProperty("draft_id")
10 12
     @Schema(description = "草稿 ID")
11 13
     private Long draftId;
12 14
 

+ 13 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftInfoResponse.java

@@ -1,5 +1,6 @@
1 1
 package com.huimv.employment.service.draft.dto;
2 2
 
3
+import com.fasterxml.jackson.annotation.JsonProperty;
3 4
 import io.swagger.v3.oas.annotations.media.Schema;
4 5
 
5 6
 import java.util.List;
@@ -8,6 +9,10 @@ import java.util.Map;
8 9
 @Schema(description = "MCP 草稿详情与状态")
9 10
 public class McpDraftInfoResponse {
10 11
 
12
+    @JsonProperty("draft_id")
13
+    @Schema(description = "草稿 ID")
14
+    private Long draftId;
15
+
11 16
     @Schema(description = "草稿状态:incomplete / ready / submitted", example = "incomplete")
12 17
     private String status;
13 18
 
@@ -20,6 +25,14 @@ public class McpDraftInfoResponse {
20 25
     @Schema(description = "待补充字段")
21 26
     private List<String> missingFields;
22 27
 
28
+    public Long getDraftId() {
29
+        return draftId;
30
+    }
31
+
32
+    public void setDraftId(Long draftId) {
33
+        this.draftId = draftId;
34
+    }
35
+
23 36
     public String getStatus() {
24 37
         return status;
25 38
     }

+ 14 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftSubmitRequest.java

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
4 4
 import io.swagger.v3.oas.annotations.media.Schema;
5 5
 
6 6
 import javax.validation.constraints.NotBlank;
7
+import javax.validation.constraints.NotNull;
7 8
 
8 9
 @Schema(description = "MCP 确认提交草稿请求(v2 §6.3.5)")
9 10
 public class McpDraftSubmitRequest {
@@ -14,6 +15,11 @@ public class McpDraftSubmitRequest {
14 15
             example = "a1b2c3d4e5f6", requiredMode = Schema.RequiredMode.REQUIRED)
15 16
     private String sessionId;
16 17
 
18
+    @NotNull(message = "draft_id 不能为空")
19
+    @JsonProperty("draft_id")
20
+    @Schema(description = "草稿 ID(generate 返回)", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
21
+    private Long draftId;
22
+
17 23
     @NotBlank(message = "selected_scheme_code 不能为空")
18 24
     @JsonProperty("selected_scheme_code")
19 25
     @Schema(description = "用户选定的方案编码", example = "SCHEME_A", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -27,6 +33,14 @@ public class McpDraftSubmitRequest {
27 33
         this.sessionId = sessionId;
28 34
     }
29 35
 
36
+    public Long getDraftId() {
37
+        return draftId;
38
+    }
39
+
40
+    public void setDraftId(Long draftId) {
41
+        this.draftId = draftId;
42
+    }
43
+
30 44
     public String getSelectedSchemeCode() {
31 45
         return selectedSchemeCode;
32 46
     }

+ 12 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftSubmitResponse.java

@@ -6,6 +6,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
6 6
 @Schema(description = "MCP 确认提交草稿响应(v2 §6.3.5)")
7 7
 public class McpDraftSubmitResponse {
8 8
 
9
+    @JsonProperty("draft_id")
10
+    @Schema(description = "草稿 ID")
11
+    private Long draftId;
12
+
9 13
     @Schema(description = "提交结果", example = "success")
10 14
     private String status;
11 15
 
@@ -25,6 +29,14 @@ public class McpDraftSubmitResponse {
25 29
     @Schema(description = "小程序码图片 URL")
26 30
     private String qrCodeUrl;
27 31
 
32
+    public Long getDraftId() {
33
+        return draftId;
34
+    }
35
+
36
+    public void setDraftId(Long draftId) {
37
+        this.draftId = draftId;
38
+    }
39
+
28 40
     public String getStatus() {
29 41
         return status;
30 42
     }

+ 14 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftUpdateRequest.java

@@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
5 5
 
6 6
 import javax.validation.constraints.NotBlank;
7 7
 import javax.validation.constraints.NotEmpty;
8
+import javax.validation.constraints.NotNull;
8 9
 import java.util.Map;
9 10
 
10 11
 @Schema(description = "MCP 更新草稿请求")
@@ -16,6 +17,11 @@ public class McpDraftUpdateRequest {
16 17
             example = "a1b2c3d4e5f6", requiredMode = Schema.RequiredMode.REQUIRED)
17 18
     private String sessionId;
18 19
 
20
+    @NotNull(message = "draft_id 不能为空")
21
+    @JsonProperty("draft_id")
22
+    @Schema(description = "草稿 ID(generate 返回)", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
23
+    private Long draftId;
24
+
19 25
     @Schema(description = "待更新字段(snake_case 键名)", requiredMode = Schema.RequiredMode.REQUIRED,
20 26
             example = "{\"worker_count\": 10, \"total_amount\": 3000}")
21 27
     @NotEmpty(message = "fields 不能为空")
@@ -29,6 +35,14 @@ public class McpDraftUpdateRequest {
29 35
         this.sessionId = sessionId;
30 36
     }
31 37
 
38
+    public Long getDraftId() {
39
+        return draftId;
40
+    }
41
+
42
+    public void setDraftId(Long draftId) {
43
+        this.draftId = draftId;
44
+    }
45
+
32 46
     public Map<String, Object> getFields() {
33 47
         return fields;
34 48
     }

+ 13 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/dto/McpDraftUpdateResponse.java

@@ -1,13 +1,26 @@
1 1
 package com.huimv.employment.service.draft.dto;
2 2
 
3
+import com.fasterxml.jackson.annotation.JsonProperty;
3 4
 import io.swagger.v3.oas.annotations.media.Schema;
4 5
 
5 6
 @Schema(description = "MCP 更新草稿响应")
6 7
 public class McpDraftUpdateResponse {
7 8
 
9
+    @JsonProperty("draft_id")
10
+    @Schema(description = "草稿 ID")
11
+    private Long draftId;
12
+
8 13
     @Schema(description = "更新结果:success / fail / ban", example = "success")
9 14
     private String status;
10 15
 
16
+    public Long getDraftId() {
17
+        return draftId;
18
+    }
19
+
20
+    public void setDraftId(Long draftId) {
21
+        this.draftId = draftId;
22
+    }
23
+
11 24
     public String getStatus() {
12 25
         return status;
13 26
     }