jyc 1 miesiąc temu
rodzic
commit
3bf1b1a8a8

+ 113 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerChatMessageController.java

@@ -0,0 +1,113 @@
+package shop.alien.lawyer.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerChatMessage;
+import shop.alien.lawyer.service.LawyerChatMessageService;
+import shop.alien.util.myBaticsPlus.QueryBuilder;
+
+import java.util.List;
+
+/**
+ * 聊天消息 前端控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"律师平台-聊天消息"})
+@ApiSort(16)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/chatMessage")
+@RequiredArgsConstructor
+public class LawyerChatMessageController {
+
+    private final LawyerChatMessageService chatMessageService;
+
+    @ApiOperation("新增聊天消息")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/addChatMessage")
+    public R<LawyerChatMessage> addChatMessage(@RequestBody LawyerChatMessage chatMessage) {
+        log.info("LawyerChatMessageController.addChatMessage?chatMessage={}", chatMessage);
+        return chatMessageService.addChatMessage(chatMessage);
+    }
+
+    @ApiOperation("编辑聊天消息")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/editChatMessage")
+    public R<LawyerChatMessage> editChatMessage(@RequestBody LawyerChatMessage chatMessage) {
+        log.info("LawyerChatMessageController.editChatMessage?chatMessage={}", chatMessage);
+        return chatMessageService.editChatMessage(chatMessage);
+    }
+
+    @ApiOperation("删除聊天消息")
+    @ApiOperationSupport(order = 3)
+    @DeleteMapping("/deleteChatMessage")
+    public R<Boolean> deleteChatMessage(@RequestParam(value = "id") Integer id) {
+        log.info("LawyerChatMessageController.deleteChatMessage?id={}", id);
+        return chatMessageService.deleteChatMessage(id);
+    }
+
+    @ApiOperation("保存或更新聊天消息")
+    @ApiOperationSupport(order = 4)
+    @PostMapping("/saveOrUpdate")
+    public R<LawyerChatMessage> saveOrUpdate(@RequestBody LawyerChatMessage chatMessage) {
+        log.info("LawyerChatMessageController.saveOrUpdate?chatMessage={}", chatMessage);
+        boolean result = chatMessageService.saveOrUpdate(chatMessage);
+        if (result) {
+            return R.data(chatMessage);
+        }
+        return R.fail("操作失败");
+    }
+
+    @ApiOperation("通用列表查询")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "chatSessionId", value = "聊天会话ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "consultationOrderId", value = "咨询订单ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "senderType", value = "发送者类型", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getList")
+    public R<List<LawyerChatMessage>> getList(@ModelAttribute LawyerChatMessage chatMessage) {
+        log.info("LawyerChatMessageController.getList?chatMessage={}", chatMessage);
+        List<LawyerChatMessage> list = QueryBuilder.of(chatMessage)
+                .build()
+                .list(chatMessageService);
+        return R.data(list);
+    }
+
+    @ApiOperation("通用分页查询")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "页数(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "页容(默认10)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "chatSessionId", value = "聊天会话ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "consultationOrderId", value = "咨询订单ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "senderType", value = "发送者类型", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getPage")
+    public R<IPage<LawyerChatMessage>> getPage(@ModelAttribute LawyerChatMessage chatMessage,
+                                               @RequestParam(defaultValue = "1") int page,
+                                               @RequestParam(defaultValue = "10") int size) {
+        log.info("LawyerChatMessageController.getPage?chatMessage={},page={},size={}", chatMessage, page, size);
+        int pageNum = page > 0 ? page : 1;
+        int pageSize = size > 0 ? size : 10;
+        IPage<LawyerChatMessage> pageResult = QueryBuilder.of(chatMessage)
+                .page(pageNum, pageSize)
+                .build()
+                .page(chatMessageService);
+        return R.data(pageResult);
+    }
+}
+

+ 178 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerChatSessionController.java

@@ -0,0 +1,178 @@
+package shop.alien.lawyer.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerChatSession;
+import shop.alien.lawyer.service.LawyerChatSessionService;
+import shop.alien.util.myBaticsPlus.QueryBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 聊天会话 前端控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"律师平台-聊天会话"})
+@ApiSort(15)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/chatSession")
+@RequiredArgsConstructor
+public class LawyerChatSessionController {
+
+    private final LawyerChatSessionService chatSessionService;
+
+    @ApiOperation("新增聊天会话")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/addChatSession")
+    public R<LawyerChatSession> addChatSession(@RequestBody LawyerChatSession chatSession) {
+        log.info("LawyerChatSessionController.addChatSession?chatSession={}", chatSession);
+        return chatSessionService.addChatSession(chatSession);
+    }
+
+    @ApiOperation("编辑聊天会话")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/editChatSession")
+    public R<LawyerChatSession> editChatSession(@RequestBody LawyerChatSession chatSession) {
+        log.info("LawyerChatSessionController.editChatSession?chatSession={}", chatSession);
+        return chatSessionService.editChatSession(chatSession);
+    }
+
+    @ApiOperation("删除聊天会话")
+    @ApiOperationSupport(order = 3)
+    @DeleteMapping("/deleteChatSession")
+    public R<Boolean> deleteChatSession(@RequestParam(value = "id") Integer id) {
+        log.info("LawyerChatSessionController.deleteChatSession?id={}", id);
+        return chatSessionService.deleteChatSession(id);
+    }
+
+    @ApiOperation("保存或更新聊天会话")
+    @ApiOperationSupport(order = 4)
+    @PostMapping("/saveOrUpdate")
+    public R<LawyerChatSession> saveOrUpdate(@RequestBody LawyerChatSession chatSession) {
+        log.info("LawyerChatSessionController.saveOrUpdate?chatSession={}", chatSession);
+        boolean result = chatSessionService.saveOrUpdate(chatSession);
+        if (result) {
+            return R.data(chatSession);
+        }
+        return R.fail("操作失败");
+    }
+
+    @ApiOperation("通用列表查询")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "consultationOrderId", value = "咨询订单ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "clientUserId", value = "客户端用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "status", value = "会话状态", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getList")
+    public R<List<LawyerChatSession>> getList(@ModelAttribute LawyerChatSession chatSession) {
+        log.info("LawyerChatSessionController.getList?chatSession={}", chatSession);
+        List<LawyerChatSession> list = QueryBuilder.of(chatSession)
+                .build()
+                .list(chatSessionService);
+        return R.data(list);
+    }
+
+    @ApiOperation("通用分页查询")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "页数(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "页容(默认10)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "consultationOrderId", value = "咨询订单ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "clientUserId", value = "客户端用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "status", value = "会话状态", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getPage")
+    public R<IPage<LawyerChatSession>> getPage(@ModelAttribute LawyerChatSession chatSession,
+                                              @RequestParam(defaultValue = "1") int page,
+                                              @RequestParam(defaultValue = "10") int size) {
+        log.info("LawyerChatSessionController.getPage?chatSession={},page={},size={}", chatSession, page, size);
+        int pageNum = page > 0 ? page : 1;
+        int pageSize = size > 0 ? size : 10;
+        IPage<LawyerChatSession> pageResult = QueryBuilder.of(chatSession)
+                .page(pageNum, pageSize)
+                .build()
+                .page(chatSessionService);
+        return R.data(pageResult);
+    }
+
+    @ApiOperation("获取聊天历史记录")
+    @ApiOperationSupport(order = 7)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "sessionId", value = "会话ID(可选,不传则获取所有会话列表)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "page", value = "页码(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "pageSize", value = "每页数量(默认20)", dataType = "int", paramType = "query")
+    })
+    @GetMapping("/history")
+    public R<Map<String, Object>> getChatHistory(
+            @RequestParam(required = false) String sessionId,
+            @RequestParam(defaultValue = "1") int page,
+            @RequestParam(defaultValue = "20") int pageSize) {
+        log.info("LawyerChatSessionController.getChatHistory?sessionId={},page={},pageSize={}", sessionId, page, pageSize);
+        return chatSessionService.getChatHistory(sessionId, page, pageSize);
+    }
+
+    @ApiOperation("保存聊天消息")
+    @ApiOperationSupport(order = 8)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "sessionId", value = "会话ID(可选,不传则创建新会话)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "content", value = "消息内容", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "type", value = "消息类型:user或ai", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "clientUserId", value = "客户端用户ID(当type=user时必填)", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "consultationOrderId", value = "咨询订单ID(可选)", dataType = "Integer", paramType = "query")
+    })
+    @PostMapping("/saveMessage")
+    public R<Map<String, Object>> saveChatMessage(
+            @RequestParam(required = false) String sessionId,
+            @RequestParam String content,
+            @RequestParam String type,
+            @RequestParam(required = false) Integer clientUserId,
+            @RequestParam(required = false) Integer consultationOrderId) {
+        log.info("LawyerChatSessionController.saveChatMessage?sessionId={},content={},type={},clientUserId={},consultationOrderId={}",
+                sessionId, content, type, clientUserId, consultationOrderId);
+        return chatSessionService.saveChatMessage(sessionId, content, type, clientUserId, consultationOrderId);
+    }
+
+    @ApiOperation("删除聊天消息")
+    @ApiOperationSupport(order = 9)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "messageIds", value = "消息ID数组(逗号分隔)", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "sessionId", value = "会话ID(可选)", dataType = "String", paramType = "query")
+    })
+    @PostMapping("/deleteMessage")
+    public R<String> deleteChatMessages(
+            @RequestParam String messageIds,
+            @RequestParam(required = false) String sessionId) {
+        log.info("LawyerChatSessionController.deleteChatMessages?messageIds={},sessionId={}", messageIds, sessionId);
+        return chatSessionService.deleteChatMessages(messageIds, sessionId);
+    }
+
+    @ApiOperation("删除会话(通过会话ID)")
+    @ApiOperationSupport(order = 10)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "sessionId", value = "会话ID", dataType = "String", paramType = "query", required = true)
+    })
+    @PostMapping("/deleteSessionById")
+    public R<String> deleteChatSession(@RequestParam String sessionId) {
+        log.info("LawyerChatSessionController.deleteChatSession?sessionId={}", sessionId);
+        return chatSessionService.deleteChatSessionBySessionId(sessionId);
+    }
+}
+

+ 129 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerCommonQuestionController.java

@@ -0,0 +1,129 @@
+package shop.alien.lawyer.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerCommonQuestion;
+import shop.alien.lawyer.service.LawyerCommonQuestionService;
+import shop.alien.util.myBaticsPlus.QueryBuilder;
+
+import java.util.List;
+
+/**
+ * 常见问题 前端控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"律师平台-常见问题"})
+@ApiSort(18)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/commonQuestion")
+@RequiredArgsConstructor
+public class LawyerCommonQuestionController {
+
+    private final LawyerCommonQuestionService commonQuestionService;
+
+    @ApiOperation("新增常见问题")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/addCommonQuestion")
+    public R<LawyerCommonQuestion> addCommonQuestion(@RequestBody LawyerCommonQuestion commonQuestion) {
+        log.info("LawyerCommonQuestionController.addCommonQuestion?commonQuestion={}", commonQuestion);
+        return commonQuestionService.addCommonQuestion(commonQuestion);
+    }
+
+    @ApiOperation("编辑常见问题")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/editCommonQuestion")
+    public R<LawyerCommonQuestion> editCommonQuestion(@RequestBody LawyerCommonQuestion commonQuestion) {
+        log.info("LawyerCommonQuestionController.editCommonQuestion?commonQuestion={}", commonQuestion);
+        return commonQuestionService.editCommonQuestion(commonQuestion);
+    }
+
+    @ApiOperation("删除常见问题")
+    @ApiOperationSupport(order = 3)
+    @DeleteMapping("/deleteCommonQuestion")
+    public R<Boolean> deleteCommonQuestion(@RequestParam(value = "id") Integer id) {
+        log.info("LawyerCommonQuestionController.deleteCommonQuestion?id={}", id);
+        return commonQuestionService.deleteCommonQuestion(id);
+    }
+
+    @ApiOperation("保存或更新常见问题")
+    @ApiOperationSupport(order = 4)
+    @PostMapping("/saveOrUpdate")
+    public R<LawyerCommonQuestion> saveOrUpdate(@RequestBody LawyerCommonQuestion commonQuestion) {
+        log.info("LawyerCommonQuestionController.saveOrUpdate?commonQuestion={}", commonQuestion);
+        boolean result = commonQuestionService.saveOrUpdate(commonQuestion);
+        if (result) {
+            return R.data(commonQuestion);
+        }
+        return R.fail("操作失败");
+    }
+
+    @ApiOperation("通用列表查询")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "questionText", value = "问题文本(支持模糊查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "categoryType", value = "分类类型, 0:推荐, 1:常见问题", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "problemScenarioId", value = "法律问题场景ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "status", value = "状态, 0:禁用, 1:启用", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getList")
+    public R<List<LawyerCommonQuestion>> getList(@ModelAttribute LawyerCommonQuestion commonQuestion) {
+        log.info("LawyerCommonQuestionController.getList?commonQuestion={}", commonQuestion);
+        List<LawyerCommonQuestion> list = QueryBuilder.of(commonQuestion)
+                .likeFields("questionText")  // 问题文本支持模糊查询
+                .build()
+                .list(commonQuestionService);
+        return R.data(list);
+    }
+
+    @ApiOperation("通用分页查询")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "页数(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "页容(默认10)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "questionText", value = "问题文本(支持模糊查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "categoryType", value = "分类类型, 0:推荐, 1:常见问题", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "problemScenarioId", value = "法律问题场景ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "status", value = "状态, 0:禁用, 1:启用", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getPage")
+    public R<IPage<LawyerCommonQuestion>> getPage(@ModelAttribute LawyerCommonQuestion commonQuestion,
+                                                  @RequestParam(defaultValue = "1") int page,
+                                                  @RequestParam(defaultValue = "10") int size) {
+        log.info("LawyerCommonQuestionController.getPage?commonQuestion={},page={},size={}", commonQuestion, page, size);
+        int pageNum = page > 0 ? page : 1;
+        int pageSize = size > 0 ? size : 10;
+        IPage<LawyerCommonQuestion> pageResult = QueryBuilder.of(commonQuestion)
+                .likeFields("questionText")  // 问题文本支持模糊查询
+                .page(pageNum, pageSize)
+                .build()
+                .page(commonQuestionService);
+        return R.data(pageResult);
+    }
+
+    @ApiOperation("根据数量获取常见问题列表")
+    @ApiOperationSupport(order = 7)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "num", value = "获取数量", dataType = "Integer", paramType = "query", required = true)
+    })
+    @GetMapping("/getListByNum")
+    public R<List<LawyerCommonQuestion>> getListByNum(@RequestParam Integer num) {
+        log.info("LawyerCommonQuestionController.getListByNum?num={}", num);
+        return commonQuestionService.getCommonQuestionListByNum(num);
+    }
+
+}
+

+ 115 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerConsultationReviewController.java

@@ -0,0 +1,115 @@
+package shop.alien.lawyer.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerConsultationReview;
+import shop.alien.lawyer.service.LawyerConsultationReviewService;
+import shop.alien.util.myBaticsPlus.QueryBuilder;
+
+import java.util.List;
+
+/**
+ * 咨询评价 前端控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"律师平台-咨询评价"})
+@ApiSort(19)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/consultationReview")
+@RequiredArgsConstructor
+public class LawyerConsultationReviewController {
+
+    private final LawyerConsultationReviewService consultationReviewService;
+
+    @ApiOperation("新增咨询评价")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/addConsultationReview")
+    public R<LawyerConsultationReview> addConsultationReview(@RequestBody LawyerConsultationReview consultationReview) {
+        log.info("LawyerConsultationReviewController.addConsultationReview?consultationReview={}", consultationReview);
+        return consultationReviewService.addConsultationReview(consultationReview);
+    }
+
+    @ApiOperation("编辑咨询评价")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/editConsultationReview")
+    public R<LawyerConsultationReview> editConsultationReview(@RequestBody LawyerConsultationReview consultationReview) {
+        log.info("LawyerConsultationReviewController.editConsultationReview?consultationReview={}", consultationReview);
+        return consultationReviewService.editConsultationReview(consultationReview);
+    }
+
+    @ApiOperation("删除咨询评价")
+    @ApiOperationSupport(order = 3)
+    @DeleteMapping("/deleteConsultationReview")
+    public R<Boolean> deleteConsultationReview(@RequestParam(value = "id") Integer id) {
+        log.info("LawyerConsultationReviewController.deleteConsultationReview?id={}", id);
+        return consultationReviewService.deleteConsultationReview(id);
+    }
+
+    @ApiOperation("保存或更新咨询评价")
+    @ApiOperationSupport(order = 4)
+    @PostMapping("/saveOrUpdate")
+    public R<LawyerConsultationReview> saveOrUpdate(@RequestBody LawyerConsultationReview consultationReview) {
+        log.info("LawyerConsultationReviewController.saveOrUpdate?consultationReview={}", consultationReview);
+        boolean result = consultationReviewService.saveOrUpdate(consultationReview);
+        if (result) {
+            return R.data(consultationReview);
+        }
+        return R.fail("操作失败");
+    }
+
+    @ApiOperation("通用列表查询")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "consultationOrderId", value = "咨询订单ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "clientUserId", value = "客户端用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "rating", value = "评分, 1-5星", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getList")
+    public R<List<LawyerConsultationReview>> getList(@ModelAttribute LawyerConsultationReview consultationReview) {
+        log.info("LawyerConsultationReviewController.getList?consultationReview={}", consultationReview);
+        List<LawyerConsultationReview> list = QueryBuilder.of(consultationReview)
+                .build()
+                .list(consultationReviewService);
+        return R.data(list);
+    }
+
+    @ApiOperation("通用分页查询")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "页数(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "页容(默认10)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "id", value = "主键", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "consultationOrderId", value = "咨询订单ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "clientUserId", value = "客户端用户ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "rating", value = "评分, 1-5星", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_Start", value = "创建时间开始(范围查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createdTime_End", value = "创建时间结束(范围查询)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getPage")
+    public R<IPage<LawyerConsultationReview>> getPage(@ModelAttribute LawyerConsultationReview consultationReview,
+                                                       @RequestParam(defaultValue = "1") int page,
+                                                       @RequestParam(defaultValue = "10") int size) {
+        log.info("LawyerConsultationReviewController.getPage?consultationReview={},page={},size={}", consultationReview, page, size);
+        int pageNum = page > 0 ? page : 1;
+        int pageSize = size > 0 ? size : 10;
+        IPage<LawyerConsultationReview> pageResult = QueryBuilder.of(consultationReview)
+                .page(pageNum, pageSize)
+                .build()
+                .page(consultationReviewService);
+        return R.data(pageResult);
+    }
+}
+

+ 63 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerChatMessageService.java

@@ -0,0 +1,63 @@
+package shop.alien.lawyer.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerChatMessage;
+
+import java.util.List;
+
+/**
+ * 聊天消息 服务类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface LawyerChatMessageService extends IService<LawyerChatMessage> {
+
+    /**
+     * 分页查询聊天消息列表
+     *
+     * @param pageNum             页码
+     * @param pageSize            页容
+     * @param chatSessionId       聊天会话ID
+     * @param consultationOrderId 咨询订单ID
+     * @param senderType          发送者类型
+     * @return IPage<LawyerChatMessage>
+     */
+    R<IPage<LawyerChatMessage>> getChatMessageList(int pageNum, int pageSize, Integer chatSessionId,
+                                             Integer consultationOrderId, Integer senderType);
+
+    /**
+     * 根据会话ID查询消息列表
+     *
+     * @param chatSessionId 聊天会话ID
+     * @return List<LawyerChatMessage>
+     */
+    List<LawyerChatMessage> getListBySessionId(Integer chatSessionId);
+
+    /**
+     * 新增聊天消息
+     *
+     * @param chatMessage 聊天消息
+     * @return R<LawyerChatMessage>
+     */
+    R<LawyerChatMessage> addChatMessage(LawyerChatMessage chatMessage);
+
+    /**
+     * 编辑聊天消息
+     *
+     * @param chatMessage 聊天消息
+     * @return R<LawyerChatMessage>
+     */
+    R<LawyerChatMessage> editChatMessage(LawyerChatMessage chatMessage);
+
+    /**
+     * 删除聊天消息
+     *
+     * @param id 主键
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteChatMessage(Integer id);
+}
+

+ 103 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerChatSessionService.java

@@ -0,0 +1,103 @@
+package shop.alien.lawyer.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerChatSession;
+
+import java.util.Map;
+
+/**
+ * 聊天会话 服务类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface LawyerChatSessionService extends IService<LawyerChatSession> {
+
+    /**
+     * 分页查询聊天会话列表
+     *
+     * @param pageNum             页码
+     * @param pageSize            页容
+     * @param consultationOrderId 咨询订单ID
+     * @param clientUserId        客户端用户ID
+     * @param lawyerUserId        律师用户ID
+     * @param status              会话状态
+     * @return IPage<LawyerChatSession>
+     */
+    R<IPage<LawyerChatSession>> getChatSessionList(int pageNum, int pageSize, Integer consultationOrderId,
+                                             Integer clientUserId, Integer lawyerUserId, Integer status);
+
+    /**
+     * 根据订单ID查询会话
+     *
+     * @param consultationOrderId 咨询订单ID
+     * @return LawyerChatSession
+     */
+    LawyerChatSession getByOrderId(Integer consultationOrderId);
+
+    /**
+     * 新增聊天会话
+     *
+     * @param chatSession 聊天会话
+     * @return R<LawyerChatSession>
+     */
+    R<LawyerChatSession> addChatSession(LawyerChatSession chatSession);
+
+    /**
+     * 编辑聊天会话
+     *
+     * @param chatSession 聊天会话
+     * @return R<LawyerChatSession>
+     */
+    R<LawyerChatSession> editChatSession(LawyerChatSession chatSession);
+
+    /**
+     * 删除聊天会话
+     *
+     * @param id 主键
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteChatSession(Integer id);
+
+    /**
+     * 获取聊天历史记录
+     *
+     * @param sessionId 会话ID(可选,不传则获取所有会话列表)
+     * @param page      页码
+     * @param pageSize  每页数量
+     * @return R<Map<String, Object>>
+     */
+    R<Map<String, Object>> getChatHistory(String sessionId, int page, int pageSize);
+
+    /**
+     * 保存聊天消息
+     *
+     * @param sessionId         会话ID(可选,不传则创建新会话)
+     * @param content           消息内容
+     * @param type              消息类型:user或ai
+     * @param clientUserId      客户端用户ID(当type=user时必填)
+     * @param consultationOrderId 咨询订单ID(可选)
+     * @return R<Map<String, Object>>
+     */
+    R<Map<String, Object>> saveChatMessage(String sessionId, String content, String type, Integer clientUserId, Integer consultationOrderId);
+
+    /**
+     * 删除聊天消息
+     *
+     * @param messageIds 消息ID数组(逗号分隔)
+     * @param sessionId 会话ID(可选)
+     * @return R<String>
+     */
+    R<String> deleteChatMessages(String messageIds, String sessionId);
+
+    /**
+     * 删除会话(通过会话ID字符串)
+     *
+     * @param sessionId 会话ID
+     * @return R<String>
+     */
+    R<String> deleteChatSessionBySessionId(String sessionId);
+}
+

