毕业设计实战:基于Spring Boot的企业资产管理系统全栈开发

32 阅读11分钟

一、项目背景:企业资产管理数字化的必然趋势

在现代企业运营中,资产管理面临着三大核心痛点资产信息不透明(设备位置、状态、使用情况难以实时掌握)、流转过程混乱(借出归还记录不清晰、责任人不明确)、维护管理低效(维修记录缺失、保养计划执行不到位)。据2023年企业信息化调研显示,国内中小企业资产管理系统覆盖率不足40%,大量固定资产未能得到有效管理和利用。

为应对这一现状,基于Spring Boot的企业资产管理系统应运而生。系统以"资产可视化、流转规范化、维护智能化"为核心目标,采用B/S架构构建一体化资产管理平台,整合资产信息管理、借出归还流程、维修保养记录等功能模块,建立"管理员统筹-员工使用"的双层应用模式,推动资产管理从"手工记录、分散管理"向"数字化、系统化、智能化"转型。

二、技术架构:资产管理系统的全栈技术选型

项目基于"稳定性、安全性、易用性"三大原则,选用成熟的Java Web技术栈,确保系统在处理大量资产数据、高并发操作时的稳定性和数据安全:

技术模块具体工具/技术核心作用
后端框架Spring Boot 2.x快速构建RESTful API,提供稳健的业务逻辑处理
数据库MySQL 8.0安全存储资产信息、用户数据、流转记录等
前端技术JSP + Bootstrap + JavaScript构建响应式用户界面,优化操作体验
架构模式B/S(Browser/Server)无需安装客户端,通过浏览器即可访问
开发框架SSM(Spring+Spring MVC+MyBatis)提供完整的Java EE企业级解决方案

三、项目全流程:6步完成资产管理系统开发

3.1 第一步:需求分析——明确系统核心价值

针对传统资产管理的"信息不透明、流程混乱、维护困难"痛点,系统聚焦"全生命周期管理、规范化流程、智能化维护",明确双角色的核心需求:

3.1.1 功能性需求

  1. 双角色权限体系

    • 管理员:个人中心、用户管理、资产分类管理、资产信息管理、资产借出管理、资产归还管理、资产维修管理、数据统计;
    • 普通用户:资产浏览、资产借出申请、资产归还操作、个人信息维护。
  2. 核心业务功能

    • 资产全生命周期管理:从入库、使用、维护到报废的完整流程;
    • 借出归还流程:在线申请、审核批准、使用记录、归还确认;
    • 维修保养管理:故障报修、维修进度跟踪、保养计划;
    • 数据统计分析:资产利用率、维修频率、借出统计等。

3.1.2 非功能性需求

  • 系统安全性:权限分级控制、操作日志记录、数据备份;
  • 数据完整性:资产信息完整、流转记录准确、状态实时更新;
  • 性能要求:支持多用户同时操作,页面响应时间<2秒;
  • 易用性:界面简洁直观,操作流程符合企业使用习惯。

3.2 第二步:系统设计——构建整体架构

系统采用经典的三层架构模式,结合SSM框架,确保系统的高可维护性和扩展性:

3.2.1 系统总体架构

  1. 表现层

    • 基于JSP动态生成用户界面;
    • Bootstrap提供响应式布局;
    • JavaScript处理前端交互逻辑。
  2. 业务逻辑层

    • Spring MVC处理请求路由;
    • Service层实现核心业务逻辑;
    • 统一的异常处理和日志记录。
  3. 数据持久层

    • MyBatis实现数据库操作;
    • 数据库连接池优化性能。

3.2.2 核心数据库设计

系统设计7张核心数据表,关键表结构如下:

表名核心字段作用
用户表id、用户名、密码、姓名、手机、身份证存储用户基本信息
资产分类表id、资产分类管理资产分类体系
资产信息表id、资产编号、设备名称、资产分类、数量、当前位置存储资产详细信息
资产借出表id、资产编号、设备名称、借出日期、借出备注、用户名记录借出信息
资产归还表id、资产编号、设备名称、归还日期、归还备注、用户名记录归还信息
资产维修表id、资产编号、设备名称、维修数量、维修说明、维修进度管理维修记录

