简介:固定资产管理系统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:
| 字段名 | 类型 | 含义 |
|---|---|---|
| id | bigint | 主键 |
| asset_code | varchar(50) | 资产编号,业务唯一 |
| asset_name | varchar(100) | 资产名称 |
| category_id | bigint | 分类ID,关联分类表 |
| dept_id | bigint | 所属部门 |
| manager_user_id | bigint | 责任人 |
| original_value | decimal(12,2) | 原值 |
| net_value | decimal(12,2) | 净值 |
| status | tinyint | 0在库、1已领用、2维修中、3已报废 |
| purchase_date | date | 购入日期 |
| location | varchar(100) | 存放地点 |
| remark | varchar(255) | 备注 |
领用归还记录表 asset_record:
| 字段名 | 类型 | 含义 |
|---|---|---|
| id | bigint | 主键 |
| asset_id | bigint | 资产ID |
| user_id | bigint | 操作人(领用人) |
| record_type | tinyint | 1领用、2归还、3借用、4借还 |
| operate_date | datetime | 操作时间 |
| remark | varchar(255) | 备注 |
两个设计细节值得注意:status 用 tinyint 而不是字符串,是为了统计时能直接 sum 和 group by,性能更好;资产编号不直接用自增 ID,而是用“分类前缀+年月+流水号”,比如 BG-202501-001,因为线下贴标签、扫码盘点要求编号有可读性。
3. 部署启动:从源码包到能点开登录页
3.1 环境清单与版本约束
固定资产管理系统属于典型企业级单体应用,环境要求不复杂:
- JDK 1.8(部分源码基于 javax 命名空间,高版本 JDK 可能遇到兼容问题)
- Maven 3.6+
- MySQL 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?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/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,否则插入中文会乱码;serverTimezone=Asia/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 id="selectByCondition" resultMap="AssetResultMap"> SELECT * FROM asset_info <where> <if test="deptId != null"> AND dept_id = #{deptId} </if> <if test="categoryId != null"> AND category_id = #{categoryId} </if> <if test="status != null"> AND status = #{status} </if> <if test="startDate != null"> AND purchase_date >= #{startDate} </if> <if test="endDate != null"> AND purchase_date <= #{endDate} </if> </where> ORDER BY purchase_date DESC </select>逻辑说明:<where>标签自动处理前导 AND,传空条件时不会生成多余的 WHERE 关键字;每个 if 单独判断,用户勾选哪个条件就拼接哪个条件。特别注意<号在 XML 里要写成<,否则 XML 解析会直接报错,这是 MyBatis XML 里最常见的低级错误。
4.4 折旧计算:直线法还是按年摊销
固定资产系统里折旧大部分是直线法:月折旧额 =(原值 - 残值)/ 使用月数。源码里通常有一个定时任务或者月度报表触发折旧计算:
List<AssetInfo> 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 认证插件,客户端第一次连接时需要请求服务端公钥,而连接参数里没有允许自动获取。
解决:在数据库连接串后面加 allowPublicKeyRetrieval=true,或者把认证方式改回 mysql_native_password。我一般直接用前者:
url: jdbc:mysql://localhost:3306/fixed_asset?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true5.2 登录页图片和样式全部丢失
现象:登录页能打开但没有任何样式,控制台一片 404。
原因:项目配置了静态资源拦截,或者部署时把前端静态目录放在了错误位置。Spring Boot 默认静态资源在 classpath:/static/ 下,如果打包时 resources 目录没被识别,页面引用的 css/js 全部失效。
解决:打开 target 目录,确认静态文件有没有进到 classpath 里;没有就检查 pom.xml 的 resources 配置,或者把静态资源放到 src/main/resources/static 下重新打包。
5.3 盘点时把“报废”也算进盘亏
现象:盘点差异报表出现大量盘亏,逐条核对发现都是已报废资产。
原因:盘点对账 SQL 只 join 了资产表和盘点明细表,没有过滤 status=3 的资产。报废资产不参与实物盘点,统计时必须排除。
解决:在盘点差异查询里加过滤条件:
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,再抽查几条资产的状态流转记录,确认无误才把账号交给业务方。这种习惯帮我挡掉了好几次上线后的返工。希望帮到你。
本文还有配套的精品资源,点击获取