Selaa lähdekoodia

增加与ai大模型对话

wwh 2 viikkoa sitten
vanhempi
commit
95f717967b

+ 21 - 1
huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mp/ConversationController.java

@@ -13,6 +13,8 @@ import com.huimv.employment.service.conversation.dto.ConversationChatRequest;
13 13
 import com.huimv.employment.service.conversation.dto.ConversationCreateRequest;
14 14
 import com.huimv.employment.service.conversation.dto.ConversationMessagePageResponse;
15 15
 import com.huimv.employment.service.conversation.dto.ConversationSummaryResponse;
16
+import com.huimv.employment.service.draft.DraftService;
17
+import com.huimv.employment.service.draft.dto.McpDraftCalculateResponse;
16 18
 import io.swagger.v3.oas.annotations.Operation;
17 19
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
18 20
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -54,13 +56,16 @@ public class ConversationController {
54 56
     private final ConversationService conversationService;
55 57
     private final ConversationChatService conversationChatService;
56 58
     private final ConversationMessageService conversationMessageService;
59
+    private final DraftService draftService;
57 60
 
58 61
     public ConversationController(ConversationService conversationService,
59 62
                                   ConversationChatService conversationChatService,
60
-                                  ConversationMessageService conversationMessageService) {
63
+                                  ConversationMessageService conversationMessageService,
64
+                                  DraftService draftService) {
61 65
         this.conversationService = conversationService;
62 66
         this.conversationChatService = conversationChatService;
63 67
         this.conversationMessageService = conversationMessageService;
68
+        this.draftService = draftService;
64 69
     }
65 70
 
66 71
     /**
@@ -106,6 +111,21 @@ public class ConversationController {
106 111
                 loginUser.getUserId(), conversationId, page, size));
107 112
     }
108 113
 
114
+    /**
115
+     * 查询指定会话下全部草稿的成本测算(方案对比)。
116
+     */
117
+    @GetMapping("/{id}/drafts/cost-comparison")
118
+    @Operation(summary = "按会话查询全部草稿成本测算",
119
+            description = "返回该会话下可测算草稿的方案对比列表;"
120
+                    + "每个元素结构与 GET /api/v1/mp/drafts/{id}/cost-comparison 一致(含 draft_id、schemes)。"
121
+                    + "字段不完整无法测算的草稿自动跳过。仅可查询本企业用户自己的会话。")
122
+    public R<List<McpDraftCalculateResponse>> listDraftCostComparisons(
123
+            @PathVariable("id") Long conversationId) {
124
+        LoginUser loginUser = requireEnterprise();
125
+        return R.ok(draftService.listCostComparisonsByConversation(
126
+                loginUser.getUserId(), conversationId));
127
+    }
128
+
109 129
     /**
110 130
      * 在已有会话内发起 AI 对话(SSE 流式,流结束后落库)。
111 131
      */

+ 45 - 0
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/draft/DraftService.java

@@ -24,6 +24,7 @@ import com.huimv.employment.service.draft.dto.DraftFieldResponse;
24 24
 import com.huimv.employment.service.draft.dto.DraftUpdateRequest;
25 25
 import com.huimv.employment.service.draft.dto.McpDraftCalculateResponse;
26 26
 import com.huimv.employment.service.enterprise.EnterpriseService;
27
+import com.huimv.employment.service.conversation.ConversationService;
27 28
 import com.huimv.employment.service.registration.RegistrationBatchService;
28 29
 import org.springframework.dao.DuplicateKeyException;
29 30
 import org.springframework.stereotype.Service;
@@ -32,6 +33,7 @@ import org.springframework.util.StringUtils;
32 33
 
33 34
 import java.time.LocalDate;
34 35
 import java.time.LocalDateTime;
36
+import java.util.ArrayList;
35 37
 import java.util.Arrays;
36 38
 import java.util.Collections;
37 39
 import java.util.HashMap;
@@ -81,6 +83,7 @@ public class DraftService {
81 83
     private final FeEmploymentOrderMapper feEmploymentOrderMapper;
82 84
     private final FeRegistrationBatchMapper feRegistrationBatchMapper;
83 85
     private final EnterpriseService enterpriseService;
86
+    private final ConversationService conversationService;
84 87
     private final DraftCostCalculationEngine draftCostCalculationEngine;
85 88
     private final RegistrationBatchService registrationBatchService;
86 89
     private final ObjectMapper objectMapper;
@@ -91,6 +94,7 @@ public class DraftService {
91 94
                         FeEmploymentOrderMapper feEmploymentOrderMapper,
92 95
                         FeRegistrationBatchMapper feRegistrationBatchMapper,
93 96
                         EnterpriseService enterpriseService,
97
+                        ConversationService conversationService,
94 98
                         DraftCostCalculationEngine draftCostCalculationEngine,
95 99
                         RegistrationBatchService registrationBatchService,
96 100
                         ObjectMapper objectMapper) {
@@ -100,6 +104,7 @@ public class DraftService {
100 104
         this.feEmploymentOrderMapper = feEmploymentOrderMapper;
101 105
         this.feRegistrationBatchMapper = feRegistrationBatchMapper;
102 106
         this.enterpriseService = enterpriseService;
107
+        this.conversationService = conversationService;
103 108
         this.draftCostCalculationEngine = draftCostCalculationEngine;
104 109
         this.registrationBatchService = registrationBatchService;
105 110
         this.objectMapper = objectMapper;
@@ -173,6 +178,46 @@ public class DraftService {
173 178
         return response;
174 179
     }
175 180
 
181
+    /**
182
+     * 按会话查询其下全部草稿的成本测算结果。
183
+     * <p>返回元素结构与 {@link #calculateCostComparison} / {@code GET .../drafts/{id}/cost-comparison} 相同。
184
+     * 字段不足以测算的草稿跳过,不中断整次查询。</p>
185
+     */
186
+    @Transactional(rollbackFor = Exception.class)
187
+    public List<McpDraftCalculateResponse> listCostComparisonsByConversation(Long userId, Long conversationId) {
188
+        conversationService.requireOwned(userId, conversationId);
189
+        FeEnterprise enterprise = enterpriseService.findEnterpriseByUserId(userId);
190
+        if (enterprise == null) {
191
+            throw new BizException(ErrorCode.BAD_REQUEST, "请先完成企业登记");
192
+        }
193
+        List<FeEmploymentDraft> drafts = feEmploymentDraftMapper.selectList(
194
+                new LambdaQueryWrapper<FeEmploymentDraft>()
195
+                        .eq(FeEmploymentDraft::getConversationId, conversationId)
196
+                        .eq(FeEmploymentDraft::getEnterpriseId, enterprise.getId())
197
+                        .orderByAsc(FeEmploymentDraft::getId));
198
+        List<McpDraftCalculateResponse> result = new ArrayList<>();
199
+        if (drafts == null || drafts.isEmpty()) {
200
+            return result;
201
+        }
202
+        LocalDateTime now = LocalDateTime.now();
203
+        for (FeEmploymentDraft draft : drafts) {
204
+            try {
205
+                List<DraftCostCalculationEngine.CalculatedScheme> schemes =
206
+                        draftCostCalculationEngine.calculate(draft);
207
+                if (STATUS_PENDING.equals(draft.getStatus())) {
208
+                    persistCostSnapshots(draft, schemes);
209
+                    updateDraftEstimates(draft, schemes, now);
210
+                }
211
+                McpDraftCalculateResponse response = draftCostCalculationEngine.toApiResponse(schemes);
212
+                response.setDraftId(draft.getId());
213
+                result.add(response);
214
+            } catch (BizException ignored) {
215
+                // 草稿不完整或无法测算时跳过
216
+            }
217
+        }
218
+        return result;
219
+    }
220
+
176 221
     /**
177 222
      * 微信端确认此方案:选定 SCHEME_A/SCHEME_B,转正式订单。
178 223
      * <p>若尚未测算,将自动先测算再确认。</p>