固定资产管理系统Java源码:基于Spring Boot+MyBatis的全生命周期实战
简介固定资产管理系统Java项目源码压缩包适合有一定Java Web基础的开发者学习以及企业用于固定资产信息化管理参考。系统基于Java技术开发涵盖资产增删改查、库存与生命周期管理等核心功能默认使用SQL Server同时可通过ODBC配置接入MySQL、Oracle等数据库具备良好跨平台性与扩展性。压缩包共606个文件大小8.73MB主要包含131个Java源文件、59个JSP页面、177个Class编译文件、42个Jar依赖包以及JSP标签库描述文件、HTML静态页面、XML配置文件和项目架构说明PPTX等便于对照源码理解前后端交互与业务逻辑。已有1686人学习下载。配套PPTX中梳理了系统架构、数据库表结构与ODBC连接配置步骤可帮助快速搭建环境、进行二次开发。这套资源既能作为Java Web项目练习的完整案例也可作为资产管理系统定制开发的起点适合学习者与中小企业IT人员使用。1. 固定资产管理系统 Java 项目源码它解决的是台账与实物的脱节财务拿着 Excel 台账去库房盘点编号对不上、领用人没登记、报废单压在抽屉里这就是固定资产管理最常见的痛点。这套固定资产管理系统 Java 项目源码把资产从入库登记、分类建档、领用归还、维修报废到盘点统计的全生命周期做成了一套可运行的 Web 应用核心价值是让每一笔资产去向都有记录、每一条状态流转都有时间线。它适合三类人想用完整案例练习企业级开发流程的初学者需要快速给内部交付一套资产工具的在职开发者以及准备课设但不想从零搭框架的学生。拿到手先看数据库脚本和业务模块划分再跑起来改参数基本半天就能进入状态。2. 技术选型与模块拆解为什么这套组合扛得住资产场景2.1 技术栈选型逻辑Spring Boot 把集成成本压到了最低这套源码的典型技术栈是 Spring Boot MyBatis MySQL权限用拦截器实现前端以模板页为主。为什么不是 SSH资产业务没有复杂分布式需求单机能解决的问题不需要引入微服务为什么不用 JPA资产台账的查询条件太多——按部门、按分类、按状态、按时间范围、按金额区间MyBatis 的动态 SQL 能精准控制每一条查询语句比 JPA 自动生成的查询更可控。层技术职责前端Thymeleaf 模板 JQuery表单页、列表页、移动端适配少表现层Spring MVC Controller参数接收与校验业务层Service 事务注解状态流转、审批数据层MyBatis Mapper动态 SQL、多条件查询数据库MySQL 5.7 / 8.0资产台账及相关台账这套组合最大的优势在“老项目可维护”MyBatis 的 SQL 是明文写出来的接手的人不用猜框架自动做了什么出问题时直接看 SQL 就能定位。另一个隐性优势是部署轻打成一个可执行 JAR 就能跑对于只有一台服务器的中小团队运维成本非常低。2.2 六大功能模块拆解资产生命周期被拆成了哪几步源码里的功能大致划分为六个模块理解了这个划分就等于掌握了整份代码的阅读地图。资产分类管理树形结构通常支持两级或三级分类比如“办公设备-电脑-笔记本”。分类变动会影响台账的统计口径所以源码里对删除操作一般会做子节点校验。资产台账管理核心模块。每一条资产记录包含资产编号、名称、分类、原值、净值、存放地点、责任人、购入日期等字段。这里最需要注意的是资产编号的唯一性后续的领用、盘点、折旧都靠编号定位。领用与归还管理资产的“状态变更通道”领用时把资产状态从在库改为已领用归还是逆操作。如果系统还支持借出会有独立的借用记录表。维修与报废管理维修记录会累加在资产档案里报废不是直接删除而是把状态改为已报废并保留历史记录这是资产系统与普通增删改查系统的核心区别。盘点管理按批次生成盘点任务录入实盘结果后与台账对账输出盘盈盘亏明细。报表统计资产总额按部门/分类汇总、本月新增/减少、折旧明细表。报表模块的 SQL 占据了源码的大部分篇幅也是最有复用价值的部分。权限划分一般分为三层管理员管用户和全部模块资产专员负责登记、审批领用、执行盘点普通员工只能看自己名下的资产并发起领用申请。2.3 数据库表设计几张核心表把业务串起来不看表结构直接读代码会非常吃力。我从源码里抽取了核心表的关键字段理解了这几张表业务逻辑就能对号入座。资产表 asset_info字段名类型含义idbigint主键asset_codevarchar(50)资产编号业务唯一asset_namevarchar(100)资产名称category_idbigint分类ID关联分类表dept_idbigint所属部门manager_user_idbigint责任人original_valuedecimal(12,2)原值net_valuedecimal(12,2)净值statustinyint0在库、1已领用、2维修中、3已报废purchase_datedate购入日期locationvarchar(100)存放地点remarkvarchar(255)备注领用归还记录表 asset_record字段名类型含义idbigint主键asset_idbigint资产IDuser_idbigint操作人领用人record_typetinyint1领用、2归还、3借用、4借还operate_datedatetime操作时间remarkvarchar(255)备注两个设计细节值得注意status 用 tinyint 而不是字符串是为了统计时能直接 sum 和 group by性能更好资产编号不直接用自增 ID而是用“分类前缀年月流水号”比如 BG-202501-001因为线下贴标签、扫码盘点要求编号有可读性。3. 部署启动从源码包到能点开登录页3.1 环境清单与版本约束固定资产管理系统属于典型企业级单体应用环境要求不复杂JDK 1.8部分源码基于 javax 命名空间高版本 JDK 可能遇到兼容问题Maven 3.6MySQL 5.7 或 8.0开发工具随便选只要能导入 Maven 工程先用命令确认本地环境java -version mvn -version mysql --version如果 java 版本高于 1.8建议先装一个 JDK 8 并切换默认版本。常见的做法是用 IDE 的切换功能或者直接改环境变量。这里多花五分钟能省掉后面一堆编译报错。3.2 数据库初始化与配置改动源码包一般会带一个 sql 目录里面是建库脚本比如固定资产.sql。连接数据库执行脚本mysql -uroot -p 固定资产.sql执行完可以用一条命令快速确认表是否建全SHOW TABLES;下一步改后端配置。找到 resources 目录下的 application.yml或者 application.properties需要重点修改四个参数spring: datasource: url: jdbc:mysql://localhost:3306/fixed_asset?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver servlet: multipart: max-file-size: 10MB max-request-size: 20MB server: port: 8080参数说明url 里必须带 useUnicode 和 characterEncoding否则插入中文会乱码serverTimezoneAsia/Shanghai 是 MySQL 8.x 的强制要求5.7 可以不带但建议带上multipart 配置限制上传图片大小资产照片在这里起作用。3.3 启动与验证命令行三步走进入项目根目录执行mvn spring-boot:run如果日志出现Started关键字说明启动成功。如果只想后台跑先打包再执行mvn clean package -DskipTests java -jar target/fixed-asset-0.0.1-SNAPSHOT.jar启动完成后浏览器访问http://localhost:8080/login能看到登录页说明部署成功。如果在服务器上部署需要把数据库地址改为远程库地址并在安全组放行 8080 端口。登录后先不做任何操作直接看菜单是否完整、页面是否能取到数据这一步能排除 90% 的前后端联通问题。4. 上手改代码资产登记与状态流转的四个关键点4.1 资产登记一条完整链路从 Controller 到 Mapper最常见的改造需求是调整资产必填字段。以新增资产为例控制层代码长这样PostMapping(/asset/add) ResponseBody public Result addAsset(RequestBody AssetInfo asset) { // 1. 校验资产编号是否重复 if (assetMapper.countByCode(asset.getAssetCode()) 0) { return Result.error(资产编号已存在); } // 2. 初始化状态和时间 asset.setStatus(0); asset.setCreateTime(new Date()); // 3. 入库 assetMapper.insert(asset); return Result.success(); }逻辑说明countByCode 先做唯一性校验阻止重复资产编号状态初始化为 0在库新登记的资产默认未领用createTime 由后端补全不信任前端传值。如果你要加字段比如增加“供应商”和“质保到期日期”需要同时改三处AssetInfo 实体类、Mapper 里的 insert 和 resultMap、前端新增表单页的输入框。漏掉任何一处要么编译不过要么新增的数据存不进去。4.2 领用与归还状态流转的约束放在哪里资产业务最容易出的 bug 就是把状态改乱了——已报废的资产被再次领用还在维修中的资产被归还。正确的做法是在 Service 层校验状态Transactional public Result useAsset(Long assetId, Long userId) { AssetInfo asset assetMapper.selectById(assetId); // 状态必须在库才能领用 if (asset.getStatus() ! 0) { return Result.error(当前状态不可领用); } // 写入领用记录 AssetRecord record new AssetRecord(); record.setAssetId(assetId); record.setUserId(userId); record.setRecordType(1); record.setOperateDate(new Date()); assetRecordMapper.insert(record); // 更新资产状态 assetMapper.updateStatus(assetId, 1); return Result.success(); }逻辑说明Transactional 保证记录写入和状态更新要么都成功要么都失败避免出现领用记录写了但状态没改的脏数据状态校验放在更新之前相当于一道业务层拦截。归还的逻辑是镜像操作先判断状态是否为 1再写归还记录最后把状态改回 0。这里有一个常见的偷懒写法直接在 Controller 里操作状态不校验也不开事务。小项目看不出问题一旦并发操作同一台资产就会产生两边都领用成功的脏数据。4.3 多条件组合查询MyBatis 动态 SQL 的正确姿势资产列表页支持按部门、分类、状态、购入日期范围联合查询。源码里的典型写法是select idselectByCondition resultMapAssetResultMap SELECT * FROM asset_info where if testdeptId ! null AND dept_id #{deptId} /if if testcategoryId ! null AND category_id #{categoryId} /if if teststatus ! null AND status #{status} /if if teststartDate ! null AND purchase_date gt; #{startDate} /if if testendDate ! null AND purchase_date lt; #{endDate} /if /where ORDER BY purchase_date DESC /select逻辑说明where标签自动处理前导 AND传空条件时不会生成多余的 WHERE 关键字每个 if 单独判断用户勾选哪个条件就拼接哪个条件。特别注意号在 XML 里要写成lt;否则 XML 解析会直接报错这是 MyBatis XML 里最常见的低级错误。4.4 折旧计算直线法还是按年摊销固定资产系统里折旧大部分是直线法月折旧额 原值 - 残值/ 使用月数。源码里通常有一个定时任务或者月度报表触发折旧计算ListAssetInfo list assetMapper.selectNeedDepreciation(); for (AssetInfo asset : list) { BigDecimal monthly asset.getOriginalValue() .subtract(asset.getResidualValue()) .divide(new BigDecimal(asset.getMonths()), 2, RoundingMode.HALF_UP); asset.setNetValue(asset.getNetValue().subtract(monthly)); assetMapper.updateNetValue(asset); }逻辑说明selectNeedDepreciation 只捞满足折旧条件的资产避免每台都算一遍RoundingMode.HALF_UP 统一四舍五入防止浮点数误差净值不能小于残值这个边界判断在工业级实现里必须加否则几年后净值会算成负数。5. 避坑指南这套源码常见的五个翻车点5.1 MySQL 8.x 连不上报 Public Key Retrieval is not allowed现象启动后第一次访问接口就报 SQLNonTransientConnectionException连接被拒绝。原因MySQL 8.x 默认使用 caching_sha2_password 认证插件客户端第一次连接时需要请求服务端公钥而连接参数里没有允许自动获取。解决在数据库连接串后面加 allowPublicKeyRetrievaltrue或者把认证方式改回 mysql_native_password。我一般直接用前者url: jdbc:mysql://localhost:3306/fixed_asset?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue5.2 登录页图片和样式全部丢失现象登录页能打开但没有任何样式控制台一片 404。原因项目配置了静态资源拦截或者部署时把前端静态目录放在了错误位置。Spring Boot 默认静态资源在 classpath:/static/ 下如果打包时 resources 目录没被识别页面引用的 css/js 全部失效。解决打开 target 目录确认静态文件有没有进到 classpath 里没有就检查 pom.xml 的 resources 配置或者把静态资源放到 src/main/resources/static 下重新打包。5.3 盘点时把“报废”也算进盘亏现象盘点差异报表出现大量盘亏逐条核对发现都是已报废资产。原因盘点对账 SQL 只 join 了资产表和盘点明细表没有过滤 status3 的资产。报废资产不参与实物盘点统计时必须排除。解决在盘点差异查询里加过滤条件WHERE a.status ! 35.4 权限拦截器把登录页也拦截了现象启动后访问 /login 直接被重定向到 401 页面登录都进不去。原因拦截器里写了拦全部路径的规则忘了放行登录接口和静态资源。常见的是放行了 /login 但没放行 /css、/js、/images。解决拦截器注册处增加放行列表registry.addInterceptor(authInterceptor) .addPathPatterns(/**) .excludePathPatterns(/login, /css/**, /js/**, /images/**);5.5 资产编号在并发场景下重复现象两个用户同时提交新增资产编号都生成了 BG-202501-001后插入的那条被唯一索引挡住。原因编号生成逻辑是“查询当前最大编号再加一”并发时两个请求查到同一个最大值。解决稳妥的做法是先 insert 拿到自增 ID再结合日期和 ID 生成业务编号回写assetMapper.insert(asset); String code BG- new SimpleDateFormat(yyyyMM).format(new Date()) - String.format(%04d, asset.getId()); asset.setAssetCode(code); assetMapper.updateCode(asset);6. 结尾技巧一条 SQL 核对本月折旧与盘点差异资产系统的上线验收重点不是页面能打开而是数据的一致性。我实践下来最有效的核对方式是两条 SQL比任何页面验证都快。第一条核对本月折旧是否漏算SELECT SUM(original_value) AS total_original, SUM(net_value) AS total_net FROM asset_info WHERE status ! 3;把上月底的净值总额、本月新增原值、本月报废原值拿出来手工算一下“上月末净值 - 本月折旧 本月新增原值 - 本月报废原值 本月末净值”对不上就说明折旧任务有遗漏或重复执行。第二条盘点差异检查SELECT a.asset_code, a.asset_name, a.status, i.quantity AS actual_qty, CASE WHEN i.quantity IS NULL THEN 盘亏 WHEN i.quantity 1 THEN 盘盈 ELSE 一致 END AS check_result FROM asset_info a LEFT JOIN inventory_result i ON a.asset_code i.asset_code WHERE a.status ! 3 ORDER BY check_result DESC;这条 SQL 会把所有未报废资产和盘点结果做左连接盘点表里没有的即为盘亏多出来的即为盘盈。跑完直接导出 Excel 就是一张可汇报的差异清单。从那以后我每次部署固定资产系统上线前都强制走一遍折旧核对 SQL再抽查几条资产的状态流转记录确认无误才把账号交给业务方。这种习惯帮我挡掉了好几次上线后的返工。希望帮到你。本文还有配套的精品资源点击获取