diff --git a/开发者文档/04-前端开发/04-常见坑点与调试指南.md b/开发者文档/04-前端开发/04-常见坑点与调试指南.md
new file mode 100644
index 0000000..57c31dc
--- /dev/null
+++ b/开发者文档/04-前端开发/04-常见坑点与调试指南.md
@@ -0,0 +1,334 @@
+# 04-常见坑点与调试指南
+
+本文档收集前端开发过程中高频出现的坑点、错误案例和调试技巧。所有前端开发人员在遇到类似问题时应先查阅本文档。
+
+---
+
+## 一、高频踩坑记录
+
+### 1.1 路由跳转后页面不刷新
+
+**现象**:从列表页点击进入详情页,URL 已变但页面内容未更新。
+
+**原因**:Vue Router 复用了同一个组件实例,`onMounted` 不会再次触发。
+
+**解决方案**:
+
+```vue
+
+```
+
+---
+
+### 1.2 Pinia Store 数据响应式丢失
+
+**现象**:修改 Store 中的数据后,页面未更新。
+
+**错误写法**:
+
+```typescript
+// ❌ 错误:直接替换整个对象,丢失响应式
+const userStore = useUserStore()
+userStore.userInfo = { name: 'new', age: 25 }
+```
+
+**正确写法**:
+
+```typescript
+// ✅ 正确:使用 Object.assign 保持响应式
+const userStore = useUserStore()
+Object.assign(userStore.userInfo, { name: 'new', age: 25 })
+
+// 或者在定义 Store 时使用 ref
+export const useUserStore = defineStore('user', () => {
+ const userInfo = ref({ name: '', age: 0 })
+
+ const updateInfo = (newInfo: any) => {
+ userInfo.value = { ...userInfo.value, ...newInfo }
+ }
+
+ return { userInfo, updateInfo }
+})
+```
+
+---
+
+### 1.3 表格分页参数不生效
+
+**现象**:切换页码后,表格数据未更新或总是返回第一页。
+
+**原因**:Pagination 组件未正确绑定 `v-model:current` 和 `v-model:pageSize`。
+
+**正确写法**:
+
+```vue
+
+
+
+
+
+```
+
+---
+
+### 1.4 权限指令不生效
+
+**现象**:添加了 `v-hasPermi` 但按钮仍然显示。
+
+**排查步骤**:
+
+1. 检查后端返回的权限标识是否正确(`/system/user/get-permission`)
+2. 检查权限标识字符串是否与后端 `@PreAuthorize` 注解完全一致
+3. 检查是否在登录完成后才注册指令(确保 `permissionStore` 已加载)
+
+**调试命令**:
+
+```typescript
+// 在浏览器控制台执行
+window.$permission = usePermission()
+window.$permission.hasPermission('ops:ticket:update')
+// 返回 true/false
+```
+
+---
+
+### 1.5 Axios 请求重复发送
+
+**现象**:点击一次按钮,接口被调用多次。
+
+**常见原因**:
+
+1. 按钮未添加 `loading` 状态防抖
+2. 表单验证触发多次提交
+3. Vue 3 的 `watch` 未正确配置 `immediate` 导致初始化时多触发一次
+
+**解决方案**:
+
+```vue
+
+
+
+ 提交
+
+```
+
+---
+
+## 二、调试技巧
+
+### 2.1 快速定位组件来源
+
+在浏览器 DevTools 中:
+
+```javascript
+// 在控制台执行,点击页面元素后自动定位到源码
+import { inspect } from 'vue'
+inspect()
+```
+
+---
+
+### 2.2 查看 Pinia Store 状态
+
+```javascript
+// 浏览器控制台
+window.$pinia = usePinia()
+Object.keys(window.$pinia.state.value).forEach(key => {
+ console.log(key, window.$pinia.state.value[key])
+})
+```
+
+---
+
+### 2.3 网络请求调试
+
+在 `src/utils/http/axios/index.ts` 中临时开启详细日志:
+
+```typescript
+axios.interceptors.request.use(config => {
+ console.log('[AXIOS REQUEST]', config.url, config.params, config.data)
+ return config
+})
+
+axios.interceptors.response.use(response => {
+ console.log('[AXIOS RESPONSE]', response.config.url, response.data)
+ return response
+}, error => {
+ console.error('[AXIOS ERROR]', error.config?.url, error.response?.data)
+ return Promise.reject(error)
+})
+```
+
+---
+
+### 2.4 路由调试
+
+```javascript
+// 查看当前路由信息
+console.log($route)
+
+// 查看所有已注册路由
+console.log($router.getRoutes())
+
+// 动态添加路由后检查是否生效
+console.log($router.hasRoute('ops-ticket-list'))
+```
+
+---
+
+## 三、性能优化建议
+
+### 3.1 大列表渲染优化
+
+**问题**:一次性渲染 1000+ 条数据导致页面卡顿。
+
+**解决方案**:
+
+1. 使用虚拟滚动(`vue-virtual-scroller`)
+2. 开启分页(推荐)
+3. 使用 `v-memo` 缓存静态内容(Vue 3.2+)
+
+```vue
+
+
+ {{ item.name }}
+
+
+```
+
+---
+
+### 3.2 组件懒加载
+
+```typescript
+// 路由懒加载
+const routes = [
+ {
+ path: '/ops',
+ component: () => import('@/views/ops/index.vue'),
+ children: [
+ {
+ path: 'ticket',
+ component: () => import('@/views/ops/ticket/index.vue')
+ }
+ ]
+ }
+]
+```
+
+---
+
+### 3.3 避免不必要的计算
+
+```vue
+
+```
+
+---
+
+## 四、开发环境配置
+
+### 4.1 推荐 VS Code 插件
+
+- Volar(Vue 3 官方插件)
+- ESLint
+- Prettier
+- TypeScript Vue Plugin
+
+### 4.2 本地调试配置
+
+```bash
+# 安装依赖
+pnpm install
+
+# 启动开发服务器
+pnpm dev
+
+# 构建生产版本
+pnpm build
+
+# 类型检查
+pnpm type-check
+
+# Lint 检查
+pnpm lint
+```
+
+### 4.3 环境变量配置
+
+```bash
+# .env.development
+VITE_API_BASE_URL=http://localhost:48080
+VITE_APP_TITLE=AIOT 管理后台 - 开发环境
+
+# .env.production
+VITE_API_BASE_URL=https://api.example.com
+VITE_APP_TITLE=AIOT 管理后台
+```
+
+---
+
+## 五、相关文档
+
+- [01-前端工程结构与协作边界.md](./01-前端工程结构与协作边界.md)
+- [02-API 交互与状态管理规范.md](./02-API 交互与状态管理规范.md)
+- [03-RBAC 权限控制与开发规范.md](./03-RBAC 权限控制与开发规范.md)
diff --git a/开发者文档/06-平台支撑/07-API 文档/01-接口分域与维护原则.md b/开发者文档/06-平台支撑/07-API 文档/01-接口分域与维护原则.md
new file mode 100644
index 0000000..df0320d
--- /dev/null
+++ b/开发者文档/06-平台支撑/07-API 文档/01-接口分域与维护原则.md
@@ -0,0 +1,226 @@
+# 01-接口分域与维护原则
+
+本文档定义 AIOT 系统 API 接口的组织原则、文档维护责任边界,以及接口变更的协作流程。
+
+**核心原则**:接口文档优先按**业务域**维护,而非按页面或客户端维护。因为页面会变、客户端会增,但领域边界相对稳定。
+
+---
+
+## 一、接口分域架构
+
+### 1.1 四大核心域
+
+| 域标识 | 对应微服务 | 职责范围 | 负责人 |
+|--------|-----------|---------|--------|
+| `system` | `module-system` | 用户、角色、菜单、部门、租户、字典 | 后端架构组 |
+| `infra` | `module-infra` | 文件管理、定时任务、代码生成、消息推送 | 后端架构组 |
+| `ops` | `module-ops` | 工单、巡检、保洁、安保、排班、考勤 | Ops 业务组 |
+| `iot` | `module-iot` | 设备、物模型、规则引擎、告警、MQTT 桥接 | IoT 业务组 |
+
+### 1.2 接口 URL 规范
+
+所有接口必须遵循 RESTful 风格,并按域组织路径:
+
+```
+GET /api/system/users # 用户列表
+POST /api/system/users # 创建用户
+GET /api/system/users/{id} # 用户详情
+PUT /api/system/users/{id} # 更新用户
+DELETE /api/system/users/{id} # 删除用户
+
+GET /api/ops/tickets # 工单列表
+POST /api/ops/tickets/{id}/dispatch # 派单(业务操作)
+POST /api/ops/tickets/{id}/confirm # 确认到岗(业务操作)
+
+GET /api/iot/devices # 设备列表
+POST /api/iot/devices/{id}/reboot # 重启设备(业务操作)
+```
+
+**禁止事项**:
+- ❌ `/api/getUserList` - 非 RESTful
+- ❌ `/api/ticket/updateStatus` - 动词在 URL 中,应使用 `/api/tickets/{id}/status`
+- ❌ `/api/opsAndIot/xxx` - 跨域接口应拆分或通过事件驱动
+
+---
+
+## 二、接口文档维护责任
+
+### 2.1 Swagger 注解是唯一的真理源
+
+**所有接口必须在 Controller 方法上完整标注 Swagger 注解**:
+
+```java
+@RestController
+@RequestMapping("/ops/tickets")
+@Tag(name = "工单管理", description = "工单 CRUD 及状态流转")
+public class TicketController {
+
+ @PostMapping("/dispatch")
+ @Operation(summary = "派单", description = "将工单派发给指定保洁员")
+ @PreAuthorize("@ss.hasPermi('ops:ticket:dispatch')")
+ public CommonResult dispatchTicket(@RequestBody @Valid TicketDispatchReqVO reqVO) {
+ // ...
+ }
+}
+```
+
+**必填注解**:
+- `@Tag` - 接口分组(对应域)
+- `@Operation(summary = ..., description = ...)` - 接口用途
+- `@Parameter` / `@Schema` - 参数说明
+- `@ApiResponse` - 返回码说明(特别是业务错误码)
+
+### 2.2 接口变更流程
+
+```
+开发者修改接口
+ ↓
+更新 Swagger 注解
+ ↓
+提交 MR → 自动触发 Swagger 文档生成
+ ↓
+前端/移动端负责人 Review 文档
+ ↓
+确认无破坏性变更后合并
+```
+
+**破坏性变更定义**(需提前通知所有调用方):
+- 删除或重命名已有字段
+- 修改字段类型(如 `String` → `Integer`)
+- 增加必填参数
+- 修改接口路径或 HTTP 方法
+
+**非破坏性变更**(可直接发布):
+- 新增可选参数
+- 新增接口
+- 增加返回字段
+
+---
+
+## 三、为什么不按页面维护接口文档
+
+### 3.1 错误示例
+
+```
+❌ 按页面组织:
+- 保洁管理页面接口
+ - 获取保洁员列表
+ - 创建保洁员
+ - 编辑保洁员
+- 工单列表页面接口
+ - 获取工单列表
+ - 工单详情
+```
+
+**问题**:
+1. 同一个 `/api/ops/cleaners` 接口可能被保洁管理页面、工单派发页面、排班页面同时使用
+2. 新增一个移动端页面时,接口文档需要重复维护
+3. 页面重构或合并时,接口文档需要大量调整
+
+### 3.2 正确示例
+
+```
+✅ 按业务域组织:
+- ops 域
+ - 保洁员管理
+ - GET /api/ops/cleaners - 保洁员列表
+ - POST /api/ops/cleaners - 创建保洁员
+ - PUT /api/ops/cleaners/{id} - 更新保洁员
+ - 工单管理
+ - GET /api/ops/tickets - 工单列表
+ - POST /api/ops/tickets/{id}/dispatch - 派单
+```
+
+**优势**:
+1. 接口与页面解耦,一个接口服务多个客户端
+2. 领域边界清晰,便于微服务拆分
+3. 新增客户端(如小程序)时,直接引用已有域文档
+
+---
+
+## 四、接口版本管理
+
+### 4.1 版本号位置
+
+当需要发布不兼容的接口变更时,使用 URL 路径版本号:
+
+```
+GET /api/v1/ops/tickets # 旧版本
+GET /api/v2/ops/tickets # 新版本(字段结构变化)
+```
+
+**禁止使用**:
+- ❌ Query 参数版本:`/api/ops/tickets?version=2`
+- ❌ Header 版本:`X-API-Version: 2`(不利于缓存和调试)
+
+### 4.2 版本共存策略
+
+- 新版本发布后,旧版本至少保留 **3 个月** 过渡期
+- 在网关层监控旧版本接口的调用量,提前通知调用方迁移
+- 过渡期结束后,在网关层返回 `410 Gone` 并引导升级
+
+---
+
+## 五、跨域接口处理
+
+### 5.1 禁止跨域直接调用
+
+```java
+// ❌ 错误:ops 服务直接调用 iot 服务的 Feign Client
+@Autowired
+private IotDeviceClient deviceClient;
+
+public void dispatchTicket() {
+ // 直接调用 IoT 服务
+ deviceClient.getDeviceStatus(deviceId);
+}
+```
+
+**问题**:
+- 微服务之间产生强耦合
+- 无法独立部署和扩展
+- 故障传播(IoT 服务宕机拖垮 Ops 服务)
+
+### 5.2 正确做法:事件驱动
+
+```java
+// ✅ 正确:通过消息队列解耦
+// Ops 服务发布事件
+applicationEventPublisher.publishEvent(new TicketDispatchedEvent(ticketId, deviceId));
+
+// IoT 服务监听事件并处理
+@EventListener
+public void onTicketDispatched(TicketDispatchedEvent event) {
+ // 处理设备相关逻辑
+}
+```
+
+---
+
+## 六、接口文档访问
+
+### 6.1 Swagger UI 地址
+
+| 环境 | 地址 |
+|------|------|
+| 开发环境 | `http://localhost:48080/swagger-ui.html` |
+| 测试环境 | `http://test-api.example.com/swagger-ui.html` |
+| 生产环境 | **不开放**(通过内部文档平台查看) |
+
+### 6.2 导出 OpenAPI 规范
+
+```bash
+# 导出 YAML 格式
+curl http://localhost:48080/v3/api-docs -o openapi.yaml
+
+# 导出 JSON 格式
+curl http://localhost:48080/v3/api-docs -o openapi.json
+```
+
+---
+
+## 七、相关文档
+
+- [00-支撑平台总览.md](../00-支撑平台总览.md)
+- [01-统一网关入口规范.md](../01-统一网关入口规范.md)
+- [08-数据库/01-数据域划分与表关系思路.md](../08-数据库/01-数据域划分与表关系思路.md)
diff --git a/开发者文档/06-平台支撑/08-数据库/01-数据域划分与表关系思路.md b/开发者文档/06-平台支撑/08-数据库/01-数据域划分与表关系思路.md
index 7b2055a..dc78278 100644
--- a/开发者文档/06-平台支撑/08-数据库/01-数据域划分与表关系思路.md
+++ b/开发者文档/06-平台支撑/08-数据库/01-数据域划分与表关系思路.md
@@ -1,31 +1,415 @@
-# 🗄️ 数据域划分与表关系思路
+# 01-数据域划分与表关系思路
-当前数据库文档最重要的不是表清单,而是先划分数据域。
+本文档定义 AIOT 系统 MySQL 数据库的逻辑分域原则、表命名规范,以及跨域关联查询的底线。
-## 1. 系统主数据
+**核心原则**:数据库表按业务域划分,域内可自由关联,跨域关联必须通过冗余字段或事件驱动,禁止跨域 JOIN。
-- 用户
-- 角色
-- 菜单
-- 部门
-- 租户
+---
-## 2. IoT 主数据与过程数据
+## 一、数据库分域架构
-- 产品
-- 设备
-- 设备分组
-- 物模型
-- 告警配置
-- 告警记录
-- 设备消息
+### 1.1 三大核心数据域
-## 3. Ops 主数据与过程数据
+```
+┌─────────────────────────────────────────────────────────────┐
+│ AIOT Database │
+├─────────────────┬─────────────────┬─────────────────────────┤
+│ SYSTEM 域 │ OPS 域 │ IoT 域 │
+│ (系统主数据) │ (业务过程数据) │ (设备与物联数据) │
+├─────────────────┼─────────────────┼─────────────────────────┤
+│ - sys_user │ - ops_ticket │ - iot_product │
+│ - sys_role │ - ops_order │ - iot_device │
+│ - sys_menu │ - ops_cleaner │ - iot_thing_model │
+│ - sys_dept │ - ops_inspection│ - iot_rule │
+│ - sys_dict │ - ops_security │ - iot_alarm │
+│ - sys_tenant │ - ops_shift │ - iot_message_log │
+└─────────────────┴─────────────────┴─────────────────────────┘
+```
-- 工单主记录
-- 工单业务日志
-- 工单事件
-- 队列记录
-- 执行人状态
-- 统计结果
+### 1.2 域职责边界
+| 域 | 职责 | 数据特点 | 读写比例 |
+|----|------|---------|---------|
+| **SYSTEM** | 用户、角色、权限、组织架构、字典 | 低频变更、高一致性要求 | 读 95% / 写 5% |
+| **OPS** | 工单、排班、考勤、巡检记录 | 高频写入、状态流转复杂 | 读 60% / 写 40% |
+| **IoT** | 设备、物模型、消息、告警 | 超高频写入、时序性强 | 读 20% / 写 80% |
+
+---
+
+## 二、表命名规范
+
+### 2.1 强制前缀规则
+
+所有表名必须带域前缀,格式:`{域标识}_{模块名}_{实体名}`
+
+```sql
+-- ✅ 正确
+sys_user -- 系统域 - 用户
+sys_role -- 系统域 - 角色
+ops_ticket -- Ops 域 - 工单
+ops_order_queue -- Ops 域 - 工单队列
+iot_device -- IoT 域 - 设备
+iot_alarm_record -- IoT 域 - 告警记录
+
+-- ❌ 错误
+user -- 缺少域前缀
+ticket -- 缺少域前缀
+iot_device_info -- 冗余后缀(device 本身就表示信息)
+```
+
+### 2.2 关联表命名
+
+多对多关联表使用 `_{域}_关联实体 A_关联实体 B` 格式:
+
+```sql
+sys_user_role -- 用户 - 角色关联
+sys_role_menu -- 角色 - 菜单关联
+ops_ticket_cleaner -- 工单 - 保洁员关联(历史派单记录)
+```
+
+### 2.3 扩展表命名
+
+当主表字段过多需要拆分时:
+
+```sql
+ops_ticket -- 主表(核心字段)
+ops_ticket_ext -- 扩展表(低频访问的大字段)
+ops_ticket_trace -- 追踪表(状态流转日志)
+```
+
+---
+
+## 三、核心表结构概览
+
+### 3.1 SYSTEM 域
+
+```sql
+-- 用户表
+CREATE TABLE sys_user (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL COMMENT '租户 ID',
+ username VARCHAR(50) NOT NULL COMMENT '用户名',
+ password VARCHAR(100) NOT NULL COMMENT '密码',
+ nickname VARCHAR(50) COMMENT '昵称',
+ email VARCHAR(255) COMMENT '邮箱',
+ phone VARCHAR(20) COMMENT '手机号',
+ status TINYINT DEFAULT 1 COMMENT '状态 (0-禁用 1-正常)',
+ dept_id BIGINT COMMENT '部门 ID',
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+
+ INDEX idx_tenant_username (tenant_id, username),
+ INDEX idx_phone (phone)
+);
+
+-- 角色表
+CREATE TABLE sys_role (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL,
+ name VARCHAR(50) NOT NULL COMMENT '角色名称',
+ code VARCHAR(50) NOT NULL COMMENT '角色标识',
+ status TINYINT DEFAULT 1,
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+
+ UNIQUE KEY uk_tenant_code (tenant_id, code)
+);
+
+-- 用户角色关联表
+CREATE TABLE sys_user_role (
+ user_id BIGINT NOT NULL,
+ role_id BIGINT NOT NULL,
+ PRIMARY KEY (user_id, role_id)
+);
+```
+
+### 3.2 OPS 域
+
+```sql
+-- 工单表
+CREATE TABLE ops_ticket (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL,
+ ticket_no VARCHAR(32) NOT NULL COMMENT '工单号',
+ type TINYINT NOT NULL COMMENT '工单类型 (1-保洁 2-安保 3-巡检)',
+ status TINYINT NOT NULL COMMENT '状态 (见 WorkOrderStatusEnum)',
+ priority TINYINT DEFAULT 1 COMMENT '优先级 (1-P0 紧急 2-P1 高 3-P2 中 4-P3 低)',
+
+ -- 位置信息
+ location_name VARCHAR(100) COMMENT '位置名称',
+ location_address VARCHAR(255) COMMENT '详细地址',
+ beacon_id VARCHAR(50) COMMENT '关联信标 ID',
+
+ -- 派单信息
+ assigned_cleaner_id BIGINT COMMENT '指派保洁员 ID',
+ assigned_at DATETIME COMMENT '派单时间',
+ confirmed_at DATETIME COMMENT '确认时间',
+ arrived_at DATETIME COMMENT '到岗时间 (信标感应)',
+ completed_at DATETIME COMMENT '完成时间',
+
+ -- 队列评分 (用于智能派单排序)
+ queue_score DECIMAL(10,2) COMMENT '队列评分',
+
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+
+ UNIQUE KEY uk_ticket_no (tenant_id, ticket_no),
+ INDEX idx_status (status),
+ INDEX idx_assigned_cleaner (assigned_cleaner_id),
+ INDEX idx_beacon (beacon_id)
+);
+
+-- 工单状态流转日志表
+CREATE TABLE ops_ticket_log (
+ id BIGINT PRIMARY KEY,
+ ticket_id BIGINT NOT NULL,
+ from_status TINYINT NOT NULL,
+ to_status TINYINT NOT NULL,
+ operator_id BIGINT COMMENT '操作人 ID',
+ operator_type TINYINT COMMENT '操作人类型 (1-人 2-系统 3-信标)',
+ remark VARCHAR(500) COMMENT '备注',
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+
+ INDEX idx_ticket (ticket_id),
+ INDEX idx_created (created_at)
+);
+
+-- 保洁员表
+CREATE TABLE ops_cleaner (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL,
+ user_id BIGINT NOT NULL COMMENT '关联系统用户 ID',
+ name VARCHAR(50) NOT NULL,
+ phone VARCHAR(20) NOT NULL,
+ status TINYINT DEFAULT 1 COMMENT '状态 (1-空闲 2-工作中 3-离线)',
+ current_ticket_id BIGINT COMMENT '当前工单 ID',
+ badge_no VARCHAR(50) COMMENT '工牌编号',
+
+ -- 统计字段 (冗余,避免实时 COUNT)
+ total_tickets INT DEFAULT 0 COMMENT '累计完成工单数',
+ today_tickets INT DEFAULT 0 COMMENT '今日完成工单数',
+
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+
+ UNIQUE KEY uk_user (tenant_id, user_id),
+ INDEX idx_status (status),
+ INDEX idx_badge (badge_no)
+);
+```
+
+### 3.3 IoT 域
+
+```sql
+-- 产品表 (设备模板)
+CREATE TABLE iot_product (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL,
+ name VARCHAR(100) NOT NULL,
+ product_key VARCHAR(50) NOT NULL COMMENT '产品唯一标识',
+ product_secret VARCHAR(100) COMMENT '产品密钥',
+
+ -- 物模型
+ thing_model_id BIGINT COMMENT '关联物模型 ID',
+
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+
+ UNIQUE KEY uk_product_key (tenant_id, product_key)
+);
+
+-- 设备表
+CREATE TABLE iot_device (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL,
+ product_id BIGINT NOT NULL,
+ device_name VARCHAR(100) NOT NULL,
+ device_key VARCHAR(50) NOT NULL COMMENT '设备唯一标识',
+ device_secret VARCHAR(100) COMMENT '设备密钥',
+
+ -- 状态
+ status TINYINT DEFAULT 0 COMMENT '状态 (0-未激活 1-在线 2-离线 3-禁用)',
+ last_heartbeat_at DATETIME COMMENT '最后心跳时间',
+
+ -- 关联信息
+ beacon_id VARCHAR(50) COMMENT '绑定信标 ID',
+ cleaner_id BIGINT COMMENT '绑定保洁员 ID (工牌设备)',
+
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+
+ UNIQUE KEY uk_device_key (tenant_id, device_key),
+ INDEX idx_product (product_id),
+ INDEX idx_status (status),
+ INDEX idx_cleaner (cleaner_id)
+);
+
+-- 物模型定义表
+CREATE TABLE iot_thing_model (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL,
+ name VARCHAR(100) NOT NULL,
+
+ -- 属性定义 (JSON 存储)
+ properties JSON COMMENT '属性列表',
+ events JSON COMMENT '事件列表',
+ services JSON COMMENT '服务列表',
+
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
+);
+
+-- 告警记录表
+CREATE TABLE iot_alarm (
+ id BIGINT PRIMARY KEY,
+ tenant_id BIGINT NOT NULL,
+ device_id BIGINT NOT NULL,
+ alarm_type VARCHAR(50) NOT NULL COMMENT '告警类型',
+ alarm_level TINYINT NOT NULL COMMENT '告警级别 (1-紧急 2-重要 3-一般)',
+ content VARCHAR(500) COMMENT '告警内容',
+ status TINYINT DEFAULT 0 COMMENT '状态 (0-未处理 1-已处理)',
+
+ triggered_at DATETIME NOT NULL,
+ handled_at DATETIME COMMENT '处理时间',
+ handler_id BIGINT COMMENT '处理人 ID',
+
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+
+ INDEX idx_device (device_id),
+ INDEX idx_status (status),
+ INDEX idx_triggered (triggered_at)
+);
+```
+
+---
+
+## 四、跨域关联原则
+
+### 4.1 禁止跨域 JOIN
+
+```sql
+-- ❌ 错误:跨域 JOIN(Ops 域直接 JOIN System 域)
+SELECT t.*, u.nickname
+FROM ops_ticket t
+JOIN sys_user u ON t.assigned_cleaner_id = u.id
+WHERE t.status = 1;
+
+-- ❌ 错误:跨域 JOIN(IoT 域直接 JOIN Ops 域)
+SELECT d.*, c.name
+FROM iot_device d
+JOIN ops_cleaner c ON d.cleaner_id = c.id;
+```
+
+**问题**:
+- 违反微服务边界,未来无法拆分数据库
+- 跨域查询性能不可控
+- 事务边界模糊
+
+### 4.2 正确做法:冗余字段 + 应用层组装
+
+```sql
+-- ✅ 正确:在 Ops 域冗余 System 域的必要字段
+CREATE TABLE ops_cleaner (
+ id BIGINT PRIMARY KEY,
+ user_id BIGINT NOT NULL,
+ name VARCHAR(50) NOT NULL, -- 冗余 sys_user.nickname
+ phone VARCHAR(20) NOT NULL, -- 冗余 sys_user.phone
+ -- ...
+);
+
+-- 应用层查询时:
+-- 1. 先查 ops_ticket 获取 assigned_cleaner_id
+-- 2. 批量查询 ops_cleaner 获取保洁员信息(含冗余的 name/phone)
+-- 3. 在内存中组装结果
+```
+
+### 4.3 必须跨域查询时的方案
+
+**场景**:后台管理页面需要展示工单列表,包含保洁员姓名、部门等信息。
+
+**方案 A:应用层批量查询(推荐)**
+
+```java
+// 1. 查询工单列表
+List tickets = ticketMapper.selectList(query);
+
+// 2. 批量查询保洁员信息
+List cleanerIds = tickets.stream()
+ .map(Ticket::getAssignedCleanerId)
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toList());
+
+List cleaners = cleanerMapper.selectBatchIds(cleanerIds);
+Map cleanerMap = cleaners.stream()
+ .collect(Collectors.toMap(Cleaner::getId, Function.identity()));
+
+// 3. 批量查询用户信息(System 域)
+List userIds = cleaners.stream()
+ .map(Cleaner::getUserId)
+ .collect(Collectors.toList());
+
+List users = userMapper.selectBatchIds(userIds);
+
+// 4. 内存组装
+tickets.forEach(ticket -> {
+ Cleaner cleaner = cleanerMap.get(ticket.getAssignedCleanerId());
+ if (cleaner != null) {
+ ticket.setCleanerName(cleaner.getName());
+ // ...
+ }
+});
+```
+
+**方案 B:数据同步(读多写少场景)**
+
+```java
+// System 域的用户信息变更时,发布事件
+applicationEventPublisher.publishEvent(new UserInfoChangedEvent(userId));
+
+// Ops 域监听事件,更新冗余字段
+@EventListener
+public void onUserInfoChanged(UserInfoChangedEvent event) {
+ User user = userService.getById(event.getUserId());
+ cleanerMapper.updateByUserId(user.getId(),
+ CleanerUpdateParams.builder()
+ .name(user.getNickname())
+ .phone(user.getPhone())
+ .build()
+ );
+}
+```
+
+---
+
+## 五、索引设计规范
+
+### 5.1 必建索引场景
+
+| 场景 | 索引类型 | 示例 |
+|------|---------|------|
+| 主键 | PRIMARY KEY | `id` |
+| 唯一业务键 | UNIQUE KEY | `tenant_id + ticket_no` |
+| 外键关联 | INDEX | `assigned_cleaner_id` |
+| 状态筛选 | INDEX | `status` |
+| 时间范围查询 | INDEX | `created_at` |
+| 组合查询 | 复合索引 | `tenant_id + status + created_at` |
+
+### 5.2 复合索引顺序原则
+
+```sql
+-- ✅ 正确:高选择性字段在前
+INDEX idx_tenant_status_created (tenant_id, status, created_at)
+
+-- 查询时:
+WHERE tenant_id = ? AND status = ? AND created_at > ?
+WHERE tenant_id = ? AND status = ?
+WHERE tenant_id = ?
+
+-- ❌ 错误:低选择性字段在前
+INDEX idx_status_tenant (status, tenant_id)
+-- 当 status 只有 4 个值时,区分度极低
+```
+
+---
+
+## 六、相关文档
+
+- [00-支撑平台总览.md](../00-支撑平台总览.md)
+- [02-中间件使用规约.md](../02-中间件使用规约.md)
+- [07-API 文档/01-接口分域与维护原则.md](../07-API 文档/01-接口分域与维护原则.md)
diff --git a/开发者文档/06-平台支撑/09-DevOps 运维/01-部署运行与排障视角.md b/开发者文档/06-平台支撑/09-DevOps 运维/01-部署运行与排障视角.md
new file mode 100644
index 0000000..f25abc0
--- /dev/null
+++ b/开发者文档/06-平台支撑/09-DevOps 运维/01-部署运行与排障视角.md
@@ -0,0 +1,350 @@
+# 01-部署运行与排障视角
+
+本文档建立 AIOT 系统的排障方法论,帮助开发和运维人员快速定位问题所属层次,而非堆砌命令。
+
+**核心原则**:排障第一刀先判断问题属于哪一层,再逐层深入。禁止一上来就 `kubectl logs` 或 `docker exec` 盲目翻日志。
+
+---
+
+## 一、系统分层架构
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ 客户端层 (Client) │
+│ Web 管理后台 │ 移动端 App │ 小程序 │ 工牌/信标 │
+└─────────────────────────────────────────────────────────────┘
+ ↓ HTTPS / MQTT
+┌─────────────────────────────────────────────────────────────┐
+│ 网关入口层 (Gateway) │
+│ viewsh-gateway (Spring Cloud Gateway + Sentinel) │
+│ - 路由分发 - JWT 鉴权 - 限流熔断 - 黑白名单 │
+└─────────────────────────────────────────────────────────────┘
+ ↓ 内部 HTTP / Feign
+┌─────────────────────────────────────────────────────────────┐
+│ 主服务装配层 (Microservices) │
+│ ┌─────────────┬─────────────┬─────────────┬─────────────┐ │
+│ │module-system│ module-infra│ module-ops │ module-iot │ │
+│ │ 用户角色权限 │ 文件任务消息│ 工单巡检保洁│ 设备物模型 │ │
+│ └─────────────┴─────────────┴─────────────┴─────────────┘ │
+│ Nacos (注册发现/配置中心) │
+│ Redis (缓存/分布式锁) │
+│ MQ (RabbitMQ/Kafka 消息队列) │
+└─────────────────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────┐
+│ IoT 规则与设备层 (IoT Edge) │
+│ MQTT Broker (EMQX) │ 规则引擎 │ 设备影子 │ 边缘网关 │
+└─────────────────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────┐
+│ Ops 状态与执行层 (Physical) │
+│ 智能工牌 (Badge) │ 蓝牙信标 (Beacon) │ 现场工作人员 │
+└─────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## 二、排障决策树
+
+### 2.1 第一刀:问题现象归类
+
+```
+用户报告问题
+ ↓
+┌──────────────────────────────────────────┐
+│ 1. 所有用户都访问不了? │
+│ → 网关入口层 / 基础设施层 │
+│ → 检查网关健康度、Nacos、数据库连接池 │
+└──────────────────────────────────────────┘
+ ↓ 否
+┌──────────────────────────────────────────┐
+│ 2. 特定功能访问不了? │
+│ → 主服务装配层 │
+│ → 检查对应微服务状态、日志、依赖中间件 │
+└──────────────────────────────────────────┘
+ ↓ 否
+┌──────────────────────────────────────────┐
+│ 3. 设备数据不上报/不响应? │
+│ → IoT 规则与设备层 │
+│ → 检查 MQTT Broker、设备在线状态、规则引擎│
+└──────────────────────────────────────────┘
+ ↓ 否
+┌──────────────────────────────────────────┐
+│ 4. 工单状态不更新/信标无感应? │
+│ → Ops 状态与执行层 │
+│ → 检查工牌电量、信标广播、蓝牙连接日志 │
+└──────────────────────────────────────────┘
+```
+
+---
+
+## 三、各层排障清单
+
+### 3.1 网关入口层
+
+**典型症状**:
+- 所有接口返回 `502 Bad Gateway` 或 `503 Service Unavailable`
+- 登录接口正常,业务接口全部 `401 Unauthorized`
+- 部分用户访问正常,部分用户报错
+
+**检查步骤**:
+
+```bash
+# 1. 检查网关容器状态
+docker ps | grep gateway
+docker logs viewsh-gateway --tail 100
+
+# 2. 检查网关健康端点
+curl http://gateway-host:18080/actuator/health
+
+# 3. 检查 Nacos 服务注册
+curl http://nacos-host:8848/nacos/v1/ns/instance/list?serviceName=module-ops
+
+# 4. 检查网关路由配置 (Nacos 配置中心)
+# Data ID: viewsh-gateway.yaml
+# 检查 route 配置是否指向正确的服务名
+
+# 5. 检查 JWT 密钥配置
+# 确认 gateway 和 各微服务使用相同的 jwt.secret
+```
+
+**常见问题**:
+| 问题 | 原因 | 解决方案 |
+|------|------|---------|
+| 全部 502 | 下游服务全部未注册 | 检查 Nacos 是否正常,微服务是否启动 |
+| 全部 401 | JWT 密钥不一致 | 统一 Nacos 中的 `jwt.secret` 配置 |
+| 部分路由 404 | 路由配置遗漏 | 在 Nacos 网关配置中补充 route |
+| 限流报错 429 | 触发 Sentinel 限流 | 检查限流阈值,临时调高或扩容 |
+
+---
+
+### 3.2 主服务装配层
+
+**典型症状**:
+- 特定功能报错(如工单列表打不开,但用户管理正常)
+- 接口响应极慢(>5s)
+- 间歇性报错,重试后正常
+
+**检查步骤**:
+
+```bash
+# 1. 定位问题服务
+# 根据功能确定所属微服务:
+# - 工单/保洁/巡检 → module-ops
+# - 设备/物模型/告警 → module-iot
+# - 用户/角色/权限 → module-system
+
+# 2. 检查服务容器状态
+docker ps | grep module-ops
+docker stats module-ops # 查看 CPU/内存使用率
+
+# 3. 查看应用日志
+docker logs module-ops --tail 200 | grep -E "ERROR|WARN"
+
+# 4. 检查 JVM 状态
+docker exec module-ops jstat -gcutil 1000 5
+
+# 5. 检查数据库连接池
+# 登录 MySQL 查看连接数
+SHOW PROCESSLIST;
+SHOW STATUS LIKE 'Threads_connected';
+
+# 6. 检查 Redis 连接
+redis-cli -h redis-host ping
+redis-cli -h redis-host KEYS "aiot:ops:*" | head 20
+
+# 7. 检查 MQ 队列积压
+# RabbitMQ 管理界面:http://mq-host:15672
+# 查看队列消息数,确认是否有消费失败
+```
+
+**常见问题**:
+| 问题 | 原因 | 解决方案 |
+|------|------|---------|
+| 接口超时 | 数据库慢查询 | 检查慢查询日志,添加索引 |
+| 内存溢出 OOM | 堆内存不足 | 调大 `-Xmx`,检查内存泄漏 |
+| 数据库连接耗尽 | 连接池配置过小 | 调大 `maximum-pool-size` |
+| Redis 连接失败 | Redis 宕机或密码错误 | 检查 Redis 状态和 Nacos 配置 |
+| MQ 消息积压 | 消费者处理慢或宕机 | 检查消费者日志,增加并发数 |
+
+---
+
+### 3.3 IoT 规则与设备层
+
+**典型症状**:
+- 设备显示离线,但实际已通电
+- 设备上报数据,但系统未收到
+- 规则引擎未触发预期动作
+
+**检查步骤**:
+
+```bash
+# 1. 检查 MQTT Broker 状态
+docker ps | grep emqx
+docker logs emqx --tail 100
+
+# 2. 检查设备在线状态
+# EMQX 管理界面:http://emqx-host:18083
+# 查看设备连接数、订阅主题
+
+# 3. 检查设备认证日志
+docker logs emqx | grep "device-xxx"
+
+# 4. 检查规则引擎
+# EMQX 规则界面:查看规则执行日志
+# 确认规则 SQL 是否正确,动作是否配置
+
+# 5. 检查设备消息日志
+# 查询 iot_message_log 表
+SELECT * FROM iot_message_log
+WHERE device_id = xxx
+ORDER BY created_at DESC
+LIMIT 10;
+
+# 6. 模拟设备上报测试
+# 使用 MQTT.fx 或命令行工具
+mosquitto_pub -h emqx-host -t "/sys/xxx/xxx/post" -m '{"temp": 25}'
+```
+
+**常见问题**:
+| 问题 | 原因 | 解决方案 |
+|------|------|---------|
+| 设备连不上 | 设备密钥错误或 Broker 宕机 | 检查设备三元组,重启 EMQX |
+| 数据不上报 | 网络问题或主题错误 | 检查设备网络,确认发布主题 |
+| 规则不触发 | 规则 SQL 语法错误 | 在 EMQX 控制台测试规则 SQL |
+| 消息丢失 | QoS 级别过低 | 设备端使用 QoS 1 或 2 |
+
+---
+
+### 3.4 Ops 状态与执行层
+
+**典型症状**:
+- 保洁员已到岗,但系统显示未到达
+- 工单派发了,但工牌未收到通知
+- 信标感应失败,无法自动完工
+
+**检查步骤**:
+
+```bash
+# 1. 检查工牌状态
+# 查询 ops_cleaner 表
+SELECT id, name, badge_no, status, current_ticket_id
+FROM ops_cleaner
+WHERE id = xxx;
+
+# 2. 检查信标绑定关系
+# 查询 iot_device 或 ops_location 表
+SELECT beacon_id, location_name
+FROM ops_location
+WHERE id = xxx;
+
+# 3. 检查工单状态流转日志
+SELECT * FROM ops_ticket_log
+WHERE ticket_id = xxx
+ORDER BY created_at DESC;
+
+# 4. 检查蓝牙信标广播
+# 使用手机 App 或 nRF Connect 扫描信标
+# 确认信标 UUID、Major、Minor 是否正确广播
+
+# 5. 检查工牌电量
+# 工牌管理界面查看电量,或询问现场人员
+# 电量低于 20% 可能导致蓝牙断开
+
+# 6. 检查信标感应日志
+# 查看 IoT 服务日志中信标事件上报记录
+docker logs module-iot | grep "beacon:xxx"
+```
+
+**常见问题**:
+| 问题 | 原因 | 解决方案 |
+|------|------|---------|
+| 未自动到岗 | 信标未广播或工牌未感应 | 检查信标电量,重新绑定 |
+| 工牌未收到派单 | 工牌离线或 MQTT 断开 | 检查工牌网络,重启工牌 |
+| 状态不更新 | 工牌按键损坏或固件 bug | 更换工牌,升级固件 |
+| 误感应 | 信标位置过近或信号穿透 | 调整信标位置,降低发射功率 |
+
+---
+
+## 四、常用诊断命令速查
+
+### 4.1 容器诊断
+
+```bash
+# 查看所有容器状态
+docker ps -a
+
+# 查看容器资源使用
+docker stats
+
+# 查看容器日志
+docker logs --tail 100 -f
+
+# 进入容器调试
+docker exec -it bash
+
+# 重启容器
+docker restart
+```
+
+### 4.2 数据库诊断
+
+```bash
+# 查看当前连接
+SHOW PROCESSLIST;
+
+# 查看慢查询
+SHOW VARIABLES LIKE 'slow_query_log';
+SHOW VARIABLES LIKE 'long_query_time';
+
+# 查看表锁
+SHOW OPEN TABLES WHERE In_use > 0;
+
+# 查看连接数
+SHOW STATUS LIKE 'Threads_connected';
+SHOW VARIABLES LIKE 'max_connections';
+```
+
+### 4.3 Redis 诊断
+
+```bash
+# 连接测试
+redis-cli -h ping
+
+# 查看内存使用
+redis-cli info memory
+
+# 查看慢查询
+redis-cli slowlog get 10
+
+# 查看 Key 数量
+redis-cli dbsize
+
+# 查看特定 Key
+redis-cli get "aiot:ops:ticket:1001"
+```
+
+### 4.4 网络诊断
+
+```bash
+# 测试端口连通性
+telnet
+nc -zv
+
+# DNS 解析
+nslookup
+dig
+
+# 路由追踪
+traceroute
+mtr
+```
+
+---
+
+## 五、相关文档
+
+- [00-支撑平台总览.md](../00-支撑平台总览.md)
+- [01-统一网关入口规范.md](../01-统一网关入口规范.md)
+- [02-中间件使用规约.md](../02-中间件使用规约.md)
+- [02-环境部署指南.md](./02-环境部署指南.md)
diff --git a/开发者文档/06-平台支撑/09-DevOps 运维/02-环境部署指南.md b/开发者文档/06-平台支撑/09-DevOps 运维/02-环境部署指南.md
new file mode 100644
index 0000000..76e078d
--- /dev/null
+++ b/开发者文档/06-平台支撑/09-DevOps 运维/02-环境部署指南.md
@@ -0,0 +1,548 @@
+# 02-环境部署指南
+
+本文档描述 AIOT 项目从开发环境到生产环境的完整部署流程、配置规范和运维操作。
+
+---
+
+## 一、环境规划
+
+### 1.1 环境清单
+
+| 环境 | 用途 | 域名 | 数据库 | 更新频率 | 负责人 |
+|------|------|------|--------|---------|--------|
+| **开发 (Dev)** | 本地开发联调 | `dev-api.example.com` | 共享 Dev DB | 随时 | 开发者 |
+| **测试 (Test)** | QA 功能测试 | `test-api.example.com` | 独立 Test DB | 每日 | QA |
+| **预生产 (Staging)** | 上线前验证 | `staging-api.example.com` | 生产库只读副本 | 每周 | DevOps |
+| **生产 (Prod)** | 正式用户 | `api.example.com` | 生产主库 | 计划性 | DevOps+PM |
+
+### 1.2 环境隔离原则
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ 开发环境 (Dev) │
+│ - 开发者本地 Docker Compose 或 WSL2 运行 │
+│ - 连接共享 Dev 数据库(多人共用) │
+│ - Nacos 配置:dev Profile │
+└─────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────┐
+│ 测试环境 (Test) │
+│ - 独立服务器/容器集群 │
+│ - 独立 Test 数据库(每日从生产脱敏同步) │
+│ - Nacos 配置:test Profile │
+│ - Jenkins 自动部署(test 分支触发) │
+└─────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────┐
+│ 预生产环境 (Staging) │
+│ - 独立服务器/容器集群(配置同生产) │
+│ - 生产库只读副本(用于验证 SQL) │
+│ - Nacos 配置:prod Profile(但指向测试 MQ/Redis) │
+│ - 手动触发部署(Release 分支) │
+└─────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────┐
+│ 生产环境 (Prod) │
+│ - 高可用集群(多副本 + 负载均衡) │
+│ - 生产主数据库(主从复制) │
+│ - Nacos 配置:prod Profile │
+│ - 严格审批流程(PM+Tech Lead 签字) │
+└─────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## 二、开发环境部署(本地)
+
+### 2.1 前置条件
+
+```bash
+# 必需软件
+- Docker 20.10+
+- Docker Compose 2.0+
+- JDK 11/17
+- Maven 3.8+
+- Node.js 18+
+- pnpm 8+
+
+# 可选工具
+- MySQL Workbench / DBeaver
+- Redis Desktop Manager
+- Postman / Apifox
+```
+
+### 2.2 启动基础设施
+
+```bash
+# 进入项目根目录
+cd /path/to/aiot-platform-cloud
+
+# 启动核心中间件(Nacos + MySQL + Redis + EMQX)
+docker-compose -f docker-compose.core.yml up -d
+
+# 检查容器状态
+docker-compose -f docker-compose.core.yml ps
+
+# 查看 Nacos 日志(确认启动成功)
+docker logs aiot-nacos --tail 50
+```
+
+**核心服务端口**:
+| 服务 | 端口 | 访问地址 |
+|------|------|---------|
+| Nacos | 8848 | `http://localhost:8848/nacos` |
+| MySQL | 3306 | `localhost:3306` |
+| Redis | 6379 | `localhost:6379` |
+| EMQX | 1883/18083 | `localhost:18083` |
+| RabbitMQ | 5672/15672 | `localhost:15672` |
+
+**默认账号**:
+- Nacos: `nacos / nacos`
+- MySQL: `root / aiot123456`
+- Redis: 无密码
+- RabbitMQ: `guest / guest`
+- EMQX: `admin / public`
+
+### 2.3 初始化数据库
+
+```bash
+# 1. 创建数据库
+mysql -h localhost -u root -p << EOF
+CREATE DATABASE IF NOT EXISTS aiot_platform
+ DEFAULT CHARACTER SET utf8mb4
+ DEFAULT COLLATE utf8mb4_general_ci;
+USE aiot_platform;
+EOF
+
+# 2. 导入表结构
+mysql -h localhost -u root -p aiot_platform < sql/aiot_schema.sql
+
+# 3. 导入初始数据(租户、管理员账号、菜单权限)
+mysql -h localhost -u root -p aiot_platform < sql/aiot_data.sql
+```
+
+### 2.4 配置 Nacos
+
+1. 访问 `http://localhost:8848/nacos`
+2. 登录(`nacos / nacos`)
+3. 导入配置(`导入` → 选择 `config/` 目录下的配置文件)
+ - `viewsh-gateway.yaml`
+ - `module-system.yaml`
+ - `module-ops.yaml`
+ - `module-iot.yaml`
+ - `application-common.yaml`
+
+**关键配置项检查**:
+```yaml
+# application-common.yaml
+spring:
+ datasource:
+ url: jdbc:mysql://host.docker.internal:3306/aiot_platform?useSSL=false
+ username: root
+ password: aiot123456
+ redis:
+ host: host.docker.internal
+ port: 6379
+
+# 开发环境特殊配置
+aiot:
+ dev-mode: true
+ swagger-enable: true
+ mock-iot-device: true # 启用模拟设备上报
+```
+
+> **注意**:Docker 容器内访问宿主机服务需使用 `host.docker.internal` 而非 `localhost`。
+
+### 2.5 启动后端服务
+
+```bash
+# 1. 编译网关
+cd viewsh-gateway
+mvn clean package -DskipTests -P dev
+java -jar target/viewsh-gateway.jar --spring.profiles.active=dev
+
+# 2. 编译主服务(module-system / module-ops / module-iot)
+cd module-system
+mvn clean package -DskipTests -P dev
+java -jar target/module-system.jar --spring.profiles.active=dev
+
+# 3. 检查服务注册
+# 访问 Nacos 控制台,确认服务状态为「健康」
+```
+
+### 2.6 启动前端
+
+```bash
+# 1. 安装依赖
+cd yudao-ui-admin-vben
+pnpm install
+
+# 2. 配置环境变量
+# 复制 .env.development 并修改 API 地址
+cp .env.development .env.development.local
+echo "VITE_API_BASE_URL=http://localhost:18080" >> .env.development.local
+
+# 3. 启动开发服务器
+pnpm dev
+
+# 4. 访问管理后台
+# http://localhost:5173
+# 默认管理员账号:admin / admin123
+```
+
+---
+
+## 三、测试环境部署(Jenkins 自动)
+
+### 3.1 部署流程
+
+```
+开发者推送代码到 test 分支
+ ↓
+GitLab Webhook 触发 Jenkins Job
+ ↓
+Jenkins 拉取代码 → Maven 编译 → 运行单元测试
+ ↓
+构建 Docker 镜像(Tag: test-{commit_hash})
+ ↓
+推送到私有镜像仓库
+ ↓
+SSH 登录测试服务器 → docker pull → docker stop → docker run
+ ↓
+健康检查(/actuator/health)
+ ↓
+发送通知到飞书/钉钉群
+```
+
+### 3.2 Jenkinsfile 示例
+
+```groovy
+pipeline {
+ agent any
+
+ environment {
+ DOCKER_IMAGE = "registry.example.com/aiot/module-ops"
+ DOCKER_TAG = "test-${env.GIT_COMMIT.take(7)}"
+ }
+
+ stages {
+ stage('Checkout') {
+ steps {
+ git branch: 'test',
+ url: 'git@gitlab.example.com:aiot/aiot-platform-cloud.git'
+ }
+ }
+
+ stage('Build') {
+ steps {
+ sh 'cd module-ops && mvn clean package -DskipTests -P test'
+ }
+ }
+
+ stage('Unit Test') {
+ steps {
+ sh 'cd module-ops && mvn test'
+ }
+ }
+
+ stage('Docker Build') {
+ steps {
+ sh '''
+ cd module-ops
+ docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .
+ docker push ${DOCKER_IMAGE}:${DOCKER_TAG}
+ '''
+ }
+ }
+
+ stage('Deploy') {
+ steps {
+ sh '''
+ ssh deploy@test-server "
+ docker pull ${DOCKER_IMAGE}:${DOCKER_TAG} &&
+ docker stop module-ops || true &&
+ docker rm module-ops || true &&
+ docker run -d --name module-ops \\
+ -p 18081:18080 \\
+ -e SPRING_PROFILES_ACTIVE=test \\
+ ${DOCKER_IMAGE}:${DOCKER_TAG}
+ "
+ '''
+ }
+ }
+
+ stage('Health Check') {
+ steps {
+ sh '''
+ for i in {1..30}; do
+ if curl -s http://test-server:18081/actuator/health | grep -q UP; then
+ echo "Deploy successful!"
+ exit 0
+ fi
+ sleep 2
+ done
+ echo "Health check failed!"
+ exit 1
+ '''
+ }
+ }
+ }
+
+ post {
+ success {
+ // 发送飞书通知
+ sh '''
+ curl -X POST https://open.feishu.cn/open-apis/bot/v2/hook/xxx \\
+ -H "Content-Type: application/json" \\
+ -d '{"msg_type":"text","content":{"text":"✅ module-ops 测试环境部署成功\\n版本:${DOCKER_TAG}"}}'
+ '''
+ }
+ failure {
+ // 发送失败通知
+ sh '''
+ curl -X POST https://open.feishu.cn/open-apis/bot/v2/hook/xxx \\
+ -H "Content-Type: application/json" \\
+ -d '{"msg_type":"text","content":{"text":"❌ module-ops 测试环境部署失败\\n请检查 Jenkins 日志"}}'
+ '''
+ }
+ }
+}
+```
+
+---
+
+## 四、生产环境部署(严格审批)
+
+### 4.1 部署前检查清单
+
+**必须全部勾选才能执行部署**:
+
+- [ ] **代码审查**:MR 已获 2 人以上 Approve
+- [ ] **测试报告**:QA 已签署测试通过报告
+- [ ] **SQL 审查**:涉及数据库变更的 SQL 已获 DBA 审核
+- [ ] **回滚方案**:已制定明确回滚步骤并验证
+- [ ] **备份确认**:生产数据库已完成全量备份
+- [ ] **通知到位**:相关干系人(客服、运营)已收到部署通知
+- [ ] **时间窗口**:部署时间在低峰期(凌晨 2:00-4:00)
+- [ ] **值班人员**:DevOps 和业务负责人在线待命
+
+### 4.2 部署流程
+
+```bash
+# 1. 创建 Release 分支(从 master 最新提交)
+git checkout master
+git pull
+git checkout -b release/v1.2.0
+
+# 2. 更新版本号
+# 修改各模块 pom.xml 中的 1.2.0
+# 修改 CHANGELOG.md
+
+# 3. 提交并打 Tag
+git add .
+git commit -m "release: v1.2.0"
+git tag -a v1.2.0 -m "Release version 1.2.0"
+
+# 4. 推送 Release 分支和 Tag
+git push origin release/v1.2.0
+git push origin v1.2.0
+
+# 5. 在 Jenkins 触发生产部署 Job
+# 选择 Release 分支,确认版本号,点击「部署到生产」
+
+# 6. 部署过程中实时监控
+# - Grafana 仪表盘(CPU、内存、QPS、错误率)
+# - 日志平台(ELK)
+# - 业务监控(工单处理量、设备在线数)
+
+# 7. 部署完成后验证
+# - 冒烟测试(核心功能快速验证)
+# - 确认无异常日志
+# - 通知干系人部署完成
+```
+
+### 4.3 回滚流程
+
+**当生产部署后出现严重 Bug 时**:
+
+```bash
+# 1. 立即通知
+# 飞书群通知:「生产环境出现异常,准备回滚到 v1.1.0」
+
+# 2. 执行回滚
+# Jenkins 选择「回滚」Job,选择上一个稳定版本 v1.1.0
+
+# 3. 验证回滚
+# - 确认服务恢复正常
+# - 检查数据一致性(是否有脏数据)
+
+# 4. 事后复盘
+# - 记录事故时间线
+# - 分析根本原因
+# - 制定改进措施
+```
+
+---
+
+## 五、Docker 部署详解
+
+### 5.1 Dockerfile 示例(后端)
+
+```dockerfile
+# 构建阶段
+FROM maven:3.8-openjdk-17 AS builder
+
+WORKDIR /build
+COPY pom.xml .
+COPY module-ops/pom.xml module-ops/
+RUN mvn -f module-ops/pom.xml dependency:go-offline -B
+
+COPY module-ops/src module-ops/src
+RUN mvn -f module-ops/pom.xml clean package -DskipTests
+
+# 运行阶段
+FROM openjdk:17-slim
+
+WORKDIR /app
+
+# 创建非 root 用户
+RUN useradd -m -u 1000 appuser
+
+# 复制 JAR
+COPY --from=builder /build/module-ops/target/*.jar app.jar
+
+# 设置时区
+ENV TZ=Asia/Shanghai
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+# 健康检查
+HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \\
+ CMD curl -f http://localhost:18080/actuator/health || exit 1
+
+# 切换用户
+USER appuser
+
+EXPOSE 18080
+
+ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=prod"]
+```
+
+### 5.2 Docker Compose 示例(生产)
+
+```yaml
+version: '3.8'
+
+services:
+ gateway:
+ image: registry.example.com/aiot/viewsh-gateway:v1.2.0
+ ports:
+ - "80:18080"
+ - "443:18443"
+ environment:
+ - SPRING_PROFILES_ACTIVE=prod
+ - NACOS_SERVER_ADDR=nacos:8848
+ depends_on:
+ - nacos
+ restart: always
+ deploy:
+ replicas: 2
+ resources:
+ limits:
+ cpus: '2'
+ memory: 2G
+
+ module-ops:
+ image: registry.example.com/aiot/module-ops:v1.2.0
+ environment:
+ - SPRING_PROFILES_ACTIVE=prod
+ - NACOS_SERVER_ADDR=nacos:8848
+ depends_on:
+ - nacos
+ - mysql
+ - redis
+ restart: always
+ deploy:
+ replicas: 3
+ resources:
+ limits:
+ cpus: '4'
+ memory: 4G
+
+ nacos:
+ image: nacos/nacos-server:2.2.0
+ environment:
+ - MODE=cluster
+ - NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
+ volumes:
+ - ./nacos/cluster-logs:/home/nacos/logs
+ restart: always
+
+ mysql:
+ image: mysql:8.0
+ environment:
+ - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
+ volumes:
+ - mysql-data:/var/lib/mysql
+ restart: always
+
+ redis:
+ image: redis:7-alpine
+ command: redis-server --appendonly yes
+ volumes:
+ - redis-data:/data
+ restart: always
+
+volumes:
+ mysql-data:
+ redis-data:
+```
+
+---
+
+## 六、监控与告警
+
+### 6.1 关键监控指标
+
+| 指标类别 | 指标名称 | 告警阈值 | 告警级别 |
+|---------|---------|---------|---------|
+| **应用层** | HTTP 错误率 | > 1% | P1 |
+| | API 响应时间 P99 | > 2000ms | P2 |
+| | JVM 堆内存使用率 | > 85% | P2 |
+| **中间件** | MySQL 连接数 | > 80% | P2 |
+| | Redis 内存使用率 | > 80% | P2 |
+| | MQ 消息积压 | > 10000 | P2 |
+| **业务层** | 工单派发失败率 | > 5% | P1 |
+| | 设备离线率 | > 10% | P2 |
+| | 信标感应成功率 | < 95% | P2 |
+
+### 6.2 告警通知渠道
+
+```yaml
+# Prometheus Alertmanager 配置
+receivers:
+ - name: 'feishu-p1'
+ webhook_configs:
+ - url: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx'
+ send_resolved: true
+ # P1 级别:电话 + 飞书
+
+ - name: 'feishu-p2'
+ webhook_configs:
+ - url: 'https://open.feishu.cn/open-apis/bot/v2/hook/yyy'
+ send_resolved: true
+ # P2 级别:飞书
+
+ - name: 'email'
+ email_configs:
+ - to: 'devops@example.com'
+ send_resolved: true
+ # P3 级别:邮件
+```
+
+---
+
+## 七、相关文档
+
+- [03-CICD 与部署流水线规范.md](../03-CICD 与部署流水线规范.md)
+- [01-部署运行与排障视角.md](./01-部署运行与排障视角.md)
+- [07-协作规范/02-开发工作流与-Git-规约.md](../../07-协作规范/02-开发工作流与-Git-规约.md)