1. 项目背景与需求分析
东晟密封件作为一家专业生产工业密封件的制造企业,随着业务规模扩大和产品线丰富,原有的静态网站已无法满足产品展示和内容管理的需求。作为技术负责人,我接手了这个企业官网后台系统的重构项目。
核心痛点在于:
- 产品文档更新依赖前端开发人员手动修改HTML
- 技术文章发布流程繁琐,需要多部门邮件往来
- 缺乏统一的内容版本管理和回收站机制
- 移动端访问体验不佳,图片加载速度慢
经过与市场部、技术部的多轮需求确认,我们明确了系统需要实现的三大核心功能模块:
- 可视化产品文档编辑器
- 多角色协作的内容审核流
- 响应式前端展示框架
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体架构方案
采用前后端分离的架构设计:
code复制前端:Vue 3 + Element Plus
后端:Spring Boot 2.7 + MyBatis Plus
数据库:MySQL 8.0 + Redis缓存
文件存储:MinIO自建对象存储
选择这套技术栈主要基于以下考虑:
- 企业IT团队已有Java技术积累,降低学习成本
- Vue3的Composition API更适合复杂后台交互
- MinIO相比云存储服务更符合企业数据管控要求
2.2 数据库设计要点
产品文档表的核心字段设计:
sql复制CREATE TABLE `product_article` (
`id` bigint NOT NULL AUTO_INCREMENT,
`product_code` varchar(32) NOT NULL COMMENT '关联产品编号',
`version` int NOT NULL DEFAULT '1' COMMENT '文档版本',
`content` longtext NOT NULL COMMENT 'HTML内容',
`status` tinyint NOT NULL COMMENT '1-草稿 2-待审核 3-已发布',
`creator_id` bigint NOT NULL,
`reviewer_id` bigint DEFAULT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_product_version` (`product_code`,`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
特别说明几个设计决策:
- 采用version字段实现文档版本控制,而非物理删除
- 使用utf8mb4字符集支持emoji等特殊符号
- 建立产品编码+版本的联合唯一索引
3. 核心功能实现
3.1 可视化编辑器开发
基于TinyMCE定制开发的编辑器模块,关键改造点包括:
- 集成企业专属的密封件规格表插入插件
- 开发拖拽上传组件直连MinIO存储
- 添加水印功能防止技术文档外泄
编辑器初始化配置示例:
javascript复制const initEditor = () => {
tinymce.init({
selector: '#editor',
plugins: 'code table lists image link media',
toolbar: 'undo redo | styleselect | bold italic | alignleft aligncenter alignright | bullist numlist outdent indent | insertfile',
images_upload_handler: async (blobInfo) => {
const file = new File([blobInfo.blob()], blobInfo.filename())
const { url } = await minioClient.upload(file)
return Promise.resolve(url)
}
})
}
3.2 工作流引擎实现
采用状态机模式实现文档审核流程:
java复制public enum ArticleState {
DRAFT {
@Override
public boolean canTransferTo(ArticleState targetState) {
return targetState == UNDER_REVIEW;
}
},
UNDER_REVIEW {
@Override
public boolean canTransferTo(ArticleState targetState) {
return targetState == PUBLISHED || targetState == REJECTED;
}
},
// 其他状态...
}
// 使用示例
if(currentState.canTransferTo(targetState)) {
// 执行状态转移
}
实际开发中遇到的坑:
- 需要处理审核驳回后版本回退问题
- 邮件通知服务要支持重试机制
- 操作日志需要记录完整上下文
4. 性能优化实践
4.1 前端加载优化
针对产品文档中的高清图片:
- 使用Sharp进行服务端自动压缩
- 实现WebP格式自动转换
- 按屏幕尺寸加载不同分辨率图片
Nginx配置片段示例:
code复制location ~* \.(jpg|png)$ {
image_filter resize 800 -;
image_filter_buffer 10M;
image_filter_jpeg_quality 85;
}
4.2 缓存策略设计
采用多级缓存方案:
- Redis缓存热点文档HTML内容(TTL 1小时)
- 浏览器强缓存静态资源(max-age=31536000)
- 协商缓存API响应(ETag验证)
关键代码实现:
java复制@GetMapping("/articles/{id}")
@Cacheable(value = "articles", key = "#id")
public ArticleDTO getArticle(@PathVariable Long id) {
// 数据库查询逻辑
}
5. 安全防护措施
5.1 XSS防护方案
除了常规的输入过滤外,特别处理了:
- 白名单方式过滤HTML标签(允许table但禁用script)
- 内容安全策略(CSP)配置:
code复制Content-Security-Policy: default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';
- 富文本内容在渲染前进行DOM净化
5.2 权限控制实现
基于RBAC模型的权限设计:
java复制@PreAuthorize("hasRole('CONTENT_EDITOR') &&
@permissionService.canEditArticle(#articleId)")
@PostMapping("/articles/{articleId}")
public ResponseEntity updateArticle(@PathVariable Long articleId) {
// 更新逻辑
}
权限校验特别注意:
- 部门隔离:销售部只能看到销售相关文档
- 数据权限:区域经理只能操作本区域产品
- 操作日志:记录完整的修改前后对比
6. 部署与监控
6.1 容器化部署
使用Docker Compose编排服务:
yaml复制version: '3'
services:
backend:
image: java:8-jre
ports:
- "8080:8080"
volumes:
- ./logs:/app/logs
depends_on:
- redis
- minio
minio:
image: minio/minio
volumes:
- ./minio-data:/data
6.2 监控方案
- Spring Boot Actuator暴露健康检查
- Prometheus采集JVM指标
- ELK收集业务日志
关键监控指标:
- 文档保存成功率
- 审核流程平均耗时
- 图片加载耗时P99值
7. 项目总结与改进方向
经过三个月的开发和迭代,系统已稳定运行半年,支撑了2000+产品文档和300+技术文章的管理。几个值得分享的经验:
-
内容版本管理一定要在设计初期考虑,我们通过version字段的方案,后续轻松实现了文档对比功能
-
对于工业品的技术文档,要特别注意特殊符号(如Φ、±等)的兼容性测试
-
审核流程的异常处理要预留足够缓冲,我们遇到过节假日审核人不在岗导致的流程阻塞
下一步计划:
- 实现基于AI的文档自动分类
- 增加多语言支持能力
- 开发移动端专用编辑组件
这个项目让我深刻体会到:企业级内容管理系统不是简单的CRUD,需要深入理解业务场景,在技术实现上做好平衡。比如我们为技术文档特别开发的公式编辑器,就极大提升了工程师的使用体验。