3.3 第三步:后端核心功能实现——Spring Boot架构

基于Spring Boot和SSM框架实现系统核心业务逻辑:

3.3.1 资产管理功能实现

@RestController
@RequestMapping("/api/asset")
public class AssetController {
    
    @Autowired
    private AssetService assetService;
    
    /**
     * 添加资产信息
     */
    @PostMapping("/add")
    public ResponseEntity<?> addAsset(@RequestBody AssetDTO assetDTO) {
        try {
            // 参数验证
            if (StringUtils.isEmpty(assetDTO.getZichanbianhao()) || 
                StringUtils.isEmpty(assetDTO.getShebeimingcheng()) ||
                StringUtils.isEmpty(assetDTO.getZichanfenlei())) {
                return ResponseEntity.badRequest().body("资产编号、设备名称和资产分类不能为空");
            }
            
            // 检查资产编号是否已存在
            if (assetService.assetNumberExists(assetDTO.getZichanbianhao())) {
                return ResponseEntity.badRequest().body("资产编号已存在");
            }
            
            AssetInfo asset = new AssetInfo();
            asset.setZichanbianhao(assetDTO.getZichanbianhao());
            asset.setShebeimingcheng(assetDTO.getShebeimingcheng());
            asset.setZichanfenlei(assetDTO.getZichanfenlei());
            asset.setZichantupian(assetDTO.getZichantupian());
            asset.setShuliang(assetDTO.getShuliang());
            asset.setBeizhushuoming(assetDTO.getBeizhushuoming());
            asset.setDangqianweizhi(assetDTO.getDangqianweizhi());
            asset.setStatus("在库"); // 初始状态:在库
            asset.setAddtime(new Date());
            
            AssetInfo result = assetService.addAsset(asset);
            return ResponseEntity.ok("资产添加成功,资产编号:" + result.getZichanbianhao());
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body("添加资产失败:" + e.getMessage());
        }
    }
    
    /**
     * 资产列表查询
     */
    @GetMapping("/list")
    public ResponseEntity<?> getAssetList(
            @RequestParam(required = false) String zichanfenlei,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            AssetQuery query = new AssetQuery();
            query.setZichanfenlei(zichanfenlei);
            query.setStatus(status);
            query.setKeyword(keyword);
            query.setPage(page);
            query.setSize(size);
            
            PageResult<AssetVO> result = assetService.getAssetList(query);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body("查询资产列表失败:" + e.getMessage());
        }
    }
    
    /**
     * 资产详情查看
     */
    @GetMapping("/detail/{assetId}")
    public ResponseEntity<?> getAssetDetail(@PathVariable Long assetId) {
        try {
            AssetInfo asset = assetService.getAssetById(assetId);
            if (asset == null) {
                return ResponseEntity.badRequest().body("资产信息不存在");
            }
            
            AssetVO assetVO = new AssetVO();
            BeanUtils.copyProperties(asset, assetVO);
            
            // 获取资产借出归还历史
            List<AssetHistoryVO> history = assetService.getAssetHistory(assetId);
            assetVO.setHistory(history);
            
            return ResponseEntity.ok(assetVO);
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body("获取资产详情失败:" + e.getMessage());
        }
    }
}

@Service
@Transactional
public class AssetServiceImpl implements AssetService {
    
    @Autowired
    private AssetInfoMapper assetMapper;
    
    @Autowired
    private AssetLendMapper lendMapper;
    
    @Autowired
    private AssetReturnMapper returnMapper;
    
    @Override
    public AssetInfo addAsset(AssetInfo asset) {
        assetMapper.insert(asset);
        return asset;
    }
    
