酒店AGENTS.md 13 KB

AGENTS.md - 酒店二维码模块开发规范

重要: 此文件会被 IDEA QoderWork 插件自动读取,为 AI 助手提供项目上下文和开发规范

项目: Forge Admin - 酒店二维码模块 (Hotel QR Code Module)
技术栈: Spring Boot 3.2 + Vue 3.5 + Naive UI 2.42 + MyBatis-Plus 3.5
最后更新: 2026-08-10


一、核心开发规范(必须遵守)

1.1 后端规范

启动类: ForgeAdminServerApplication(主应用入口,聚合所有插件)

依赖注入:

@RequiredArgsConstructor  // ✅ Lombok 构造器注入
private final HotelQrCodeMapper qrCodeMapper;

// ❌ 禁止使用 @Autowired

响应体:

// ✅ 必须使用 RespInfo
return RespInfo.success(data);
return RespInfo.error("错误信息");

// ❌ 禁止使用 DataResult / ResponseUtil

ID生成:

// ✅ 使用雪花算法(MyBatis-Plus ASSIGN_ID)
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;

// ❌ 禁止使用 UUID / 自增ID

实体继承:

// ✅ 所有实体必须继承 TenantEntity
public class HotelQrCode extends TenantEntity { ... }
// TenantEntity 包含: tenantId, createBy, createTime, createDept, updateBy, updateTime

逻辑删除:

// ✅ 必须显式声明 @TableLogic
@TableLogic(value = "0", delval = "id")
private Long delFlag;

// Mapper XML 查询必须显式过滤: AND del_flag = 0

Controller路由:

@RestController
@RequestMapping("/hotel")
public class HotelQrCodeController { ... }

// 实际访问: /hotel/qrcode/page, /hotel/room/page 等

SQL 规范:

  • 查询类 SQL 禁止在 Service 层用 LambdaQueryWrapper 构建
  • 必须写在 Mapper XML 中(DataScopeInterceptor 按 mapperMethod 精确匹配)
  • 例外:仅单表 selectByIdinsertupdateByIddeleteById 等内置方法允许

租户 ID 规则:

  • 业务数据的 tenant_id 必须设为 1(默认租户),禁止设 0
  • TenantLineInnerInterceptor 自动追加 WHERE tenant_id = 当前租户ID

1.2 前端规范

组件语法:

<!-- ✅ 必须使用 Composition API -->
<script setup>
import { ref, computed } from 'vue'
const data = ref([])
</script>

<!-- ❌ 禁止使用 Options API (Vue 2语法) -->

列表页面:

<!-- ✅ 必须使用 AiCrudPage 组件 -->
<AiCrudPage
  ref="crudRef"
  :api-config="{ list: 'get@/hotel/qrcode/page' }"
  :search-schema="searchSchema"
  :columns="tableColumns"
  row-key="id"
/>

<!-- ❌ 禁止手动拼接 NInput/NSelect/NButton 搜索栏 -->

字典使用:

<!-- ✅ 必须使用字典组件,禁止硬编码 -->
<script setup>
import DictTag from '@/components/DictTag.vue'
import { useDict } from '@/composables/useDict'
const { dict } = useDict('sys_normal_disable')
</script>

<template>
  <DictTag dictType="sys_normal_disable" :value="row.status" />
</template>

<!-- ❌ 禁止在前端写死 options 或标签映射 -->

按钮样式约定: | 类名 | 颜色 | 场景 | |------|------|------| | text-primary | 蓝 | 编辑、查看、绑定、下载 | | text-warning | 黄 | 解绑、禁用、重置 | | text-error | 红 | 删除 | | text-success | 绿 | 启用 | | text-info | 灰蓝 | 详情、日志 |


二、项目架构

2.1 模块位置

forge-server/forge-business/forge-hotel/     # 酒店业务模块
├── controller/    # REST 控制器
├── service/       # 服务接口
│   └── impl/      # 服务实现
├── mapper/        # MyBatis Mapper 接口 + XML
├── domain/        # 数据库实体
├── dto/           # 请求 DTO
── vo/            # 响应 VO
├── constant/      # 常量定义
└── utils/         # 工具类(二维码生成、签名校验)

forge-admin-ui/src/views/hotel/            # 前端页面
├── qrcode.vue     # 二维码管理(AiCrudPage)
├── room.vue       # 房间管理(AiCrudPage)
└── roomType.vue   # 房型管理(AiCrudPage)

forge-h5-ui/src/pages/hotel/             # H5 移动端
└── scan-bind.vue  # 扫码绑定房间页面

2.2 三端架构

技术 部署 核心功能
PC 管理后台 Vue3 + Naive UI + AiCrudPage PC浏览器 批量生成、批量删除、批量下载ZIP、绑定/重绑/解绑、状态管理
H5 移动端 UniApp + html5-qrcode 手机浏览器(HTTPS) 员工扫码绑定房间、查看绑定状态
开放接口 REST API 免登录 顾客扫码查询二维码信息