+ 73 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerCommonQuestionService.java

@@ -0,0 +1,73 @@
+package shop.alien.lawyer.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerCommonQuestion;
+
+import java.util.List;
+
+/**
+ * 常见问题 服务类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface LawyerCommonQuestionService extends IService<LawyerCommonQuestion> {
+
+    /**
+     * 分页查询常见问题列表
+     *
+     * @param pageNum         页码
+     * @param pageSize        页容
+     * @param questionText    问题文本
+     * @param categoryType    分类类型
+     * @param problemScenarioId 法律问题场景ID
+     * @param status          状态
+     * @return IPage<LawyerCommonQuestion>
+     */
+    R<IPage<LawyerCommonQuestion>> getCommonQuestionList(int pageNum, int pageSize, String questionText,
+                                                    Integer categoryType, Integer problemScenarioId, Integer status);
+
+    /**
+     * 根据分类类型查询常见问题列表
+     *
+     * @param categoryType 分类类型
+     * @return List<LawyerCommonQuestion>
+     */
+    List<LawyerCommonQuestion> getListByCategoryType(Integer categoryType);
+
+    /**
+     * 新增常见问题
+     *
+     * @param commonQuestion 常见问题
+     * @return R<LawyerCommonQuestion>
+     */
+    R<LawyerCommonQuestion> addCommonQuestion(LawyerCommonQuestion commonQuestion);
+
+    /**
+     * 编辑常见问题
+     *
+     * @param commonQuestion 常见问题
+     * @return R<LawyerCommonQuestion>
+     */
+    R<LawyerCommonQuestion> editCommonQuestion(LawyerCommonQuestion commonQuestion);
+
+    /**
+     * 删除常见问题
+     *
+     * @param id 主键
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteCommonQuestion(Integer id);
+
+    /**
+     * 根据数量获取常见问题列表
+     *
+     * @param num 获取数量
+     * @return R<List<LawyerCommonQuestion>>
+     */
+    R<List<LawyerCommonQuestion>> getCommonQuestionListByNum(Integer num);
+
+}
+