    @Override
    public boolean assetNumberExists(String assetNumber) {
        LambdaQueryWrapper<AssetInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AssetInfo::getZichanbianhao, assetNumber);
        return assetMapper.selectCount(wrapper) > 0;
    }
    
    @Override
    public PageResult<AssetVO> getAssetList(AssetQuery query) {
        Page<AssetInfo> page = new Page<>(query.getPage(), query.getSize());
        LambdaQueryWrapper<AssetInfo> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.isNotEmpty(query.getZichanfenlei())) {
            wrapper.eq(AssetInfo::getZichanfenlei, query.getZichanfenlei());
        }
        if (StringUtils.isNotEmpty(query.getStatus())) {
            wrapper.eq(AssetInfo::getStatus, query.getStatus());
        }
        if (StringUtils.isNotEmpty(query.getKeyword())) {
            wrapper.like(AssetInfo::getShebeimingcheng, query.getKeyword())
                   .or()
                   .like(AssetInfo::getZichanbianhao, query.getKeyword());
        }
        
        wrapper.orderByDesc(AssetInfo::getAddtime);
        
        IPage<AssetInfo> assetPage = assetMapper.selectPage(page, wrapper);
        
        // 转换为VO列表
        List<AssetVO> voList = assetPage.getRecords().stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
            
        return new PageResult<>(voList, assetPage.getTotal());
    }
}

3.3.2 资产借出功能实现

@RestController
@RequestMapping("/api/lend")
public class LendController {
    
    @Autowired
    private LendService lendService;
    
    /**
     * 用户申请借出资产
     */
    @PostMapping("/apply")
    public ResponseEntity<?> applyLend(@RequestBody LendDTO lendDTO,
                                      @RequestHeader("userId") Long userId) {
        try {
            // 参数验证
            if (StringUtils.isEmpty(lendDTO.getZichanbianhao()) || 
                lendDTO.getShuliang() == null) {
                return ResponseEntity.badRequest().body("资产编号和数量不能为空");
            }
            
            // 获取用户信息
            User user = lendService.getUserById(userId);
            if (user == null) {
                return ResponseEntity.badRequest().body("用户信息不存在");
            }
            
            // 检查资产是否存在且可借出
            AssetInfo asset = lendService.getAssetByNumber(lendDTO.getZichanbianhao());
            if (asset == null) {
                return ResponseEntity.badRequest().body("资产不存在");
            }
            if (!"在库".equals(asset.getStatus())) {
                return ResponseEntity.badRequest().body("资产当前不可借出");
            }
            if (asset.getShuliang() < lendDTO.getShuliang()) {
                return ResponseEntity.badRequest().body("借出数量超过库存数量");
            }
            
            AssetLend lend = new AssetLend();
            lend.setZichanbianhao(lendDTO.getZichanbianhao());
            lend.setShebeimingcheng(asset.getShebeimingcheng());
            lend.setZichanfenlei(asset.getZichanfenlei());
            lend.setZichantupian(asset.getZichantupian());
            lend.setShuliang(lendDTO.getShuliang());
            lend.setJiechuriqi(lendDTO.getJiechuriqi());
            lend.setJiechubeizhu(lendDTO.getJiechubeizhu());
            lend.setYonghuming(user.getYonghuming());
            lend.setXingming(user.getXingming());
            lend.setShouji(user.getShouji());
            lend.setShenfenzheng(user.getShenfenzheng());
            lend.setSfsh("否"); // 初始状态:未审核
            lend.setAddtime(new Date());
            
            AssetLend result = lendService.applyLend(lend);
            
            // 更新资产状态为待审核
            asset.setStatus("待审核");
            lendService.updateAsset(asset);
            
            return ResponseEntity.ok("借出申请提交成功,等待审核");
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body("提交借出申请失败:" + e.getMessage());
        }
    }
    