三、技术栈清单

后端

  • Java 17 + Spring Boot 3.2
  • MyBatis-Plus 3.5 + 动态数据源
  • Sa-Token 1.38(认证授权)
  • 多租户隔离(TenantLineInnerInterceptor)
  • ZXing 3.5.3(二维码生成)
  • MySQL 8.0+ / Redis 6.0+

前端

  • Vue 3.5 + Naive UI 2.42
  • Vite 7 + Pinia 3 + UnoCSS 66
  • AiCrudPage / AiSearch / AiTable(框架标准组件)
  • html5-qrcode(H5 扫码)

四、数据库设计

4.1 表结构

hotel_qr_code(二维码表):

字段 类型 说明
id BIGINT 主键(雪花算法)
tenant_id BIGINT 租户ID,默认1
short_code VARCHAR(32) 二维码唯一短码(8位大写字母+数字)
sign VARCHAR(64) MD5签名值
room_id BIGINT 绑定房间ID(NULL=未绑定)
room_no VARCHAR(32) 冗余房间号
status VARCHAR(16) 状态:0=启用, 1=禁用(对应字典 sys_normal_disable)
batch_no VARCHAR(32) 批次号(格式:QR+yyyyMMddHHmmss)
bind_user_id BIGINT 最近绑定人ID
bind_user_name VARCHAR(64) 最近绑定人姓名
bind_time DATETIME 最近绑定时间
unbind_user_id BIGINT 最近解绑人ID
unbind_user_name VARCHAR(64) 最近解绑人姓名
unbind_time DATETIME 最近解绑时间
del_flag BIGINT 逻辑删除标记(0=未删除,删除时写入主键ID)

唯一索引: UNIQUE (tenant_id, short_code, del_flag)

hotel_room(房间表):

字段 类型 说明
id BIGINT 主键
tenant_id BIGINT 租户ID
room_no VARCHAR(32) 房间号(租户内唯一)
room_type_id BIGINT 房型ID
floor_no VARCHAR(16) 楼层
status VARCHAR(16) 状态:VACANT/OCCUPIED/CLEANING/MAINTENANCE
sort_order INT 排序号
remark VARCHAR(256) 备注
del_flag BIGINT 逻辑删除标记

唯一索引: UNIQUE (tenant_id, room_no, del_flag)

hotel_room_type(房型表):

字段 类型 说明
id BIGINT 主键
tenant_id BIGINT 租户ID
type_name VARCHAR(64) 房型名称
description VARCHAR(256) 房型描述
sort_order INT 排序号
del_flag BIGINT 逻辑删除标记

hotel_qr_bind_log(绑定日志表):

字段 类型 说明
id BIGINT 主键
tenant_id BIGINT 租户ID
qr_code_id BIGINT 二维码ID
short_code VARCHAR(32) 冗余短码
room_id BIGINT 房间ID
room_no VARCHAR(32) 冗余房间号
action_type VARCHAR(16) 操作类型:BIND/REBIND/UNBIND
operator_id BIGINT 操作人ID
operator_name VARCHAR(64) 操作人姓名
operate_time DATETIME 操作时间
remark VARCHAR(256) 备注

4.2 字典数据

字典类型 字典值 标签 标签样式
sys_normal_disable 0 正常 success
sys_normal_disable 1 停用 danger
hotel_room_status VACANT 空闲 success
hotel_room_status OCCUPIED 入住 primary
hotel_room_status CLEANING 打扫中 warning
hotel_room_status MAINTENANCE 维护中 danger
hotel_qr_bind_action BIND 绑定 success
hotel_qr_bind_action REBIND 重绑 warning
hotel_qr_bind_action UNBIND 解绑 danger

五、API 接口清单

5.1 管理端接口(需 Sa-Token 登录)

二维码管理:

方法 路径 说明
GET /hotel/qrcode/page 分页查询二维码
GET /hotel/qrcode/:id 查询二维码详情
POST /hotel/qrcode/batch-generate 批量生成二维码
POST /hotel/qrcode/:id/bind 绑定房间
POST /hotel/qrcode/:id/rebind 重新绑定房间
POST /hotel/qrcode/:id/unbind 解绑房间
PUT /hotel/qrcode/:id/status 更新二维码状态
POST /hotel/qrcode/batch-remove 批量删除二维码(逻辑删除)
POST /hotel/qrcode/batch-download 批量下载二维码ZIP
GET /hotel/qrcode/:id/bind-logs 查询绑定日志

房间管理:

