瀏覽代碼

开发 获取所有律所的对账
开发 获取所有律所的对账统计列表(分页)
开发 获取律所下所有律师的对账统计列表(分页)
开发 获取律所下所有律师的对账统计列表(分页,支持律师名称模糊查询)
开发 获取律师的已完成订单列表(分页)

LuTong 3 周之前
父節點
當前提交
ca6c27e23b

+ 0 - 591
Lawyer System Table Structure Specification.md

@@ -1,591 +0,0 @@
-# 法律咨询平台系统 - 数据库表结构分析
-
-## 一、表结构概览
-
-### 核心用户表(2个)
-1. `lawyer_user` - 律师用户表(✅ 已完成)
-2. `life_user` - 客户端用户表(✅ 已存在)
-
-### 基础配置表(1个)
-3. `lawyer_legal_problem_scenario` - 法律问题场景表(✅ 已完成)
-
-### 核心业务表(4个)
-4. `lawyer_consultation_order` - 咨询订单表(✅ 已完成)
-5. `lawyer_chat_session` - 聊天会话表(✅ 已完成)
-6. `lawyer_chat_message` - 聊天消息表(✅ 已完成)
-7. `lawyer_service_area` - 律师服务领域关联表(✅ 已完成)
-
-### 扩展功能表(5个)
-8. `lawyer_img` - 律师图片表(✅ 已完成)
-9. `lawyer_common_question` - 常见问题表(✅ 已完成)
-10. `lawyer_consultation_review` - 咨询评价表(✅ 已完成)
-11. `lawyer_payment_transaction` - 支付交易表(✅ 已完成)
-12. `lawyer_ai_interaction_log` - AI交互日志表(✅ 已完成)
-13. `lawyer_user_search_history` - 用户搜索历史表(✅ 已完成)
-
----
-
-## 二、详细表结构分析
-
-### 1. `lawyer_user` - 律师用户表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 存储律师用户的基本信息、认证信息、服务信息等
-- **关键字段**:
-  - `id` (主键)
-  - `phone` (手机号, 唯一)
-  - `name` (姓名)
-  - `lawyer_certificate_no` (律师执业证号)
-  - `law_firm` (所属律师事务所名称)
-  - `certification_status` (资质认证状态)
-  - `consultation_fee` (咨询收费标准)
-  - `agency_fee` (代理收费标准)
-  - `service_score` (服务评分)
-  - `service_count` (服务次数)
-- **关联关系**:
-  - **一对多**: 一个律师可以有多个图片 (`lawyer_img`)
-  - **一对多**: 一个律师可以有多个服务领域 (`lawyer_service_area`)
-  - **一对多**: 一个律师可以有多个咨询订单 (`lawyer_consultation_order`)
-  - **一对多**: 一个律师可以有多个聊天会话 (`lawyer_chat_session`)
-  - **一对多**: 一个律师可以收到多个评价 (`lawyer_consultation_review`)
-
----
-
-### 2. `lawyer_legal_problem_scenario` - 法律问题场景表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 存储法律问题分类的树形结构(一级分类7个,二级分类14个,三级分类30个)
-- **关键字段**:
-  - `id` (主键)
-  - `code` (编号, 如: L1, L1-01, L1-01-01)
-  - `name` (名称)
-  - `parent_id` (父类主键)
-  - `parent_code` (父类编号)
-  - `parentName` (父类名称)
-  - `sort_order` (排序字段)
-  - `status` (状态)
-- **关联关系**:
-  - **自关联**: 树形结构,通过 `parent_id` 关联自身
-  - **一对多**: 一个法律问题场景可以关联多个律师服务领域 (`lawyer_service_area`)
-  - **一对多**: 一个法律问题场景可以有多个咨询订单 (`lawyer_consultation_order`)
-  - **一对多**: 一个法律问题场景可以有多个常见问题 (`lawyer_common_question`)
-  - **一对多**: 一个法律问题场景可以关联多个AI交互日志 (`lawyer_ai_interaction_log`)
-
----
-
-### 8. `lawyer_img` - 律师图片表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 存储律师相关的图片(头像、执业证、身份证、案例图片等)
-- **关键字段**:
-  - `id` (主键)
-  - `lawyer_id` (律师用户ID, FK -> lawyer_user)
-  - `img_type` (图片类型: 0:其他, 1:头像, 2:执业证照片, 3:身份证正面, 4:身份证反面, 5:案例图片, 6:相册图片, 7:资质证书, 8:荣誉证书, 9:工作照片)
-  - `img_url` (图片链接)
-  - `img_description` (图片描述)
-  - `img_sort` (图片排序)
-  - `business_id` (业务ID)
-- **关联关系**:
-  - **多对一**: 多个图片属于一个律师 (`lawyer_user`)
-
----
-
-### 7. `lawyer_service_area` - 律师服务领域关联表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 律师与法律问题场景的多对多关联表(律师擅长哪些领域)
-- **关键字段**:
-  - `id` (主键)
-  - `lawyer_user_id` (律师用户ID, FK -> lawyer_user)
-  - `problem_scenar_id` (法律问题场景ID, FK -> lawyer_legal_problem_scenario)
-  - `sort_order` (排序, 数值越小越靠前)
-  - `status` (状态)
-  - **唯一索引**: UK(lawyer_user_id, problem_scenar_id)
-- **关联关系**:
-  - **多对一**: 多个关联记录属于一个律师 (`lawyer_user`)
-  - **多对一**: 多个关联记录关联一个法律问题场景 (`lawyer_legal_problem_scenario`)
-  - **作用**: 实现律师与法律问题场景的多对多关系
-
----
-
-### 4. `lawyer_consultation_order` - 咨询订单表(核心业务表)
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 记录用户与律师之间的咨询订单,是整个业务的核心
-- **关键字段**:
-  - `id` (主键)
-  - `order_number` (订单编号, 唯一, 如: LAW2023071500123)
-  - `client_user_id` (客户端用户ID, FK -> life_user)
-  - `lawyer_user_id` (律师用户ID, FK -> lawyer_user)
-  - `problem_scenar_id` (法律问题场景ID, FK -> lawyer_legal_problem_scenario)
-  - `problem_description` (问题描述)
-  - `order_amount` (订单金额, 单位:分)
-  - `consultation_fee` (咨询费用, 单位:分)
-  - `start_time` (咨询开始时间)
-  - `end_time` (咨询结束时间)
-  - `order_status` (订单状态: 0:待支付, 1:已支付, 2:进行中, 3:已完成, 4:已取消)
-  - `payment_status` (支付状态: 0:未支付, 1:已支付)
-  - `payment_time` (支付时间)
-  - `validity_period` (订单有效期)
-  - `rating` (用户评分, 1-5星)
-  - `comment` (用户评价内容)
-- **关联关系**:
-  - **多对一**: 多个订单属于一个客户端用户 (`life_user`)
-  - **多对一**: 多个订单属于一个律师 (`lawyer_user`)
-  - **多对一**: 多个订单关联一个法律问题场景 (`lawyer_legal_problem_scenario`)
-  - **一对多**: 一个订单可以有一个聊天会话 (`lawyer_chat_session`)
-  - **一对多**: 一个订单可以有多条聊天消息 (`lawyer_chat_message`)
-  - **一对多**: 一个订单可以有多笔支付交易 (`lawyer_payment_transaction`)
-  - **一对一**: 一个订单可以有一个评价 (`lawyer_consultation_review`)
-
----
-
-### 5. `lawyer_chat_session` - 聊天会话表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 管理咨询会话,关联订单和消息
-- **关键字段**:
-  - `id` (主键)
-  - `consultation_order_id` (咨询订单ID, FK -> lawyer_consultation_order)
-  - `client_user_id` (客户端用户ID, FK -> life_user)
-  - `lawyer_user_id` (律师用户ID, FK -> lawyer_user)
-  - `session_type` (会话类型: 0:文本咨询, 1:语音咨询, 2:视频咨询)
-  - `status` (会话状态: 0:未开始, 1:进行中, 2:已结束)
-  - `last_message_id` (最后一条消息ID, FK -> lawyer_chat_message)
-  - `last_message_time` (最后一条消息时间)
-- **关联关系**:
-  - **多对一**: 多个会话属于一个咨询订单 (`lawyer_consultation_order`)
-  - **多对一**: 多个会话属于一个客户端用户 (`life_user`)
-  - **多对一**: 多个会话属于一个律师 (`lawyer_user`)
-  - **多对一**: 一个会话的最后一条消息 (`lawyer_chat_message`)
-  - **一对多**: 一个会话可以有多条聊天消息 (`lawyer_chat_message`)
-
----
-
-### 6. `lawyer_chat_message` - 聊天消息表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 存储咨询会话中的具体聊天消息
-- **关键字段**:
-  - `id` (主键)
-  - `chat_session_id` (聊天会话ID, FK -> lawyer_chat_session)
-  - `consultation_order_id` (咨询订单ID, FK -> lawyer_consultation_order, 冗余字段便于查询)
-  - `sender_id` (发送者ID, 可以是life_user的id或lawyer_user的id)
-  - `sender_type` (发送者类型: 0:客户端用户, 1:律师用户)
-  - `message_content` (消息内容, TEXT)
-  - `message_type` (消息类型: 0:文本, 1:图片, 2:语音, 3:文件, 4:视频)
-  - `media_url` (媒体文件URL)
-  - `message_timestamp` (消息发送时间)
-  - `read_status` (阅读状态: 0:未读, 1:已读)
-  - `read_time` (阅读时间)
-- **关联关系**:
-  - **多对一**: 多条消息属于一个聊天会话 (`lawyer_chat_session`)
-  - **多对一**: 多条消息属于一个咨询订单 (`lawyer_consultation_order`)
-  - **被关联**: 可以被 `lawyer_chat_session.last_message_id` 引用
-
----
-
-### 9. `lawyer_common_question` - 常见问题表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 存储常见问题及回答(FAQ)
-- **关键字段**:
-  - `id` (主键)
-  - `question_text` (问题文本)
-  - `answer_text` (回答内容, TEXT)
-  - `category_type` (分类类型: 0:推荐, 1:常见问题)
-  - `problem_scenar_id` (关联法律问题场景ID, FK -> lawyer_legal_problem_scenario, 可选)
-  - `sort_order` (排序)
-  - `view_count` (浏览次数)
-  - `status` (状态)
-- **关联关系**:
-  - **多对一**: 多个常见问题可以关联一个法律问题场景 (`lawyer_legal_problem_scenario`)
-
----
-
-### 10. `lawyer_consultation_review` - 咨询评价表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 存储用户对咨询服务的评价
-- **关键字段**:
-  - `id` (主键)
-  - `consultation_order_id` (咨询订单ID, FK -> lawyer_consultation_order)
-  - `client_user_id` (评价用户ID, FK -> life_user)
-  - `lawyer_user_id` (被评价律师ID, FK -> lawyer_user)
-  - `rating` (评分, 1-5星)
-  - `comment` (评价内容, TEXT)
-  - `service_quality` (服务质量评分, 1-5星)
-  - `response_speed` (响应速度评分, 1-5星)
-  - `professional_level` (专业水平评分, 1-5星)
-  - **唯一索引**: UK(consultation_order_id, delete_flag) - 确保一个订单只有一个有效评价
-- **关联关系**:
-  - **一对一**: 一个订单对应一个评价 (`lawyer_consultation_order`)
-  - **多对一**: 多个评价属于一个客户端用户 (`life_user`)
-  - **多对一**: 多个评价属于一个律师 (`lawyer_user`)
-
----
-
-### 11. `lawyer_payment_transaction` - 支付交易表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 记录支付交易信息
-- **关键字段**:
-  - `id` (主键)
-  - `consultation_order_id` (咨询订单ID, FK -> lawyer_consultation_order)
-  - `client_user_id` (支付用户ID, FK -> life_user)
-  - `transaction_number` (交易流水号, 唯一)
-  - `transaction_amount` (交易金额, 单位:分)
-  - `payment_method` (支付方式: 0:微信, 1:支付宝, 2:银行卡)
-  - `transaction_status` (交易状态: 0:待支付, 1:支付成功, 2:支付失败, 3:已退款)
-  - `transaction_time` (交易时间)
-  - `third_party_trade_no` (第三方交易号)
-  - `refund_amount` (退款金额, 单位:分)
-  - `refund_time` (退款时间)
-- **关联关系**:
-  - **多对一**: 多笔交易属于一个咨询订单 (`lawyer_consultation_order`)
-  - **多对一**: 多笔交易属于一个客户端用户 (`life_user`)
-
----
-
-### 12. `lawyer_ai_interaction_log` - AI交互日志表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 记录用户与AI助手的对话历史
-- **关键字段**:
-  - `id` (主键)
-  - `client_user_id` (客户端用户ID, FK -> life_user)
-  - `conversation_id` (会话ID, 用于关联同一会话的多条消息)
-  - `query_text` (用户输入内容, TEXT)
-  - `response_text` (AI回复内容, TEXT)
-  - `problem_scenar_id` (关联的法律问题场景ID, FK -> lawyer_legal_problem_scenario, 可选)
-  - `interaction_time` (交互时间)
-- **关联关系**:
-  - **多对一**: 多条日志属于一个客户端用户 (`life_user`)
-  - **多对一**: 多条日志可以关联一个法律问题场景 (`lawyer_legal_problem_scenario`)
-
----
-
-### 13. `lawyer_user_search_history` - 用户搜索历史表
-- **状态**: ✅ 已创建实体类、Mapper、Service、Controller、XML、SQL
-- **用途**: 存储用户搜索历史(如:搜索律师姓名、法律问题、律所名称)
-- **关键字段**:
-  - `id` (主键)
-  - `client_user_id` (用户ID, FK -> life_user)
-  - `search_keyword` (搜索关键词)
-  - `search_type` (搜索类型: 0:律师姓名, 1:法律问题, 2:律所名称)
-  - `search_time` (搜索时间)
-- **关联关系**:
-  - **多对一**: 多条搜索历史属于一个客户端用户 (`life_user`)
-
----
-
-### 14. `life_user` - 客户端用户表
-- **状态**: ✅ 已存在实体类、Mapper、Service、Controller
-- **用途**: 存储使用平台进行咨询的普通用户信息(与律师用户区分)
-- **关键字段**:
-  - `id` (主键)
-  - `user_phone` (用户手机号)
-  - `guanfang_phone` (官方手机号)
-  - `user_name` (用户昵称)
-  - `real_name` (真实姓名)
-  - `user_sex` (性别, String类型)
-  - `user_brithday` (生日, 注意字段名拼写)
-  - `user_image` (用户头像URL)
-  - `id_card` (身份证号)
-  - `province`, `city`, `district`, `address` (地址信息)
-  - `jianjie` (简介)
-  - `money` (用户余额, 单位:分)
-  - `pay_password` (支付密码)
-  - `alipay_account` (支付宝账号)
-  - `invited_num` (邀请码)
-  - `invite_code` (个人邀请码)
-  - `bind_invite_code` (绑定他人邀请码)
-  - `xiaofei_time` (消费次数)
-  - `xiaofei_amount` (消费金额)
-  - `chaping_time` (差评次数)
-  - `clock_img_id` (打卡广场小人图片id)
-  - `logout_flag` (注销标记: 0:未注销, 1:已注销)
-  - `logout_reason` (注销原因)
-  - `logout_time` (注销申请时间)
-- **关联关系**:
-  - **一对多**: 一个用户可以有多个咨询订单 (`lawyer_consultation_order`)
-  - **一对多**: 一个用户可以有多个聊天会话 (`lawyer_chat_session`)
-  - **一对多**: 一个用户可以有多个评价 (`lawyer_consultation_review`)
-  - **一对多**: 一个用户可以有多笔支付交易 (`lawyer_payment_transaction`)
-  - **一对多**: 一个用户可以有多个AI交互日志 (`lawyer_ai_interaction_log`)
-  - **一对多**: 一个用户可以有多个搜索历史 (`lawyer_user_search_history`)
-
----
-
-## 三、表关系图(ER图)
-
-```
-┌─────────────────────────────────────────────────────────────────────────────┐
-│                          核心用户表                                           │
-├─────────────────────────────────────────────────────────────────────────────┤
-│  lawyer_user (律师用户) ──────────┐                                           │
-│  life_user (客户端用户) ──────────┼───────────────────────────┐               │
-└─────────────────────────────────┼───────────────────────────┼───────────────┘
-                                  │                           │
-                                  │                           │
-┌─────────────────────────────────┼───────────────────────────┼──────────────────┐
-│        基础配置表                 │                           │                  │
-├─────────────────────────────────┼───────────────────────────┼──────────────────┤
-│  lawyer_legal_problem_scenario (法律问题场景)                 │                  │
-│       ▲                                                     │                  │
-│       │ (1:N)                                               │                  │
-└─────────────────────────────────────────────────────────────┼──────────────────┘
-                                                              │
-┌─────────────────────────────────────────────────────────────┼──────────────────┐
-│                   核心业务表                                  │                  │
-├─────────────────────────────────────────────────────────────┼──────────────────┤
-│  lawyer_consultation_order (咨询订单) ◄──────────────────────┼───────────────────┤
-│       │                                                     │                  │
-│       │ (1:1)                                               │                  │
-│       ├──► lawyer_consultation_review (咨询评价)             │                  │
-│       │                                                     │                  │
-│       │ (1:N)                                               │                  │
-│       ├──► lawyer_payment_transaction (支付交易)             │                  │
-│       │                                                     │                  │
-│       │ (1:N)                                               │                  │
-│       ├──► lawyer_chat_session (聊天会话)                    │                  │
-│       │       │                                             │                  │
-│       │       │ (1:N)                                       │                  │
-│       │       └──► lawyer_chat_message (聊天消息)            │                  │
-│       │                                                     │                  │
-│                                                             │                  │
-│  lawyer_service_area (律师服务领域)                           │                  │
-│       │                                                     │                  │
-│       ├──► lawyer_user                                      │                  │
-│       └──► lawyer_legal_problem_scenario                    │                  │
-└─────────────────────────────────────────────────────────────┼──────────────────┘
-                                                              │
-┌─────────────────────────────────────────────────────────────┼──────────────────┐
-│                     扩展功能表                                │                  │
-├─────────────────────────────────────────────────────────────┼──────────────────┤
-│  lawyer_img (律师图片) ────► lawyer_user                      │                  │
-│                                                             │                  │
-│  lawyer_common_question (常见问题) ────► lawyer_legal_problem_scenario           │
-│                                                             │                  │
-│  lawyer_ai_interaction_log (AI交互日志) ────► life_user       │                  │
-│                               └───► lawyer_legal_problem_scenario              │
-│                                                             │                  │
-│  lawyer_user_search_history (搜索历史) ────► life_user       │                   │
-└─────────────────────────────────────────────────────────────┴──────────────────┘
-```
-
----
-
-## 四、表关系详细说明
-
-### 4.1 核心业务关系链
-
-#### 业务流程:咨询订单 → 聊天会话 → 聊天消息
-```
-life_user (客户端用户)
-    └──► lawyer_consultation_order (咨询订单)
-            ├──► lawyer_chat_session (聊天会话)
-            │       └──► lawyer_chat_message (聊天消息) [多条]
-            │
-            ├──► lawyer_payment_transaction (支付交易) [多条]
-            │
-            └──► lawyer_consultation_review (咨询评价) [1条]
-```
-
-#### 律师信息关系链
-```
-lawyer_user (律师用户)
-    ├──► lawyer_img (律师图片) [多条]
-    ├──► lawyer_service_area (服务领域) [多条]
-    │       └──► lawyer_legal_problem_scenario (法律问题场景)
-    │
-    └──► lawyer_consultation_order (咨询订单) [多条]
-```
-
-#### 法律问题场景关系链
-```
-lawyer_legal_problem_scenario (法律问题场景) [树形结构]
-    ├──► lawyer_service_area (律师服务领域) [多条]
-    │       └──► lawyer_user (律师用户)
-    │
-    ├──► lawyer_consultation_order (咨询订单) [多条]
-    │
-    ├──► lawyer_common_question (常见问题) [多条]
-    │
-    └──► lawyer_ai_interaction_log (AI交互日志) [多条]
-```
-
-### 4.2 外键关系汇总
-
-| 子表 | 外键字段 | 父表 | 关系类型 | 说明 |
-|------|---------|------|---------|------|
-| `lawyer_img` | `lawyer_id` | `lawyer_user` | 多对一 | 多个图片属于一个律师 |
-| `lawyer_service_area` | `lawyer_user_id` | `lawyer_user` | 多对一 | 多个服务领域属于一个律师 |
-| `lawyer_service_area` | `problem_scenar_id` | `lawyer_legal_problem_scenario` | 多对一 | 多个关联记录关联一个法律问题场景 |
-| `lawyer_consultation_order` | `client_user_id` | `life_user` | 多对一 | 多个订单属于一个客户端用户 |
-| `lawyer_consultation_order` | `lawyer_user_id` | `lawyer_user` | 多对一 | 多个订单属于一个律师 |
-| `lawyer_consultation_order` | `problem_scenar_id` | `lawyer_legal_problem_scenario` | 多对一 | 多个订单关联一个法律问题场景 |
-| `lawyer_chat_session` | `consultation_order_id` | `lawyer_consultation_order` | 多对一 | 多个会话属于一个订单 |
-| `lawyer_chat_session` | `client_user_id` | `life_user` | 多对一 | 多个会话属于一个客户端用户 |
-| `lawyer_chat_session` | `lawyer_user_id` | `lawyer_user` | 多对一 | 多个会话属于一个律师 |
-| `lawyer_chat_session` | `last_message_id` | `lawyer_chat_message` | 多对一 | 会话的最后一条消息 |
-| `lawyer_chat_message` | `chat_session_id` | `lawyer_chat_session` | 多对一 | 多条消息属于一个会话 |
-| `lawyer_chat_message` | `consultation_order_id` | `lawyer_consultation_order` | 多对一 | 多条消息属于一个订单(冗余) |
-| `lawyer_common_question` | `problem_scenar_id` | `lawyer_legal_problem_scenario` | 多对一 | 多个常见问题关联一个法律问题场景 |
-| `lawyer_consultation_review` | `consultation_order_id` | `lawyer_consultation_order` | 一对一 | 一个订单对应一个评价 |
-| `lawyer_consultation_review` | `client_user_id` | `life_user` | 多对一 | 多个评价属于一个客户端用户 |
-| `lawyer_consultation_review` | `lawyer_user_id` | `lawyer_user` | 多对一 | 多个评价属于一个律师 |
-| `lawyer_payment_transaction` | `consultation_order_id` | `lawyer_consultation_order` | 多对一 | 多笔交易属于一个订单 |
-| `lawyer_payment_transaction` | `client_user_id` | `life_user` | 多对一 | 多笔交易属于一个客户端用户 |
-| `lawyer_ai_interaction_log` | `client_user_id` | `life_user` | 多对一 | 多条日志属于一个客户端用户 |
-| `lawyer_ai_interaction_log` | `problem_scenar_id` | `lawyer_legal_problem_scenario` | 多对一 | 多条日志关联一个法律问题场景 |
-| `lawyer_user_search_history` | `client_user_id` | `life_user` | 多对一 | 多条搜索历史属于一个客户端用户 |
-
-### 4.3 自关联关系
-
-| 表名 | 自关联字段 | 说明 |
-|------|-----------|------|
-| `lawyer_legal_problem_scenario` | `parent_id` | 树形结构,通过 `parent_id` 关联自身,实现三级分类 |
-
----
-
-## 五、数据完整性约束
-
-### 5.1 唯一约束
-- `lawyer_user.phone` - 手机号唯一
-- `lawyer_consultation_order.order_number` - 订单编号唯一
-- `lawyer_payment_transaction.transaction_number` - 交易流水号唯一
-- `lawyer_service_area(lawyer_user_id, problem_scenar_id)` - 律师与法律问题场景的组合唯一
-- `lawyer_consultation_review(consultation_order_id, delete_flag)` - 一个订单只能有一个有效评价
-
-### 5.2 逻辑删除
-所有表都使用 `delete_flag` 字段进行逻辑删除:
-- `delete_flag = 0` - 未删除
-- `delete_flag = 1` - 已删除
-
-### 5.3 状态字段
-- **订单状态**: `order_status` (0:待支付, 1:已支付, 2:进行中, 3:已完成, 4:已取消)
-- **支付状态**: `payment_status` (0:未支付, 1:已支付)
-- **交易状态**: `transaction_status` (0:待支付, 1:支付成功, 2:支付失败, 3:已退款)
-- **会话状态**: `status` (0:未开始, 1:进行中, 2:已结束)
-- **认证状态**: `certification_status` (0:未认证, 1:认证中, 2:已认证, 3:认证失败)
-
----
-
-## 六、索引设计建议
-
-### 6.1 主键索引
-所有表的主键 `id` 自动创建主键索引。
-
-### 6.2 外键索引
-所有外键字段都创建索引,提高关联查询性能。
-
-### 6.3 联合索引
-根据常用查询场景创建联合索引:
-
-| 表名 | 联合索引 | 说明 |
-|------|---------|------|
-| `lawyer_user` | `(status, delete_flag)` | 查询可用律师 |
-| `lawyer_consultation_order` | `(client_user_id, order_status, delete_flag)` | 用户订单查询(关联life_user) |
-| `lawyer_consultation_order` | `(lawyer_user_id, order_status, delete_flag)` | 律师订单查询 |
-| `lawyer_chat_message` | `(chat_session_id, message_timestamp, delete_flag)` | 会话消息查询 |
-| `lawyer_service_area` | `(lawyer_user_id, problem_scenar_id, delete_flag)` | 律师服务领域查询 |
-| `lawyer_img` | `(lawyer_id, img_type, delete_flag)` | 律师图片查询 |
-
-### 6.4 时间字段索引
-- `created_time` - 创建时间索引,用于按时间排序
-- `updated_time` - 更新时间索引
-- `last_message_time` - 最后消息时间索引
-- `message_timestamp` - 消息时间戳索引
-
----
-
-## 七、业务场景查询示例
-
-### 7.1 查询律师的详细信息
-```sql
-SELECT lu.*
-FROM lawyer_user lu
-WHERE lu.id = ? AND lu.delete_flag = 0;
-```
-
-### 7.2 查询律师的服务领域
-```sql
-SELECT lsa.*, lps.name as problem_scenario_name
-FROM lawyer_service_area lsa
-INNER JOIN lawyer_legal_problem_scenario lps ON lsa.problem_scenar_id = lps.id
-WHERE lsa.lawyer_user_id = ? AND lsa.delete_flag = 0 AND lsa.status = 1
-ORDER BY lsa.sort_order;
-```
-
-### 7.3 查询用户的订单列表
-```sql
-SELECT lco.*, lu.name as lawyer_name, lps.name as problem_scenario_name
-FROM lawyer_consultation_order lco
-LEFT JOIN lawyer_user lu ON lco.lawyer_user_id = lu.id
-LEFT JOIN lawyer_legal_problem_scenario lps ON lco.problem_scenar_id = lps.id
-WHERE lco.client_user_id = ? AND lco.delete_flag = 0
-ORDER BY lco.created_time DESC;
-```
-
-### 7.4 查询订单的聊天记录
-```sql
-SELECT lcm.*
-FROM lawyer_chat_message lcm
-WHERE lcm.consultation_order_id = ? AND lcm.delete_flag = 0
-ORDER BY lcm.message_timestamp ASC;
-```
-
-### 7.5 查询律师的评价统计
-```sql
-SELECT 
-    COUNT(*) as total_reviews,
-    AVG(rating) as avg_rating,
-    AVG(service_quality) as avg_service_quality,
-    AVG(response_speed) as avg_response_speed,
-    AVG(professional_level) as avg_professional_level
-FROM lawyer_consultation_review
-WHERE lawyer_user_id = ? AND delete_flag = 0;
-```
-
----
-
-## 八、注意事项
-
-1. **统一字段命名规范**:
-   - 所有表都包含标准字段:`delete_flag`, `created_time`, `created_user_id`, `updated_time`, `updated_user_id`
-   - 主键统一使用 `id` (INT, AUTO_INCREMENT)
-   - 外键统一命名为 `xxx_id`
-
-2. **逻辑删除**:
-   - 所有表都使用 `delete_flag` 字段进行逻辑删除(0:未删除, 1:已删除)
-   - 使用 `@TableLogic` 注解
-
-3. **索引设计**:
-   - 主键自动创建索引
-   - 外键字段创建索引
-   - 常用查询字段创建联合索引(如:`lawyer_user_id + status + delete_flag`)
-
-4. **金额字段**:
-   - 统一使用 INT 类型,单位:分(避免浮点数精度问题)
-
-5. **时间字段**:
-   - `created_time`: DEFAULT CURRENT_TIMESTAMP
-   - `updated_time`: DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
-
-6. **数据一致性**:
-   - 订单状态变更时,需要同步更新相关表的记录
-   - 评价添加后,需要更新律师的评分统计(`lawyer_user.service_score`等)
-
-7. **树形结构**:
-   - `lawyer_legal_problem_scenario` 使用 `parent_id` 实现三级分类
-   - 查询子节点时使用递归查询或维护 `parent_code` 路径
-
----
-
-## 九、表状态统计
-
-### 已完成(13个表)
-✅ lawyer_user  
-✅ lawyer_legal_problem_scenario  
-✅ lawyer_img  
-✅ lawyer_service_area  
-✅ lawyer_consultation_order  
-✅ lawyer_chat_session  
-✅ lawyer_chat_message  
-✅ lawyer_common_question  
-✅ lawyer_consultation_review  
-✅ lawyer_payment_transaction  
-✅ lawyer_ai_interaction_log  
-✅ lawyer_user_search_history  
-✅ life_user - 客户端用户表(已存在)
-