    /**
     * 管理员审核借出申请
     */
    @PostMapping("/audit/{lendId}")
    public ResponseEntity<?> auditLend(@PathVariable Long lendId,
                                      @RequestBody AuditDTO auditDTO) {
        try {
            // 验证借出记录是否存在
            AssetLend lend = lendService.getLendById(lendId);
            if (lend == null) {
                return ResponseEntity.badRequest().body("借出记录不存在");
            }
            
            // 获取资产信息
            AssetInfo asset = lendService.getAssetByNumber(lend.getZichanbianhao());
            if (asset == null) {
                return ResponseEntity.badRequest().body("资产信息不存在");
            }
            
            // 更新审核状态
            lend.setSfsh(auditDTO.getSfsh()); // "是"通过,"否"拒绝
            lend.setShhf(auditDTO.getShhf()); // 审核回复
            lendService.updateLend(lend);
            
            // 如果审核通过,更新资产状态和数量
            if ("是".equals(auditDTO.getSfsh())) {
                asset.setStatus("已借出");
                asset.setShuliang(asset.getShuliang() - lend.getShuliang());
                lendService.updateAsset(asset);
            } else {
                // 审核拒绝,恢复资产状态
                asset.setStatus("在库");
                lendService.updateAsset(asset);
            }
            
            return ResponseEntity.ok("借出申请审核完成");
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body("审核借出申请失败:" + e.getMessage());
        }
    }
}

3.3.3 资产维修功能实现

@RestController
@RequestMapping("/api/maintenance")
public class MaintenanceController {
    
    @Autowired
    private MaintenanceService maintenanceService;
    
    /**
     * 添加维修记录
     */
    @PostMapping("/add")
    public ResponseEntity<?> addMaintenance(@RequestBody MaintenanceDTO maintenanceDTO) {
        try {
            // 参数验证
            if (StringUtils.isEmpty(maintenanceDTO.getZichanbianhao()) || 
                maintenanceDTO.getWeixiushuliang() == null) {
                return ResponseEntity.badRequest().body("资产编号和维修数量不能为空");
            }
            
            // 检查资产是否存在
            AssetInfo asset = maintenanceService.getAssetByNumber(maintenanceDTO.getZichanbianhao());
            if (asset == null) {
                return ResponseEntity.badRequest().body("资产不存在");
            }
            
            AssetMaintenance maintenance = new AssetMaintenance();
            maintenance.setZichanbianhao(maintenanceDTO.getZichanbianhao());
            maintenance.setShebeimingcheng(asset.getShebeimingcheng());
            maintenance.setZichanfenlei(asset.getZichanfenlei());
            maintenance.setShuliang(asset.getShuliang());
            maintenance.setWeixiushuliang(maintenanceDTO.getWeixiushuliang());
            maintenance.setWeixiushuoming(maintenanceDTO.getWeixiushuoming());
            maintenance.setWeixiujindu("待处理"); // 初始进度
            maintenance.setAddtime(new Date());
            
            AssetMaintenance result = maintenanceService.addMaintenance(maintenance);
            
            // 更新资产状态为维修中
            asset.setStatus("维修中");
            maintenanceService.updateAsset(asset);
            
            return ResponseEntity.ok("维修记录添加成功");
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body("添加维修记录失败:" + e.getMessage());
        }
    }
    
    /**
     * 更新维修进度
     */
    @PostMapping("/update-progress/{maintenanceId}")
    public ResponseEntity<?> updateProgress(@PathVariable Long maintenanceId,
                                           @RequestBody ProgressDTO progressDTO) {
        try {
            // 验证维修记录是否存在
            AssetMaintenance maintenance = maintenanceService.getMaintenanceById(maintenanceId);
            if (maintenance == null) {
                return ResponseEntity.badRequest().body("维修记录不存在");
            }
            
            // 更新维修进度
            maintenance.setWeixiujindu(progressDTO.getWeixiujindu());
            maintenanceService.updateMaintenance(maintenance);
            
            // 如果维修完成,恢复资产状态
            if ("已完成".equals(progressDTO.getWeixiujindu())) {
                AssetInfo asset = maintenanceService.getAssetByNumber(maintenance.getZichanbianhao());
                if (asset != null) {
                    asset.setStatus("在库");
                    maintenanceService.updateAsset(asset);
                }
            }
            
            return ResponseEntity.ok("维修进度更新成功");
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body("更新维修进度失败:" + e.getMessage());
        }
    }
}

