基于若依框架的固定资产管理系统源码解析与二次开发实战
简介面向Java开发者与企业信息化实施人员的一套固定资产管理完整源码基于若依RuoYi框架搭配layui前端构建覆盖资产登记、领用、借用、归还、维修、调拨、转移、报废及统计分析等业务闭环并内置组织结构管理与角色权限分配可用于二次开发、课程设计或企业内部资产管理系统的搭建参考。压缩包共1883个文件约8.88MB以317个Java源文件、180个HTML页面、90个JavaScript脚本和40个CSS样式为主辅以XML配置、VM模板、SQL脚本及图片字体等静态资源前后端结构完整、模块划分清晰。目前已有563人学习下载。读者可从中获得可直接运行的若依项目骨架、资产全生命周期业务实现、基于角色的权限控制方案以及layui表格表单交互范例便于对照理解框架集成方式与业务代码组织思路快速复用或裁剪出符合自身需求的资产管理模块。1. 固定资产管理系统一套基于若依框架的 Java 后台工程拿到手就能跑很多团队做内部资产台账第一反应是上 Excel结果资产编号重复、领用记录对不上、折旧算到一半发现公式写错最后变成一张没人敢动的“祖传表格”。这套固定资产管理源码就是冲着这个场景来的用 Java 写的一套后台管理系统底层是若依框架覆盖资产入库、领用、归还、报废、折旧这些日常动作适合中小企业内部 IT 或行政团队自建台账也适合 Java 开发者拿来做若依框架的二次开发练手项目。它不是一个玩具 Demo而是一套带权限、带菜单、带代码生成器的完整后台骨架你拿到源码后最该关心的不是“它有什么功能”而是“它的模块怎么切、数据怎么流、我改哪里不会把权限体系搞崩”。下面按跑起来、拆结构、改功能的顺序讲。2. 环境准备与启动从拉代码到登录后台的完整链路2.1 技术栈与依赖版本怎么定这套工程的技术选型是若依框架的典型组合后端 Spring Boot MyBatis Spring Security前端如果是分离版就是 Vue Element UI如果是单体版则是 Thymeleaf 模板。固定资产模块本身不引入额外中间件数据库用 MySQL 就够缓存层若依默认带 Redis但资产台账这种读多写少的场景Redis 主要用来存登录 token 和字典缓存不是业务强依赖。我一般会先确认三件事再动手JDK 版本、MySQL 版本、Node 版本。若依较新的分支要求 JDK 8 或 17MySQL 5.7 以上前端 Node 14 到 16 之间比较稳。版本对不上是最常见的翻车点比如 JDK 17 跑老分支会报模块访问异常Node 18 跑老版本 node-sass 会直接编译失败。# 先看本机环境别急着 mvn java -version mysql --version node -v npm -v这段命令不是走形式是让你在报错之前就知道自己站在什么地基上。JDK 输出里如果是 1.8 或 17 都行MySQL 低于 5.7 建议换Node 高于 16 的话前端依赖大概率要调。2.2 数据库初始化与配置修改源码包里一般带一个 sql 目录里面分两块若依基础表用户、角色、菜单、字典和固定资产业务表资产信息、领用记录、折旧记录等。导入顺序不能反业务表有外键或菜单关联依赖基础表。-- 先建库字符集用 utf8mb4别用 utf8 CREATE DATABASE asset_manage DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 再按顺序导入 -- 1. ry_2021xxxx.sql 若依基础表 -- 2. quartz.sql 定时任务表若依自带 -- 3. asset_xxxx.sql 固定资产业务表导入完成后改配置文件后端一般在application-druid.yml或application.yml里重点改数据库连接、Redis 地址、文件上传路径。固定资产模块如果带资产图片或附件上传路径要指向一个真实存在的目录否则新增资产时上传会静默失败日志里只有一行路径异常。spring: datasource: druid: url: jdbc:mysql://localhost:3306/asset_manage?useUnicodetruecharacterEncodingutf8serverTimezoneGMT%2B8 username: root password: 你的密码 redis: host: localhost port: 6379 password:serverTimezoneGMT%2B8这个参数别省资产折旧按日期算时区不对会导致折旧月份错位这种 bug 排查起来很费时间。2.3 前后端启动与首次登录后端启动类在ruoyi-admin模块下直接跑 main 方法或mvn spring-boot:run。前端分离版进ruoyi-ui目录先npm install再npm run dev。若依默认端口后端 8080前端 80 或 1024代理配置在vue.config.js里指向后端。# 后端 cd ruoyi-admin mvn clean package -DskipTests java -jar target/ruoyi-admin.jar # 前端 cd ruoyi-ui npm install --registryhttps://registry.npmmirror.com npm run dev首次登录用若依默认账号 admin/admin123进去后先看左侧菜单有没有“固定资产管理”这一组。如果没有说明业务菜单 sql 没导入或菜单权限没挂到角色上去“系统管理-菜单管理”里确认再在“角色管理”里给 admin 角色勾上。这一步是新手最容易卡住的地方代码跑起来了菜单不显示以为是前端问题其实是权限数据没配。3. 目录结构与核心模块拆解资产台账的数据是怎么流转的3.1 工程分层与固定资产模块的位置若依是多模块 Maven 工程固定资产业务代码通常落在ruoyi-system或独立建一个ruoyi-asset模块。分层是标准的 Controller-Service-Mapper 三层外加 domain 实体和 resources/mapper 下的 XML。ruoyi-admin └─ controller/asset/AssetInfoController.java 资产入口 ruoyi-system ├─ service/IAssetInfoService.java 业务接口 ├─ service/impl/AssetInfoServiceImpl.java 业务实现 ├─ mapper/AssetInfoMapper.java 数据访问 └─ domain/AssetInfo.java 实体 ruoyi-ui └─ src/views/asset/info/index.vue 资产列表页这个结构的好处是资产模块和若依自带的用户、角色模块完全解耦你改资产代码不会碰到权限核心。坏处是如果资产模块要引用部门、用户数据得通过若依已有的 service 去查不能自己再写一套用户表查询否则数据口径会分叉。3.2 资产新增的完整请求链路拿“新增资产”这条链路看一个请求从进入 Controller 到落库中间经过参数校验、业务编号生成、状态初始化、操作日志记录几个环节。RestController RequestMapping(/asset/info) public class AssetInfoController extends BaseController { Autowired private IAssetInfoService assetInfoService; PreAuthorize(ss.hasPermi(asset:info:add)) Log(title 资产信息, businessType BusinessType.INSERT) PostMapping public AjaxResult add(Validated RequestBody AssetInfo assetInfo) { // 资产编号由后端生成不信任前端传值 assetInfo.setAssetCode(assetInfoService.generateAssetCode()); // 初始状态置为在库 assetInfo.setStatus(0); assetInfo.setCreateBy(getUsername()); return toAjax(assetInfoService.insertAssetInfo(assetInfo)); } }PreAuthorize这行是权限校验asset:info:add这个权限标识必须和菜单表里的 perms 字段一致否则接口 403。Log是若依的操作日志注解会往sys_oper_log表写一条记录资产这种需要审计的场景建议保留。generateAssetCode()放在 service 里而不是前端生成是因为并发新增时前端生成的编号会撞后端可以用日期加序列或数据库自增兜底。3.3 领用与归还的状态机设计固定资产的核心不是增删改查是状态流转。一台资产从“在库”到“领用中”再到“在库”或“报废”每次流转都要留痕。源码里一般用一张asset_use_record表记录领用归还资产主表只存当前状态。Override Transactional(rollbackFor Exception.class) public int useAsset(Long assetId, String useUserId) { AssetInfo asset assetInfoMapper.selectAssetInfoById(assetId); // 只有在库状态才能领用防止重复领用 if (!0.equals(asset.getStatus())) { throw new ServiceException(该资产当前不可领用); } asset.setStatus(1); asset.setUseUserId(useUserId); assetInfoMapper.updateAssetInfo(asset); AssetUseRecord record new AssetUseRecord(); record.setAssetId(assetId); record.setUseUserId(useUserId); record.setUseTime(DateUtils.getNowDate()); return assetUseRecordMapper.insertRecord(record); }Transactional必须加状态更新和记录插入要么都成功要么都回滚否则会出现资产显示已领用但查不到领用人的黑匣子状态。状态值用字符串01而不是枚举是若依字典体系的习惯前端下拉框直接读字典数据改状态含义时只改字典不改代码。这种设计在资产种类多、状态扩展频繁的场景下比硬编码枚举灵活。3.4 折旧计算的定时任务接入折旧是固定资产区别于普通物品管理的点。源码里通常用若依自带的 Quartz 定时任务每月跑一次折旧计算把结果写进asset_depreciation表。Component(assetDepreciationTask) public class AssetDepreciationTask { Autowired private IAssetInfoService assetInfoService; public void calcMonthly() { // 查出所有未报废且未提足折旧的资产 ListAssetInfo list assetInfoService.selectDepreciableList(); for (AssetInfo asset : list) { BigDecimal monthly asset.getOriginalValue() .subtract(asset.getResidualValue()) .divide(new BigDecimal(asset.getUsefulLife()), 2, RoundingMode.HALF_UP); assetInfoService.recordDepreciation(asset.getId(), monthly); } } }usefulLife是使用月数residualValue是残值除的时候要指定精度和舍入方式不然 BigDecimal 除不尽会抛异常。定时任务在若依后台“定时任务”菜单里配置 cron 表达式比如每月 1 号凌晨跑任务调用目标写assetDepreciationTask.calcMonthly()。这里有个坑任务类必须注册成 Spring BeanComponent的 bean 名要和调用目标里写的一致否则任务执行时报找不到方法。4. 避坑与常见问题跑这套源码时最容易翻车的几个点4.1 菜单不显示或接口 403现象是登录后左侧没有固定资产菜单或者手动输 URL 能进页面但接口返回 403。原因基本是菜单 sql 没导入、菜单权限标识和 Controller 里的PreAuthorize对不上、或者角色没勾选新菜单。解决顺序是先查sys_menu表里有没有 asset 相关记录再核对 perms 字段和代码里的字符串是否完全一致最后去角色管理重新分配权限并让用户重新登录因为权限缓存存在 Redis 里不重登不刷新。4.2 资产编号重复导致新增失败现象是并发新增或批量导入时提示主键冲突或唯一索引报错。原因是编号生成逻辑放在前端或用时间戳同一毫秒内多次请求拿到相同值。解决是把生成逻辑收到后端 service用“前缀 日期 数据库序列”或直接依赖自增主键做业务编号并在asset_code字段上加唯一索引兜底让数据库帮你挡住重复。4.3 折旧金额算出来是负数或为零现象是某些资产每月折旧额为 0 甚至负数。原因通常是残值填得比原值还大或者使用月数填了 0除法时被除数为零。解决是在新增资产时做参数校验残值不能大于原值使用月数必须大于 0折旧计算前再判断一次“已提折旧 本月折旧是否超过应提总额”超过就按剩余可提金额封顶。4.4 文件上传成功但页面不显示现象是新增资产时上传了图片或附件保存成功但详情页图片裂开。原因是上传路径配的是相对路径实际文件存到了临时目录或者 Nginx 没配静态资源映射。解决是把上传路径配成绝对路径确认ruoyi.profile配置指向真实目录分离版部署时在 Nginx 里把/profile/映射到该目录本地开发则确认后端资源映射配置已生效。4.5 定时任务执行报找不到 bean现象是定时任务到点不跑日志里提示 target bean 不存在。原因是任务类没加Component或者 bean 名和调用目标字符串不一致也可能是任务类不在启动类扫描包路径下。解决是确认任务类在ruoyi-admin或ruoyi-system的扫描范围内bean 名显式指定调用目标写成beanName.methodName的形式改完重启后端再手动执行一次验证。5. 二次开发改造从能跑到能用的几个具体下手点5.1 先摸清字典和权限再动业务表拿到这套源码想加功能我建议第一件事不是写新 Controller而是把sys_dict_type和sys_dict_data里资产相关的字典项看一遍。资产分类、状态、来源这些下拉框都走字典你新增一个“资产状态”值改字典就行不用改前端代码。权限同理新加一个“资产导出”按钮先在菜单表加按钮权限再在 Controller 方法上加PreAuthorize(ss.hasPermi(asset:info:export))最后给角色勾上。跳过这一步直接写接口后面权限收口时会返工。5.2 用代码生成器加速新表接入若依自带代码生成器在“系统工具-代码生成”里导入新表配好字段类型和查询方式能直接生成 Controller、Service、Mapper、XML 和 Vue 页面。固定资产模块里如果要加“资产维修记录”这种新表用生成器出骨架再改业务逻辑比手写快很多。生成时注意把包路径指到资产模块下别生成到若依默认的 system 包否则模块边界会乱。生成配置示例 表名asset_repair_record 包路径com.ruoyi.asset 模块名asset 业务名repairRecord 功能名资产维修记录生成后重点改三处Service 实现里的业务校验、Controller 里的权限标识、Vue 页面里的字典回显字段。生成器给的是通用 CRUD资产维修这种有状态流转的表校验逻辑必须自己补。5.3 折旧逻辑的扩展与验证方法如果公司折旧政策不是直线法比如要支持双倍余额递减改AssetDepreciationTask里的计算方法就行但改完必须做一轮验证。我的习惯是造三条测试数据一条正常资产、一条残值接近原值的边界资产、一条已提足折旧的资产手动触发任务后核对asset_depreciation表里的累计折旧是否等于原值减残值。验证通过再配 cron别一上来就挂定时任务跑错了整月数据都要回滚。5.4 导出功能的性能注意点资产台账导出是高频需求若依的 Excel 导出用 EasyExcel 或 POI数据量上千条时要注意别一次性查全表再写。常见做法是分页查询后分批写或者限制单次导出条数并在前端提示。导出字段里如果有字典翻译别在循环里逐条查字典先把字典数据加载成 Map 再映射否则几千条数据会打出几千次查询接口直接超时。这套源码我拆下来最大的感受是若依的骨架很稳但固定资产的业务细节全在状态流转和折旧计算上这两块没有标准答案必须按自己公司的台账规则改。从那以后我每次接这类后台项目都先把字典、权限、状态机三样东西画在纸上再动代码省下来的返工时间比写代码的时间还多。希望帮到你。本文还有配套的精品资源点击获取