+ 0 - 578
QueryBuilder使用示例.md

@@ -1,578 +0,0 @@
-# QueryBuilder 通用查询工具类使用指南
-
-## 一、功能特点
-
-- ✅ **自动构建查询条件**:根据对象非空字段自动生成查询条件
-- ✅ **支持分页查询**:内置分页功能
-- ✅ **支持模糊查询**:可指定字段或全局设置String字段模糊查询
-- ✅ **支持批量查询**:集合类型字段自动使用IN查询
-- ✅ **支持范围查询**:识别Start/End后缀字段
-- ✅ **链式调用**:流畅的API设计
-- ✅ **类型安全**:自动处理序列化问题,避免类型转换错误
-- ✅ **字段过滤**:自动跳过静态字段、transient字段、不存在字段
-
-## 二、基本使用
-
-### 1. 简单查询
-
-```java
-// Controller中
-@GetMapping("/getList")
-public R<List<LawyerUser>> getList(@ModelAttribute LawyerUser query) {
-    List<LawyerUser> list = QueryBuilder.of(query)
-        .build()
-        .list(lawyerUserService);
-    return R.data(list);
-}
-```
-
-**请求示例:**
-```
-GET /lawyer/user/getList?name=张三&status=1
-```
-
-**说明:**
-- 所有非空字段都会作为等值查询条件(`=`)
-- String类型字段默认使用等值查询
-
-### 2. 分页查询
-
-```java
-@GetMapping("/getPage")
-public R<IPage<LawyerUser>> getPage(
-    @ModelAttribute LawyerUser query,
-    @RequestParam(defaultValue = "1") int pageNum,
-    @RequestParam(defaultValue = "10") int pageSize) {
-    
-    IPage<LawyerUser> page = QueryBuilder.of(query)
-        .page(pageNum, pageSize)  // 设置分页
-        .build()
-        .page(lawyerUserService);  // 执行分页查询
-    
-    return R.data(page);
-}
-```
-
-### 3. 模糊查询
-
-#### 方式一:指定字段模糊查询(推荐)
-
-```java
-@GetMapping("/search")
-public R<List<LawyerUser>> search(@ModelAttribute LawyerUser query) {
-    List<LawyerUser> list = QueryBuilder.of(query)
-        .likeFields("name", "phone")  // 指定 name 和 phone 字段使用模糊查询
-        .build()
-        .list(lawyerUserService);
-    return R.data(list);
-}
-```
-
-**请求示例:**
-```
-GET /lawyer/user/search?name=张&phone=138
-```
-
-**生成的SQL:**
-```sql
-WHERE name LIKE '%张%' AND phone LIKE '%138%'
-```
-
-#### 方式二:全局String字段模糊查询
-
-```java
-@GetMapping("/search")
-public R<List<LawyerUser>> search(@ModelAttribute LawyerUser query) {
-    List<LawyerUser> list = QueryBuilder.of(query)
-        .stringFieldLike(true)  // 所有String类型字段都使用模糊查询
-        .build()
-        .list(lawyerUserService);
-    return R.data(list);
-}
-```
-
-#### 方式三:使用_Like后缀字段(自动识别)
-
-在实体类中添加_Like后缀字段(仅用于查询,不需要对应数据库字段):
-
-```java
-// 查询实体类(继承基础实体类)
-public class LawyerUserQuery extends LawyerUser {
-    private String name_Like;  // 模糊查询姓名
-    private String phone_Like;  // 模糊查询手机号
-}
-```
-
-```java
-// Controller中
-@GetMapping("/search")
-public R<List<LawyerUser>> search(@ModelAttribute LawyerUserQuery query) {
-    List<LawyerUser> list = QueryBuilder.of(query)
-        .build()
-        .list(lawyerUserService);
-    return R.data(list);
-}
-```
-
-**请求示例:**
-```
-GET /lawyer/user/search?name_Like=张&phone_Like=138
-```
-
-### 4. 批量查询(IN查询)
-
-在实体类中添加_List后缀字段:
-
-```java
-// 查询实体类(继承基础实体类)
-public class LawyerUserQuery extends LawyerUser {
-    private List<Integer> id_List;  // 批量查询ID
-    private List<String> status_List;  // 批量查询状态
-}
-```
-
-```java
-// Controller中
-@GetMapping("/getByIds")
-public R<List<LawyerUser>> getByIds(@ModelAttribute LawyerUserQuery query) {
-    List<LawyerUser> list = QueryBuilder.of(query)
-        .build()
-        .list(lawyerUserService);
-    return R.data(list);
-}
-```
-
-**请求示例:**
-```
-GET /lawyer/user/getByIds?id_List=1&id_List=2&id_List=3
-```
-
-**生成的SQL:**
-```sql
-WHERE id IN (1, 2, 3)
-```
-
-### 5. 范围查询
-
-在实体类中添加_Start/_End后缀字段:
-
-```java
-// 查询实体类(继承基础实体类)
-public class LawyerUserQuery extends LawyerUser {
-    private Date createdTime_Start;  // 创建时间开始
-    private Date createdTime_End;    // 创建时间结束
-    private Integer serviceCount_Start;  // 服务次数范围开始
-    private Integer serviceCount_End;    // 服务次数范围结束
-}
-```
-
-```java
-// Controller中
-@GetMapping("/getByTimeRange")
-public R<List<LawyerUser>> getByTimeRange(@ModelAttribute LawyerUserQuery query) {
-    List<LawyerUser> list = QueryBuilder.of(query)
-        .build()
-        .list(lawyerUserService);
-    return R.data(list);
-}
-```
-
-**请求示例:**
-```
-GET /lawyer/user/getByTimeRange?createdTime_Start=2025-01-01&createdTime_End=2025-01-31
-```
-
-**生成的SQL:**
-```sql
-WHERE created_time >= '2025-01-01' AND created_time <= '2025-01-31'
-```
-
-## 三、组合查询示例
-
-### 复杂查询场景
-
-```java
-@GetMapping("/complexQuery")
-public R<IPage<LawyerUser>> complexQuery(
-    @ModelAttribute LawyerUserQuery query,
-    @RequestParam(defaultValue = "1") int pageNum,
-    @RequestParam(defaultValue = "10") int pageSize) {
-    
-    IPage<LawyerUser> page = QueryBuilder.of(query)
-        .page(pageNum, pageSize)           // 分页
-        .likeFields("name", "phone")        // 指定字段模糊查询
-        .ignoreEmptyStr(true)               // 忽略空字符串(默认true)
-        .build()
-        .page(lawyerUserService);
-    
-    return R.data(page);
-}
-```
-
-**请求示例:**
-```
-GET /lawyer/user/complexQuery?name=张&phone=138&status=1&createdTime_Start=2025-01-01&createdTime_End=2025-01-31&pageNum=1&pageSize=10
-```
-
-**生成的SQL:**
-```sql
-WHERE name LIKE '%张%' 
-  AND phone LIKE '%138%'
-  AND status = 1
-  AND created_time >= '2025-01-01'
-  AND created_time <= '2025-01-31'
-LIMIT 10 OFFSET 0
-```
-
-## 四、API方法说明
-
-### QueryBuilder 方法
-
-#### 1. `of(T queryEntity)` - 创建查询构建器
-```java
-QueryBuilder.of(queryEntity)
-```
-
-#### 2. `ignoreEmptyStr(boolean ignore)` - 设置是否忽略空字符串
-```java
-QueryBuilder.of(query)
-    .ignoreEmptyStr(true)   // 默认true,忽略空字符串
-    .build()
-    .list(service);
-
-QueryBuilder.of(query)
-    .ignoreEmptyStr(false)  // 保留空字符串作为查询条件
-    .build()
-    .list(service);
-```
-
-#### 3. `stringFieldLike(boolean like)` - 设置String字段是否默认模糊查询
-```java
-QueryBuilder.of(query)
-    .stringFieldLike(true)   // 所有String字段使用模糊查询
-    .build()
-    .list(service);
-
-QueryBuilder.of(query)
-    .stringFieldLike(false)  // 所有String字段使用等值查询(默认)
-    .build()
-    .list(service);
-```
-
-#### 4. `likeFields(String... fieldNames)` - 指定字段使用模糊查询
-```java
-QueryBuilder.of(query)
-    .likeFields("name")              // 单个字段
-    .build()
-    .list(service);
-
-QueryBuilder.of(query)
-    .likeFields("name", "phone")     // 多个字段
-    .build()
-    .list(service);
-```
-
-#### 5. `page(int pageNum, int pageSize)` - 设置分页参数
-```java
-QueryBuilder.of(query)
-    .page(1, 10)  // 第1页,每页10条
-    .build()
-    .page(service);
-```
-
-#### 6. `page(Page<T> page)` - 设置分页对象
-```java
-Page<LawyerUser> pageObj = new Page<>(1, 10);
-QueryBuilder.of(query)
-    .page(pageObj)
-    .build()
-    .page(service);
-```
-
-#### 7. `build()` - 构建查询条件
-```java
-QueryResult<LawyerUser> result = QueryBuilder.of(query)
-    .build();  // 返回 QueryResult 对象
-```
-
-### QueryResult 方法
-
-#### 1. `list(IService<T> service)` - 列表查询
-```java
-List<LawyerUser> list = builder.build().list(lawyerUserService);
-```
-
-#### 2. `page(IService<T> service)` - 分页查询
-```java
-IPage<LawyerUser> page = builder.page(1, 10).build().page(lawyerUserService);
-```
-
-#### 3. `one(IService<T> service)` - 单条查询
-```java
-LawyerUser user = builder.build().one(lawyerUserService);
-```
-
-#### 4. `count(IService<T> service)` - 计数查询
-```java
-long count = builder.build().count(lawyerUserService);
-```
-
-#### 5. `getWrapper()` - 获取查询条件(用于调试)
-```java
-QueryWrapper<LawyerUser> wrapper = builder.build().getWrapper();
-System.out.println(wrapper.getTargetSql());  // 打印SQL
-```
-
-## 五、命名规则
-
-### 1. 模糊查询字段
-
-**方式一:使用 likeFields 方法指定**
-```java
-.likeFields("name", "phone")  // 在代码中指定
-```
-
-**方式二:字段名以 `_Like` 结尾**
-- 字段名以 `_Like` 结尾
-- 示例:`name_Like` → 查询 `name` 字段,使用 `LIKE '%value%'`
-
-### 2. 批量查询字段
-- 字段类型为 `Collection`(List、Set等)
-- 字段名以 `_List` 结尾(推荐)
-- 示例:`id_List` → 查询 `id` 字段,使用 `IN (1,2,3)`
-
-### 3. 范围查询字段
-- 字段名以 `_Start` 或 `_End` 结尾
-- 成对出现:`xxx_Start` 和 `xxx_End`
-- 示例:
-  - `createdTime_Start` → `createdTime >= value`
-  - `createdTime_End` → `createdTime <= value`
-
-## 六、查询优先级
-
-### 模糊查询优先级
-
-1. **最高优先级**:`likeFields()` 方法指定的字段
-2. **次优先级**:字段名以 `_Like` 结尾的字段
-3. **全局设置**:`stringFieldLike(true)` 时,所有String字段使用模糊查询
-4. **默认**:等值查询(`=`)
-
-### 示例
-
-```java
-QueryBuilder.of(query)
-    .stringFieldLike(true)      // 全局:所有String字段模糊查询
-    .likeFields("name")         // 指定:name字段模糊查询(优先级更高)
-    .build()
-    .list(service);
-```
-
-**结果:**
-- `name` 字段:使用模糊查询(`likeFields` 优先级更高)
-- 其他String字段:使用模糊查询(`stringFieldLike` 生效)
-- 非String字段:使用等值查询
-
-## 七、完整示例
-
-### 实体类定义
-
-```java
-import java.util.Date;
-import java.util.List;
-import lombok.Data;
-
-@Data
-public class LawyerUserQuery extends LawyerUser {
-    // 模糊查询字段(方式一:在代码中指定,不需要在实体类中定义)
-    // 方式二:使用_Like后缀字段
-    private String name_Like;
-    private String phone_Like;
-    
-    // 批量查询字段
-    private List<Integer> id_List;
-    private List<Integer> status_List;
-    
-    // 范围查询字段
-    private Date createdTime_Start;
-    private Date createdTime_End;
-    private Integer serviceCount_Start;
-    private Integer serviceCount_End;
-}
-```
-
-### Controller 完整示例
-
-```java
-import org.springframework.web.bind.annotation.*;
-import lombok.RequiredArgsConstructor;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-
-@RestController
-@RequestMapping("/lawyer/user")
-@RequiredArgsConstructor
-public class LawyerUserController {
-    
-    private final LawyerUserService lawyerUserService;
-    
-    /**
-     * 通用查询接口(支持所有查询方式)
-     */
-    @GetMapping("/query")
-    public R<IPage<LawyerUser>> query(
-        @ModelAttribute LawyerUserQuery query,
-        @RequestParam(defaultValue = "1") int pageNum,
-        @RequestParam(defaultValue = "10") int pageSize) {
-        
-        IPage<LawyerUser> page = QueryBuilder.of(query)
-            .page(pageNum, pageSize)
-            .likeFields("name", "phone")  // 指定字段模糊查询
-            .build()
-            .page(lawyerUserService);
-        
-        return R.data(page);
-    }
-    
-    /**
-     * 简单查询(只使用等值查询)
-     */
-    @GetMapping("/simple")
-    public R<List<LawyerUser>> simple(@ModelAttribute LawyerUser query) {
-        List<LawyerUser> list = QueryBuilder.of(query)
-            .build()
-            .list(lawyerUserService);
-        return R.data(list);
-    }
-    
-    /**
-     * 全局模糊查询(所有String字段都模糊查询)
-     */
-    @GetMapping("/search")
-    public R<List<LawyerUser>> search(@ModelAttribute LawyerUser query) {
-        List<LawyerUser> list = QueryBuilder.of(query)
-            .stringFieldLike(true)  // 所有String字段模糊查询
-            .build()
-            .list(lawyerUserService);
-        return R.data(list);
-    }
-}
-```
-
-## 八、注意事项
-
-### 1. 字段过滤规则
-
-- **自动跳过**:静态字段(`static`)、transient字段(`transient`)
-- **自动跳过**:`@TableField(exist = false)` 标记的字段
-- **自动跳过**:空值(`null`)、空字符串(如果启用 `ignoreEmptyStr`)
-- **自动跳过**:空集合
-
-### 2. 字段名映射
-
-- **优先使用**:`@TableField` 注解的 `value` 属性
-- **默认规则**:驼峰命名转下划线命名(`userName` → `user_name`)
-
-### 3. 序列化安全
-
-- 自动过滤不可序列化的对象
-- 只支持基本类型:Number、String、Boolean、Date等
-- 集合元素会自动过滤不可序列化的项
-
-### 4. 性能考虑
-
-- 批量查询(IN)建议限制集合大小,避免SQL过长
-- 模糊查询(LIKE)在大数据量时可能较慢,建议添加索引
-
-### 5. 日期处理
-
-- 日期字段会自动处理空字符串绑定问题
-- 支持 `java.util.Date`、`java.sql.Date`、`LocalDate`、`LocalDateTime`
-
-## 九、常见问题
-
-### Q1: 如何让某个String字段使用等值查询,其他字段使用模糊查询?
-
-```java
-// 方式一:使用全局模糊查询,然后排除特定字段
-QueryBuilder.of(query)
-    .stringFieldLike(true)  // 全局模糊查询
-    .build()
-    .list(service);
-// 注意:没有单独排除的方法,可以使用Like后缀字段的方式
-    
-// 方式二:只指定需要模糊查询的字段
-QueryBuilder.of(query)
-    .likeFields("name", "phone")  // 只指定这些字段模糊查询
-    .build()
-    .list(service);
-```
-
-### Q2: 如何同时使用等值查询和模糊查询?
-
-```java
-// 在实体类中定义两个字段
-// 查询实体类(继承基础实体类)
-public class LawyerUserQuery extends LawyerUser {
-    private String name;        // 等值查询
-    private String name_Like;    // 模糊查询
-}
-
-// 使用时
-QueryBuilder.of(query)
-    .build()  // name使用等值查询,name_Like使用模糊查询
-    .list(service);
-```
-
-### Q3: 如何查询空值?
-
-```java
-QueryBuilder.of(query)
-    .ignoreEmptyStr(false)  // 不忽略空字符串
-    .build()
-    .list(service);
-```
-
-### Q4: 如何调试生成的SQL?
-
-```java
-QueryResult<LawyerUser> result = QueryBuilder.of(query).build();
-QueryWrapper<LawyerUser> wrapper = result.getWrapper();
-System.out.println(wrapper.getTargetSql());  // 打印SQL语句
-```
-
-## 十、最佳实践
-
-### 1. 推荐使用方式
-
-```java
-// ✅ 推荐:指定字段模糊查询
-QueryBuilder.of(query)
-    .likeFields("name", "phone")
-    .build()
-    .list(service);
-
-// ✅ 推荐:使用_Like后缀字段(更灵活)
-// 在实体类中定义 name_Like 字段
-QueryBuilder.of(query)
-    .build()
-    .list(service);
-```
-
-### 2. 不推荐使用方式
-
-```java
-// ❌ 不推荐:全局String字段模糊查询(可能影响不需要模糊的字段)
-QueryBuilder.of(query)
-    .stringFieldLike(true)  // 除非你真的需要所有String字段都模糊
-    .build()
-    .list(service);
-```
-
-### 3. 性能优化建议
-
-- 模糊查询字段建议添加数据库索引
-- 批量查询(IN)建议限制集合大小(如:最多1000个)
-- 复杂查询建议使用分页,避免一次性查询大量数据
-
----
-
-**总结**:`QueryBuilder` 提供了强大而灵活的查询能力,只需要传入对象,就能自动构建各种查询条件,大大简化了开发工作。通过合理使用 `likeFields()` 和 `stringFieldLike()` 方法,可以灵活控制模糊查询行为。

