# 麻将组局预约小程序项目说明 ## 项目概述 这是一个**麻将组局预约小程序**,帮助麻将爱好者在线上发起、加入麻将局,线下到店进行游戏。小程序提供了完整的预约流程管理,包括房间选择、预约发起、参与管理、签到评价等功能。 **技术栈:** - **前端**: UniApp(支持多端发布) - **后端**: .NET Core + SqlSugar ORM - **数据库**: Microsoft SQL Server --- ## 核心功能模块 ### 1. 首页预约列表 **文件位置:** - 前端: `uniapp/mahjong_group/pages/index/index.vue` - 后端: `server/CoreCms.Net.Web.WebApi/Controllers/SQController.cs:170` (GetReservationList) **功能描述:** - 展示所有未结束的预约列表(按开始时间升序) - 自动过滤黑名单用户发起的预约 - 分页加载,支持下拉刷新 - 卡片式展示预约信息(标题、时间、房间、人数、玩法等) **关键逻辑:** ```sql -- 查询未结束的预约(status < 3,end_time > now) -- 如果用户已登录,排除黑名单用户发起的预约 -- 按开始时间升序排列 ``` --- ### 2. 发起预约 **文件位置:** - 前端: `uniapp/mahjong_group/pages/appointment/appointment-page.vue` - 后端API: `SQController.cs:524` (AddSQReservation) **预约流程:** #### 第一步:选择房间和日期 - 页面: `book-room-page.vue` - API: `GetRoomListWithSlotsNew` (获取房间列表及时段状态) - 支持按**四个时段**查看房间可用性: - 凌晨: 00:00-06:00 - 上午: 06:00-12:00 - 下午: 12:00-18:00 - 晚上: 18:00-00:00 #### 第二步:填写预约信息 填写内容包括: **基本信息:** - 组局名称 - 人数(最多4人) - 玩法类型(血战、血流成河等) - 具体规则(几番起胡、几倍封顶等) - 其他补充说明 **参与者限制:** - 是否禁烟(可选) - 性别限制(不限/男/女) - 年龄范围(最小年龄-最大年龄) - 信誉要求(0.0-5.0分) **鸽子费(押金):** - 固定金额(0元、5元、10元、20元) - 自定义金额(0-50元) - 说明: 参与者需缴纳押金,爽约者押金由到场者平分,预约完成后全额返还 #### 第三步:提交预约 1. 调用 `canCreateSQReservation` 验证是否可以创建 2. 如有鸽子费,调用 `usePay` 发起微信支付 3. 调用 `addSQReservation` 创建预约记录 4. 创建发起者的参与记录(role=1) **验证规则:** - 房间是否存在且可用 - 时间段是否已被预约 - 用户是否有时间冲突的预约 - 房间在该时段是否有不可用时间 --- ### 3. 加入预约 **后端API:** `SQController.cs:804` (JoinReservation) **加入流程:** 1. 校验预约是否存在且未结束 2. 校验用户是否已加入 3. 校验是否为"独享模式"(无需组局) 4. 校验用户是否符合参与条件: - 信誉分是否达到要求 - 性别是否符合限制 - 年龄是否在范围内 5. 校验是否有时间冲突的预约 6. 校验预约是否已满员 7. 如有鸽子费,验证支付信息 8. 创建参与者记录(role=0) **重要提示:** - 参与者需满足发起者设置的所有限制条件 - 加入预约后可以取消,但在开始前30分钟内无法取消 - 如有鸽子费需先完成支付 --- ### 4. 预约签到 **后端API:** `SQController.cs:1207` (CheckInReservation) **签到权限:** 仅发起者可操作 **签到时机:** 预约开始后,由发起者确认实际到场人员 **签到流程:** 1. 发起者在预约详情页点击"签到"按钮 2. 勾选实际到场的参与者(发起者默认到场) 3. 提交签到 **签到效果:** - 预约状态变更为"进行中"(status=2) - 到场人员标记为`is_arrive=1` - 未到场人员标记为`is_arrive=2`并退出预约 - 爽约者扣除0.5信誉分,增加鸽子次数 - 到场者增加0.2信誉分(最高5.0) - 如有鸽子费,到场者标记为"发起退款"状态 **信誉系统:** ```javascript // 爽约处罚 credit_score -= 0.5 dove_count++ // 守约奖励(信誉<5.0时) credit_score += 0.2 (最高5.0) ``` --- ### 5. 评价系统 **后端API:** - 获取评价列表: `SQController.cs:252` (GetEvaluateServices) - 添加评价: `SQController.cs:330` (AddEvaluateServices) **评价条件:** - 预约已完成且已签到 - 只能评价实际到场的参与者 - 每个参与者只能被评价一次 **评价维度:** - 游戏水平(play_level): 1-5分 - 技能水平(skills_level): 1-5分 **评价计算:** 用户的最终评分采用加权平均: ```javascript // 初始值为4分 play_level = (sum(评价分数) + 4) / (评价次数 + 1) skills_level = (sum(评价分数) + 4) / (评价次数 + 1) // 如果只有1次评价,分母+1避免偏差 if (评价次数 == 1) { 分母 = 评价次数 + 2 } ``` **评价作用:** - 其他用户可在预约详情看到参与者的平均评分 - 评分影响用户在列表中的展示排序 - 高评分用户更容易被其他人接受加入 --- ### 6. 取消预约 **后端API:** `SQController.cs:1036` (CancelReservation) **取消规则:** **发起者取消:** - 预约开始前30分钟内无法取消 - 取消后预约状态变为"已取消"(status=4) - 所有参与者自动退出 - 如有押金,已支付者发起退款 - 通知所有参与者"发起者解散组局" **参与者取消:** - 预约开始前30分钟内无法取消 - 只退出自己,不影响其他人 - 如有押金,发起退款 **退款状态说明:** - `is_refund=1`: 待支付 - `is_refund=2`: 已支付 - `is_refund=3`: 待退款(发起退款流程) - `is_refund=4`: 已退款 - `is_refund=5`: 退款异常 --- ### 7. 我的预约记录 **后端API:** `SQController.cs:120` (GetMyReservation) **分类查看:** - `type=0`: 我参与的预约(role=0) - `type=1`: 我发起的预约(role=1) **记录状态:** - 待开始(status=0) - 已锁定(status=1)- 人满 - 进行中(status=2)- 已签到 - 已结束(status=3) - 已取消(status=4) **我正在进行的预约:** API: `GetMyUseReservation` - 查询未取消且未结束的预约 - 按状态排序:进行中 > 已锁定 > 待开始 > 已结束 --- ### 8. 黑名单功能 **说明:** - 用户可将不友好的参与者加入黑名单 - 首页自动过滤黑名单用户发起的预约 - 黑名单用户无法加入我发起的预约(待实现) **相关表:** `CoreCmsUserBlacklist` --- ### 9. 消息系统 **后端API:** - 获取消息列表: `SQController.cs:1778` (GetMessageList) - 获取未读数量: `SQController.cs:1814` (GetUnreadCount) - 全部标记已读: `SQController.cs:1850` (MarkAllAsRead) **消息类型:** - 系统消息:预约相关通知(组局成功、被取消等) - 私信消息(暂未实现) **消息状态:** - 未读:红点提示 - 已读:正常显示 **相关表:** - `SQMessage`: 消息表 - `SQMessageRead`: 已读记录表 --- ### 10. 收益系统 **后端API:** - 获取收益统计: `SQController.cs:1897` (GetEarningsSummary) - 获取收益记录: `SQController.cs:1970` (GetEarningsRecordList) - 申请提现: `SQController.cs:2050` (ApplyWithdraw) **收益来源:** - 发起预约的抽成(具体规则待配置) - 爽约者的鸽子费分成 **提现规则:** - 最低提现金额:0.01元 - 提现到账时间:3-5个工作日 - 提现记录可查询 **相关表:** - `SQEarningsRecord`: 收益记录表 - `SQWithdrawRecord`: 提现记录表 --- ## 数据库设计 ### 核心数据表 #### 1. SQReservations (预约表) 主要字段: ```sql id -- 预约ID room_id -- 房间ID room_name -- 房间名称 start_time -- 开始时间 end_time -- 结束时间 duration_minutes -- 时长(分钟) title -- 组局名称 game_type -- 游戏类型 game_rule -- 游戏规则 player_count -- 需要人数 status -- 状态(0待开始 1已锁定 2进行中 3已结束 4已取消) deposit_fee -- 押金费用 credit_limit -- 最低信誉要求 gender_limit -- 性别限制(0不限 1男 2女) min_age -- 最小年龄 max_age -- 最大年龄 is_smoking -- 是否禁烟 latest_arrival_time -- 最晚到店时间 extra_info -- 其他说明 is_solo_mode -- 是否独享模式(无需组局) created_at -- 创建时间 updated_at -- 更新时间 ``` #### 2. SQReservationParticipants (参与者表) 主要字段: ```sql id -- 参与记录ID reservation_id -- 预约ID user_id -- 用户ID role -- 角色(0参与者 1发起者) status -- 状态(0正常 1已退出) join_time -- 加入时间 quit_time -- 退出时间 is_arrive -- 是否到场(0未签到 1到场 2未到场) check_reservation -- 签到时间 is_refund -- 退款状态(1待支付 2已支付 3待退款 4已退款 5异常) paymentId -- 支付订单号 important_data -- 重要数据(JSON) ``` #### 3. SQRooms (房间表) 主要字段: ```sql id -- 房间ID name -- 房间名称 capacity -- 容量(人数) price_per_hour -- 每小时价格 description -- 描述 image_url -- 图片 status -- 状态(true可用 false不可用) created_at -- 创建时间 ``` #### 4. SQReservationEvaluate (评价表) 主要字段: ```sql id -- 评价ID reservation_id -- 预约ID user_id -- 评价人ID to_user_id -- 被评价人ID role -- 被评价人角色 play_level -- 游戏水平评分 skills_level -- 技能水平评分 created_at -- 评价时间 ``` #### 5. SQReservationReputation (声誉记录表) 主要字段: ```sql id -- 记录ID user_id -- 用户ID reservation_id -- 相关预约ID reputation_value -- 声誉变化值(±0.5、±0.2等) remark -- 变化原因 created_at -- 记录时间 ``` #### 6. SQRoomUnavailableTimes (房间不可用时间表) 主要字段: ```sql id -- 记录ID room_id -- 房间ID start_time -- 不可用开始时间 end_time -- 不可用结束时间 reason -- 原因 created_at -- 创建时间 ``` #### 7. SQMessage (消息表) 主要字段: ```sql id -- 消息ID user_id -- 接收用户ID(0表示全体用户) title -- 消息标题 content -- 消息内容 message_type -- 消息类型(0系统 1私信) created_at -- 创建时间 ``` #### 8. SQEarningsRecord (收益记录表) 主要字段: ```sql id -- 记录ID user_id -- 用户ID reservation_id -- 相关预约ID amount -- 收益金额 type -- 收益类型 description -- 描述 created_at -- 创建时间 ``` --- ## 前端页面结构 ### TabBar(底部导航) 1. **首页** (`pages/index/index`) - 预约列表展示 - 支持下拉刷新、上拉加载 - 点击卡片查看详情/加入预约 2. **预约** (`pages/appointment/book-room-page`) - 选择房间和日期 - 查看房间时段可用性 - 进入预约表单 3. **我的** (`pages/me/me-page`) - 用户信息展示 - 预约记录入口 - 我的收益入口 - 消息通知入口 ### 主要功能页面 #### 预约相关 - `pages/appointment/book-room-page.vue` - 选择房间页面 - `pages/appointment/appointment-page.vue` - 发起预约页面 #### 个人中心 - `pages/me/appointment-record-page.vue` - 预约记录 - `pages/me/my-earnings-page.vue` - 我的收益 - `pages/me/my-message-page.vue` - 消息列表 - `pages/me/my-record.vue` - 历史记录 - `pages/me/blacklist-page.vue` - 黑名单管理 - `pages/me/edit-info.vue` - 编辑个人信息 - `pages/me/login.vue` - 登录页面 #### 其他页面 - `pages/other/agreement.vue` - 用户协议 - `pages/other/payment-records.vue` - 支付记录 - `pages/other/faq.vue` - 常见问题 --- ## API接口汇总 ### 预约相关接口 | 接口名称 | 路径 | 方法 | 权限 | 说明 | |---------|------|------|------|------| | 获取预约列表 | `api/sq/GetReservationList` | GET | 无需 | 首页预约列表 | | 获取预约详情 | `api/sq/GetReservationDetail` | GET | 无需 | 根据ID获取详情 | | 我的预约记录 | `api/sq/GetMyReservation` | GET | 需要 | 我参与/发起的预约 | | 正在进行的预约 | `api/sq/GetMyUseReservation` | GET | 需要 | 未结束的预约 | | 验证是否可创建 | `api/sq/CanCreateSQReservation` | POST | 需要 | 创建预约前验证 | | 创建预约 | `api/sq/AddSQReservation` | POST | 需要 | 发起新预约 | | 加入预约 | `api/sq/JoinReservation` | POST | 需要 | 参与现有预约 | | 取消预约 | `api/sq/CancelReservation` | POST | 需要 | 发起者/参与者取消 | | 预约签到 | `api/sq/CheckInReservation` | POST | 需要 | 发起者签到确认 | ### 房间相关接口 | 接口名称 | 路径 | 方法 | 权限 | 说明 | |---------|------|------|------|------| | 获取可选日期 | `api/sq/GetAvailableDates` | GET | 无需 | 今天+未来6天 | | 获取房间列表 | `api/sq/GetRoomListWithSlotsNew` | GET | 无需 | 按时段显示房间状态 | | 获取房间详情 | `api/sq/GetRoomDetail` | GET | 无需 | 房间信息及可用时段 | | 获取可预约房间 | `api/sq/GetReservationRoomList` | GET | 无需 | 指定时间段可预约房间 | ### 评价相关接口 | 接口名称 | 路径 | 方法 | 权限 | 说明 | |---------|------|------|------|------| | 获取预约评价 | `api/sq/GetEvaluateServices` | GET | 需要 | 获取可评价参与者 | | 添加评价 | `api/sq/AddEvaluateServices` | POST | 需要 | 评价参与者 | | 获取声誉记录 | `api/sq/GetReputationByUser` | GET | 需要 | 我的信誉变化记录 | | 获取评价给我的 | `api/sq/GetEvaluateToMe` | GET | 需要 | 别人给我的评价 | ### 消息相关接口 | 接口名称 | 路径 | 方法 | 权限 | 说明 | |---------|------|------|------|------| | 获取消息列表 | `api/sq/GetMessageList` | GET | 需要 | 站内信列表 | | 获取未读数量 | `api/sq/GetUnreadCount` | GET | 需要 | 未读消息数量 | | 全部标记已读 | `api/sq/MarkAllAsRead` | POST | 需要 | 标记所有消息已读 | ### 收益相关接口 | 接口名称 | 路径 | 方法 | 权限 | 说明 | |---------|------|------|------|------| | 获取收益统计 | `api/sq/GetEarningsSummary` | GET | 需要 | 总收益、可提现等 | | 获取收益记录 | `api/sq/GetEarningsRecordList` | POST | 需要 | 收益明细列表 | | 获取提现记录 | `api/sq/GetWithdrawRecordList` | POST | 需要 | 提现记录列表 | | 申请提现 | `api/sq/ApplyWithdraw` | POST | 需要 | 发起提现申请 | | 获取收益规则 | `api/sq/GetEarningsRule` | GET | 无需 | 收益规则说明 | ### 其他接口 | 接口名称 | 路径 | 方法 | 权限 | 说明 | |---------|------|------|------|------| | 获取支付记录 | `api/sq/GetPaymentRecords` | GET | 需要 | 鸽子费支付记录 | | 获取营业时间 | `api/sq/GetBusinessHours` | GET | 无需 | 店铺营业时间配置 | --- ## 业务流程图 ### 完整预约流程 ``` 用户浏览首页预约列表 ↓ 选择"发起预约"或"加入预约" ↓ [发起预约流程] [加入预约流程] ↓ ↓ 选择房间和日期 查看预约详情 ↓ ↓ 选择时段 检查参与条件 ↓ ↓ 填写组局信息 支付鸽子费(如有) ↓ ↓ 设置参与限制 加入成功 ↓ ↓ 设置鸽子费 等待预约开始 ↓ ↓ 支付鸽子费(如有) 收到开始通知 ↓ 发起成功 ↓ 等待参与者加入 ↓ 人满/时间到达开始 ↓ 发起者签到确认到场人员 ↓ 预约进行中 ↓ 预约时间结束 ↓ 参与者互相评价 ↓ 预约完成(鸽子费退还) ``` ### 签到流程详解 ``` 预约开始时间到达 ↓ 发起者收到签到通知 ↓ 发起者打开预约详情 ↓ 点击"签到"按钮 ↓ 勾选实际到场的参与者 ↓ 提交签到 ↓ 系统处理: - 预约状态→进行中 - 到场者:is_arrive=1,信誉+0.2 - 未到场者:is_arrive=2,信誉-0.5,鸽子次数+1 - 未到场者押金→到场者平分(待定时任务处理) - 到场者押金→发起退款 ↓ 签到完成 ↓ 预约正常进行 ``` ### 取消预约流程 ``` 用户查看我的预约 ↓ 选择要取消的预约 ↓ 点击"取消预约" ↓ 检查取消条件: - 是否在开始前30分钟 - 是否已开始(只有发起者可取消已开始的) - 是否已结束或已取消 ↓ [发起者取消] [参与者取消] ↓ ↓ 预约状态→已取消 只退出自己 ↓ ↓ 所有参与者→已退出 预约继续有效 ↓ ↓ 发起押金退款 发起押金退款(自己的) ↓ ↓ 通知所有参与者 无需通知 ↓ ↓ 取消完成 ``` --- ## 业务规则总结 ### 时间规则 1. 预约可选时间:今天 + 未来6天 2. 时段划分:凌晨(0-6h)、上午(6-12h)、下午(12-18h)、晚上(18-24h) 3. 营业时间:09:00-23:00 4. 取消限制:开始前30分钟内无法取消 ### 人数规则 1. 每个预约最少1人(独享模式),最多4人 2. 独享模式(player_count=1)不接受其他人加入 3. 人满后预约状态→已锁定(status=1) ### 押金规则 1. 押金范围:0-50元 2. 押金用途:防止爽约 3. 退款时机: - 签到后到场者:全额退还 - 爽约者:押金被扣除,由到场者平分 - 预约取消:全额退还 ### 信誉规则 1. 初始信誉:5.0分(满分) 2. 守约奖励:+0.2分/次(最高5.0) 3. 爽约惩罚:-0.5分/次 4. 信誉作用:发起者可设置最低信誉要求 ### 评价规则 1. 评价时机:预约完成后 2. 评价对象:实际到场的参与者 3. 评价维度:游戏水平、技能水平(各1-5分) 4. 评价次数:每个参与者只能被评价一次 5. 平均分计算:(所有评价之和 + 4) / (评价次数 + 1) ### 参与限制规则 1. 性别限制:不限/男/女 2. 年龄限制:最小-最大年龄 3. 信誉限制:最低信誉要求 4. 时间冲突检查:不能同时参与多个时间重叠的预约 --- ## 定时任务(推测) 根据代码逻辑,应该有以下定时任务: 1. **押金退款任务** - 扫描 `is_refund=3`(待退款)的记录 - 调用微信退款API - 更新退款状态为 `is_refund=4`(已退款) 2. **预约自动结束任务** - 扫描 `end_time < now` 且 `status=2`(进行中)的预约 - 更新状态为 `status=3`(已结束) 3. **预约失败通知任务** - 扫描开始时间到达但人数不足的预约 - 通知参与者"组局失败" - 退还所有押金 --- ## 项目特色 ### 1. 完善的信誉体系 - 守约加分、爽约扣分 - 鸽子次数统计 - 参与条件限制 ### 2. 灵活的押金机制 - 防止恶意爽约 - 爽约者押金补偿到场者 - 守约者全额退还 ### 3. 双向评价系统 - 游戏水平、技能水平分开评价 - 加权平均算法避免偏差 - 评价影响用户可信度 ### 4. 智能房间管理 - 按时段展示房间可用性 - 自动过滤已预约/不可用时段 - 支持房间不可用时间配置 ### 5. 黑名单机制 - 避免与不友好用户组局 - 首页自动过滤黑名单预约 --- ## 注意事项 ### 代码特点 1. 后端代码是从商城系统改造的,包含一些未使用的表和字段 2. 核心预约功能集中在 `SQController` 中 3. 前端使用 UniApp 开发,支持多端发布 4. 数据库使用 SqlSugar ORM,部分查询直接使用原生SQL ### 需要改进的地方 1. 部分业务逻辑写在 Controller 中,应该抽离到 Service 层 2. 定时任务的具体实现需要补充 3. 消息推送功能需要完善(微信模板消息/订阅消息) 4. 收益分配规则需要明确配置 5. 单元测试和接口文档需要完善 --- ## 部署建议 ### 环境要求 - .NET Core 6.0+ - SQL Server 2016+ - Redis(如需缓存) ### 配置项 1. 数据库连接字符串 2. 微信小程序配置(AppId、AppSecret) 3. 微信支付配置(商户号、密钥) 4. 营业时间配置 5. 收益规则配置 ### 运行步骤 1. 恢复数据库(执行建表脚本) 2. 配置 `appsettings.json` 3. 编译后端项目 4. 部署到IIS或使用Kestrel 5. 配置前端小程序AppId 6. 编译上传小程序 --- ## 总结 这是一个功能完善的**麻将组局预约小程序**,核心流程包括: 1. 用户浏览首页预约列表 2. 发起/加入预约 3. 支付鸽子费(押金) 4. 预约开始后发起者签到 5. 预约完成后互相评价 6. 押金退还、收益分配 项目采用前后端分离架构,数据库设计合理,业务逻辑清晰。通过信誉体系、押金机制、评价系统等功能,有效防止了恶意爽约问题,提高了用户参与组局的积极性和可靠性。