spec.md 11 KB

酒店-餐厅对账功能

status: in-progress created: 2026-09-30 complexity: ⭐⭐⭐中等 需求依据:用户口述 + 需求汇总讨论(2026-09-30)


1. 背景与目标

1.1 业务背景

酒店与餐厅为独立法人实体(同一老板、不同公司),属于合作关系。顾客在酒店房间扫码点餐,钱付给酒店(通过支付宝等渠道)。酒店需要按月与餐厅对账,确认应付金额后付款给餐厅。

1.2 目标

  • 酒店端按月自动生成对账单,汇总该月顾客点餐订单
  • 退款订单单独标注,系统提供「排除」能力(排除后自动重算应付金额)
  • 餐厅端可查看、确认对账单
  • 双方均可导出 Excel
  • 对账单状态流转:待确认 → 已确认 → 已结算

1.3 不做的事

  • ❌ 不实现平台抽成/服务费计算(暂不扣除)
  • ❌ 不实现线上签字/电子签章
  • ❌ 不按餐厅维度拆分(目前只有一个餐厅)
  • ❌ 不改动现有订单模块逻辑

2. 多租户架构(方案一:受控跨租户)

对账单数据归属酒店租户,餐厅通过后端受控跨租户访问。

酒店端(tenant_id = A):
  生成对账单 / 排除订单 / 标记结算 / 导出
  → 正常操作,TenantLine 自动追加 tenant_id = A

餐厅端(tenant_id = B):
  查看对账单 / 确认 / 导出
  → 后端 TenantContextHolder.executeWithTenant(A, ...) 切到酒店租户
  → 仅暴露对账相关接口,不暴露订单/支付等其他数据

