1. 项目概述与核心需求
广告公司线上订单平台是一个基于SpringBoot框架开发的B2B业务管理系统,主要解决传统广告行业订单处理效率低下、流程不透明的问题。这个毕业设计项目完整实现了从客户需求提交、方案设计、报价审批到生产跟踪的全流程数字化管理。
我在实际开发中发现,这类系统最核心的痛点在于如何平衡业务流程的规范性和灵活性。广告行业的订单往往存在大量非标需求,比如一个简单的宣传单页制作,可能涉及特殊工艺、加急费用、多次修改等变量因素。因此系统设计时需要特别注意以下几个关键点:
- 订单模板的可配置性:支持自定义字段和流程节点
- 价格体系的灵活性:允许设置基础价、附加费、折扣规则
- 状态机的可扩展性:适应不同业务线的审批流程差异
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 技术选型依据
选择SpringBoot作为基础框架主要基于以下考虑:
- 快速开发:广告公司通常IT资源有限,需要快速迭代
- 生态丰富:整合支付、消息推送等第三方服务方便
- 学习成本低:便于后续维护人员接手
技术栈组成:
- 前端:Thymeleaf + Bootstrap(考虑后台管理系统特性)
- 后端:SpringBoot 2.7 + MyBatis-Plus
- 数据库:MySQL 8.0(事务需求不强,但需要处理多表关联)
- 中间件:Redis(会话管理+缓存)、RabbitMQ(异步通知)
特别注意:广告行业图片资源较多,需要单独配置静态资源服务器。我采用Nginx做文件服务,通过MD5重命名解决重复上传问题。
2.2 核心模块设计
系统采用经典的三层架构,但针对广告业务做了特殊调整:
-
订单中心模块
- 采用状态模式实现订单生命周期管理
- 支持自定义审批流(通过工作流引擎)
- 集成电子签章功能(使用阿里云SDK)
-
客户管理模块
- 客户分级体系(VIP/普通/黑名单)
- 联系人关系图谱(记录决策链)
- 历史订单分析(推荐相似方案)
-
财务模块
- 多维度对账功能
- 特殊账期支持(广告行业常见月结)
- 发票自动匹配
3. 关键实现细节
3.1 动态表单实现
广告业务需求多变,采用JSON Schema定义表单结构:
java复制// 订单模板配置示例
{
"fields": [
{
"name": "material",
"label": "材质选择",
"type": "select",
"options": ["铜版纸","哑粉纸","特种纸"],
"required": true
},
{
"name": "urgency",
"label": "加急处理",
"type": "radio",
"options": ["普通3天","加急24小时","特急12小时"],
"pricingRules": {
"加急24小时": {"base": 500, "formula": "total*0.1"},
"特急12小时": {"base": 800, "formula": "total*0.15"}
}
}
]
}
前端通过Vue动态渲染表单,后端使用Jackson处理JSON字段的持久化。这里有个坑:MySQL的JSON字段查询性能较差,建议对高频查询条件建立单独索引。
3.2 价格计算引擎
广告行业报价存在多种计算模式:
- 基础价 + 附加费(如特殊工艺)
- 阶梯价(数量折扣)
- 组合价(套餐优惠)
实现策略模式的价格计算器:
java复制public interface PricingStrategy {
BigDecimal calculate(Order order);
}
@Service
public class CompositePricing implements PricingStrategy {
@Autowired
private List<PricingStrategy> strategies;
public BigDecimal calculate(Order order) {
return strategies.stream()
.map(s -> s.calculate(order))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
实际使用中发现,需要特别注意浮点数精度问题。建议金额计算全部使用BigDecimal,并在数据库中用DECIMAL(12,2)类型存储。
4. 典型问题解决方案
4.1 文件版本管理
广告设计稿常需要多次修改,采用如下存储方案:
code复制/uploads/
└── [order_id]/
├── v1/
│ ├── design.ai
│ └── preview.jpg
├── v2/
└── current -> v2 # 符号链接指向最新版本
关键实现代码:
java复制public String saveVersion(Long orderId, MultipartFile file) {
String version = "v" + (getLatestVersion(orderId) + 1);
Path dir = Paths.get(uploadRoot, orderId.toString(), version);
Files.createDirectories(dir);
String filename = file.getOriginalFilename();
Path target = dir.resolve(Objects.requireNonNull(filename));
file.transferTo(target);
// 更新current链接
Path link = Paths.get(uploadRoot, orderId.toString(), "current");
Files.deleteIfExists(link);
Files.createSymbolicLink(link, Paths.get(version));
return version;
}
4.2 审批流程引擎
基于Activiti改造的轻量级审批流:
- 使用YAML定义流程节点
yaml复制approvalFlow:
- name: 设计确认
approvers: ["design_leader"]
actions: ["approve", "reject", "request_change"]
timeout: 48 # 小时
- name: 财务审核
condition: "order.totalAmount > 10000"
approvers: ["finance_manager"]
- 动态生成审批任务表
sql复制CREATE TABLE `approval_task` (
`id` BIGINT AUTO_INCREMENT,
`order_id` BIGINT NOT NULL,
`node_name` VARCHAR(50) NOT NULL,
`assignee` VARCHAR(30) NOT NULL,
`status` ENUM('pending','approved','rejected') DEFAULT 'pending',
`comments` TEXT,
`created_at` DATETIME NOT NULL,
`expire_at` DATETIME NOT NULL,
PRIMARY KEY (`id`),
INDEX `idx_order` (`order_id`, `node_name`)
) ENGINE=InnoDB;
5. 部署与优化实践
5.1 生产环境配置
推荐使用Docker Compose部署:
yaml复制version: '3'
services:
app:
image: ad-platform:1.0
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- REDIS_HOST=redis
depends_on:
- redis
- mysql
mysql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=ad_platform
redis:
image: redis:6-alpine
volumes:
- redis_data:/data
volumes:
mysql_data:
redis_data:
5.2 性能优化技巧
-
订单查询优化:
- 添加复合索引:
(customer_id, create_time) - 分页查询使用游标方式而非LIMIT offset
sql复制SELECT * FROM orders WHERE customer_id = ? AND create_time < ? ORDER BY create_time DESC LIMIT 20 - 添加复合索引:
-
缓存策略:
- 客户信息:TTL 1小时
- 价格模板:变更时主动失效
- 审批流程:启动时加载,不变更
-
日志处理:
- 业务操作日志存入MongoDB
- 系统日志通过Logstash导入ELK
- 关键操作添加审计注解
java复制@AuditLog(action = "订单创建") public Order createOrder(OrderDTO dto) { // ... }
这个项目让我深刻体会到,业务系统开发最重要的是理解行业特性。比如广告行业对设计稿版本极其敏感,而传统制造业更关注物料追溯。下次再做类似项目,我会更早地深入业务现场观察实际工作流程。
