266 lines
9.4 KiB
Markdown
266 lines
9.4 KiB
Markdown
# 鸽子费审核功能需求文档
|
||
|
||
## 📌 功能概述
|
||
|
||
开发后台鸽子费审核功能,允许员工审核未按时赴约用户的鸽子费处理。审核通过则扣除鸽子费并分发给已赴约用户,审核未通过则退还鸽子费。
|
||
|
||
---
|
||
|
||
## 🎯 核心功能
|
||
|
||
### 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. **批量审核**:是否需要支持批量审核功能?(不需要)
|