# 鸽子费审核功能需求文档 ## 📌 功能概述 开发后台鸽子费审核功能,允许员工审核未按时赴约用户的鸽子费处理。审核通过则扣除鸽子费并分发给已赴约用户,审核未通过则退还鸽子费。 --- ## 🎯 核心功能 ### 1. 待审核列表展示 #### 1.1 筛选条件 - **用户状态**:`is_arrive = 2`(未赴约,待审核) - **预约状态**:预约未结束或已结束但未处理 - **鸽子费条件**:`deposit_fee > 0`(有鸽子费的预约) - **参与状态**:`status = 0`(未退出) #### 1.2 列表显示字段 | 字段 | 说明 | |------|------| | 预约ID | reservation_id | | 预约标题 | reservation.title | | 用户ID | user_id | | 用户昵称 | 关联用户表获取 | | 用户手机号 | 关联用户表获取 | | 鸽子费金额 | reservation.deposit_fee | | 预约时间 | reservation.start_time ~ end_time | | 标记时间 | 发起者签到时间(is_arrive=2的更新时间) | | 操作按钮 | 审核通过 / 审核未通过 | #### 1.3 列表规则 - 只显示有鸽子费(`deposit_fee > 0`)的未赴约用户 - 已审核通过的(`is_arrive = 3`)不显示在列表中 - 按标记时间倒序排列 --- ## ✅ 审核通过流程 ### 2.1 状态更新 - 将用户状态改为:`is_arrive = 3`(未赴约,已审核) - 用户参与状态保持:`status = 0`(未退出,但已标记为未赴约) ### 2.2 鸽子费分配规则 #### 分配对象 - **已赴约且未退出的参与者**:`is_arrive = 1` 且 `status = 0` - **时间限制**:只计算在签到时间之前加入的参与者(`join_time < 签到时间`) - **排除对象**: - 未赴约的用户(`is_arrive = 2` 或 `is_arrive = 3`) - 已退出的用户(`status = 1`) - 签到时间之后加入的用户 #### 分配计算 ``` 鸽子费总额 = reservation.deposit_fee 参与人数 = 符合条件的已赴约用户数量(不包括发起者) 每人分得金额 = 鸽子费总额 / 参与人数(保留两位小数,四舍五入) ``` **注意**: - 如果参与人数为0,鸽子费不分配(但状态仍改为已审核) - 金额保留两位小数,使用四舍五入 - 分配后的总金额可能略有差异(因四舍五入),需要处理尾差 ### 2.3 收益记录创建 为每个分到鸽子费的用户创建收益记录: 使用现有的收益服务SQEarningsServices - **表**:`SQEarningsRecord` - **字段**: - `user_id`:分到钱的用户ID - `reservation_id`:预约ID - `room_id`:预约的房间ID - `room_number`:房间号 - `room_name`:房间名 - `room_fee`:预约的房费(可为空) - `earnings`:分到的鸽子费金额 - `type`:2(鸽子费) - `remark`:`"未赴约用户鸽子费分配"` - `create_time`:当前时间 - `operator_id`:审核员工ID ### 2.4 用户收益更新 为每个分到鸽子费的用户更新: SQEarningsServices 使用收益服务后,就不需要这一步了,因为收益中会自己处理的。 - `CoreCmsUser.pending_earnings` += 分到的金额 ### 2.5 消息通知 #### 2.5.1 给未赴约用户发送消息 - **接收人**:被扣除鸽子费的用户 - **标题**:`"鸽子费扣除通知"` - **内容**:`"您未按时参加预约,鸽子费已扣除{金额}元。"` - **消息类型**:系统通知(`message_type = 0`) - **关联业务**:`related_type = 1`(组局),`related_id = reservation_id` #### 2.5.2 给分到钱的用户发送消息 - **接收人**:每个分到鸽子费的用户 - **标题**:`"鸽子费分配通知"` - **内容**:`"{未赴约用户昵称} 未能按时参加预约,您收到鸽子费{金额}元"` - **消息类型**:系统通知(`message_type = 0`) - **关联业务**:`related_type = 1`(组局),`related_id = reservation_id` ### 2.6 列表更新 - 审核通过后,该记录不再显示在待审核列表中(因为 `is_arrive = 3`) --- ## ❌ 审核未通过流程 ### 3.1 状态更新 - `is_arrive = 1`(已赴约) - `status = 0`(正常,未退出) - `is_refund = 3`(发起退款,由退款任务处理) ### 3.2 退款处理 - 不立即退款,只标记为 `is_refund = 3` - 由现有的退款定时任务统一处理实际退款 ### 3.3 消息通知 - **接收人**:被审核的用户 - **标题**:`"鸽子费审核结果"` - **内容**:`"您的鸽子费已原路退回。"` - **消息类型**:系统通知(`message_type = 0`) - **关联业务**:`related_type = 1`(组局),`related_id = reservation_id` ### 3.4 列表更新 - 审核未通过后,该记录不再显示在待审核列表中(因为 `is_arrive = 1`) --- ## 🔍 业务规则说明 ### 4.1 时间限制说明 **"按照时间去处理一下,后面参与的人不算平均"** 的含义: - **签到时间**:发起者执行签到操作的时间(`check_reservation` 接口调用时间) - **目的**:防止在签到之后才加入的用户也能分到钱 ### 4.2 特殊情况处理 1. **没有已赴约用户**: - 仍然将状态改为 `is_arrive = 3` - 不分配鸽子费(鸽子费保留在系统中或按其他规则处理) - 只给未赴约用户发送扣除通知 2. **只有发起者一人**: - 如果发起者已赴约,鸽子费不分配(因为没有其他参与者) - 如果发起者未赴约,这种情况不应该出现(发起者不能标记自己未赴约) 3. **金额尾差处理**: - 由于四舍五入,分配总额可能略小于或大于原金额 - 建议:将尾差加给最后一个用户,或加给发起者 --- ## 📋 后台管理功能 ### 5.1 页面路径 - **建议路径**:`/views/sq/sqreservations/pigeon-fee-audit.html` ### 5.2 功能按钮 - **审核通过**:点击后弹出确认框,确认后执行审核通过流程 - **审核未通过**:点击后弹出确认框(可选填写原因),确认后执行审核未通过流程 ### 5.3 筛选功能 - 按预约ID筛选 - 按用户ID/昵称/手机号筛选 - 按预约时间范围筛选 - 按标记时间范围筛选 --- ## 🗄️ 数据库影响 ### 6.1 涉及的表 1. **SQReservationParticipants**:更新 `is_arrive`、`status`、`is_refund` 2. **SQEarningsRecord**:新增收益记录 3. **CoreCmsUser**:更新 `pending_earnings` 4. **SQMessage**:新增消息记录 ### 6.2 事务要求 - 审核通过操作需要使用事务,确保: - 状态更新成功 - 收益记录创建成功 - 用户收益更新成功 - 消息发送成功 - 任一环节失败,全部回滚 --- ## 📝 接口设计建议 ### 7.1 获取待审核列表 - **接口**:`POST /api/SQReservations/GetPigeonFeeAuditList` - **参数**:分页参数、筛选条件 - **返回**:待审核列表数据 ### 7.2 审核通过 - **接口**:`POST /api/SQReservations/ApprovePigeonFee` - **参数**:`{ participantId: int, reservationId: int }` - **返回**:操作结果 ### 7.3 审核未通过 - **接口**:`POST /api/SQReservations/RejectPigeonFee` - **参数**:`{ participantId: int, reservationId: int, reason?: string }` - **返回**:操作结果 --- ## ⚠️ 注意事项 1. **并发控制**:同一用户的审核操作需要加锁,防止重复审核 2. **数据一致性**:所有涉及金额的操作必须使用事务 3. **审计日志**:记录审核操作的操作员ID和时间 4. **消息发送**:消息发送失败不应影响审核流程(可异步处理或记录日志)(使用现有的消息服务) 5. **金额精度**:所有金额计算使用 `decimal(18,2)`,保留两位小数 --- ## 🔄 业务流程总结 ### 审核通过流程 ``` 员工查看待审核列表 → 点击"审核通过" → 系统计算已赴约用户(按时间筛选) → 计算每人分得金额 → 开启事务 → 更新用户状态 is_arrive=3 → 为每个分到钱的用户创建收益记录(使用SQEarningsServices,看有没有满足的方法) → 更新每个用户的 pending_earnings → 发送消息给未赴约用户(使用现有的消息服务SQMessageServices,看有没有满足的方法) → 发送消息给每个分到钱的用户(使用现有的消息服务SQMessageServices,看有没有满足的方法) → 提交事务 → 刷新列表(该记录不再显示) ``` ### 审核未通过流程 ``` 员工查看待审核列表 → 点击"审核未通过" → 开启事务 → 更新用户状态 is_arrive=1, status=0, is_refund=3 → 发送消息给用户(使用现有的消息服务SQMessageServices,看有没有满足的方法) → 提交事务 → 刷新列表(该记录不再显示) → 退款由定时任务处理 ``` --- ## ❓ 已确认问题 1. **签到时间的获取**:如何准确获取发起者签到的具体时间?是否需要在 `check_reservation` 接口中记录签到时间? 2. **尾差处理**:当分配金额因四舍五入产生尾差时,如何处理?是加给最后一个用户,还是加给发起者,还是忽略?(忽略,只保留两位小数) 3. **没有已赴约用户的情况**:如果所有参与者都未赴约,鸽子费如何处理?是保留在系统中,还是退还给未赴约用户?(如果发起者未签到,不处理,如果是发起者签到了,按现在的流程走,由员工去线下判断,审核) 4. **发起者未赴约**:如果发起者自己未赴约(这种情况是否可能?),如何处理?(不处理,发起者未签到,不处理) 5. **批量审核**:是否需要支持批量审核功能?(不需要)