安全边界:

  • 餐厅角色仅配 hotel:reconciliation:partner:* 权限
  • 餐厅仅能访问 /hotel/reconciliation/partner/** 专用接口
  • 跨租户接口内部写死只查对账相关表

3. 功能点

3.1 酒店端

# 功能 说明
F1 生成对账单 选月份 → 自动拉取该月已完成订单(status=6),生成对账单
F2 对账单列表 按月查看,状态筛选(待确认/已确认/已结算)
F3 对账单详情 查看每笔订单明细:订单号、房间号、联系人、金额、订单状态、退款状态
F4 排除订单 对争议订单点击「排除」,排除后自动重算应付金额
F5 导出 Excel 导出对账单明细(含排除标记)
F6 标记已结算 餐厅确认后,酒店财务标记结算完成,填写结算备注

3.2 餐厅端

# 功能 说明
F7 查看对账单列表 只看到「已确认」和「已结算」的对账单(待确认的还没提交)
F8 查看对账单详情 查看明细(含被排除的订单,排除订单标注)
F9 确认对账单 核对无误后点击确认
F10 导出 Excel 同酒店端导出内容

4. 业务规则

规则 内容
R1 对账范围:仅顾客点餐订单(hotel_order 中 status = 6 已完成的订单)
R2 对账单编号格式:DZ-YYYYMM-NNN(如 DZ-202609-001)
R3 同一月份只能生成一张对账单(重复生成提示已存在)
R4 退款订单默认包含在对账单中,酒店可手动排除
R5 排除订单需填写排除原因
R6 应付金额 = 订单总额 - 排除金额(自动重算)
R7 状态流转:待确认(0) → 已确认(1) → 已结算(2),单向不可逆
R8 餐厅端只能看到「已确认」和「已结算」状态的对账单
R9 只有「已确认」状态的对账单才能被酒店标记为「已结算」
R10 对账单生成后,对应的订单数据快照到明细表,后续订单状态变更不影响已生成的对账单

5. 数据库设计

5.1 hotel_reconciliation(对账单主表)

字段 类型 说明
id bigint NOT NULL 主键(雪花算法)
tenant_id bigint NOT NULL DEFAULT 1 租户ID(酒店租户)
reconciliation_no varchar(20) NOT NULL 对账单编号(DZ-YYYYMM-NNN)
period_start date NOT NULL 对账周期开始
period_end date NOT NULL 对账周期结束
order_count int NOT NULL DEFAULT 0 订单总笔数(含排除)
total_amount decimal(10,2) NOT NULL DEFAULT 0 订单总额
excluded_count int NOT NULL DEFAULT 0 排除笔数
excluded_amount decimal(10,2) NOT NULL DEFAULT 0 排除金额
settlement_amount decimal(10,2) NOT NULL DEFAULT 0 应付金额 = total - excluded
status tinyint NOT NULL DEFAULT 0 0=待确认 / 1=已确认 / 2=已结算
confirmed_by bigint DEFAULT NULL 确认人
confirmed_time datetime DEFAULT NULL 确认时间
settled_by bigint DEFAULT NULL 结算操作人
settled_time datetime DEFAULT NULL 结算时间
settled_remark varchar(500) DEFAULT NULL 结算备注
del_flag bigint NOT NULL DEFAULT 0 逻辑删除
create_by / create_time / create_dept / update_by / update_time — 审计字段

5.2 hotel_reconciliation_item(对账单明细)

字段 类型 说明
id bigint NOT NULL 主键
tenant_id bigint NOT NULL DEFAULT 1 租户ID
reconciliation_id bigint NOT NULL 对账单ID
order_id bigint NOT NULL 关联 hotel_order.id
order_no varchar(30) 冗余订单号
room_no varchar(10) 冗余房间号
contact_name varchar(50) 联系人
pay_amount decimal(10,2) 实付金额
order_status tinyint 订单状态(冗余快照)
refund_status tinyint 退款状态(冗余快照,0/1/2)
excluded tinyint NOT NULL DEFAULT 0 是否排除(0=否 / 1=是)
exclude_reason varchar(200) DEFAULT NULL 排除原因
del_flag bigint NOT NULL DEFAULT 0 逻辑删除
create_by / create_time / create_dept / update_by / update_time — 审计字段

5.3 字典

字典类型 dict_value dict_label list_class
hotel_reconciliation_status 0 待确认 warning
hotel_reconciliation_status 1 已确认 primary
hotel_reconciliation_status 2 已结算 success

6. 后端接口设计

6.1 酒店端(/hotel/reconciliation)

方法 路径 说明 权限
GET /page 对账单分页列表 hotel:reconciliation:query
GET /detail 对账单详情(含明细列表) hotel:reconciliation:query
POST /generate 生成对账单 hotel:reconciliation:generate
POST /excludeItem 排除/恢复明细 hotel:reconciliation:exclude
POST /settle 标记已结算 hotel:reconciliation:settle
GET /export 导出 Excel hotel:reconciliation:export

6.2 餐厅端(/hotel/reconciliation/partner)

方法 路径 说明 权限
GET /page 对账单分页列表(仅已确认+已结算) hotel:reconciliation:partner:query
GET /detail 对账单详情 hotel:reconciliation:partner:query
POST /confirm 确认对账单 hotel:reconciliation:partner:confirm
GET /export 导出 Excel hotel:reconciliation:partner:export

7. 前端页面设计

7.1 酒店端 reconciliation.vue

  • AiCrudPage 列表(隐藏新增/批量删除/选择列)
  • 工具栏:生成对账单按钮
  • 搜索筛选:状态(DictSelect)、月份范围
  • 表格列:对账单编号、周期、订单笔数、总额、排除笔数/金额、应付金额、状态(DictTag)、操作
  • 操作列:详情(text-info)、排除管理(text-warning,仅待确认)、导出(text-success)、确认提交(仅待确认→提交给餐厅看)、标记结算(text-primary,仅已确认)
  • 详情弹窗:汇总信息 + 明细表格(排除订单灰显+标注原因)
  • 排除弹窗:选择要排除的订单 + 填写原因

7.2 餐厅端 reconciliationPartner.vue

  • AiCrudPage 列表(只读,隐藏新增/批量删除/选择列)
  • 搜索筛选:状态(仅已确认+已结算)
  • 表格列:同酒店端(去掉排除管理操作)
  • 操作列:详情(text-info)、确认(text-success,仅已确认)、导出(text-success)
  • 详情弹窗:同酒店端(排除订单灰显标注)

8. 菜单与权限

对账管理(一级菜单,sort=12,与餐厅管理同级)
├── 对账单(酒店端)  path=/hotel/reconciliation  component=hotel/reconciliation
│   └── 按钮权限:hotel:reconciliation:query / generate / exclude / settle / export / submit
└── 对账单(餐厅端)  path=/hotel/reconciliation/partner  component=hotel/reconciliationPartner
    └── 按钮权限:hotel:reconciliation:partner:query / confirm / export

9. Excel 导出配置

config_key: hotel_reconciliation_export data_source_bean: hotelReconciliationServiceImpl query_method: queryExportList

导出列:对账单编号、周期、订单笔数、总额、排除笔数、排除金额、应付金额、状态、确认时间、结算时间


10. 技术决策

决策 说明
多租户方案 方案一:受控跨租户。对账单归酒店租户,餐厅通过 TenantContextHolder.executeWithTenant() 访问
对账单编号生成 按月份查当前最大序号 +1,格式 DZ-YYYYMM-NNN
订单数据快照 生成对账单时将订单关键信息复制到 hotel_reconciliation_item,后续订单变更不影响已生成对账单
退款订单处理 默认包含,酒店可排除;排除后自动重算应付金额
餐厅可见范围 餐厅只能看到「已确认」和「已结算」的对账单,酒店需先「提交」才推送给餐厅
导出方式 复用 sys_excel_export_config + sys_excel_column_config 配置化导出

11. 对现有模块的影响

模块 影响
hotel_order 只读,生成对账单时 SELECT 该月已完成订单
hotel_order_item 只读,取明细金额
租户/角色/菜单 新增对账菜单 + 按钮权限(Flyway 脚本)
现有代码 零改动,纯增量开发

12. 代码结构

reconciliation/
├── controller/
│   ├── HotelReconciliationController.java        # 酒店端 /hotel/reconciliation/**
│   └── HotelReconciliationPartnerController.java # 餐厅端 /hotel/reconciliation/partner/**
├── domain/
│   ├── HotelReconciliation.java
│   └── HotelReconciliationItem.java
├── dto/
│   └── ReconciliationGenerateDTO.java            # 生成请求(yearMonth)
├── vo/
│   ├── HotelReconciliationVO.java
│   └── ReconciliationDetailVO.java               # 含明细列表
├── mapper/
│   ├── HotelReconciliationMapper.java
│   └── HotelReconciliationItemMapper.java
└── service/
    ├── HotelReconciliationService.java
    └── impl/
        └── HotelReconciliationServiceImpl.java

前端:

  • forge-admin-ui/src/views/hotel/reconciliation.vue — 酒店端
  • forge-admin-ui/src/views/hotel/reconciliationPartner.vue — 餐厅端
  • forge-admin-ui/src/api/hotel.js — 追加对账相关 API 函数