+ 63 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerConsultationReviewService.java

@@ -0,0 +1,63 @@
+package shop.alien.lawyer.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerConsultationReview;
+
+import java.util.List;
+
+/**
+ * 咨询评价 服务类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface LawyerConsultationReviewService extends IService<LawyerConsultationReview> {
+
+    /**
+     * 分页查询咨询评价列表
+     *
+     * @param pageNum             页码
+     * @param pageSize            页容
+     * @param consultationOrderId 咨询订单ID
+     * @param lawyerUserId        律师用户ID
+     * @param clientUserId        客户端用户ID
+     * @return IPage<LawyerConsultationReview>
+     */
+    R<IPage<LawyerConsultationReview>> getConsultationReviewList(int pageNum, int pageSize, Integer consultationOrderId,
+                                                            Integer lawyerUserId, Integer clientUserId);
+
+    /**
+     * 根据律师ID查询评价列表
+     *
+     * @param lawyerUserId 律师用户ID
+     * @return List<LawyerConsultationReview>
+     */
+    List<LawyerConsultationReview> getListByLawyerId(Integer lawyerUserId);
+
+    /**
+     * 新增咨询评价
+     *
+     * @param consultationReview 咨询评价
+     * @return R<LawyerConsultationReview>
+     */
+    R<LawyerConsultationReview> addConsultationReview(LawyerConsultationReview consultationReview);
+
+    /**
+     * 编辑咨询评价
+     *
+     * @param consultationReview 咨询评价
+     * @return R<LawyerConsultationReview>
+     */
+    R<LawyerConsultationReview> editConsultationReview(LawyerConsultationReview consultationReview);
+
+    /**
+     * 删除咨询评价
+     *
+     * @param id 主键
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteConsultationReview(Integer id);
+}
+

+ 95 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerChatMessageServiceImpl.java

@@ -0,0 +1,95 @@
+package shop.alien.lawyer.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerChatMessage;
+import shop.alien.lawyer.service.LawyerChatMessageService;
+import shop.alien.mapper.LawyerChatMessageMapper;
+
+
+import java.util.List;
+
+/**
+ * 聊天消息 服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Transactional
+@Service
+@RequiredArgsConstructor
+public class LawyerChatMessageServiceImpl extends ServiceImpl<LawyerChatMessageMapper, LawyerChatMessage> implements LawyerChatMessageService {
+
+    private final LawyerChatMessageMapper chatMessageMapper;
+
+    @Override
+    public R<IPage<LawyerChatMessage>> getChatMessageList(int pageNum, int pageSize, Integer chatSessionId,
+                                                     Integer consultationOrderId, Integer senderType) {
+        log.info("LawyerChatMessageServiceImpl.getChatMessageList?pageNum={},pageSize={},chatSessionId={},consultationOrderId={},senderType={}",
+                pageNum, pageSize, chatSessionId, consultationOrderId, senderType);
+        Page<LawyerChatMessage> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<LawyerChatMessage> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerChatMessage::getDeleteFlag, 0);
+        if (chatSessionId != null) {
+            queryWrapper.eq(LawyerChatMessage::getChatSessionId, chatSessionId);
+        }
+        if (consultationOrderId != null) {
+            queryWrapper.eq(LawyerChatMessage::getConsultationOrderId, consultationOrderId);
+        }
+        if (senderType != null) {
+            queryWrapper.eq(LawyerChatMessage::getSenderType, senderType);
+        }
+        queryWrapper.orderByAsc(LawyerChatMessage::getMessageTimestamp);
+        IPage<LawyerChatMessage> pageResult = this.page(page, queryWrapper);
+        return R.data(pageResult);
+    }
+
+    @Override
+    public List<LawyerChatMessage> getListBySessionId(Integer chatSessionId) {
+        log.info("LawyerChatMessageServiceImpl.getListBySessionId?chatSessionId={}", chatSessionId);
+        LambdaQueryWrapper<LawyerChatMessage> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerChatMessage::getChatSessionId, chatSessionId)
+                .eq(LawyerChatMessage::getDeleteFlag, 0)
+                .orderByAsc(LawyerChatMessage::getMessageTimestamp);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public R<LawyerChatMessage> addChatMessage(LawyerChatMessage chatMessage) {
+        log.info("LawyerChatMessageServiceImpl.addChatMessage?chatMessage={}", chatMessage);
+        boolean result = this.save(chatMessage);
+        if (result) {
+            return R.data(chatMessage);
+        }
+        return R.fail("新增失败");
+    }
+
+    @Override
+    public R<LawyerChatMessage> editChatMessage(LawyerChatMessage chatMessage) {
+        log.info("LawyerChatMessageServiceImpl.editChatMessage?chatMessage={}", chatMessage);
+        boolean result = this.updateById(chatMessage);
+        if (result) {
+            return R.data(chatMessage);
+        }
+        return R.fail("修改失败");
+    }
+
+    @Override
+    public R<Boolean> deleteChatMessage(Integer id) {
+        log.info("LawyerChatMessageServiceImpl.deleteChatMessage?id={}", id);
+        boolean result = this.removeById(id);
+        if (result) {
+            return R.success("删除成功");
+        }
+        return R.fail("删除失败");
+    }
+}
+

+ 245 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerChatSessionServiceImpl.java

@@ -0,0 +1,245 @@
+package shop.alien.lawyer.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerChatMessage;
+import shop.alien.entity.store.LawyerChatSession;
+import shop.alien.lawyer.service.LawyerChatMessageService;
+import shop.alien.lawyer.service.LawyerChatSessionService;
+import shop.alien.mapper.LawyerChatSessionMapper;
+import shop.alien.util.myBaticsPlus.QueryBuilder;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 聊天会话 服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Transactional
+@Service
+@RequiredArgsConstructor
+public class LawyerChatSessionServiceImpl extends ServiceImpl<LawyerChatSessionMapper, LawyerChatSession> implements LawyerChatSessionService {
+
+    private final LawyerChatSessionMapper chatSessionMapper;
+    private final LawyerChatMessageService chatMessageService;
+    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+
+    @Override
+    public R<IPage<LawyerChatSession>> getChatSessionList(int pageNum, int pageSize, Integer consultationOrderId,
+                                                     Integer clientUserId, Integer lawyerUserId, Integer status) {
+        log.info("LawyerChatSessionServiceImpl.getChatSessionList?pageNum={},pageSize={},consultationOrderId={},clientUserId={},lawyerUserId={},status={}",
+                pageNum, pageSize, consultationOrderId, clientUserId, lawyerUserId, status);
+        Page<LawyerChatSession> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<LawyerChatSession> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerChatSession::getDeleteFlag, 0);
+        if (consultationOrderId != null) {
+            queryWrapper.eq(LawyerChatSession::getConsultationOrderId, consultationOrderId);
+        }
+        if (clientUserId != null) {
+            queryWrapper.eq(LawyerChatSession::getClientUserId, clientUserId);
+        }
+        if (lawyerUserId != null) {
+            queryWrapper.eq(LawyerChatSession::getLawyerUserId, lawyerUserId);
+        }
+        if (status != null) {
+            queryWrapper.eq(LawyerChatSession::getStatus, status);
+        }
+        queryWrapper.orderByDesc(LawyerChatSession::getLastMessageTime);
+        IPage<LawyerChatSession> pageResult = this.page(page, queryWrapper);
+        return R.data(pageResult);
+    }
+
+    @Override
+    public LawyerChatSession getByOrderId(Integer consultationOrderId) {
+        log.info("LawyerChatSessionServiceImpl.getByOrderId?consultationOrderId={}", consultationOrderId);
+        LambdaQueryWrapper<LawyerChatSession> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerChatSession::getConsultationOrderId, consultationOrderId)
+                .eq(LawyerChatSession::getDeleteFlag, 0)
+                .last("LIMIT 1");
+        return this.getOne(queryWrapper);
+    }
+
+    @Override
+    public R<LawyerChatSession> addChatSession(LawyerChatSession chatSession) {
+        log.info("LawyerChatSessionServiceImpl.addChatSession?chatSession={}", chatSession);
+        boolean result = this.save(chatSession);
+        if (result) {
+            return R.data(chatSession);
+        }
+        return R.fail("新增失败");
+    }
+
+    @Override
+    public R<LawyerChatSession> editChatSession(LawyerChatSession chatSession) {
+        log.info("LawyerChatSessionServiceImpl.editChatSession?chatSession={}", chatSession);
+        boolean result = this.updateById(chatSession);
+        if (result) {
+            return R.data(chatSession);
+        }
+        return R.fail("修改失败");
+    }
+
+    @Override
+    public R<Boolean> deleteChatSession(Integer id) {
+        log.info("LawyerChatSessionServiceImpl.deleteChatSession?id={}", id);
+        boolean result = this.removeById(id);
+        if (result) {
+            return R.success("删除成功");
+        }
+        return R.fail("删除失败");
+    }
+
+    @Override
+    public R<Map<String, Object>> getChatHistory(String sessionId, int page, int pageSize) {
+        log.info("LawyerChatSessionServiceImpl.getChatHistory?sessionId={},page={},pageSize={}", sessionId, page, pageSize);
+
+        Map<String, Object> result = new HashMap<>();
+
+        if (StringUtils.hasText(sessionId)) {
+            // 返回该会话的消息列表
+            LawyerChatMessage query = new LawyerChatMessage();
+            query.setChatSessionId(Integer.parseInt(sessionId));
+
+            int pageNum = page > 0 ? page : 1;
+            int pageSizeNum = pageSize > 0 ? pageSize : 20;
+
+            IPage<LawyerChatMessage> pageResult = QueryBuilder.of(query)
+                    .page(pageNum, pageSizeNum)
+                    .build()
+                    .page(chatMessageService);
+
+            List<Map<String, Object>> messages = pageResult.getRecords().stream().map(msg -> {
+                Map<String, Object> msgMap = new HashMap<>();
+                msgMap.put("id", msg.getId());
+                msgMap.put("content", msg.getMessageContent());
+                msgMap.put("type", msg.getSenderType() == 0 ? "user" : "ai");  // 0:客户端用户, 1:律师用户,这里假设AI消息
+                msgMap.put("time", msg.getMessageTimestamp() != null ?
+                        DATE_FORMAT.format(msg.getMessageTimestamp()) : "");
+                msgMap.put("sessionId", sessionId);
+                // TODO: 处理图片和视频URL数组
+                msgMap.put("images", new ArrayList<>());
+                msgMap.put("videos", new ArrayList<>());
+                return msgMap;
+            }).collect(Collectors.toList());
+
+            result.put("messages", messages);
+        } else {
+            // 返回会话列表
+            QueryWrapper<LawyerChatSession> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("delete_flag", 0)
+                    .orderByDesc("last_message_time", "created_time");
+
+            int pageNum = page > 0 ? page : 1;
+            int pageSizeNum = pageSize > 0 ? pageSize : 20;
+            Page<LawyerChatSession> pageObj = new Page<>(pageNum, pageSizeNum);
+            IPage<LawyerChatSession> pageResult = this.page(pageObj, queryWrapper);
+
+            List<Map<String, Object>> sessions = pageResult.getRecords().stream().map(session -> {
+                Map<String, Object> sessionMap = new HashMap<>();
+                sessionMap.put("id", session.getId().toString());
+                // TODO: 获取会话标题(通常是第一条消息)
+                sessionMap.put("title", "咨询会话");
+                // TODO: 获取最后一条消息内容
+                sessionMap.put("lastMessage", "");
+                sessionMap.put("lastMessageTime", session.getLastMessageTime() != null ?
+                        DATE_FORMAT.format(session.getLastMessageTime()) : "");
+                // TODO: 获取消息数量
+                sessionMap.put("messageCount", 0);
+                return sessionMap;
+            }).collect(Collectors.toList());
+
+            result.put("sessions", sessions);
+        }
+
+        return R.data(result);
+    }
+
+    @Override
+    public R<Map<String, Object>> saveChatMessage(String sessionId, String content, String type, Integer clientUserId, Integer consultationOrderId) {
+        log.info("LawyerChatSessionServiceImpl.saveChatMessage?sessionId={},content={},type={},clientUserId={},consultationOrderId={}",
+                sessionId, content, type, clientUserId, consultationOrderId);
+
+        Integer chatSessionId = null;
+        if (StringUtils.hasText(sessionId)) {
+            chatSessionId = Integer.parseInt(sessionId);
+        } else {
+            // 创建新会话
+            LawyerChatSession newSession = new LawyerChatSession();
+            newSession.setClientUserId(clientUserId);
+            newSession.setConsultationOrderId(consultationOrderId);
+            newSession.setStatus(1);  // 进行中
+            this.save(newSession);
+            chatSessionId = newSession.getId();
+        }
+
+        // 保存消息
+        LawyerChatMessage message = new LawyerChatMessage();
+        message.setChatSessionId(chatSessionId);
+        message.setConsultationOrderId(consultationOrderId);
+        message.setSenderId(clientUserId);
+        message.setSenderType("user".equals(type) ? 0 : 1);  // 0:客户端用户, 1:律师用户
+        message.setMessageContent(content);
+        message.setMessageType(0);  // 文本消息
+        message.setMessageTimestamp(new Date());
+        message.setReadStatus(0);  // 未读
+
+        chatMessageService.save(message);
+
+        // 更新会话的最后消息时间和ID
+        LawyerChatSession session = this.getById(chatSessionId);
+        if (session != null) {
+            session.setLastMessageId(message.getId());
+            session.setLastMessageTime(new Date());
+            this.updateById(session);
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("messageId", message.getId());
+        result.put("sessionId", chatSessionId.toString());
+        result.put("time", DATE_FORMAT.format(message.getMessageTimestamp()));
+
+        return R.data(result);
+    }
+
+    @Override
+    public R<String> deleteChatMessages(String messageIds, String sessionId) {
+        log.info("LawyerChatSessionServiceImpl.deleteChatMessages?messageIds={},sessionId={}", messageIds, sessionId);
+
+        String[] ids = messageIds.split(",");
+        List<Integer> idList = Arrays.stream(ids)
+                .map(String::trim)
+                .filter(s -> !s.isEmpty())
+                .map(Integer::parseInt)
+                .collect(Collectors.toList());
+
+        if (!idList.isEmpty()) {
+            chatMessageService.removeByIds(idList);
+        }
+
+        return R.success("删除成功");
+    }
+
+    @Override
+    public R<String> deleteChatSessionBySessionId(String sessionId) {
+        log.info("LawyerChatSessionServiceImpl.deleteChatSessionBySessionId?sessionId={}", sessionId);
+
+        this.removeById(Integer.parseInt(sessionId));
+
+        return R.success("删除成功");
+    }
+}
+

+ 117 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerCommonQuestionServiceImpl.java

@@ -0,0 +1,117 @@
+package shop.alien.lawyer.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerCommonQuestion;
+import shop.alien.lawyer.service.LawyerCommonQuestionService;
+import shop.alien.mapper.LawyerCommonQuestionMapper;
+
+import java.util.List;
+
+/**
+ * 常见问题 服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Transactional
+@Service
+@RequiredArgsConstructor
+public class LawyerCommonQuestionServiceImpl extends ServiceImpl<LawyerCommonQuestionMapper, LawyerCommonQuestion> implements LawyerCommonQuestionService {
+
+    private final LawyerCommonQuestionMapper commonQuestionMapper;
+
+    @Override
+    public R<IPage<LawyerCommonQuestion>> getCommonQuestionList(int pageNum, int pageSize, String questionText,
+                                                           Integer categoryType, Integer problemScenarioId, Integer status) {
+        log.info("LawyerCommonQuestionServiceImpl.getCommonQuestionList?pageNum={},pageSize={},questionText={},categoryType={},problemScenarioId={},status={}",
+                pageNum, pageSize, questionText, categoryType, problemScenarioId, status);
+        Page<LawyerCommonQuestion> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<LawyerCommonQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerCommonQuestion::getDeleteFlag, 0);
+        if (StringUtils.hasText(questionText)) {
+            queryWrapper.like(LawyerCommonQuestion::getQuestionText, questionText);
+        }
+        if (categoryType != null) {
+            queryWrapper.eq(LawyerCommonQuestion::getCategoryType, categoryType);
+        }
+        if (problemScenarioId != null) {
+            queryWrapper.eq(LawyerCommonQuestion::getProblemScenarioId, problemScenarioId);
+        }
+        if (status != null) {
+            queryWrapper.eq(LawyerCommonQuestion::getStatus, status);
+        }
+        queryWrapper.orderByAsc(LawyerCommonQuestion::getSortOrder);
+        IPage<LawyerCommonQuestion> pageResult = this.page(page, queryWrapper);
+        return R.data(pageResult);
+    }
+
+    @Override
+    public List<LawyerCommonQuestion> getListByCategoryType(Integer categoryType) {
+        log.info("LawyerCommonQuestionServiceImpl.getListByCategoryType?categoryType={}", categoryType);
+        LambdaQueryWrapper<LawyerCommonQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerCommonQuestion::getCategoryType, categoryType)
+                .eq(LawyerCommonQuestion::getDeleteFlag, 0)
+                .eq(LawyerCommonQuestion::getStatus, 1)
+                .orderByAsc(LawyerCommonQuestion::getSortOrder);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public R<LawyerCommonQuestion> addCommonQuestion(LawyerCommonQuestion commonQuestion) {
+        log.info("LawyerCommonQuestionServiceImpl.addCommonQuestion?commonQuestion={}", commonQuestion);
+        boolean result = this.save(commonQuestion);
+        if (result) {
+            return R.data(commonQuestion);
+        }
+        return R.fail("新增失败");
+    }
+
+    @Override
+    public R<LawyerCommonQuestion> editCommonQuestion(LawyerCommonQuestion commonQuestion) {
+        log.info("LawyerCommonQuestionServiceImpl.editCommonQuestion?commonQuestion={}", commonQuestion);
+        boolean result = this.updateById(commonQuestion);
+        if (result) {
+            return R.data(commonQuestion);
+        }
+        return R.fail("修改失败");
+    }
+
+    @Override
+    public R<Boolean> deleteCommonQuestion(Integer id) {
+        log.info("LawyerCommonQuestionServiceImpl.deleteCommonQuestion?id={}", id);
+        boolean result = this.removeById(id);
+        if (result) {
+            return R.success("删除成功");
+        }
+        return R.fail("删除失败");
+    }
+
+    @Override
+    public R<List<LawyerCommonQuestion>> getCommonQuestionListByNum(Integer num) {
+        log.info("LawyerCommonQuestionServiceImpl.getCommonQuestionListByNum?num={}", num);
+        
+        // 参数校验:如果 num 小于等于0,返回空列表
+        if (num == null || num <= 0) {
+            return R.data(new java.util.ArrayList<>());
+        }
+        
+        // 构建查询条件:只查询未删除的记录,随机排序
+        LambdaQueryWrapper<LawyerCommonQuestion> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerCommonQuestion::getDeleteFlag, 0)
+                .last("ORDER BY RAND() LIMIT " + num);
+        
+        List<LawyerCommonQuestion> list = this.list(queryWrapper);
+        return R.data(list);
+    }
+}
+

+ 94 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerConsultationReviewServiceImpl.java

@@ -0,0 +1,94 @@
+package shop.alien.lawyer.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerConsultationReview;
+import shop.alien.lawyer.service.LawyerConsultationReviewService;
+import shop.alien.mapper.LawyerConsultationReviewMapper;
+
+import java.util.List;
+
+/**
+ * 咨询评价 服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Transactional
+@Service
+@RequiredArgsConstructor
+public class LawyerConsultationReviewServiceImpl extends ServiceImpl<LawyerConsultationReviewMapper, LawyerConsultationReview> implements LawyerConsultationReviewService {
+
+    private final LawyerConsultationReviewMapper consultationReviewMapper;
+
+    @Override
+    public R<IPage<LawyerConsultationReview>> getConsultationReviewList(int pageNum, int pageSize, Integer consultationOrderId,
+                                                                  Integer lawyerUserId, Integer clientUserId) {
+        log.info("LawyerConsultationReviewServiceImpl.getConsultationReviewList?pageNum={},pageSize={},consultationOrderId={},lawyerUserId={},clientUserId={}",
+                pageNum, pageSize, consultationOrderId, lawyerUserId, clientUserId);
+        Page<LawyerConsultationReview> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<LawyerConsultationReview> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerConsultationReview::getDeleteFlag, 0);
+        if (consultationOrderId != null) {
+            queryWrapper.eq(LawyerConsultationReview::getConsultationOrderId, consultationOrderId);
+        }
+        if (lawyerUserId != null) {
+            queryWrapper.eq(LawyerConsultationReview::getLawyerUserId, lawyerUserId);
+        }
+        if (clientUserId != null) {
+            queryWrapper.eq(LawyerConsultationReview::getClientUserId, clientUserId);
+        }
+        queryWrapper.orderByDesc(LawyerConsultationReview::getCreatedTime);
+        IPage<LawyerConsultationReview> pageResult = this.page(page, queryWrapper);
+        return R.data(pageResult);
+    }
+
+    @Override
+    public List<LawyerConsultationReview> getListByLawyerId(Integer lawyerUserId) {
+        log.info("LawyerConsultationReviewServiceImpl.getListByLawyerId?lawyerUserId={}", lawyerUserId);
+        LambdaQueryWrapper<LawyerConsultationReview> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerConsultationReview::getLawyerUserId, lawyerUserId)
+                .eq(LawyerConsultationReview::getDeleteFlag, 0)
+                .orderByDesc(LawyerConsultationReview::getCreatedTime);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public R<LawyerConsultationReview> addConsultationReview(LawyerConsultationReview consultationReview) {
+        log.info("LawyerConsultationReviewServiceImpl.addConsultationReview?consultationReview={}", consultationReview);
+        boolean result = this.save(consultationReview);
+        if (result) {
+            return R.data(consultationReview);
+        }
+        return R.fail("新增失败");
+    }
+
+    @Override
+    public R<LawyerConsultationReview> editConsultationReview(LawyerConsultationReview consultationReview) {
+        log.info("LawyerConsultationReviewServiceImpl.editConsultationReview?consultationReview={}", consultationReview);
+        boolean result = this.updateById(consultationReview);
+        if (result) {
+            return R.data(consultationReview);
+        }
+        return R.fail("修改失败");
+    }
+
+    @Override
+    public R<Boolean> deleteConsultationReview(Integer id) {
+        log.info("LawyerConsultationReviewServiceImpl.deleteConsultationReview?id={}", id);
+        boolean result = this.removeById(id);
+        if (result) {
+            return R.success("删除成功");
+        }
+        return R.fail("删除失败");
+    }
+}
+