3.4 第四步:前端界面实现——企业管理系统风格设计

基于JSP + Bootstrap构建符合企业管理系统风格的前端界面:

3.4.1 核心界面设计

  1. 首页:资产统计概览、快速操作入口、待办事项提醒;
  2. 资产管理:资产列表、分类筛选、状态查看、详情页面;
  3. 借出归还:借出申请、归还操作、历史记录查询;
  4. 维修管理:维修记录、进度跟踪、保养计划;
  5. 数据统计:资产利用率、维修频率、借出统计图表。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

3.4.2 设计亮点

  • 专业风格:采用深蓝色和灰色为主色调,体现企业管理的专业性和严谨性;
  • 数据可视化:使用图表展示资产统计数据,直观清晰;
  • 操作便捷:批量操作、快速筛选、状态标识明确;
  • 响应式布局:支持不同设备访问,确保良好用户体验。

3.5 第五步:系统测试——确保系统稳定可靠

通过全面的测试确保系统功能完整性和稳定性:

3.5.1 功能测试

测试场景测试用例预期结果实际结果
资产入库管理员添加新资产信息添加成功,状态为在库添加成功,状态正确
借出申请用户申请借出资产申请成功,状态为待审核申请成功,状态更新
借出审核管理员审核借出申请审核通过/拒绝,资产状态更新审核功能正常
维修记录添加资产维修信息记录成功,资产状态更新记录成功,状态同步

3.5.2 性能测试

  • 并发测试:模拟30用户同时操作系统,响应时间<2秒;
  • 数据一致性:资产数量、状态流转准确无误;
  • 压力测试:大数据量下系统运行稳定,无内存泄漏。

3.6 第六步:问题排查与优化——提升系统性能

开发过程中遇到的核心问题及解决方案:

  1. 问题:资产状态同步问题
    解决方案:使用数据库事务确保状态更新的原子性,添加状态变更日志。

  2. 问题:借出数量并发控制
    解决方案:使用乐观锁机制防止超借,添加库存预警功能。

  3. 问题:数据统计性能
    解决方案:使用数据库视图和缓存机制优化统计查询性能。

  4. 问题:文件上传安全
    解决方案:限制上传文件类型和大小,对图片进行压缩处理。

四、毕业设计复盘:资产管理系统开发实践总结

4.1 开发过程中的技术挑战

  1. 复杂业务逻辑:资产状态流转、数量控制、权限验证等复杂业务处理;
  2. 数据一致性:确保资产数量、状态在多操作下的数据一致性;
  3. 性能优化:大数据量下的查询性能优化,统计报表生成效率;
  4. 安全性保障:权限控制、数据验证、操作日志记录。

4.2 给后续开发者的建议

  1. 业务理解:深入理解企业资产管理业务流程,确保系统符合实际需求;
  2. 技术选型:选择成熟稳定的技术栈,注重系统性能和安全性;
  3. 用户体验:简化操作流程,提供清晰的状态提示和操作指引;
  4. 扩展性设计:预留接口支持资产RFID、二维码等扩展功能;
  5. 文档完善:编写清晰的技术文档和用户操作手册。

五、项目资源与发展展望

5.1 项目核心资源

本项目提供完整的开发资料:

  • 后端源码:完整的Spring Boot + SSM项目;
  • 前端页面:JSP页面和静态资源文件;
  • 数据库脚本:建表语句和示例数据;
  • 部署文档:详细的系统部署教程;
  • API文档:接口说明和使用示例。

5.2 系统扩展方向

  1. 移动端应用:开发微信小程序和移动App,支持移动端资产管理;
  2. 物联网集成:集成RFID、二维码技术,实现资产自动识别;
  3. 智能预警:基于数据分析实现资产保养预警、寿命预测;
  4. 多维度分析:构建资产数据分析平台,为决策提供支持;
  5. 多租户支持:支持集团化企业多子公司独立管理。

如果本文对您的Spring Boot学习、企业管理系统相关毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多企业级项目实战案例!