医院物业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
- 实现细节:
- 权限变更时,通过 Redis Pub/Sub 发布变更消息
PUBLISH permission:changed <version>
- 各服务实例订阅
permission:changed 频道,收到消息后触发 Spring Event
- 监听器刷新本地权限缓存
- 优势:毫秒级延迟,零数据库压力,复用已有 Redis 实例
- 降级策略:Redis 连接断开时,权限缓存 TTL(2小时)到期后自动刷新
- 实现要点:
- 权限变更时通过
StringRedisTemplate.convertAndSend() 发布消息到 permission:changed 频道
- 各实例
MessageListener 订阅该频道,收到消息后发布 Spring Event
@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 白名单,防止外部网站直接引用 |
| 敏感文件 |
合同文件、身份证件等建议加密存储或设置独立访问权限 |
本文档为内部开发标准,所有开发人员必须严格按照此标准执行。如有疑问或需要调整,需经技术负责人审批。