+ 29 - 10
alien-entity/src/main/java/shop/alien/entity/store/vo/LawFirmReconciliationVO.java

@@ -1,11 +1,13 @@
 package shop.alien.entity.store.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -30,21 +32,38 @@ public class LawFirmReconciliationVO implements Serializable {
     @ApiModelProperty(value = "总订单数量")
     private Long totalOrderCount;
 
-    @ApiModelProperty(value = "总订单金额(单位:分)")
-    private Long totalOrderAmount;
-
     @ApiModelProperty(value = "总订单金额(单位:元)")
     private String totalOrderAmountYuan;
 
-    @ApiModelProperty(value = "平台信息服务费(单位:分)")
-    private Long platformServiceFee;
-
     @ApiModelProperty(value = "平台信息服务费(单位:元)")
     private String platformServiceFeeYuan;
 
-    @ApiModelProperty(value = "平台佣金比例(百分比,如5.0表示5%)")
-    private Float platformCommissionRatio;
+    @ApiModelProperty(value = "律师ID")
+    private Integer lawyerId;
+
+    @ApiModelProperty(value = "律师名称")
+    private String lawyerName;
+
+    @ApiModelProperty(value = "律师头像")
+    private String headImg;
+
+    @ApiModelProperty(value = "律师执业证号")
+    private String lawyerCertificateNo;
+
+    @ApiModelProperty(value = "订单编号")
+    private String orderNumber;
+
+    @ApiModelProperty(value = "订单金额(单位:分)")
+    private Integer orderAmount;
+
+    @ApiModelProperty(value = "购买时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date orderTime;
+
+    @ApiModelProperty(value = "客户端用户ID")
+    private Integer clientUserId;
+
+    @ApiModelProperty(value = "客户端用户名称")
+    private String clientUserName;
 
-    @ApiModelProperty(value = "律师对账明细列表")
-    private List<LawyerReconciliationDetailVO> lawyerDetails;
 }

+ 52 - 21
alien-entity/src/main/java/shop/alien/mapper/LawFirmMapper.java

@@ -1,18 +1,19 @@
 package shop.alien.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import shop.alien.entity.store.LawFirm;
-import shop.alien.entity.store.vo.LawyerReconciliationDetailVO;
+import shop.alien.entity.store.vo.LawFirmReconciliationVO;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 /**
- * <p>
  * 律所表 Mapper 接口
- * </p>
  *
  * @author system
  * @since 2025-01-XX
@@ -23,43 +24,73 @@ public interface LawFirmMapper extends BaseMapper<LawFirm> {
     /**
      * 查询律所对账统计信息
      *
-     * @param firmId 律所ID
-     * @param startDate 开始日期
-     * @param endDate 结束日期
-     * @return 统计信息 Map,包含 order_count 和 total_amount
+     * @param firmId   律所ID(可选,不传则查询所有律所)
+     * @param firmName 律所名称(可选,模糊查询)
+     * @param startDate 开始日期(可选)
+     * @param endDate   结束日期(可选)
+     * @return 统计信息 Map,包含 order_count、total_amount、total_platform_service_fee
      */
-    java.util.Map<String, Object> getLawFirmReconciliationStatistics(
+    Map<String, Object> getLawFirmReconciliationStatistics(
             @Param("firmId") Integer firmId,
+            @Param("firmName") String firmName,
             @Param("startDate") Date startDate,
             @Param("endDate") Date endDate
     );
 
     /**
-     * 查询律所下律师的对账明细
+     * 查询所有律所的对账统计信息(按律所分组)
      *
-     * @param firmId 律所ID
-     * @param lawyerName 律师姓名(模糊查询)
+     * @param firmName 律所名称(可选,模糊查询)
      * @param startDate 开始日期
-     * @param endDate 结束日期
-     * @return 律师对账明细列表
+     * @param endDate   结束日期
+     * @return 律所对账统计列表
      */
-    List<LawyerReconciliationDetailVO> getLawyerReconciliationDetails(
+    List<LawFirmReconciliationVO> getAllLawFirmReconciliationStatistics(
+            @Param("firmName") String firmName,
+            @Param("startDate") Date startDate,
+            @Param("endDate") Date endDate
+    );
+
+    /**
+     * 查询律所下所有律师的对账统计信息(按律师分组)
+     *
+     * @param firmId   律所ID
+     * @param startDate 开始日期(可选)
+     * @param endDate   结束日期(可选)
+     * @return 律师对账统计列表
+     */
+    List<LawFirmReconciliationVO> getLawyerReconciliationStatistics(
             @Param("firmId") Integer firmId,
-            @Param("lawyerName") String lawyerName,
             @Param("startDate") Date startDate,
             @Param("endDate") Date endDate
     );
 
     /**
-     * 根据律所ID查询该律所下的所有律师ID列表
+     * 查询律所下所有律师的对账统计信息(按律师分组,支持律师名称模糊查询)
      *
-     * @param firmId 律所ID
-     * @param lawyerName 律师姓名(可选,模糊查询)
-     * @return 律师ID列表
+     * @param firmId    律所ID
+     * @param lawyerName 律师名称(可选,模糊查询)
+     * @param startDate 开始日期(可选)
+     * @param endDate   结束日期(可选)
+     * @return 律师对账统计列表
      */
-    List<Integer> getLawyerIdsByFirmId(
+    List<LawFirmReconciliationVO> getLawyerReconciliationStatisticsWithName(
             @Param("firmId") Integer firmId,
-            @Param("lawyerName") String lawyerName
+            @Param("lawyerName") String lawyerName,
+            @Param("startDate") Date startDate,
+            @Param("endDate") Date endDate
+    );
+
+    /**
+     * 查询律师的已完成订单列表(分页)
+     *
+     * @param page     分页对象
+     * @param lawyerId 律师ID
+     * @return 律师订单列表(分页)
+     */
+    IPage<LawFirmReconciliationVO> getLawyerOrderList(
+            Page<LawFirmReconciliationVO> page,
+            @Param("lawyerId") Integer lawyerId
     );
 }
 

+ 164 - 47
alien-entity/src/main/resources/mapper/LawFirmMapper.xml

@@ -12,10 +12,6 @@
         <result column="establishment_date" property="establishmentDate" />
         <result column="firm_type" property="firmType" />
         <result column="firm_scale" property="firmScale" />
-        <result column="province" property="province" />
-        <result column="city" property="city" />
-        <result column="district" property="district" />
-        <result column="address" property="address" />
         <result column="phone" property="phone" />
         <result column="fax" property="fax" />
         <result column="email" property="email" />
@@ -43,88 +39,209 @@
         <result column="updated_time" property="updatedTime" />
         <result column="updated_user_id" property="updatedUserId" />
         <result column="remark" property="remark" />
-        <result column="payment_account" property="paymentAccount" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
         id, firm_name, credit_code, short_name, english_name, establishment_date, firm_type, firm_scale,
-        province, city, district, address, phone, fax, email, website, introduction, logo,
+        phone, fax, email, website, introduction, logo,
         business_license_image, practice_license_no, practice_license_image, director_name, director_phone,
         director_email, lawyer_count, partner_count, status, certification_status, certification_fail_reason,
         certification_time, certification_reviewer_id, is_recommended, recommend_sort, delete_flag,
-        created_time, created_user_id, updated_time, updated_user_id, remark, payment_account
+        created_time, created_user_id, updated_time, updated_user_id, remark, platform_commission_ratio
     </sql>
 
-    <!-- 查询律所对账统计信息 -->
-    <select id="getLawFirmReconciliationStatistics" resultType="java.util.HashMap">
-        SELECT
-            COUNT(DISTINCT lco.id) as order_count,
-            COALESCE(SUM(lco.order_amount), 0) as total_amount
-        FROM lawyer_consultation_order lco
-        INNER JOIN lawyer_user lu ON lco.lawyer_user_id = lu.id
-        WHERE (lco.place_id = #{firmId} OR lu.firm_id = #{firmId})
-        AND lco.delete_flag = 0
-        AND lu.delete_flag = 0
-        AND lco.payment_status = 1
+    <!-- 订单查询公共条件 -->
+    <sql id="Order_Common_Where">
+        lco.delete_flag = 0
+        AND lco.order_status = 3
         <if test="startDate != null">
-            AND DATE(lco.order_time) &gt;= DATE(#{startDate})
+            AND lco.order_time &gt;= CONCAT(#{startDate}, ' 00:00:00')
         </if>
         <if test="endDate != null">
-            AND DATE(lco.order_time) &lt;= DATE(#{endDate})
+            AND lco.order_time &lt;= CONCAT(#{endDate}, ' 23:59:59')
         </if>
+    </sql>
+
+    <!-- 查询律所对账统计信息 -->
+    <select id="getLawFirmReconciliationStatistics" resultType="java.util.HashMap">
+        <choose>
+            <when test="firmId != null">
+                <!-- 指定律所ID时,从律所表开始,确保即使没有订单也返回 -->
+                SELECT
+                    COUNT(DISTINCT lco.id) as order_count,
+                    COALESCE(SUM(lco.lawyer_earnings), 0) as total_amount,
+                    COALESCE(SUM(lco.consultation_fee), 0) as total_platform_service_fee
+                FROM law_firm lf
+                LEFT JOIN lawyer_consultation_order lco ON lco.place_id = lf.id
+                    AND lco.delete_flag = 0
+                    AND lco.order_status = 3
+                    <if test="startDate != null">
+                        AND lco.order_time &gt;= CONCAT(#{startDate}, ' 00:00:00')
+                    </if>
+                    <if test="endDate != null">
+                        AND lco.order_time &lt;= CONCAT(#{endDate}, ' 23:59:59')
+                    </if>
+                WHERE lf.delete_flag = 0
+                    AND lf.id = #{firmId}
+            </when>
+            <otherwise>
+                <!-- 未指定律所ID时,从订单表开始 -->
+                SELECT
+                    COUNT(DISTINCT lco.id) as order_count,
+                    COALESCE(SUM(lco.lawyer_earnings), 0) as total_amount,
+                    COALESCE(SUM(lco.consultation_fee), 0) as total_platform_service_fee
+                FROM lawyer_consultation_order lco
+                LEFT JOIN law_firm lf ON lco.place_id = lf.id
+                    AND lf.delete_flag = 0
+                WHERE
+                <include refid="Order_Common_Where"/>
+                <if test="firmName != null and firmName != ''">
+                    AND lf.firm_name LIKE CONCAT('%', #{firmName}, '%')
+                </if>
+            </otherwise>
+        </choose>
     </select>
 
-    <!-- 查询律所下律师的对账明细 -->
-    <resultMap id="LawyerReconciliationDetailResultMap" type="shop.alien.entity.store.vo.LawyerReconciliationDetailVO">
+    <!-- 查询所有律所的对账统计信息(按律所分组) -->
+    <resultMap id="LawFirmReconciliationStatisticsResultMap" type="shop.alien.entity.store.vo.LawFirmReconciliationVO">
+        <result column="firm_id" property="firmId" />
+        <result column="firm_name" property="firmName" />
+        <result column="order_count" property="totalOrderCount" />
+        <result column="total_amount_yuan" property="totalOrderAmountYuan" jdbcType="VARCHAR" />
+        <result column="commission_fee_yuan" property="platformServiceFeeYuan" jdbcType="VARCHAR" />
+    </resultMap>
+
+    <!-- 查询律所下所有律师的对账统计信息(按律师分组) -->
+    <resultMap id="LawyerReconciliationStatisticsResultMap" type="shop.alien.entity.store.vo.LawFirmReconciliationVO">
         <result column="lawyer_id" property="lawyerId" />
         <result column="lawyer_name" property="lawyerName" />
         <result column="head_img" property="headImg" />
         <result column="lawyer_certificate_no" property="lawyerCertificateNo" />
-        <result column="order_count" property="orderCount" />
-        <result column="order_amount" property="orderAmount" />
-        <result column="platform_service_fee" property="platformServiceFee" />
+        <result column="firm_id" property="firmId" />
+        <result column="firm_name" property="firmName" />
+        <result column="order_count" property="totalOrderCount" />
+        <result column="total_amount_yuan" property="totalOrderAmountYuan" jdbcType="VARCHAR" />
+        <result column="commission_fee_yuan" property="platformServiceFeeYuan" jdbcType="VARCHAR" />
     </resultMap>
 
-    <select id="getLawyerReconciliationDetails" resultMap="LawyerReconciliationDetailResultMap">
+    <select id="getAllLawFirmReconciliationStatistics" resultMap="LawFirmReconciliationStatisticsResultMap">
+        SELECT
+            lf.id as firm_id,
+            lf.firm_name,
+            COUNT(DISTINCT lco.id) as order_count,
+            CAST(ROUND(COALESCE(SUM(lco.lawyer_earnings), 0) / 100.0, 2) AS CHAR) as total_amount_yuan,
+            CAST(ROUND(COALESCE(SUM(lco.consultation_fee), 0) / 100.0, 2) AS CHAR) as commission_fee_yuan
+        FROM law_firm lf
+        LEFT JOIN lawyer_consultation_order lco ON lco.place_id = lf.id
+            AND lco.delete_flag = 0
+            AND lco.order_status = 3
+            <if test="startDate != null">
+                AND lco.order_time &gt;= CONCAT(#{startDate}, ' 00:00:00')
+            </if>
+            <if test="endDate != null">
+                AND lco.order_time &lt;= CONCAT(#{endDate}, ' 23:59:59')
+            </if>
+        WHERE lf.delete_flag = 0
+        <if test="firmName != null and firmName != ''">
+            AND lf.firm_name LIKE CONCAT('%', #{firmName}, '%')
+        </if>
+        GROUP BY lf.id, lf.firm_name
+        ORDER BY COALESCE(SUM(lco.lawyer_earnings), 0) DESC
+    </select>
+
+    <!-- 查询律所下所有律师的对账统计信息(按律师分组) -->
+    <select id="getLawyerReconciliationStatistics" resultMap="LawyerReconciliationStatisticsResultMap">
         SELECT
             lu.id as lawyer_id,
             lu.name as lawyer_name,
             lu.head_img,
             lu.lawyer_certificate_no,
+            lf.id as firm_id,
+            lf.firm_name,
             COUNT(DISTINCT lco.id) as order_count,
-            COALESCE(SUM(lco.order_amount), 0) as order_amount,
-            0 as platform_service_fee
+            CAST(ROUND(COALESCE(SUM(lco.lawyer_earnings), 0) / 100.0, 2) AS CHAR) as total_amount_yuan,
+            CAST(ROUND(COALESCE(SUM(lco.consultation_fee), 0) / 100.0, 2) AS CHAR) as commission_fee_yuan
         FROM lawyer_user lu
-        LEFT JOIN lawyer_consultation_order lco ON lu.id = lco.lawyer_user_id
+        INNER JOIN law_firm lf ON lu.firm_id = lf.id
+            AND lf.delete_flag = 0
+            AND lf.id = #{firmId}
+        LEFT JOIN lawyer_consultation_order lco ON lco.lawyer_user_id = lu.id
+            AND lco.place_id = #{firmId}
             AND lco.delete_flag = 0
-            AND lco.payment_status = 1
-            AND (lco.place_id = #{firmId} OR lu.firm_id = #{firmId})
+            AND lco.order_status = 3
             <if test="startDate != null">
-                AND DATE(lco.order_time) &gt;= DATE(#{startDate})
+                AND lco.order_time &gt;= CONCAT(#{startDate}, ' 00:00:00')
             </if>
             <if test="endDate != null">
-                AND DATE(lco.order_time) &lt;= DATE(#{endDate})
+                AND lco.order_time &lt;= CONCAT(#{endDate}, ' 23:59:59')
             </if>
-        WHERE lu.firm_id = #{firmId}
-        AND lu.delete_flag = 0
+        WHERE lu.delete_flag = 0
+        GROUP BY lu.id, lu.name, lu.head_img, lu.lawyer_certificate_no, lf.id, lf.firm_name
+        ORDER BY COALESCE(SUM(lco.lawyer_earnings), 0) DESC
+    </select>
+
+    <!-- 查询律所下所有律师的对账统计信息(按律师分组,支持律师名称模糊查询) -->
+    <select id="getLawyerReconciliationStatisticsWithName" resultMap="LawyerReconciliationStatisticsResultMap">
+        SELECT
+            lu.id as lawyer_id,
+            lu.name as lawyer_name,
+            lu.head_img,
+            lu.lawyer_certificate_no,
+            lf.id as firm_id,
+            lf.firm_name,
+            COUNT(DISTINCT lco.id) as order_count,
+            CAST(ROUND(COALESCE(SUM(lco.lawyer_earnings), 0) / 100.0, 2) AS CHAR) as total_amount_yuan,
+            CAST(ROUND(COALESCE(SUM(lco.consultation_fee), 0) / 100.0, 2) AS CHAR) as commission_fee_yuan
+        FROM lawyer_user lu
+        INNER JOIN law_firm lf ON lu.firm_id = lf.id
+            AND lf.delete_flag = 0
+            AND lf.id = #{firmId}
+        LEFT JOIN lawyer_consultation_order lco ON lco.lawyer_user_id = lu.id
+            AND lco.place_id = #{firmId}
+            AND lco.delete_flag = 0
+            AND lco.order_status = 3
+            <if test="startDate != null">
+                AND lco.order_time &gt;= CONCAT(#{startDate}, ' 00:00:00')
+            </if>
+            <if test="endDate != null">
+                AND lco.order_time &lt;= CONCAT(#{endDate}, ' 23:59:59')
+            </if>
+        WHERE lu.delete_flag = 0
         <if test="lawyerName != null and lawyerName != ''">
             AND lu.name LIKE CONCAT('%', #{lawyerName}, '%')
         </if>
-        GROUP BY lu.id, lu.name, lu.head_img, lu.lawyer_certificate_no
-        HAVING order_count > 0
-        ORDER BY order_amount DESC
+        GROUP BY lu.id, lu.name, lu.head_img, lu.lawyer_certificate_no, lf.id, lf.firm_name
+        ORDER BY COALESCE(SUM(lco.lawyer_earnings), 0) DESC
     </select>
 
-    <!-- 根据律所ID查询该律所下的所有律师ID列表 -->
-    <select id="getLawyerIdsByFirmId" resultType="java.lang.Integer">
-        SELECT id
-        FROM lawyer_user
-        WHERE firm_id = #{firmId}
-        AND delete_flag = 0
-        <if test="lawyerName != null and lawyerName != ''">
-            AND name LIKE CONCAT('%', #{lawyerName}, '%')
-        </if>
+    <!-- 查询律师的已完成订单列表(分页) -->
+    <resultMap id="LawyerOrderListResultMap" type="shop.alien.entity.store.vo.LawFirmReconciliationVO">
+        <result column="lawyer_name" property="lawyerName" />
+        <result column="order_number" property="orderNumber" />
+        <result column="order_amount" property="orderAmount" />
+        <result column="order_time" property="orderTime" />
+        <result column="client_user_id" property="clientUserId" />
+        <result column="client_user_name" property="clientUserName" />
+    </resultMap>
+
+    <select id="getLawyerOrderList" resultMap="LawyerOrderListResultMap">
+        SELECT
+            lu.name as lawyer_name,
+            lco.order_number,
+            lco.order_amount,
+            lco.order_time,
+            lco.client_user_id,
+            life_user.user_name as client_user_name
+        FROM lawyer_consultation_order lco
+        INNER JOIN lawyer_user lu ON lco.lawyer_user_id = lu.id
+            AND lu.delete_flag = 0
+        LEFT JOIN life_user ON lco.client_user_id = life_user.id
+            AND life_user.delete_flag = 0
+        WHERE lco.lawyer_user_id = #{lawyerId}
+            AND lco.delete_flag = 0
+            AND lco.order_status = 3
+        ORDER BY lco.order_time DESC
     </select>
 
 </mapper>

+ 60 - 38
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawFirmReconciliationController.java

@@ -8,8 +8,6 @@ import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.vo.LawFirmReconciliationVO;
-import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
-import shop.alien.entity.store.vo.LawyerReconciliationDetailVO;
 import shop.alien.lawyer.service.LawFirmReconciliationService;
 
 import java.util.Date;
@@ -31,82 +29,106 @@ public class LawFirmReconciliationController {
 
     private final LawFirmReconciliationService lawFirmReconciliationService;
 
-    @ApiOperation("获取律所对账总览")
+    @ApiOperation("获取所有律所对账")
     @ApiOperationSupport(order = 1)
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "firmId", value = "律所ID", dataType = "Integer", paramType = "query", required = true),
-            @ApiImplicitParam(name = "lawyerName", value = "律师姓名(可选,模糊查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "firmId", value = "律所ID(可选,不传则查询所有律所)", dataType = "Integer", paramType = "query", required = false),
+            @ApiImplicitParam(name = "firmName", value = "律所名称(可选,模糊查询)", dataType = "String", paramType = "query", required = false),
+            @ApiImplicitParam(name = "startDate", value = "开始日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "endDate", value = "结束日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getOverview")
+    public R<LawFirmReconciliationVO> getLawFirmReconciliation(
+            @RequestParam(value = "firmId", required = false) Integer firmId,
+            @RequestParam(value = "firmName", required = false) String firmName,
+            @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
+            @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
+        log.info("LawFirmReconciliationController.getLawFirmReconciliation?firmId={},firmName={},startDate={},endDate={}",
+                firmId, firmName, startDate, endDate);
+        return lawFirmReconciliationService.getLawFirmReconciliation(firmId, firmName, startDate, endDate);
+    }
+
+    @ApiOperation("获取所有律所的对账统计列表(分页)")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "firmName", value = "律所名称(可选,模糊查询)", dataType = "String", paramType = "query", required = false),
             @ApiImplicitParam(name = "startDate", value = "开始日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "endDate", value = "结束日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "pageNum", value = "页码(默认1)", dataType = "Integer", paramType = "query"),
             @ApiImplicitParam(name = "pageSize", value = "页容(默认10)", dataType = "Integer", paramType = "query")
     })
-    @GetMapping("/getOverview")
-    public R<LawFirmReconciliationVO> getLawFirmReconciliation(
-            @RequestParam(value = "firmId") Integer firmId,
-            @RequestParam(value = "lawyerName", required = false) String lawyerName,
+    @GetMapping("/getAllLawFirmList")
+    public R<IPage<LawFirmReconciliationVO>> getAllLawFirmReconciliationList(
+            @RequestParam(value = "firmName", required = false) String firmName,
             @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
             @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
             @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
             @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
-        log.info("LawFirmReconciliationController.getLawFirmReconciliation?firmId={},lawyerName={},startDate={},endDate={},pageNum={},pageSize={}",
-                firmId, lawyerName, startDate, endDate, pageNum, pageSize);
-        return lawFirmReconciliationService.getLawFirmReconciliation(
-                firmId, lawyerName, startDate, endDate, pageNum, pageSize);
+        log.info("LawFirmReconciliationController.getAllLawFirmReconciliationList?firmName={},startDate={},endDate={},pageNum={},pageSize={}",
+                firmName, startDate, endDate, pageNum, pageSize);
+        return lawFirmReconciliationService.getAllLawFirmReconciliationList(firmName, startDate, endDate, pageNum, pageSize);
     }
 
-    @ApiOperation("获取律师对账明细列表(分页)")
-    @ApiOperationSupport(order = 2)
+    @ApiOperation("获取律所下所有律师的对账统计列表(分页)")
+    @ApiOperationSupport(order = 3)
     @ApiImplicitParams({
             @ApiImplicitParam(name = "firmId", value = "律所ID", dataType = "Integer", paramType = "query", required = true),
-            @ApiImplicitParam(name = "lawyerName", value = "律师姓名(可选,模糊查询)", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "startDate", value = "开始日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "endDate", value = "结束日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "pageNum", value = "页码(默认1)", dataType = "Integer", paramType = "query"),
             @ApiImplicitParam(name = "pageSize", value = "页容(默认10)", dataType = "Integer", paramType = "query")
     })
-    @GetMapping("/getLawyerDetails")
-    public R<IPage<LawyerReconciliationDetailVO>> getLawyerReconciliationDetails(
+    @GetMapping("/getLawyerList")
+    public R<IPage<LawFirmReconciliationVO>> getLawyerReconciliationList(
             @RequestParam(value = "firmId") Integer firmId,
-            @RequestParam(value = "lawyerName", required = false) String lawyerName,
             @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
             @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
             @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
             @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
-        log.info("LawFirmReconciliationController.getLawyerReconciliationDetails?firmId={},lawyerName={},startDate={},endDate={},pageNum={},pageSize={}",
-                firmId, lawyerName, startDate, endDate, pageNum, pageSize);
-        return lawFirmReconciliationService.getLawyerReconciliationDetails(
-                firmId, lawyerName, startDate, endDate, pageNum, pageSize);
+        log.info("LawFirmReconciliationController.getLawyerReconciliationList?firmId={},startDate={},endDate={},pageNum={},pageSize={}",
+                firmId, startDate, endDate, pageNum, pageSize);
+        return lawFirmReconciliationService.getLawyerReconciliationList(firmId, startDate, endDate, pageNum, pageSize);
     }
 
-    @ApiOperation("查询律所下的订单列表(分页)")
-    @ApiOperationSupport(order = 3)
+    @ApiOperation("获取律所下所有律师的对账统计列表(分页,支持律师名称模糊查询)")
+    @ApiOperationSupport(order = 4)
     @ApiImplicitParams({
             @ApiImplicitParam(name = "firmId", value = "律所ID", dataType = "Integer", paramType = "query", required = true),
-            @ApiImplicitParam(name = "lawyerId", value = "律师ID(可选)", dataType = "Integer", paramType = "query"),
-            @ApiImplicitParam(name = "lawyerName", value = "律师姓名(可选,模糊查询)", dataType = "String", paramType = "query"),
-            @ApiImplicitParam(name = "orderNumber", value = "订单编号(可选,模糊查询)", dataType = "String", paramType = "query"),
-            @ApiImplicitParam(name = "orderStatus", value = "订单状态(可选,0:待支付, 2:进行中, 3:已完成, 4:已取消)", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerName", value = "律师名称(可选,模糊查询)", dataType = "String", paramType = "query", required = false),
             @ApiImplicitParam(name = "startDate", value = "开始日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "endDate", value = "结束日期(可选,格式:yyyy-MM-dd)", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "pageNum", value = "页码(默认1)", dataType = "Integer", paramType = "query"),
             @ApiImplicitParam(name = "pageSize", value = "页容(默认10)", dataType = "Integer", paramType = "query")
     })
-    @GetMapping("/getOrderList")
-    public R<IPage<LawyerConsultationOrderVO>> getOrderList(
+    @GetMapping("/getLawyerListWithName")
+    public R<IPage<LawFirmReconciliationVO>> getLawyerReconciliationListWithName(
             @RequestParam(value = "firmId") Integer firmId,
-            @RequestParam(value = "lawyerId", required = false) Integer lawyerId,
             @RequestParam(value = "lawyerName", required = false) String lawyerName,
-            @RequestParam(value = "orderNumber", required = false) String orderNumber,
-            @RequestParam(value = "orderStatus", required = false) Integer orderStatus,
             @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
             @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
             @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
             @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
-        log.info("LawFirmReconciliationController.getOrderList?firmId={},lawyerId={},lawyerName={},orderNumber={},orderStatus={},startDate={},endDate={},pageNum={},pageSize={}",
-                firmId, lawyerId, lawyerName, orderNumber, orderStatus, startDate, endDate, pageNum, pageSize);
-        return lawFirmReconciliationService.getOrderList(
-                firmId, lawyerId, lawyerName, orderNumber, orderStatus, startDate, endDate, pageNum, pageSize);
+        log.info("LawFirmReconciliationController.getLawyerReconciliationListWithName?firmId={},lawyerName={},startDate={},endDate={},pageNum={},pageSize={}",
+                firmId, lawyerName, startDate, endDate, pageNum, pageSize);
+        return lawFirmReconciliationService.getLawyerReconciliationListWithName(firmId, lawyerName, startDate, endDate, pageNum, pageSize);
+    }
+
+    @ApiOperation("获取律师的已完成订单列表(分页)")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "lawyerId", value = "律师ID", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "pageNum", value = "页码(默认1)", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "pageSize", value = "页容(默认10)", dataType = "Integer", paramType = "query")
+    })
+    @GetMapping("/getLawyerOrderList")
+    public R<IPage<LawFirmReconciliationVO>> getLawyerOrderList(
+            @RequestParam(value = "lawyerId") Integer lawyerId,
+            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
+            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
+        log.info("LawFirmReconciliationController.getLawyerOrderList?lawyerId={},pageNum={},pageSize={}",
+                lawyerId, pageNum, pageSize);
+        return lawFirmReconciliationService.getLawyerOrderList(lawyerId, pageNum, pageSize);
     }
+
 }
 

+ 51 - 33
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawFirmReconciliationService.java

@@ -3,8 +3,6 @@ package shop.alien.lawyer.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.vo.LawFirmReconciliationVO;
-import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
-import shop.alien.entity.store.vo.LawyerReconciliationDetailVO;
 
 import java.util.Date;
 
@@ -17,19 +15,33 @@ import java.util.Date;
 public interface LawFirmReconciliationService {
 
     /**
-     * 获取律所对账总览(分页)
+     * 获取律所对账总览
      *
-     * @param firmId 律所ID
-     * @param lawyerName 律师姓名(可选,模糊查询)
+     * @param firmId   律所ID(可选,不传则查询所有律所)
+     * @param firmName 律所名称(可选,模糊查询)
      * @param startDate 开始日期(可选)
-     * @param endDate 结束日期(可选)
-     * @param pageNum 页码
-     * @param pageSize 页容
-     * @return 律所对账总览
+     * @param endDate   结束日期(可选)
+     * @return 律所对账总览(包含总订单数量、总订单金额、总平台信息服务费)
      */
     R<LawFirmReconciliationVO> getLawFirmReconciliation(
             Integer firmId,
-            String lawyerName,
+            String firmName,
+            Date startDate,
+            Date endDate
+    );
+
+    /**
+     * 获取所有律所的对账统计列表(分页)
+     *
+     * @param firmName 律所名称(可选,模糊查询)
+     * @param startDate 开始日期(可选)
+     * @param endDate   结束日期(可选)
+     * @param pageNum   页码
+     * @param pageSize  页容
+     * @return 律所对账统计列表(分页)
+     */
+    R<IPage<LawFirmReconciliationVO>> getAllLawFirmReconciliationList(
+            String firmName,
             Date startDate,
             Date endDate,
             Integer pageNum,
@@ -37,19 +49,17 @@ public interface LawFirmReconciliationService {
     );
 
     /**
-     * 获取律师对账明细列表(分页)
+     * 获取律所下所有律师的对账统计列表(分页)
      *
-     * @param firmId 律所ID
-     * @param lawyerName 律师姓名(可选,模糊查询)
+     * @param firmId   律所ID
      * @param startDate 开始日期(可选)
-     * @param endDate 结束日期(可选)
-     * @param pageNum 页码
-     * @param pageSize 页容
-     * @return 律师对账明细列表
+     * @param endDate   结束日期(可选)
+     * @param pageNum   页码
+     * @param pageSize  页容
+     * @return 律师对账统计列表(分页)
      */
-    R<IPage<LawyerReconciliationDetailVO>> getLawyerReconciliationDetails(
+    R<IPage<LawFirmReconciliationVO>> getLawyerReconciliationList(
             Integer firmId,
-            String lawyerName,
             Date startDate,
             Date endDate,
             Integer pageNum,
@@ -57,29 +67,37 @@ public interface LawFirmReconciliationService {
     );
 
     /**
-     * 查询律所下的订单列表(分页
+     * 获取律所下所有律师的对账统计列表(分页,支持律师名称模糊查询
      *
-     * @param firmId 律所ID
-     * @param lawyerId 律师ID(可选)
-     * @param lawyerName 律师姓名(可选,模糊查询)
-     * @param orderNumber 订单编号(可选,模糊查询)
-     * @param orderStatus 订单状态(可选)
+     * @param firmId    律所ID
+     * @param lawyerName 律师名称(可选,模糊查询)
      * @param startDate 开始日期(可选)
-     * @param endDate 结束日期(可选)
-     * @param pageNum 页码
-     * @param pageSize 页容
-     * @return 订单列表
+     * @param endDate   结束日期(可选)
+     * @param pageNum   页码
+     * @param pageSize  页容
+     * @return 律师对账统计列表(分页)
      */
-    R<IPage<LawyerConsultationOrderVO>> getOrderList(
+    R<IPage<LawFirmReconciliationVO>> getLawyerReconciliationListWithName(
             Integer firmId,
-            Integer lawyerId,
             String lawyerName,
-            String orderNumber,
-            Integer orderStatus,
             Date startDate,
             Date endDate,
             Integer pageNum,
             Integer pageSize
     );
+
+    /**
+     * 获取律师的已完成订单列表(分页)
+     *
+     * @param lawyerId 律师ID
+     * @param pageNum   页码
+     * @param pageSize  页容
+     * @return 律师订单列表(分页)
+     */
+    R<IPage<LawFirmReconciliationVO>> getLawyerOrderList(
+            Integer lawyerId,
+            Integer pageNum,
+            Integer pageSize
+    );
 }
 

+ 0 - 97
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerReconcService.java

@@ -1,97 +0,0 @@
-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.LawyerConsultationOrder;
-import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
-
-import java.util.List;
-
-/**
- * 律师对账服务接口
- *
- * @author system
- * @since 2025-01-XX
- */
-public interface LawyerReconcService extends IService<LawyerConsultationOrder> {
-    
-    /**
-     * 获取订单详情
-     */
-    R<LawyerConsultationOrder> updateOrderPaymentStatus(Integer orderId, Integer paymentStatus);
-
-    /**
-     * 查询订单列表(分页,关联律师信息)
-     *
-     * @param pageNum 页码
-     * @param pageSize 页容
-     * @param orderNumber 订单编号(可选,支持模糊查询)
-     * @param clientUserId 客户端用户ID(可选)
-     * @param lawyerUserId 律师用户ID(可选)
-     * @param lawyerName 律师姓名(可选,支持模糊查询)
-     * @param orderStatus 订单状态(可选)
-     * @param paymentStatus 支付状态(可选)
-     * @param startTime 开始时间(可选,格式:yyyy-MM-dd HH:mm:ss)
-     * @param endTime 结束时间(可选,格式:yyyy-MM-dd HH:mm:ss)
-     * @return 分页结果(包含律师信息)
-     */
-    R<IPage<LawyerConsultationOrderVO>> getOrderListWithLawyer(
-            Integer pageNum,
-            Integer pageSize,
-            String orderNumber,
-            Integer clientUserId,
-            Integer lawyerUserId,
-            String lawyerName,
-            Integer orderStatus,
-            Integer paymentStatus,
-            String startTime,
-            String endTime
-    );
-
-    /**
-     * 查询订单列表(不分页,关联律师信息)
-     *
-     * @param orderNumber 订单编号(可选,支持模糊查询)
-     * @param clientUserId 客户端用户ID(可选)
-     * @param lawyerUserId 律师用户ID(可选)
-     * @param lawyerName 律师姓名(可选,支持模糊查询)
-     * @param orderStatus 订单状态(可选)
-     * @param paymentStatus 支付状态(可选)
-     * @param startTime 开始时间(可选,格式:yyyy-MM-dd HH:mm:ss)
-     * @param endTime 结束时间(可选,格式:yyyy-MM-dd HH:mm:ss)
-     * @return 订单列表(包含律师信息)
-     */
-    R<List<LawyerConsultationOrderVO>> getOrderList(
-            String orderNumber,
-            Integer clientUserId,
-            Integer lawyerUserId,
-            String lawyerName,
-            Integer orderStatus,
-            Integer paymentStatus,
-            String startTime,
-            String endTime
-    );
-
-    /**
-     * 获取总订单数量
-     *
-     * @param orderNumber 订单编号(可选,支持模糊查询)
-     * @param clientUserId 客户端用户ID(可选)
-     * @param lawyerUserId 律师用户ID(可选)
-     * @param orderStatus 订单状态(可选)
-     * @param paymentStatus 支付状态(可选)
-     * @param startTime 开始时间(可选,格式:yyyy-MM-dd HH:mm:ss)
-     * @param endTime 结束时间(可选,格式:yyyy-MM-dd HH:mm:ss)
-     * @return 总订单数量
-     */
-    R<Long> getTotalOrderCount(
-            String orderNumber,
-            Integer clientUserId,
-            Integer lawyerUserId,
-            Integer orderStatus,
-            Integer paymentStatus,
-            String startTime,
-            String endTime
-    );
-}

+ 149 - 169
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawFirmReconciliationServiceImpl.java

@@ -8,13 +8,12 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawFirm;
+import shop.alien.entity.store.LawyerUser;
 import shop.alien.entity.store.vo.LawFirmReconciliationVO;
-import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
-import shop.alien.entity.store.vo.LawyerReconciliationDetailVO;
 import shop.alien.lawyer.service.LawFirmReconciliationService;
 import shop.alien.lawyer.service.LawFirmService;
+import shop.alien.lawyer.service.LawyerUserService;
 import shop.alien.mapper.LawFirmMapper;
-import shop.alien.mapper.LawyerConsultationOrderMapper;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -36,232 +35,213 @@ public class LawFirmReconciliationServiceImpl implements LawFirmReconciliationSe
 
     private final LawFirmMapper lawFirmMapper;
     private final LawFirmService lawFirmService;
-    private final LawyerConsultationOrderMapper consultationOrderMapper;
+    private final LawyerUserService lawyerUserService;
 
     @Override
     public R<LawFirmReconciliationVO> getLawFirmReconciliation(
             Integer firmId,
-            String lawyerName,
+            String firmName,
             Date startDate,
-            Date endDate,
-            Integer pageNum,
-            Integer pageSize) {
-        log.info("LawFirmReconciliationServiceImpl.getLawFirmReconciliation?firmId={},lawyerName={},startDate={},endDate={},pageNum={},pageSize={}",
-                firmId, lawyerName, startDate, endDate, pageNum, pageSize);
-
-        if (firmId == null) {
-            return R.fail("律所ID不能为空");
-        }
-
-        // 获取律所信息
-        LawFirm lawFirm = lawFirmService.getById(firmId);
-        if (lawFirm == null || (lawFirm.getDeleteFlag() != null && lawFirm.getDeleteFlag() == 1)) {
-            return R.fail("律所不存在或已被删除");
-        }
+            Date endDate) {
+        log.info("LawFirmReconciliationServiceImpl.getLawFirmReconciliation?firmId={},firmName={},startDate={},endDate={}",
+                firmId, firmName, startDate, endDate);
 
         // 查询统计信息
-        java.util.Map<String, Object> statistics = lawFirmMapper.getLawFirmReconciliationStatistics(firmId, startDate, endDate);
-        Long totalOrderCount = statistics != null && statistics.get("order_count") != null 
+        java.util.Map<String, Object> statistics = lawFirmMapper.getLawFirmReconciliationStatistics(firmId, firmName, startDate, endDate);
+        long totalOrderCount = statistics != null && statistics.get("order_count") != null
                 ? ((Number) statistics.get("order_count")).longValue() : 0L;
-        Long totalOrderAmount = statistics != null && statistics.get("total_amount") != null 
+        long totalOrderAmount = statistics != null && statistics.get("total_amount") != null
                 ? ((Number) statistics.get("total_amount")).longValue() : 0L;
+        long platformServiceFee = statistics != null && statistics.get("total_platform_service_fee") != null
+                ? ((Number) statistics.get("total_platform_service_fee")).longValue() : 0L;
 
-        // 获取平台佣金比例
-        Float commissionRatio = lawFirm.getPlatformCommissionRatio().floatValue();
-        if (commissionRatio == null) {
-            commissionRatio = 5.0f; // 默认5%
-        }
+        // 获取律所名称
+        String resultFirmName = "所有律所";
 
-        // 计算平台信息服务费
-        Long platformServiceFee = Math.round(totalOrderAmount * commissionRatio / 100.0);
+        // 如果 firmId 有值,查询当前律所信息并验证佣金比例
+        if (firmId != null) {
+            LawFirm lawFirm = lawFirmService.getById(firmId);
+            if (lawFirm == null || (lawFirm.getDeleteFlag() != null && lawFirm.getDeleteFlag() == 1)) {
+                return R.fail("律所不存在或已被删除");
+            }
+            resultFirmName = lawFirm.getFirmName();
+            if (lawFirm.getPlatformCommissionRatio() == null) {
+                return R.fail("律所[" + resultFirmName + "]的平台佣金比例未设置,无法计算对账信息");
+            }
+        } else if (firmName != null && !firmName.trim().isEmpty()) {
+            // 如果只传了 firmName,使用传入的名称
+            resultFirmName = firmName;
+        }
 
         // 构建返回对象
         LawFirmReconciliationVO vo = new LawFirmReconciliationVO();
         vo.setFirmId(firmId);
-        vo.setFirmName(lawFirm.getFirmName());
+        vo.setFirmName(resultFirmName);
         vo.setTotalOrderCount(totalOrderCount);
-        vo.setTotalOrderAmount(totalOrderAmount);
         vo.setTotalOrderAmountYuan(convertFenToYuan(totalOrderAmount));
-        vo.setPlatformServiceFee(platformServiceFee);
         vo.setPlatformServiceFeeYuan(convertFenToYuan(platformServiceFee));
-        vo.setPlatformCommissionRatio(commissionRatio);
 
-        // 查询律师明细(分页)
-        List<LawyerReconciliationDetailVO> lawyerDetails = lawFirmMapper.getLawyerReconciliationDetails(
-                firmId, lawyerName, startDate, endDate);
+        return R.data(vo, "查询成功");
+    }
+
+
+
+    @Override
+    public R<IPage<LawFirmReconciliationVO>> getAllLawFirmReconciliationList(
+            String firmName,
+            Date startDate,
+            Date endDate,
+            Integer pageNum,
+            Integer pageSize) {
+        log.info("LawFirmReconciliationServiceImpl.getAllLawFirmReconciliationList?firmName={},startDate={},endDate={},pageNum={},pageSize={}",
+                firmName, startDate, endDate, pageNum, pageSize);
+
+        // 查询所有律所的统计信息(SQL中已直接计算为元)
+        List<LawFirmReconciliationVO> firmList = lawFirmMapper.getAllLawFirmReconciliationStatistics(firmName, startDate, endDate);
 
         // 手动分页
+        Page<LawFirmReconciliationVO> page = new Page<>();
         if (pageNum != null && pageSize != null && pageNum > 0 && pageSize > 0) {
+            page.setCurrent(pageNum);
+            page.setSize(pageSize);
+            page.setTotal(firmList.size());
+
             int start = (pageNum - 1) * pageSize;
-            int end = Math.min(start + pageSize, lawyerDetails.size());
-            if (start < lawyerDetails.size()) {
-                lawyerDetails = lawyerDetails.subList(start, end);
+            int end = Math.min(start + pageSize, firmList.size());
+            if (start < firmList.size()) {
+                page.setRecords(firmList.subList(start, end));
             } else {
-                lawyerDetails = Collections.emptyList();
+                page.setRecords(Collections.emptyList());
             }
+        } else {
+            page.setCurrent(1);
+            page.setSize(firmList.size());
+            page.setTotal(firmList.size());
+            page.setRecords(firmList);
         }
 
-        // 转换金额单位并计算平台服务费
-        for (LawyerReconciliationDetailVO detail : lawyerDetails) {
-            detail.setOrderAmountYuan(convertFenToYuan(detail.getOrderAmount()));
-            // 计算平台服务费
-            Long platformFee = Math.round(detail.getOrderAmount() * commissionRatio / 100.0);
-            detail.setPlatformServiceFee(platformFee);
-            detail.setPlatformServiceFeeYuan(convertFenToYuan(platformFee));
-        }
-
-        vo.setLawyerDetails(lawyerDetails);
-
-        return R.data(vo, "查询成功");
+        return R.data(page, "查询成功");
     }
 
+    @Override
+    public R<IPage<LawFirmReconciliationVO>> getLawyerReconciliationList(
+            Integer firmId,
+            Date startDate,
+            Date endDate,
+            Integer pageNum,
+            Integer pageSize) {
+        log.info("LawFirmReconciliationServiceImpl.getLawyerReconciliationList?firmId={},startDate={},endDate={},pageNum={},pageSize={}",
+                firmId, startDate, endDate, pageNum, pageSize);
 
+        // 验证律所是否存在
+        if (firmId == null) {
+            return R.fail("律所ID不能为空");
+        }
+        LawFirm lawFirm = lawFirmService.getById(firmId);
+        if (lawFirm == null || (lawFirm.getDeleteFlag() != null && lawFirm.getDeleteFlag() == 1)) {
+            return R.fail("律所不存在或已被删除");
+        }
 
-@Override
-public R<IPage<LawyerReconciliationDetailVO>> getLawyerReconciliationDetails(
-        Integer firmId,
-        String lawyerName,
-        Date startDate,
-        Date endDate,
-        Integer pageNum,
-        Integer pageSize) {
-    log.info("LawFirmReconciliationServiceImpl.getLawyerReconciliationDetails?firmId={},lawyerName={},startDate={},endDate={},pageNum={},pageSize={}",
-            firmId, lawyerName, startDate, endDate, pageNum, pageSize);
-
-    if (firmId == null) {
-        return R.fail("律所ID不能为空");
-    }
-
-    // 获取律所信息以获取平台佣金比例
-    LawFirm lawFirm = lawFirmService.getById(firmId);
-
-    // 修复:正确处理lawFirm为null的情况
-    Float commissionRatio = 5.0f; // 默认5%
-    if (lawFirm != null && lawFirm.getPlatformCommissionRatio() != null) {
-        commissionRatio = lawFirm.getPlatformCommissionRatio().floatValue();
-    }
+        // 查询律所下所有律师的统计信息(SQL中已直接计算为元)
+        List<LawFirmReconciliationVO> lawyerList = lawFirmMapper.getLawyerReconciliationStatistics(firmId, startDate, endDate);
 
-    // 查询律师明细
-    List<LawyerReconciliationDetailVO> lawyerDetails = lawFirmMapper.getLawyerReconciliationDetails(
-            firmId, lawyerName, startDate, endDate);
-
-    // 转换金额单位并计算平台服务费
-    for (LawyerReconciliationDetailVO detail : lawyerDetails) {
-        detail.setOrderAmountYuan(convertFenToYuan(detail.getOrderAmount()));
-        // 计算平台服务费
-        Long platformFee = Math.round(detail.getOrderAmount() * commissionRatio / 100.0);
-        detail.setPlatformServiceFee(platformFee);
-        detail.setPlatformServiceFeeYuan(convertFenToYuan(platformFee));
-    }
+        // 手动分页
+        Page<LawFirmReconciliationVO> page = new Page<>();
+        if (pageNum != null && pageSize != null && pageNum > 0 && pageSize > 0) {
+            page.setCurrent(pageNum);
+            page.setSize(pageSize);
+            page.setTotal(lawyerList.size());
 
-    // 手动分页
-    Page<LawyerReconciliationDetailVO> page = new Page<>();
-    if (pageNum != null && pageSize != null && pageNum > 0 && pageSize > 0) {
-        page.setCurrent(pageNum);
-        page.setSize(pageSize);
-        page.setTotal(lawyerDetails.size());
-
-        int start = (pageNum - 1) * pageSize;
-        int end = Math.min(start + pageSize, lawyerDetails.size());
-        if (start < lawyerDetails.size()) {
-            page.setRecords(lawyerDetails.subList(start, end));
+            int start = (pageNum - 1) * pageSize;
+            int end = Math.min(start + pageSize, lawyerList.size());
+            if (start < lawyerList.size()) {
+                page.setRecords(lawyerList.subList(start, end));
+            } else {
+                page.setRecords(Collections.emptyList());
+            }
         } else {
-            page.setRecords(Collections.emptyList());
+            page.setCurrent(1);
+            page.setSize(lawyerList.size());
+            page.setTotal(lawyerList.size());
+            page.setRecords(lawyerList);
         }
-    } else {
-        page.setCurrent(1);
-        page.setSize(lawyerDetails.size());
-        page.setTotal(lawyerDetails.size());
-        page.setRecords(lawyerDetails);
-    }
 
-    return R.data(page, "查询成功");
-}
+        return R.data(page, "查询成功");
+    }
 
     @Override
-    public R<IPage<LawyerConsultationOrderVO>> getOrderList(
+    public R<IPage<LawFirmReconciliationVO>> getLawyerReconciliationListWithName(
             Integer firmId,
-            Integer lawyerId,
             String lawyerName,
-            String orderNumber,
-            Integer orderStatus,
             Date startDate,
             Date endDate,
             Integer pageNum,
             Integer pageSize) {
-        log.info("LawFirmReconciliationServiceImpl.getOrderList?firmId={},lawyerId={},lawyerName={},orderNumber={},orderStatus={},startDate={},endDate={},pageNum={},pageSize={}",
-                firmId, lawyerId, lawyerName, orderNumber, orderStatus, startDate, endDate, pageNum, pageSize);
+        log.info("LawFirmReconciliationServiceImpl.getLawyerReconciliationListWithName?firmId={},lawyerName={},startDate={},endDate={},pageNum={},pageSize={}",
+                firmId, lawyerName, startDate, endDate, pageNum, pageSize);
 
+        // 验证律所是否存在
         if (firmId == null) {
             return R.fail("律所ID不能为空");
         }
-
-        // 验证律所是否存在
         LawFirm lawFirm = lawFirmService.getById(firmId);
         if (lawFirm == null || (lawFirm.getDeleteFlag() != null && lawFirm.getDeleteFlag() == 1)) {
             return R.fail("律所不存在或已被删除");
         }
 
-        // 如果指定了律师ID,直接使用;否则查询律所下的所有律师ID
-        List<Integer> lawyerUserIds = null;
-        if (lawyerId != null) {
-            lawyerUserIds = Collections.singletonList(lawyerId);
-        } else {
-            // 查询律所下的所有律师ID
-            lawyerUserIds = lawFirmMapper.getLawyerIdsByFirmId(firmId, lawyerName);
-            if (lawyerUserIds == null || lawyerUserIds.isEmpty()) {
-                // 如果没有找到律师,返回空结果
-                Page<LawyerConsultationOrderVO> emptyPage = new Page<>(pageNum != null && pageNum > 0 ? pageNum : 1,
-                        pageSize != null && pageSize > 0 ? pageSize : 10);
-                emptyPage.setRecords(Collections.emptyList());
-                emptyPage.setTotal(0);
-                return R.data(emptyPage, "未找到相关订单");
+        // 查询律所下所有律师的统计信息(SQL中已直接计算为元,支持律师名称模糊查询)
+        List<LawFirmReconciliationVO> lawyerList = lawFirmMapper.getLawyerReconciliationStatisticsWithName(firmId, lawyerName, startDate, endDate);
+
+        // 手动分页
+        Page<LawFirmReconciliationVO> page = new Page<>();
+        if (pageNum != null && pageSize != null && pageNum > 0 && pageSize > 0) {
+            page.setCurrent(pageNum);
+            page.setSize(pageSize);
+            page.setTotal(lawyerList.size());
+
+            int start = (pageNum - 1) * pageSize;
+            int end = Math.min(start + pageSize, lawyerList.size());
+            if (start < lawyerList.size()) {
+                page.setRecords(lawyerList.subList(start, end));
+            } else {
+                page.setRecords(Collections.emptyList());
             }
+        } else {
+            page.setCurrent(1);
+            page.setSize(lawyerList.size());
+            page.setTotal(lawyerList.size());
+            page.setRecords(lawyerList);
+        }
+
+        return R.data(page, "查询成功");
+    }
+
+    @Override
+    public R<IPage<LawFirmReconciliationVO>> getLawyerOrderList(
+            Integer lawyerId,
+            Integer pageNum,
+            Integer pageSize) {
+        log.info("LawFirmReconciliationServiceImpl.getLawyerOrderList?lawyerId={},pageNum={},pageSize={}",
+                lawyerId, pageNum, pageSize);
+
+        // 验证律师是否存在
+        if (lawyerId == null) {
+            return R.fail("律师ID不能为空");
+        }
+        LawyerUser lawyerUser = lawyerUserService.getById(lawyerId);
+        if (lawyerUser == null || (lawyerUser.getDeleteFlag() != null && lawyerUser.getDeleteFlag() == 1)) {
+            return R.fail("律师不存在或已被删除");
         }
 
         // 创建分页对象
         int pageNumValue = pageNum != null && pageNum > 0 ? pageNum : 1;
         int pageSizeValue = pageSize != null && pageSize > 0 ? pageSize : 10;
-        Page<LawyerConsultationOrderVO> page = new Page<>(pageNumValue, pageSizeValue);
-
-        // 如果按律师姓名搜索但已经通过lawyerUserIds过滤,则不再传递lawyerName
-        String searchLawyerName = (lawyerId != null || lawyerName == null) ? null : lawyerName;
-
-        // 使用现有的订单查询方法
-        IPage<LawyerConsultationOrderVO> voPage = consultationOrderMapper.getConsultationOrderListWithLawyer(
-                page, orderNumber, null, null, searchLawyerName, orderStatus, lawyerUserIds);
-
-        // 如果指定了日期范围,需要手动过滤
-        if ((startDate != null || endDate != null) && voPage != null && voPage.getRecords() != null) {
-            List<LawyerConsultationOrderVO> filteredRecords = voPage.getRecords().stream()
-                    .filter(order -> {
-                        if (order.getOrderTime() == null) {
-                            return false;
-                        }
-                        Date orderDate = order.getOrderTime();
-                        if (startDate != null && orderDate.before(startDate)) {
-                            return false;
-                        }
-                        if (endDate != null && orderDate.after(endDate)) {
-                            return false;
-                        }
-                        return true;
-                    })
-                    .collect(java.util.stream.Collectors.toList());
-
-            // 重新计算分页
-            long total = filteredRecords.size();
-            int start = (pageNumValue - 1) * pageSizeValue;
-            int end = Math.min(start + pageSizeValue, filteredRecords.size());
-            List<LawyerConsultationOrderVO> pagedRecords = start < filteredRecords.size()
-                    ? filteredRecords.subList(start, end)
-                    : Collections.emptyList();
-
-            voPage.setRecords(pagedRecords);
-            voPage.setTotal(total);
-        }
+        Page<LawFirmReconciliationVO> page = new Page<>(pageNumValue, pageSizeValue);
+
+        // 查询律师的已完成订单列表
+        IPage<LawFirmReconciliationVO> orderPage = lawFirmMapper.getLawyerOrderList(page, lawyerId);
 
-        return R.data(voPage, "查询成功");
+        return R.data(orderPage, "查询成功");
     }
 
     /**

+ 0 - 201
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerReconcServiceImpl.java

@@ -1,201 +0,0 @@
-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.LawyerConsultationOrder;
-import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
-import shop.alien.lawyer.service.LawyerReconcService;
-import shop.alien.mapper.LawyerConsultationOrderMapper;
-import shop.alien.mapper.LawyerReconcMapper;
-
-import java.util.List;
-
-/**
- * 律师对账服务实现类
- *
- * @author system
- * @since 2025-01-XX
- */
-@Slf4j
-@Transactional
-@Service
-@RequiredArgsConstructor
-public class LawyerReconcServiceImpl extends ServiceImpl<LawyerConsultationOrderMapper, LawyerConsultationOrder> implements LawyerReconcService {
-
-    private final LawyerReconcMapper lawyerReconcMapper;
-
-    @Override
-    public R<LawyerConsultationOrder> updateOrderPaymentStatus(Integer orderId, Integer paymentStatus) {
-        log.info("LawyerReconcServiceImpl.updateOrderPaymentStatus?orderId={},paymentStatus={}", orderId, paymentStatus);
-        // TODO: 实现更新订单支付状态的逻辑
-        return R.fail("功能待实现");
-    }
-
-    @Override
-    public R<IPage<LawyerConsultationOrderVO>> getOrderListWithLawyer(
-            Integer pageNum,
-            Integer pageSize,
-            String orderNumber,
-            Integer clientUserId,
-            Integer lawyerUserId,
-            String lawyerName,
-            Integer orderStatus,
-            Integer paymentStatus,
-            String startTime,
-            String endTime) {
-        log.info("LawyerReconcServiceImpl.getOrderListWithLawyer?pageNum={},pageSize={},orderNumber={},clientUserId={},lawyerUserId={},lawyerName={},orderStatus={},paymentStatus={},startTime={},endTime={}",
-                pageNum, pageSize, orderNumber, clientUserId, lawyerUserId, lawyerName, orderStatus, paymentStatus, startTime, endTime);
-
-        // 参数校验和默认值设置
-        int pageNumValue = (pageNum != null && pageNum > 0) ? pageNum : 1;
-        int pageSizeValue = (pageSize != null && pageSize > 0) ? pageSize : 10;
-
-        // 处理时间格式(如果只传日期,补充时间部分)
-        String startTimeValue = formatTime(startTime, true);
-        String endTimeValue = formatTime(endTime, false);
-
-        // 创建分页对象
-        Page<LawyerConsultationOrderVO> page = new Page<>(pageNumValue, pageSizeValue);
-
-        // 调用 Mapper 方法查询
-        IPage<LawyerConsultationOrderVO> result = lawyerReconcMapper.getOrderListWithLawyer(
-                page,
-                orderNumber,
-                clientUserId,
-                lawyerUserId,
-                lawyerName,
-                orderStatus,
-                paymentStatus,
-                startTimeValue,
-                endTimeValue
-        );
-
-        return R.data(result);
-    }
-
-    @Override
-    public R<List<LawyerConsultationOrderVO>> getOrderList(
-            String orderNumber,
-            Integer clientUserId,
-            Integer lawyerUserId,
-            String lawyerName,
-            Integer orderStatus,
-            Integer paymentStatus,
-            String startTime,
-            String endTime) {
-        log.info("LawyerReconcServiceImpl.getOrderList?orderNumber={},clientUserId={},lawyerUserId={},lawyerName={},orderStatus={},paymentStatus={},startTime={},endTime={}",
-                orderNumber, clientUserId, lawyerUserId, lawyerName, orderStatus, paymentStatus, startTime, endTime);
-
-        // 处理时间格式(如果只传日期,补充时间部分)
-        String startTimeValue = formatTime(startTime, true);
-        String endTimeValue = formatTime(endTime, false);
-
-        // 调用 Mapper 方法查询
-        List<LawyerConsultationOrderVO> result = lawyerReconcMapper.getOrderList(
-                orderNumber,
-                clientUserId,
-                lawyerUserId,
-                lawyerName,
-                orderStatus,
-                paymentStatus,
-                startTimeValue,
-                endTimeValue
-        );
-
-        return R.data(result);
-    }
-
-    @Override
-    public R<Long> getTotalOrderCount(
-            String orderNumber,
-            Integer clientUserId,
-            Integer lawyerUserId,
-            Integer orderStatus,
-            Integer paymentStatus,
-            String startTime,
-            String endTime) {
-        log.info("LawyerReconcServiceImpl.getTotalOrderCount?orderNumber={},clientUserId={},lawyerUserId={},orderStatus={},paymentStatus={},startTime={},endTime={}",
-                orderNumber, clientUserId, lawyerUserId, orderStatus, paymentStatus, startTime, endTime);
-
-        // 使用MyBatis Plus的LambdaQueryWrapper构建查询条件
-        LambdaQueryWrapper<LawyerConsultationOrder> queryWrapper = new LambdaQueryWrapper<>();
-
-        // 基础条件:只查询未删除的订单
-        queryWrapper.eq(LawyerConsultationOrder::getDeleteFlag, 0);
-
-        // 订单编号(模糊查询)
-        if (StringUtils.hasText(orderNumber)) {
-            queryWrapper.like(LawyerConsultationOrder::getOrderNumber, orderNumber);
-        }
-
-        // 客户端用户ID
-        if (clientUserId != null) {
-            queryWrapper.eq(LawyerConsultationOrder::getClientUserId, clientUserId);
-        }
-
-        // 律师用户ID
-        if (lawyerUserId != null) {
-            queryWrapper.eq(LawyerConsultationOrder::getLawyerUserId, lawyerUserId);
-        }
-
-        // 订单状态
-        if (orderStatus != null) {
-            queryWrapper.eq(LawyerConsultationOrder::getOrderStatus, orderStatus);
-        }
-
-        // 支付状态
-        if (paymentStatus != null) {
-            queryWrapper.eq(LawyerConsultationOrder::getPaymentStatus, paymentStatus);
-        }
-
-        // 时间范围查询
-        String startTimeValue = formatTime(startTime, true);
-        String endTimeValue = formatTime(endTime, false);
-        if (StringUtils.hasText(startTimeValue)) {
-            queryWrapper.ge(LawyerConsultationOrder::getCreatedTime, startTimeValue);
-        }
-        if (StringUtils.hasText(endTimeValue)) {
-            queryWrapper.le(LawyerConsultationOrder::getCreatedTime, endTimeValue);
-        }
-
-        // 使用MyBatis Plus的count方法统计总数量
-        long count = this.count(queryWrapper);
-
-        log.info("LawyerReconcServiceImpl.getTotalOrderCount?count={}", count);
-        return R.data(count);
-    }
-
-    /**
-     * 格式化时间字符串
-     * 如果只传日期(yyyy-MM-dd),自动补充时间部分
-     *
-     * @param time 时间字符串
-     * @param isStart 是否为开始时间(true: 补充 00:00:00, false: 补充 23:59:59)
-     * @return 格式化后的时间字符串
-     */
-    private String formatTime(String time, boolean isStart) {
-        if (!StringUtils.hasText(time)) {
-            return null;
-        }
-
-        // 如果已经包含时间部分,直接返回
-        if (time.contains(" ")) {
-            return time;
-        }
-
-        // 如果只有日期,补充时间部分
-        if (time.matches("\\d{4}-\\d{2}-\\d{2}")) {
-            return isStart ? time + " 00:00:00" : time + " 23:59:59";
-        }
-
-        return time;
-    }
-}