|
|
# 医院物业SaaS管理后台 — 项目技术要求
|
|
|
|
|
|
> 版本:v1.2
|
|
|
> 定位:内部团队开发标准,所有开发人员必须严格按照此标准执行
|
|
|
> 日期:2026-04-17
|
|
|
|
|
|
---
|
|
|
|
|
|
## 一、技术栈选型与版本要求
|
|
|
|
|
|
### 1.1 后端技术栈
|
|
|
|
|
|
| 技术 | 版本要求 | 用途 |
|
|
|
|------|----------|------|
|
|
|
| Java | 17+ | 开发语言 |
|
|
|
| Spring Boot | 3.x | 应用框架 |
|
|
|
| MariaDB | 10.6+ | 主数据库(主从复制读写分离) |
|
|
|
| Redis | 7.x | 缓存(权限/字典/菜单)、分布式锁 |
|
|
|
| MyBatis-Plus | 3.5+ | ORM框架 |
|
|
|
| Spring Security | 6.x | 认证与授权 |
|
|
|
| JWT (jjwt) | 0.12+ | Token生成与校验 |
|
|
|
|
|
|
### 1.2 前端Web技术栈
|
|
|
|
|
|
| 技术 | 版本要求 | 用途 |
|
|
|
|------|----------|------|
|
|
|
| Vue | 3.x | 前端框架 |
|
|
|
| TypeScript | 5.x | 类型安全 |
|
|
|
| Vite | 5.x | 构建工具 |
|
|
|
| Pinia | 2.x | 状态管理 |
|
|
|
| Vue Router | 4.x | 路由管理 |
|
|
|
| Element Plus | 最新稳定版 | UI组件库 |
|
|
|
| Axios | 1.x | HTTP客户端 |
|
|
|
| ECharts | 5.x | 图表可视化 |
|
|
|
|
|
|
### 1.3 微信小程序技术栈
|
|
|
|
|
|
| 技术 | 版本要求 | 用途 |
|
|
|
|------|----------|------|
|
|
|
| uni-app | 3.x | 跨端框架(Vue 3模式) |
|
|
|
| uni-ui | 最新稳定版 | UI组件库 |
|
|
|
|
|
|
### 1.4 基础设施
|
|
|
|
|
|
| 技术 | 用途 |
|
|
|
|------|------|
|
|
|
| Nginx | 反向代理 + 静态资源 + 文件存储映射 |
|
|
|
| Jenkins / GitLab CI | CI/CD流水线 |
|
|
|
| Git | 版本管理 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 二、架构设计要求
|
|
|
|
|
|
### 2.1 整体架构
|
|
|
|
|
|
```
|
|
|
┌─────────────────────────────────────────────────┐
|
|
|
│ 客户端层 │
|
|
|
│ Vue3 Web管理后台 │ uni-app微信小程序 │
|
|
|
└───────────┬───────────┴───────────┬──────────────┘
|
|
|
│ HTTPS │
|
|
|
┌───────────▼───────────────────────▼──────────────┐
|
|
|
│ 网关层 │
|
|
|
│ Nginx 反向代理 │
|
|
|
└───────────┬──────────────────────────────────────┘
|
|
|
│
|
|
|
┌───────────▼──────────────────────────────────────┐
|
|
|
│ 应用层 │
|
|
|
│ Spring Boot 单体应用(模块化 IModulePlugin) │
|
|
|
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
|
|
|
│ │报修 │ │巡检 │ │保洁 │ │考勤 │ │合同 │... │
|
|
|
│ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ │
|
|
|
│ └────────┴────────┴────────┴────────┘ │
|
|
|
│ Spring Event 模块间通信 │
|
|
|
└───────────┬──────────────────────────────────────┘
|
|
|
│
|
|
|
┌───────────▼──────────────────────────────────────┐
|
|
|
│ 数据层 │
|
|
|
│ MariaDB主库 ──复制──▶ MariaDB从库(读写分离) │
|
|
|
│ Redis 缓存(权限/字典/菜单) │
|
|
|
│ 独立文件存储站点(照片/附件/合同文件) │
|
|
|
└──────────────────────────────────────────────────┘
|
|
|
```
|
|
|
|
|
|
### 2.2 多租户方案
|
|
|
|
|
|
- **隔离方式**:共享数据库 + 行级隔离(`tenant_id`字段)
|
|
|
- **实现方式**:MyBatis-Plus `TenantLineInnerInterceptor` 自动注入 `tenant_id` 条件
|
|
|
- **租户识别**:从JWT Token中提取 `tenant_id`,无需前端传递
|
|
|
- **超管例外**:超级管理员操作不受租户隔离限制
|
|
|
|
|
|
### 2.3 模块化架构
|
|
|
|
|
|
- **核心接口**:`IModulePlugin`(详见 `05-接口规范.md`)
|
|
|
- **模块注册**:系统启动时自动扫描并注册所有 `IModulePlugin` 实现类
|
|
|
- **模块通信**:Spring `ApplicationEvent` + `ApplicationEventPublisher`
|
|
|
- **模块隔离**:各模块独立目录结构,禁止跨模块直接调用Service,必须通过Event解耦
|
|
|
- **租户级控制**:支持按租户启用/禁用特定模块(`sys_tenant_module` 表)
|
|
|
|
|
|
### 2.4 前后端分离
|
|
|
|
|
|
- Web端与后端通过RESTful API通信
|
|
|
- 小程序端与后端通过同一套API通信
|
|
|
- 前端路由由后端权限接口动态驱动
|
|
|
- 统一JWT认证,Web端存localStorage,小程序端存本地Storage
|
|
|
|
|
|
### 2.5 读写分离方案
|
|
|
|
|
|
- **实现方式**:MariaDB主从复制 + MyBatis-Plus动态数据源切换
|
|
|
- **路由规则**:
|
|
|
- 写操作(INSERT/UPDATE/DELETE)→ 主库
|
|
|
- 读操作(SELECT)→ 从库
|
|
|
- **注解标记**:自定义 `@ReadOnly` 注解标记读操作,AOP切面切换数据源
|
|
|
- **容错机制**:从库不可用时自动降级到主库读取,超时阈值3秒
|
|
|
- **配置要求**:在 `application.yml` 中分别配置 `spring.datasource.master` 和 `spring.datasource.slave` 两套数据源连接地址
|
|
|
|
|
|
---
|
|
|
|
|
|
## 三、去中间件方案
|
|
|
|
|
|
**不引入RocketMQ/Kafka等消息中间件**,采用以下Spring Boot内置机制替代:
|
|
|
|
|
|
### 3.1 权限变更实时通知
|
|
|
|
|
|
- **替代方案**:Redis Pub/Sub + Spring Event
|
|
|
- **实现细节**:
|
|
|
1. 权限变更时,通过 Redis Pub/Sub 发布变更消息 `PUBLISH permission:changed <version>`
|
|
|
2. 各服务实例订阅 `permission:changed` 频道,收到消息后触发 Spring Event
|
|
|
3. 监听器刷新本地权限缓存
|
|
|
- **优势**:毫秒级延迟,零数据库压力,复用已有 Redis 实例
|
|
|
- **降级策略**:Redis 连接断开时,权限缓存 TTL(2小时)到期后自动刷新
|
|
|
- **实现要点**:
|
|
|
1. 权限变更时通过 `StringRedisTemplate.convertAndSend()` 发布消息到 `permission:changed` 频道
|
|
|
2. 各实例 `MessageListener` 订阅该频道,收到消息后发布 Spring Event
|
|
|
3. `@EventListener` 监听事件并刷新本地权限缓存
|
|
|
|
|
|
### 3.2 异步任务处理
|
|
|
|
|
|
- **替代方案**:Spring `@Async` + 自定义线程池
|
|
|
- **线程池配置要求**:
|
|
|
- 核心线程数:CPU核心数(默认4)
|
|
|
- 最大线程数:CPU核心数×2(默认8)
|
|
|
- 队列容量:1000
|
|
|
- 线程空闲时间:60秒
|
|
|
- 拒绝策略:CallerRunsPolicy(调用者线程执行)
|
|
|
- **适用场景**:报表导出、消息推送、日志异步写入、图片处理
|
|
|
- **持久化保障**:关键任务必须先落库再异步执行,避免线程池丢失任务
|
|
|
|
|
|
### 3.3 模块间事件通信
|
|
|
|
|
|
- **替代方案**:Spring `ApplicationEvent` + `ApplicationEventPublisher`
|
|
|
- **进程内通信**:直接使用Spring Event,事件定义在共享API模块中
|
|
|
- **跨实例通信**:Redis Pub/Sub 广播事件(与权限通知同一机制)
|
|
|
- **预定义事件**:
|
|
|
|
|
|
| 事件类型 | 来源模块 | 消费方 |
|
|
|
|----------|----------|--------|
|
|
|
| ORDER_COMPLETED | repair | evaluation(触发评价) |
|
|
|
| INSPECTION_ABNORMAL | inspection | repair(生成报修) |
|
|
|
| CLEANING_TIMEOUT | cleaning | notification(推送预警) |
|
|
|
| BEACON_OFFLINE | device | notification(推送预警) |
|
|
|
| PERMISSION_CHANGED | permission | 各模块(刷新缓存) |
|
|
|
|
|
|
### 3.4 定时任务
|
|
|
|
|
|
- **实现方案**:Spring `@Scheduled`(当前为单实例部署,无需分布式锁)
|
|
|
- **适用场景**:巡检任务自动生成、保洁超时预警、合同到期提醒、Beacon心跳检测
|
|
|
- **实现要点**:定时方法加 `@Scheduled` 注解声明cron表达式即可
|
|
|
- **扩展说明**:如未来需要多实例部署,可引入 ShedLock 或数据库行锁(`SELECT ... FOR UPDATE`)防止重复执行
|
|
|
|
|
|
---
|
|
|
|
|
|
## 四、安全要求
|
|
|
|
|
|
### 4.1 认证方案
|
|
|
|
|
|
| 场景 | 认证方式 | Token管理 |
|
|
|
|------|----------|-----------|
|
|
|
| Web端登录 | 用户名+密码 → JWT | localStorage存储,2小时过期 |
|
|
|
| 小程序登录 | 微信openid静默登录 → JWT | 本地Storage存储,2小时过期 |
|
|
|
| 小程序首次使用 | 微信授权openid + 手机号绑定 | 自动创建账号 |
|
|
|
|
|
|
**JWT载荷标准字段**:
|
|
|
|
|
|
| 字段 | 说明 |
|
|
|
|------|------|
|
|
|
| sub | 用户ID |
|
|
|
| tid | 租户ID |
|
|
|
| utype | 用户类型 |
|
|
|
| hid | 医院ID |
|
|
|
| pid | 物业公司ID |
|
|
|
| sid | 员工ID |
|
|
|
| iat | 签发时间 |
|
|
|
| exp | 过期时间 |
|
|
|
|
|
|
### 4.2 四级权限体系
|
|
|
|
|
|
权限按 **功能菜单 → 页面 → 功能点 → 动作** 四级树形结构划分:
|
|
|
|
|
|
- **7种动作类型**:查看(view)、新增(create)、编辑(update)、删除(delete)、审批(approve)、导出(export)、分配(assign)
|
|
|
- **权限编码规范**:`{module}:{page}:{action}`,如 `repair:list:create`
|
|
|
- **自动同步**:新模块通过 `IModulePlugin.getPermissionDefinitions()` 自动注册到权限配置表
|
|
|
- **实时生效**:权限变更后毫秒级生效(Redis Pub/Sub),无需重新登录
|
|
|
|
|
|
### 4.3 数据权限(行级隔离)
|
|
|
|
|
|
| 角色 | 数据范围 | 实现方式 |
|
|
|
|------|----------|----------|
|
|
|
| 超级管理员 | 全局所有数据 | 不注入tenant_id条件 |
|
|
|
| 医院账号 | 本医院+关联物业公司数据 | 注入hospital_id条件,只读 |
|
|
|
| 物业公司管理员 | 绑定医院数据 | 注入tenant_id + hospital_id条件 |
|
|
|
| 主管 | 本班组数据 | 注入team_id条件 |
|
|
|
| 员工 | 仅本人数据 | 注入staff_id条件 |
|
|
|
|
|
|
**实现方式**:MyBatis-Plus拦截器自动注入SQL条件,禁止手动拼接数据权限条件。
|
|
|
|
|
|
### 4.4 蓝牙策略配置
|
|
|
|
|
|
蓝牙打卡/巡检/拍照是否强制要求连接,由物业公司配置、医院账号审核:
|
|
|
|
|
|
- **配置方**:物业公司管理员
|
|
|
- **审核方**:医院账号
|
|
|
- **配置项**:各场景是否强制蓝牙连接
|
|
|
|
|
|
| 场景 | 配置项 | 强制蓝牙时的行为 | 非强制蓝牙时的行为 |
|
|
|
|------|--------|-----------------|-------------------|
|
|
|
| 巡检打卡 | `inspection_check_in` | 必须连接Beacon打卡,失败进补录 | 可手动打卡(check_type=MANUAL) |
|
|
|
| 巡检拍照 | `inspection_photo` | 必须在蓝牙连接下拍照 | 可自由拍照 |
|
|
|
| 保洁打卡 | `cleaning_check_in` | 必须连接Beacon打卡,失败进补录 | 可手动打卡(check_type=MANUAL) |
|
|
|
| 保洁拍照 | `cleaning_photo` | 必须在蓝牙连接下拍照 | 可自由拍照 |
|
|
|
| 考勤打卡 | `attendance_check` | 必须连接Beacon打卡,失败提交异常申诉 | 可手动打卡(check_type=MANUAL) |
|
|
|
|
|
|
- **数据标记**:所有打卡记录区分 `check_type`(BLUETOOTH/MANUAL),后台列表和统计报表明确显示
|
|
|
- **降级逻辑**:
|
|
|
- 非强制蓝牙场景:蓝牙失败可直接手动打卡
|
|
|
- 强制蓝牙场景:蓝牙失败进入补录模式,需主管审核
|
|
|
- **审核流程**:物业公司提交配置 → 医院账号审核通过后生效 → 审核拒绝则维持原配置
|
|
|
|
|
|
### 4.5 审计日志
|
|
|
|
|
|
- **记录范围**:所有写操作(CREATE/UPDATE/DELETE/APPROVE/ASSIGN/EXPORT)自动记录
|
|
|
- **实现方式**:AOP切面统一处理,业务代码无感知
|
|
|
- **记录内容**:操作人、时间、IP、模块、操作类型、变更前后数据快照
|
|
|
- **权限变更日志**:单独记录,展示变更前后权限对比
|
|
|
- **数据补录日志**:单独记录,标记补录原因和审核状态
|
|
|
- **日志保留**:至少保留1年,支持导出
|
|
|
|
|
|
### 4.6 通用安全要求
|
|
|
|
|
|
| 安全项 | 要求 |
|
|
|
|--------|------|
|
|
|
| SQL注入防护 | 必须使用MyBatis-Plus参数化查询,禁止拼接SQL |
|
|
|
| XSS防护 | 所有用户输入必须HTML转义后存储,前端渲染使用v-text而非v-html |
|
|
|
| 密码存储 | BCrypt加密,禁止明文存储 |
|
|
|
| 敏感数据 | 手机号脱敏显示(138****1234),身份证号如需存储需AES加密 |
|
|
|
| 接口鉴权 | 所有API必须声明权限要求(除公开接口外) |
|
|
|
| 跨域控制 | Nginx配置白名单域名,禁止 `Access-Control-Allow-Origin: *` |
|
|
|
| 请求限流 | Redis令牌桶限流,API默认100次/分钟/用户 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 五、性能要求
|
|
|
|
|
|
### 5.1 响应时间基线
|
|
|
|
|
|
| 指标 | 要求 | 测量方式 |
|
|
|
|------|------|----------|
|
|
|
| API平均响应时间 | < 300ms | 服务端P50 |
|
|
|
| API P99响应时间 | < 500ms | 服务端P99 |
|
|
|
| 列表查询(含分页) | < 500ms | 端到端 |
|
|
|
| 报表生成(单月数据) | < 5s | 端到端 |
|
|
|
| 蓝牙扫描超时 | 3秒 | 客户端 |
|
|
|
| 蓝牙连接建立 | < 3秒 | 客户端 |
|
|
|
|
|
|
### 5.2 并发与容量
|
|
|
|
|
|
- 单实例支持100 QPS
|
|
|
- 支持水平扩展(无状态设计,Session存Redis)
|
|
|
- 数据库连接池:HikariCP,最大连接数 = CPU核心数 * 2 + 1
|
|
|
- Redis连接池:Lettuce,最大连接数 = CPU核心数 * 2
|
|
|
|
|
|
### 5.3 缓存策略
|
|
|
|
|
|
| 缓存对象 | 过期策略 | 刷新机制 |
|
|
|
|----------|----------|----------|
|
|
|
| 用户权限集 | 2小时TTL | 权限变更时实时刷新(毫秒级,Redis Pub/Sub) |
|
|
|
| 字典数据 | 24小时TTL | 字典变更时手动/自动刷新 |
|
|
|
| 菜单配置 | 24小时TTL | 菜单变更时手动/自动刷新 |
|
|
|
| 业务数据 | 按需懒加载 | 不缓存,实时查询 |
|
|
|
|
|
|
### 5.4 蓝牙交互可靠性
|
|
|
|
|
|
| 指标 | 要求 |
|
|
|
|------|------|
|
|
|
| 连接判定 | **不判断距离,只要成功连接蓝牙设备即可打卡** |
|
|
|
| 信号阈值 | RSSI > -70dBm(可配置,仅用于判定是否能建立连接) |
|
|
|
| 扫描超时 | 3秒 |
|
|
|
| 重试次数 | 3次 |
|
|
|
| 补录降级 | 蓝牙失败后必须提供补录/手动打卡入口 |
|
|
|
| 心跳检测 | Beacon每5分钟上报心跳,超15分钟标记OFFLINE |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 六、数据库备份与恢复
|
|
|
|
|
|
### 6.1 备份策略
|
|
|
|
|
|
| 备份类型 | 频率 | 工具 | 保留时间 |
|
|
|
|----------|------|------|----------|
|
|
|
| 全量备份 | 每日凌晨2:00 | mysqldump --single-transaction | 30天 |
|
|
|
| 增量备份 | 每4小时 | MariaDB binlog | 7天 |
|
|
|
| 异地备份 | 每日 | rsync/scp到备份服务器 | 30天 |
|
|
|
|
|
|
### 6.2 备份存储
|
|
|
|
|
|
- **主存储**:私有云本地磁盘(独立磁盘,与数据盘分离)
|
|
|
- **异地存储**:异地备份服务器(不同机房或不同物理机)
|
|
|
- **备份文件命名**:`hospital_mgmt_full_YYYYMMDD_HHmmss.sql.gz`、`hospital_mgmt_incr_YYYYMMDD_HHmmss.binlog.gz`
|
|
|
|
|
|
### 6.3 恢复方案
|
|
|
|
|
|
| 指标 | 要求 |
|
|
|
|------|------|
|
|
|
| RTO(恢复时间目标) | < 2小时 |
|
|
|
| RPO(恢复点目标) | < 4小时(增量备份间隔) |
|
|
|
| 恢复方式 | 全量恢复 + binlog重放 |
|
|
|
| 恢复流程 | 1. 停止应用 → 2. 恢复最近全量备份 → 3. 重放binlog到故障时间点 → 4. 验证数据完整性 → 5. 启动应用 |
|
|
|
|
|
|
### 6.4 恢复演练
|
|
|
|
|
|
- **频率**:每季度一次
|
|
|
- **内容**:在测试环境执行完整恢复流程,验证RTO和RPO
|
|
|
- **记录**:演练结果记录文档,问题纳入改进计划
|
|
|
- **责任人**:DBA + 运维
|
|
|
|
|
|
### 6.5 备份脚本要求
|
|
|
|
|
|
- 全量备份使用 `mysqldump --single-transaction` 导出并gzip压缩
|
|
|
- 备份文件命名格式:`hospital_mgmt_full_YYYYMMDD_HHmmss.sql.gz`(增量:`hospital_mgmt_incr_YYYYMMDD_HHmmss.binlog.gz`)
|
|
|
- 自动清理30天前的全量备份文件
|
|
|
- 备份完成后通过 rsync 同步到异地备份服务器
|
|
|
|
|
|
---
|
|
|
|
|
|
## 七、开发与测试规范
|
|
|
|
|
|
> 开发规范、测试规范已独立为 `04-开发与测试规范.md`,本章仅保留引用。
|
|
|
|
|
|
- **后端开发规范**(代码分层、命名、数据库、模块开发、审计日志)→ 详见 `04-开发与测试规范.md` 第一章
|
|
|
- **前端开发规范**(Vue3组件、TypeScript、状态管理、API调用)→ 详见 `04-开发与测试规范.md` 第二章
|
|
|
- **小程序开发规范**(目录、蓝牙、图片上传)→ 详见 `04-开发与测试规范.md` 第三章
|
|
|
- **Git分支与提交规范** → 详见 `04-开发与测试规范.md` 第四章
|
|
|
- **前后端协作规范** → 详见 `04-开发与测试规范.md` 第五章
|
|
|
- **代码审查要求** → 详见 `04-开发与测试规范.md` 第六章
|
|
|
- **测试规范**(单元测试、集成测试、蓝牙测试、性能测试、安全测试)→ 详见 `04-开发与测试规范.md` 第七章
|
|
|
- **前端界面开发规范**(开发流程、Mock数据、组件标准、H约束实现、共享组件管理、自测标准)→ 详见 `07-前端界面开发规范.md`
|
|
|
|
|
|
---
|
|
|
|
|
|
## 八、部署与运维要求
|
|
|
|
|
|
### 8.1 部署架构(私有云)
|
|
|
|
|
|
```
|
|
|
┌──────────────────────────────────────────────────┐
|
|
|
│ 私有云服务器 │
|
|
|
│ │
|
|
|
│ ┌─────────────────────────────────────────────┐ │
|
|
|
│ │ Nginx │ │
|
|
|
│ │ :80/:443 │ │
|
|
|
│ │ ┌──────────┐ ┌───────────┐ ┌────────────┐ │ │
|
|
|
│ │ │ API反向代理│ │ 前端静态 │ │ 文件存储 │ │ │
|
|
|
│ │ │ → :8080 │ │ dist目录 │ │ 映射 │ │ │
|
|
|
│ │ └──────────┘ └───────────┘ └────────────┘ │ │
|
|
|
│ └─────────────────────┬───────────────────────┘ │
|
|
|
│ │ │
|
|
|
│ ┌─────────────────────▼─────────────────────┐ │
|
|
|
│ │ Spring Boot 应用 (:8080) │ │
|
|
|
│ └─────────────────────┬─────────────────────┘ │
|
|
|
│ │ │
|
|
|
│ ┌─────────────────────▼──┐ ┌──────────────┐ │
|
|
|
│ │ Redis (:6379) │ │ 文件存储目录 │ │
|
|
|
│ │ │ │ /data/files/ │ │
|
|
|
│ └────────────────────────┘ └──────────────┘ │
|
|
|
│ │
|
|
|
│ ┌────────────┐ ┌────────────┐ │
|
|
|
│ │ MariaDB主库 │ │ MariaDB从库 │ │
|
|
|
│ └────────────┘ └────────────┘ │
|
|
|
└──────────────────────────────────────────────────┘
|
|
|
```
|
|
|
|
|
|
### 8.2 传统部署要求
|
|
|
|
|
|
#### 8.2.1 应用部署
|
|
|
|
|
|
| 组件 | 部署方式 | 说明 |
|
|
|
|------|----------|------|
|
|
|
| Spring Boot应用 | JAR包直接运行(`java -jar`) | 端口8080,建议使用 systemd 管理进程 |
|
|
|
| Redis | 直接安装(yum/apt 或官方二进制包) | 版本7.x,端口6379,开启持久化 |
|
|
|
| MariaDB主库 | 直接安装 | 版本10.6+,负责写操作 |
|
|
|
| MariaDB从库 | 直接安装 | 版本10.6+,配置主从复制,负责读操作 |
|
|
|
| Nginx | 直接安装 | 反向代理API + 前端静态资源 + 文件存储映射 |
|
|
|
|
|
|
- **环境变量注入**:通过 `SPRING_PROFILES_ACTIVE`、`SPRING_DATASOURCE_URL`、`SPRING_DATASOURCE_SLAVE_URL`、`SPRING_REDIS_HOST` 等环境变量配置连接信息,**禁止硬编码**
|
|
|
- **JVM参数建议**:`-Xms512m -Xmx1024 -XX:+UseG1GC`
|
|
|
- **应用启动用户**:使用非root用户运行Spring Boot应用
|
|
|
|
|
|
#### 8.2.2 文件存储站点部署
|
|
|
|
|
|
文件存储作为**独立存储目录**部署,通过 Nginx 提供静态文件访问服务:
|
|
|
|
|
|
```
|
|
|
/data/file-storage/
|
|
|
├── repair/ # 报修模块
|
|
|
├── inspection/ # 巡检模块
|
|
|
├── cleaning/ # 保洁模块
|
|
|
├── evaluation/ # 评价模块
|
|
|
├── contract/ # 合同模块
|
|
|
└── temp/ # 临时目录
|
|
|
```
|
|
|
|
|
|
- **Nginx 配置**:在 Nginx 中添加 location 映射到 `/data/file-storage/` 目录(如 `/files/` 路径或独立子域名)
|
|
|
- **权限设置**:应用启动用户对存储目录有读写权限,Nginx worker 用户有读权限
|
|
|
- **磁盘要求**:使用独立磁盘或独立分区,与系统盘分离
|
|
|
- **备份覆盖**:第六章的数据库备份策略需同步覆盖此目录
|
|
|
|
|
|
### 8.3 小程序版本更新策略
|
|
|
|
|
|
```
|
|
|
小程序启动
|
|
|
│
|
|
|
调用 GET /system/versions/latest 获取最新版本号
|
|
|
│
|
|
|
与本地版本号比较
|
|
|
│
|
|
|
├── 版本一致 ──▶ 正常使用
|
|
|
│
|
|
|
├── 小版本更新(兼容) ──▶ 提示"发现新版本,是否更新?"
|
|
|
│
|
|
|
└── 大版本更新(不兼容) ──▶ 强制更新,引导前往微信更新
|
|
|
```
|
|
|
|
|
|
### 8.4 缓存管理策略
|
|
|
|
|
|
| 触发方式 | 清理范围 | 说明 |
|
|
|
|----------|----------|------|
|
|
|
| 系统启动 | 全部缓存 | 启动时自动清理 |
|
|
|
| 权限变更 | 权限缓存 | 变更后毫秒级自动刷新(Redis Pub/Sub) |
|
|
|
| 手动清理 | 指定模块缓存 | 超管在"缓存管理"页面操作 |
|
|
|
| 系统更新 | 全部缓存 | 部署新版本后自动清理 |
|
|
|
|
|
|
### 8.5 监控与告警
|
|
|
|
|
|
| 监控项 | 告警条件 | 通知方式 |
|
|
|
|--------|----------|----------|
|
|
|
| 应用健康 | 健康检查失败 | 邮件+企业微信 |
|
|
|
| 数据库连接 | 连接池使用率>80% | 企业微信 |
|
|
|
| Redis连接 | 连接池使用率>80% | 企业微信 |
|
|
|
| Beacon离线 | 离线超过15分钟 | 系统内通知 |
|
|
|
| Beacon低电量 | 电量<20% | 系统内通知 |
|
|
|
| 磁盘空间 | 使用率>85% | 邮件+企业微信 |
|
|
|
| 备份失败 | 备份任务失败 | 邮件 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 九、接口规范
|
|
|
|
|
|
> 接口规范已独立为 `05-接口规范.md`,本章仅保留引用。
|
|
|
|
|
|
- **全局约定**(请求头、统一响应格式、错误码、查询参数)→ 详见 `05-接口规范.md` 第一章
|
|
|
- **认证规范**(认证方式、JWT载荷、权限编码)→ 详见 `05-接口规范.md` 第二章
|
|
|
- **文件上传规范** → 详见 `05-接口规范.md` 第三章
|
|
|
- **模块化架构规范**(IModulePlugin、模块注册、事件通信、版本升级、安全规范)→ 详见 `05-接口规范.md` 第四~八章
|
|
|
- **接口权限汇总** → 详见 `05-接口规范.md` 第九章
|
|
|
|
|
|
---
|
|
|
|
|
|
## 十、环境配置管理
|
|
|
|
|
|
### 10.1 环境划分
|
|
|
|
|
|
| 环境 | 用途 | 数据库 | 配置文件 |
|
|
|
|------|------|--------|----------|
|
|
|
| dev | 本地开发 | 本地MariaDB | application-dev.yml |
|
|
|
| test | 集成测试 | 测试MariaDB | application-test.yml |
|
|
|
| staging | 预发布 | 预发布MariaDB | application-staging.yml |
|
|
|
| prod | 生产 | 生产MariaDB主从 | application-prod.yml |
|
|
|
|
|
|
### 10.2 敏感配置管理
|
|
|
|
|
|
- 数据库密码、Redis密码、JWT密钥等 **禁止硬编码**
|
|
|
- 使用环境变量注入:`SPRING_DATASOURCE_PASSWORD`, `JWT_SECRET`
|
|
|
- 生产环境密码定期轮换(每季度)
|
|
|
|
|
|
### 10.3 配置项清单
|
|
|
|
|
|
| 配置项 | 说明 | 默认值 |
|
|
|
|--------|------|--------|
|
|
|
| `jwt.expiration` | Token过期时间(秒) | 7200 |
|
|
|
| `jwt.refresh-expiration` | Refresh Token过期时间(秒) | 604800 |
|
|
|
| `bluetooth.rssi-threshold` | 蓝牙信号阈值(dBm) | -70 |
|
|
|
| `bluetooth.distance-threshold` | ~~已废弃~~ 蓝牙不判断距离,连接即打卡 | — |
|
|
|
| `bluetooth.scan-timeout` | 蓝牙扫描超时(秒) | 3 |
|
|
|
| `permission.redis-channel` | 权限变更Redis频道名 | permission:changed |
|
|
|
| `async.pool.core-size` | 异步线程池核心线程数 | CPU核心数 |
|
|
|
| `async.pool.max-size` | 异步线程池最大线程数 | CPU核心数*2 |
|
|
|
| `upload.max-size` | 文件上传大小限制(MB) | 20 |
|
|
|
| `upload.local-path` | 本地文件存储根路径 | ./uploads/ |
|
|
|
| `upload.url-prefix` | 文件访问URL前缀(Nginx映射路径) | /files/ |
|
|
|
| `image.compress.enabled` | 是否启用图片自动压缩 | true |
|
|
|
| `image.compress.max-width` | 图片最大宽度(px),超过等比缩放 | 1920 |
|
|
|
| `image.compress.max-height` | 图片最大高度(px),超过等比缩放 | 1920 |
|
|
|
| `image.compress.quality` | JPEG压缩质量(0-100) | 75 |
|
|
|
| `image.compress.thumbnail-enabled` | 是否生成缩略图 | true |
|
|
|
| `image.compress.thumbnail-size` | 缩略图尺寸(px) | 300 |
|
|
|
| `backup.full-cron` | 全量备份cron | 0 2 * * ? |
|
|
|
| `backup.incr-interval-hours` | 增量备份间隔(小时) | 4 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 十一、文件存储站点规范
|
|
|
|
|
|
### 11.1 存储架构
|
|
|
|
|
|
文件存储作为**独立存储目录**部署,与 Spring Boot 主应用分离,通过 Nginx 提供静态文件 HTTP 访问服务:
|
|
|
|
|
|
```
|
|
|
{upload.local-path}/
|
|
|
├── repair/ # 报修模块文件
|
|
|
├── inspection/ # 巡检模块文件
|
|
|
├── cleaning/ # 保洁模块文件
|
|
|
├── evaluation/ # 评价模块文件
|
|
|
├── contract/ # 合同模块文件
|
|
|
├── temp/ # 临时目录(自动清理)
|
|
|
└── thumbnail/ # 缩略图目录
|
|
|
├── repair/
|
|
|
├── inspection/
|
|
|
└── ...
|
|
|
```
|
|
|
|
|
|
### 11.2 文件存储规则
|
|
|
|
|
|
| 规则项 | 说明 |
|
|
|
|--------|------|
|
|
|
| 文件路径格式 | `{module}/{YYYY/MM}/{uuid}.{ext}` |
|
|
|
| 原始文件名 | 记录在数据库中,URL 使用 UUID 防冲突和遍历 |
|
|
|
| 模块取值 | REPAIR / INSPECTION / CLEANING / EVALUATION / CONTRACT |
|
|
|
| URL访问方式 | 通过 Nginx location 映射(如 `{url-prefix}{module}/YYYY/MM/uuid.ext`) |
|
|
|
| 允许的文件类型 | 图片:jpg/jpeg/png/gif/webp;文档:pdf/doc/docx/xlsx/xls/ppt/pptx;其他:txt/zip/rar(超管可配置白名单) |
|
|
|
|
|
|
### 11.3 图片压缩规范
|
|
|
|
|
|
#### 压缩时机与方式
|
|
|
- **服务端自动压缩**:文件上传时后端自动处理,不依赖客户端
|
|
|
- **技术选型**:使用 Thumbnailator 或 Java ImageIO,无额外第三方依赖
|
|
|
- **支持格式**:JPG / PNG / WebP 输入;输出为 JPEG(透明 PNG 保持 PNG 格式)
|
|
|
|
|
|
#### 压缩参数(可在超管后台配置)
|
|
|
|
|
|
| 配置项 | 说明 | 默认值 |
|
|
|
|--------|------|--------|
|
|
|
| `image.compress.enabled` | 是否启用图片自动压缩 | true |
|
|
|
| `image.compress.max-width` | 超过此宽度则等比缩放(px) | 1920 |
|
|
|
| `image.compress.max-height` | 超过此高度则等比缩放(px) | 1920 |
|
|
|
| `image.compress.quality` | JPEG 输出质量(0-100) | 75 |
|
|
|
| `image.compress.thumbnail-enabled` | 是否同时生成缩略图 | true |
|
|
|
| `image.compress.thumbnail-size` | 缩略图宽高(px) | 300 |
|
|
|
|
|
|
#### 压缩率目标
|
|
|
|
|
|
| 场景 | 原始大小 | 压缩后目标 | 压缩率 |
|
|
|
|------|----------|-----------|--------|
|
|
|
| 普通照片(手机拍摄) | 5-15 MB | 200-500 KB | ~3%-5% |
|
|
|
| 截图等小图片 | <2 MB | <100 KB | ~5% |
|
|
|
| 高清图片(>15MB) | >15 MB | ≤1 MB | <1% |
|
|
|
|
|
|
#### EXIF 处理规则
|
|
|
- **保留**:拍摄时间、设备型号等信息
|
|
|
- **去除**:GPS 经纬度坐标等敏感位置信息
|
|
|
- **透明图片**:PNG 格式且含透明通道的图片保持原格式,不做转 JPEG 处理
|
|
|
|
|
|
### 11.4 超管后台 — 文件存储设置
|
|
|
|
|
|
#### 页面位置
|
|
|
超级管理员后台 → **系统管理 → 文件存储设置**
|
|
|
|
|
|
#### 可配置项
|
|
|
|
|
|
| 配置项 | 说明 | 默认值 |
|
|
|
|--------|------|--------|
|
|
|
| 存储根路径 | 文件存储基础路径(需重启生效) | ./uploads/ |
|
|
|
| URL访问前缀 | 文件访问的URL前缀路径 | /files/ |
|
|
|
| 最大文件大小 | 单文件上传上限(MB) | 20 |
|
|
|
| 允许的文件类型 | 文件扩展名白名单,逗号分隔 | jpg,jpeg,png,gif,webp,pdf,doc,docx,xlsx,xls |
|
|
|
| 图片压缩开关 | 全局开启/关闭图片自动压缩 | 开启 |
|
|
|
| 图片最大宽度 | 超过则等比缩放(px) | 1920 |
|
|
|
| 图片最大高度 | 超过则等比缩放(px) | 1920 |
|
|
|
| 图片压缩质量 | JPEG质量(0-100) | 75 |
|
|
|
| 缩略图开关 | 是否生成缩略图 | 开启 |
|
|
|
| 缩略图尺寸 | 缩略图宽高(px) | 300 |
|
|
|
| 磁盘告警阈值 | 使用率超过此值触发告警(%) | 85 |
|
|
|
| 临时文件清理天数 | temp目录文件自动清理周期(天) | 7 |
|
|
|
|
|
|
#### 操作功能
|
|
|
|
|
|
**存储概览面板:**
|
|
|
- 总文件数、总占用空间、今日上传量
|
|
|
- 各模块文件数及空间占比(饼图)
|
|
|
- 近30天上传量趋势折线图
|
|
|
- 磁盘使用率仪表盘
|
|
|
|
|
|
**手动管理:**
|
|
|
- 按模块 / 日期范围筛选查看已上传文件列表
|
|
|
- 支持批量删除文件(二次确认)
|
|
|
- 一键清理超过N天未引用的孤立文件(通过数据库关联检查)
|
|
|
|
|
|
**监控告警:**
|
|
|
- 磁盘使用率超阈值时触发系统内通知 + 企业微信告警
|
|
|
- 单日异常大量上传时预警(防恶意上传)
|
|
|
|
|
|
### 11.5 安全要求
|
|
|
|
|
|
| 安全项 | 要求 |
|
|
|
|--------|------|
|
|
|
| 文件名安全 | 使用 UUID 重命名,禁止原始文件名直接写入路径,防止路径遍历攻击 |
|
|
|
| 文件类型校验 | 服务端不仅校验扩展名,还需校验文件头(Magic Number),防止伪装类型上传 |
|
|
|
| 文件内容扫描 | 可选集成杀毒引擎对上传文件进行病毒扫描 |
|
|
|
| 访问控制 | 文件访问接口需鉴权(公开资源如头像除外),支持带签名的临时访问链接 |
|
|
|
| 防盗链 | Nginx 配置 Referer 白名单,防止外部网站直接引用 |
|
|
|
| 敏感文件 | 合同文件、身份证件等建议加密存储或设置独立访问权限 |
|
|
|
|
|
|
---
|
|
|
|
|
|
> **本文档为内部开发标准,所有开发人员必须严格按照此标准执行。如有疑问或需要调整,需经技术负责人审批。**
|