Explorar el Código

feat(ai-q): 控制器 — /api/ai-questionnaire/* 会话与场景端点

Xiaogang Liao hace 2 meses
padre
commit
a2964cb93c

+ 158 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/AiQuestionnaireController.java

@@ -0,0 +1,158 @@
+package com.etotem.cfc.controller;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.AiQProfile;
+import com.etotem.cfc.entity.AiQScene;
+import com.etotem.cfc.entity.AiQSession;
+import com.etotem.cfc.service.AiQuestionnaireService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * AI 动态问卷引擎 — 会话/画像/场景管理
+ */
+@Tag(name = "AI动态问卷引擎", description = "动态问卷引擎:场景管理、会话 start/answer/finish、画像查询")
+@RestController
+@RequestMapping("/api/ai-questionnaire")
+public class AiQuestionnaireController {
+
+    @Resource
+    private AiQuestionnaireService aiQuestionnaireService;
+
+    // ── 场景管理(admin)──
+
+    @Operation(summary = "场景列表")
+    @PostMapping("/scene/list")
+    public Result<List<AiQScene>> sceneList(
+            @RequestBody(required = false) Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+        boolean enabledOnly = params != null && Boolean.TRUE.equals(params.get("enabledOnly"));
+        return Result.success(aiQuestionnaireService.listScenes(enabledOnly));
+    }
+
+    @Operation(summary = "保存场景(admin)")
+    @PostMapping("/scene/save")
+    public Result<AiQScene> sceneSave(
+            @RequestBody AiQScene scene,
+            @RequestAttribute("role") String role,
+            @RequestAttribute("userId") Long userId) {
+        if (!"admin".equals(role)) return Result.error("仅管理员可操作");
+        return Result.success(aiQuestionnaireService.saveScene(scene, userId));
+    }
+
+    @Operation(summary = "删除场景(admin)")
+    @PostMapping("/scene/delete")
+    public Result<Void> sceneDelete(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("role") String role,
+            @RequestAttribute("userId") Long userId) {
+        if (!"admin".equals(role)) return Result.error("仅管理员可操作");
+        Object id = params.get("id");
+        if (id == null) return Result.error("缺少 id");
+        try {
+            aiQuestionnaireService.deleteScene(Long.valueOf(id.toString()), userId);
+            return Result.success(null);
+        } catch (RuntimeException e) {
+            return Result.error(e.getMessage());
+        }
+    }
+
+    // ── 会话 ──
+
+    @Operation(summary = "开始问卷")
+    @PostMapping("/start")
+    public Result<Map<String, Object>> start(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+        Long sceneId = params.get("sceneId") == null ? null : Long.valueOf(params.get("sceneId").toString());
+        Long memberId = params.get("memberId") == null ? null : Long.valueOf(params.get("memberId").toString());
+        if (sceneId == null || memberId == null) return Result.error("缺少 sceneId/memberId");
+        try {
+            return Result.success(aiQuestionnaireService.start(userId, sceneId, memberId));
+        } catch (RuntimeException e) {
+            return Result.error(e.getMessage());
+        }
+    }
+
+    @Operation(summary = "作答")
+    @PostMapping("/answer")
+    public Result<Map<String, Object>> answer(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+        Long sessionId = params.get("sessionId") == null ? null : Long.valueOf(params.get("sessionId").toString());
+        Object answer = params.get("answer");
+        if (sessionId == null || answer == null) return Result.error("缺少 sessionId/answer");
+        try {
+            return Result.success(aiQuestionnaireService.answer(userId, sessionId, String.valueOf(answer)));
+        } catch (RuntimeException e) {
+            return Result.error(e.getMessage());
+        }
+    }
+
+    @Operation(summary = "结束问卷并生成画像")
+    @PostMapping("/finish")
+    public Result<Map<String, Object>> finish(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+        Long sessionId = params.get("sessionId") == null ? null : Long.valueOf(params.get("sessionId").toString());
+        if (sessionId == null) return Result.error("缺少 sessionId");
+        try {
+            AiQProfile profile = aiQuestionnaireService.finish(userId, sessionId);
+            return Result.success(convertProfile(profile));
+        } catch (RuntimeException e) {
+            return Result.error(e.getMessage());
+        }
+    }
+
+    @Operation(summary = "画像详情")
+    @PostMapping("/profile/detail")
+    public Result<Map<String, Object>> profileDetail(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+        Long sessionId = params.get("sessionId") == null ? null : Long.valueOf(params.get("sessionId").toString());
+        if (sessionId == null) return Result.error("缺少 sessionId");
+        try {
+            return Result.success(aiQuestionnaireService.getProfileDetail(userId, sessionId));
+        } catch (RuntimeException e) {
+            return Result.error(e.getMessage());
+        }
+    }
+
+    @Operation(summary = "会话历史")
+    @PostMapping("/history")
+    public Result<List<AiQSession>> history(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+        Long memberId = params.get("memberId") == null ? null : Long.valueOf(params.get("memberId").toString());
+        Long sceneId = params.get("sceneId") == null ? null : Long.valueOf(params.get("sceneId").toString());
+        return Result.success(aiQuestionnaireService.getHistory(userId, memberId, sceneId));
+    }
+
+    @Operation(summary = "中止问卷")
+    @PostMapping("/abort")
+    public Result<Void> abort(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+        Long sessionId = params.get("sessionId") == null ? null : Long.valueOf(params.get("sessionId").toString());
+        if (sessionId == null) return Result.error("缺少 sessionId");
+        aiQuestionnaireService.abort(userId, sessionId);
+        return Result.success(null);
+    }
+
+    private Map<String, Object> convertProfile(AiQProfile profile) {
+        java.util.LinkedHashMap<String, Object> m = new java.util.LinkedHashMap<>();
+        m.put("id", profile.getId());
+        m.put("sessionId", profile.getSessionId());
+        m.put("memberId", profile.getMemberId());
+        m.put("userProfileJson", profile.getUserProfileJson());
+        m.put("needProfileJson", profile.getNeedProfileJson());
+        m.put("kbUsed", profile.getKbUsed());
+        m.put("createdAt", profile.getCreatedAt());
+        return m;
+    }
+}