重要: 此文件会被 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
启动类: 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 规范:
LambdaQueryWrapper 构建selectById、insert、updateById、deleteById 等内置方法允许租户 ID 规则:
tenant_id 必须设为 1(默认租户),禁止设 0TenantLineInnerInterceptor 自动追加 WHERE tenant_id = 当前租户ID组件语法:
<!-- ✅ 必须使用 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 | 灰蓝 | 详情、日志 |
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 # 扫码绑定房间页面
| 端 | 技术 | 部署 | 核心功能 |
|---|---|---|---|
| PC 管理后台 | Vue3 + Naive UI + AiCrudPage | PC浏览器 | 批量生成、批量删除、批量下载ZIP、绑定/重绑/解绑、状态管理 |
| H5 移动端 | UniApp + html5-qrcode | 手机浏览器(HTTPS) | 员工扫码绑定房间、查看绑定状态 |
| 开放接口 | REST API | 免登录 | 顾客扫码查询二维码信息 |
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) | 备注 |
| 字典类型 | 字典值 | 标签 | 标签样式 |
|---|---|---|---|
| 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 |
二维码管理:
| 方法 | 路径 | 说明 |
|---|---|---|
| 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 |
删除房型 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /hotel/open/scan?shortCode=xxx&sign=xxx |
扫码查询二维码信息 |
{baseUrl}/#/pages/hotel/scan-bind?c={shortCode}&t={tenantId}&s={sign}
| 参数 | 说明 |
|---|---|
| c | 二维码短码(8位) |
| t | 租户ID |
| s | MD5签名值 = MD5(shortCode + tenantId + secret) |
签名密钥配置:
hotel_qr_default_secretHOTEL_QR_SECRET 覆盖hotel_qr_bind_log 表{shortCode}.png| 变量名 | 必填 | 默认值 | 说明 |
|---|---|---|---|
| HOTEL_QR_SECRET | 否 | hotel_qr_default_secret | 二维码签名密钥(生产环境必须修改) |
| 扩展点 | 说明 |
|---|---|
| 钉钉 H5 集成 | 通过 DingTalk SSO 获取员工身份,调用绑定/重绑接口 |
| 小程序 openid 绑定 | 在 /hotel/open/ 下新增小程序专用接口 |
| 顾客点餐流程 | 扫码后进入点餐 H5/小程序页面 |
| 房间状态实时推送 | WebSocket 推送房间状态变更 |
当协助开发酒店模块时,请:
@RequiredArgsConstructor、RespInfo、雪花算法ID、Composition APIAiCrudPage 组件,禁止手动拼接搜索栏DictTag / useDict(),禁止硬编码@TableLogic 必须显式声明tenant_id=1,查询自动追加租户过滤forge-hotel 模块中已有实现禁止:
@Autowired(使用 @RequiredArgsConstructor)DataResult / ResponseUtil(使用 RespInfo)tenant_id=0(必须为 1)forge-server/forge-business/forge-hotel/forge-admin-ui/src/views/hotel/forge-h5-ui/src/pages/hotel/forge-admin-ui/src/api/hotel.jsforge-server/db/migration/forge-server/forge-business/forge-hotel/酒店二维码模块开发文档.md配置版本: v2.0
维护者: QoderWork AI Assistant