方法 路径 说明
GET /hotel/room/page 分页查询房间
GET /hotel/room/:id 查询房间详情
POST /hotel/room 新增房间
PUT /hotel/room 修改房间
POST /hotel/room/remove/:id 删除房间
GET /hotel/room/list-all 查询全部房间(下拉用)

房型管理:

方法 路径 说明
GET /hotel/room-type/list 查询房型列表
GET /hotel/room-type/:id 查询房型详情
POST /hotel/room-type 新增房型
PUT /hotel/room-type 修改房型
POST /hotel/room-type/remove/:id 删除房型

5.2 开放接口(免登录)

方法 路径 说明
GET /hotel/open/scan?shortCode=xxx&sign=xxx 扫码查询二维码信息

六、二维码 URL 格式

{baseUrl}/#/pages/hotel/scan-bind?c={shortCode}&t={tenantId}&s={sign}
参数 说明
c 二维码短码(8位)
t 租户ID
s MD5签名值 = MD5(shortCode + tenantId + secret)

签名密钥配置:

  • 默认值: hotel_qr_default_secret
  • 生产环境: 通过环境变量 HOTEL_QR_SECRET 覆盖

七、关键业务逻辑

7.1 批量生成

  • 生成数量:10/50/100/200 个一批,上限 500
  • 短码:8位大写字母+数字,租户内唯一
  • 批次号:QR + yyyyMMddHHmmss
  • 状态:默认启用(status=0)

7.2 绑定/重绑/解绑

  • 绑定:未绑定的二维码可绑定房间,记录绑定人/绑定时间
  • 重绑:已绑定的二维码可重新绑定,覆盖原绑定关系,更新绑定人/绑定时间
  • 解绑:清除绑定关系,记录解绑人/解绑时间(不覆盖绑定信息)
  • 所有操作均记录到 hotel_qr_bind_log

7.3 批量删除

  • 仅允许删除未绑定房间的二维码
  • 已绑定的二维码拒绝删除,提示先解绑
  • 逻辑删除(del_flag 写入主键ID)

7.4 批量下载ZIP

  • 勾选多个二维码,后端生成 PNG 图片打包为 ZIP
  • 文件名以短码命名:{shortCode}.png
  • 单条下载:操作列"下载"按钮

7.5 扫码查询(开放接口)

  • 免登录,根据 shortCode 查询二维码(忽略租户过滤)
  • 签名校验:MD5(shortCode + tenantId + secret)
  • 使用二维码所属租户 ID 设置租户上下文,执行后续查询

八、环境变量

变量名 必填 默认值 说明
HOTEL_QR_SECRET hotel_qr_default_secret 二维码签名密钥(生产环境必须修改)

九、后续扩展预留

扩展点 说明
钉钉 H5 集成 通过 DingTalk SSO 获取员工身份,调用绑定/重绑接口
小程序 openid 绑定 /hotel/open/ 下新增小程序专用接口
顾客点餐流程 扫码后进入点餐 H5/小程序页面
房间状态实时推送 WebSocket 推送房间状态变更

十、给 AI 助手的指令

当协助开发酒店模块时,请:

  1. 严格遵循规范: 使用 @RequiredArgsConstructorRespInfo、雪花算法ID、Composition API
  2. 使用 AiCrudPage: 列表页面必须使用 AiCrudPage 组件,禁止手动拼接搜索栏
  3. 使用字典组件: 状态/类型等字段必须使用 DictTag / useDict(),禁止硬编码
  4. SQL 写在 XML: 查询类 SQL 必须写在 Mapper XML 中,禁止 Service 层用 LambdaQueryWrapper
  5. 逻辑删除: 所有业务表默认逻辑删除,@TableLogic 必须显式声明
  6. 租户隔离: 业务数据 tenant_id=1,查询自动追加租户过滤
  7. 参考现有代码: 查看 forge-hotel 模块中已有实现

禁止:

  • 不使用 @Autowired(使用 @RequiredArgsConstructor
  • ❌ 不使用 DataResult / ResponseUtil(使用 RespInfo
  • ❌ 不使用 UUID / 自增ID(使用雪花算法)
  • ❌ 不在 Service 层构建查询 SQL(写在 Mapper XML)
  • 不手动拼接搜索栏(使用 AiCrudPage)
  • ❌ 不硬编码字典值(使用 DictTag / useDict)
  • ❌ 不设 tenant_id=0(必须为 1)

十一、文件路径

  • 后端模块: forge-server/forge-business/forge-hotel/
  • PC前端页面: forge-admin-ui/src/views/hotel/
  • H5前端页面: forge-h5-ui/src/pages/hotel/
  • API文件: forge-admin-ui/src/api/hotel.js
  • 数据库迁移: forge-server/db/migration/
  • 开发文档: forge-server/forge-business/forge-hotel/酒店二维码模块开发文档.md

配置版本: v2.0
维护者: QoderWork AI Assistant