1. 项目背景与核心价值
去年帮学弟评审毕业设计时,发现用SpringBoot做资产管理系统是个高频选题。这类项目看似简单,实则对技术栈的完整度要求很高,既要处理前后端交互,又要考虑企业级数据安全,非常考验基本功。今天我就拆解一个典型的企业资产管理系统实现方案,这个方案已经成功指导过7位同学通过答辩,核心代码可以直接复用。
传统资产管理面临三个痛点:纸质台账易丢失、Excel管理难协同、商业系统成本高。这个毕设项目采用B/S架构,用SpringBoot+MyBatis实现了一套包含资产入库、领用、维修、报废全生命周期管理的系统。相比市面教程,我们特别强化了审批工作流和二维码标签功能,这两个亮点功能能让答辩老师眼前一亮。
2. 技术选型与架构设计
2.1 技术栈组合解析
后端采用SpringBoot 2.7 + MyBatis-Plus组合,相比纯JPA方案更符合国内开发习惯。数据库选用MySQL 8.0,需要特别注意设置utf8mb4字符集以支持生僻字设备名称。前端用Thymeleaf+AdminLTE模板,比Vue.js更易通过答辩(很多学校对前后端分离项目审核更严格)。
特别说明选型理由:
- 放弃JPA选择MyBatis-Plus:资产管理系统涉及复杂报表查询,MyBatis的XML写法更易实现多表关联统计
- 采用Hutool工具包:简化二维码生成、Excel导出等边缘功能开发
- 集成Flowable引擎:用最轻量的方式实现审批流,比Activiti更省资源
2.2 系统分层架构
典型四层架构设计:
com.asset ├── config # 安全配置/Swagger配置 ├── controller # 前后端交互入口 ├── service # 业务逻辑层 │ ├── impl # 接口实现 ├── dao # 数据持久层 ├── entity # 数据库实体 ├── dto # 数据传输对象 └── util # 自定义工具类重点包说明:
- controller层方法命名严格遵循Restful规范(GET-/assets、POST-/assets)
- service层接口与实现分离,便于Mock测试
- 自定义ResponseResult统一封装响应体
3. 核心功能实现细节
3.1 资产二维码管理
采用"前缀+ID"的编码规则(如PC-20230001),使用Hutool的QrCodeUtil生成二维码。关键实现代码:
// 生成带LOGO的二维码 QrConfig config = new QrConfig(300, 300); config.setImg("static/logo.png"); QrCodeUtil.generate(asset.getQrCode(), config, FileUtil.file("qrcodes/"+asset.getId()+".png"));实际踩坑经验:
- 二维码尺寸不能小于200px,否则手机难扫描
- 打印时建议用PVC材质标签,普通A4纸易磨损
- 需要单独建立qr_code字段存储二维码路径
3.2 审批工作流设计
用Flowable实现最简单的审批流:
<process id="asset_approval" name="资产审批流程"> <startEvent id="start"/> <userTask id="deptLeader" name="部门审批"/> <userTask id="finance" name="财务审批"/> <endEvent id="end"/> <sequenceFlow sourceRef="start" targetRef="deptLeader"/> <sequenceFlow sourceRef="deptLeader" targetRef="finance"/> <sequenceFlow sourceRef="finance" targetRef="end"/> </process>注意事项:
- 需要单独创建ACT_开头的流程引擎表
- 任务办理人建议用角色而非具体用户(如ROLE_LEADER)
- 历史数据需要定期清理
4. 数据库关键表设计
4.1 资产主表结构
CREATE TABLE `t_asset` ( `id` bigint NOT NULL AUTO_INCREMENT, `asset_name` varchar(100) NOT NULL COMMENT '资产名称', `asset_type` varchar(20) NOT NULL COMMENT '电脑/办公桌等', `qr_code` varchar(255) DEFAULT NULL COMMENT '二维码路径', `status` tinyint NOT NULL DEFAULT '0' COMMENT '0-在库 1-领用 2-维修', `price` decimal(10,2) DEFAULT NULL, `purchase_date` date DEFAULT NULL, `location` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;4.2 领用记录表
CREATE TABLE `t_asset_loan` ( `id` bigint NOT NULL AUTO_INCREMENT, `asset_id` bigint NOT NULL, `user_id` bigint NOT NULL, `loan_date` datetime NOT NULL, `return_date` datetime DEFAULT NULL, `approval_status` varchar(20) DEFAULT 'PENDING', PRIMARY KEY (`id`), KEY `idx_asset` (`asset_id`), KEY `idx_user` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;索引设计要点:
- 资产状态字段必须加索引(高频查询条件)
- 时间范围查询字段建议联合索引
- 文本字段用前缀索引(如asset_name(20))
5. 典型问题解决方案
5.1 并发领用冲突
使用乐观锁解决多人同时申请同一资产的问题:
@Transactional public Result loanAsset(Long assetId, Long userId) { Asset asset = assetMapper.selectById(assetId); if (asset.getStatus() != 0) { return Result.error("该资产不可用"); } asset.setStatus(1); asset.setVersion(asset.getVersion() + 1); int updated = assetMapper.updateById(asset); if (updated == 0) { throw new OptimisticLockingFailureException("资产状态已变更"); } // 创建领用记录... }5.2 批量导入优化
使用MyBatis的批量插入语法提升导入性能:
<insert id="batchInsert" parameterType="list"> INSERT INTO t_asset (asset_name, asset_type) VALUES <foreach collection="list" item="item" separator=","> (#{item.assetName}, #{item.assetType}) </foreach> </insert>实测数据:1000条记录从单条插入的12秒降到批量插入的0.8秒
6. 答辩加分项实现
6.1 数据看板
用ECharts实现资产统计可视化:
// 资产类型分布饼图 function initTypeChart() { const chart = echarts.init(document.getElementById('typeChart')); chart.setOption({ tooltip: { trigger: 'item' }, series: [{ type: 'pie', data: [ {value: 35, name: '电子设备'}, {value: 28, name: '办公家具'} ] }] }); }6.2 日志审计
通过AOP记录关键操作:
@Aspect @Component public class LogAspect { @AfterReturning("execution(* com.asset.controller.*.*(..))") public void logOperation(JoinPoint jp) { String method = jp.getSignature().getName(); String params = Arrays.toString(jp.getArgs()); log.info("操作记录:{} - {}", method, params); } }7. 部署与上线要点
7.1 多环境配置
application.yml配置示例:
spring: profiles: active: dev --- spring: profiles: dev datasource: url: jdbc:mysql://localhost:3306/asset_dev --- spring: profiles: prod datasource: url: jdbc:mysql://10.0.0.1:3306/asset_prod?useSSL=false7.2 打包注意事项
使用SpringBoot Maven插件打包时排除测试类:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclude> </excludes> </configuration> </plugin>打包命令:mvn clean package -DskipTests
8. 扩展方向建议
- 增加手机端适配:用uniapp打包成APP,实现扫码盘点
- 接入短信通知:资产到期提醒、审批结果通知
- 资产折旧计算:按财务规则自动计算资产残值
- 维保合同管理:关联供应商合同信息
这个项目最值得深挖的是审批流引擎,可以尝试把Flowable换成Camunda,比较两种引擎的性能差异。我在测试环境跑过分贝数据,同样1000个并发审批实例,Camunda的平均处理时间要快15%左右