在企业实物资产管理领域,传统的手工台账和零散的Excel记录方式长期制约着管理效率的提升。数据更新滞后、盘点过程繁琐、资产流失与重复购置等问题频发,亟需一套集成的数字化解决方案来应对资产全生命周期管理的挑战。本文介绍的企业资产全生命周期管控平台正是基于这一背景,采用经典的SSH(Struts2 + Spring + Hibernate)框架构建,实现了从资产采购、入库、领用、维修、调拨到报废的全流程数字化管理。
系统架构与技术栈选型
该平台采用典型的三层架构设计,每一层都选用了成熟的JavaEE技术框架,确保了系统的稳定性、可维护性和扩展性。
表现层使用Struts2框架,通过配置struts.xml文件定义请求与Action的映射关系。Struts2的拦截器机制有效处理了通用逻辑,如权限验证、字符编码转换和异常处理,同时其标签库简化了JSP页面的开发。
<!-- struts.xml 配置片段 -->
<action name="asset_*" class="assetAction" method="{1}">
<result name="success">/pages/asset/asset_list.jsp</result>
<result name="input">/pages/asset/asset_edit.jsp</result>
<result name="error">/common/error.jsp</result>
</action>
业务逻辑层由Spring框架统一管理。通过依赖注入(DI)容器,所有Service组件和DAO组件实现了松耦合。Spring的声明式事务管理为资产的关键操作提供了数据一致性保障。
// AssetService 接口定义核心业务方法
public interface AssetService {
PageBean<Asset> findAssetByPage(int pageNo, int pageSize, Map<String, Object> params);
void saveAsset(Asset asset) throws BusinessException;
void updateAssetStatus(Long assetId, String status, Long operatorId);
List<Asset> findAssetsForRepair();
}
// Spring 配置事务管理
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
数据持久层采用Hibernate实现ORM映射。通过配置实体类的映射文件,将Java对象与数据库表关联,简化了CRUD操作。Hibernate的HQL(Hibernate Query Language)支持复杂的多表查询,如联查资产、所属部门和当前使用人信息。
// AssetDAO 使用HibernateTemplate进行数据操作
@Repository
public class AssetDAOImpl extends HibernateDaoSupport implements AssetDAO {
public PageBean<Asset> findByPage(int pageNo, int pageSize, DetachedCriteria criteria) {
PageBean<Asset> pageBean = new PageBean<>(pageNo, pageSize);
// 查询总记录数
criteria.setProjection(Projections.rowCount());
List<?> countList = getHibernateTemplate().findByCriteria(criteria);
Long totalCount = (Long) countList.get(0);
pageBean.setTotalCount(totalCount.intValue());
// 查询分页数据
criteria.setProjection(null);
criteria.setResultTransformer(Criteria.ROOT_ENTITY);
List<Asset> assetList = (List<Asset>) getHibernateTemplate().findByCriteria(criteria,
(pageNo - 1) * pageSize, pageSize);
pageBean.setRecordList(assetList);
return pageBean;
}
public List<Asset> findAssetsByCondition(String assetName, Long departmentId, String status) {
String hql = "FROM Asset a LEFT JOIN FETCH a.department LEFT JOIN FETCH a.employee WHERE 1=1";
Map<String, Object> params = new HashMap<>();
if (StringUtils.isNotBlank(assetName)) {
hql += " AND a.assetName LIKE :assetName";
params.put("assetName", "%" + assetName + "%");
}
if (departmentId != null) {
hql += " AND a.department.id = :departmentId";
params.put("departmentId", departmentId);
}
if (StringUtils.isNotBlank(status)) {
hql += " AND a.status = :status";
params.put("status", status);
}
return getHibernateTemplate().findByNamedParam(hql, params);
}
}
数据库设计深度解析
系统数据库共设计6张核心表,以下是其中关键表的结构分析:
固定资产表(fixed_asset) 作为核心业务表,采用严谨的字段设计确保资产信息的完整性:
CREATE TABLE fixed_asset (
asset_id BIGINT PRIMARY KEY AUTO_INCREMENT,
asset_code VARCHAR(50) UNIQUE NOT NULL COMMENT '资产编码',
asset_name VARCHAR(100) NOT NULL COMMENT '资产名称',
asset_type VARCHAR(50) NOT NULL COMMENT '资产类型',
specification VARCHAR(200) COMMENT '规格型号',
purchase_date DATE NOT NULL COMMENT '购置日期',
purchase_price DECIMAL(15,2) NOT NULL COMMENT '购置价格',
current_value DECIMAL(15,2) COMMENT '当前估值',
useful_life INT COMMENT '使用年限',
depreciation_method VARCHAR(20) COMMENT '折旧方法',
status VARCHAR(20) DEFAULT '在库' COMMENT '资产状态',
location VARCHAR(100) COMMENT '存放地点',
department_id BIGINT COMMENT '所属部门',
employee_id BIGINT COMMENT '使用人',
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (department_id) REFERENCES department(dept_id),
FOREIGN KEY (employee_id) REFERENCES employee(emp_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='固定资产表';
该表设计的亮点在于:
- 资产全生命周期追踪:通过
status字段记录资产从"在库"、"领用中"、"维修中"到"报废"的状态流转 - 财务信息完整性:包含购置价格、当前估值、使用年限和折旧方法,为资产折旧计算提供数据基础
- 空间与组织关联:通过
department_id和employee_id外键关联,明确资产的责任归属
资产维修记录表(asset_repair) 体现了维修管理的精细化设计:
CREATE TABLE asset_repair (
repair_id BIGINT PRIMARY KEY AUTO_INCREMENT,
asset_id BIGINT NOT NULL COMMENT '维修资产',
repair_date DATE NOT NULL COMMENT '报修日期',
repair_reason TEXT NOT NULL COMMENT '报修原因',
repair_cost DECIMAL(10,2) COMMENT '维修费用',
repair_status VARCHAR(20) DEFAULT '待处理' COMMENT '维修状态',
completed_date DATE COMMENT '完成日期',
repair_notes TEXT COMMENT '维修备注',
created_by BIGINT COMMENT '登记人',
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (asset_id) REFERENCES fixed_asset(asset_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资产维修记录表';
该表设计的特色包括:
- 维修流程状态管理:通过
repair_status跟踪维修进度(待处理、维修中、已完成) - 成本控制支持:
repair_cost字段记录每次维修的费用,为维修成本分析提供数据 - 时间维度完整:记录报修日期和完成日期,便于计算维修周期和效率分析
核心功能模块深度解析
1. 资产信息综合管理
资产信息管理模块实现了对固定资产的全面管控,支持资产的增删改查、状态变更和详细信息维护。

核心实现代码展示了资产查询和分页处理的业务逻辑:
// AssetAction 处理资产相关请求
public class AssetAction extends BaseAction {
private AssetService assetService;
private Integer pageNo = 1;
private Integer pageSize = 10;
private Map<String, Object> conditionMap = new HashMap<>();
private PageBean<Asset> pageBean;
public String list() {
try {
// 构建查询条件
if (StringUtils.isNotBlank(asset.getAssetName())) {
conditionMap.put("assetName", asset.getAssetName());
}
if (asset.getDepartment() != null && asset.getDepartment().getDeptId() != null) {
conditionMap.put("departmentId", asset.getDepartment().getDeptId());
}
if (StringUtils.isNotBlank(asset.getStatus())) {
conditionMap.put("status", asset.getStatus());
}
pageBean = assetService.findAssetByPage(pageNo, pageSize, conditionMap);
return SUCCESS;
} catch (Exception e) {
addActionError("查询资产信息失败:" + e.getMessage());
return ERROR;
}
}
public String save() {
try {
if (asset.getAssetId() == null) {
assetService.saveAsset(asset);
addActionMessage("资产信息添加成功");
} else {
assetService.updateAsset(asset);
addActionMessage("资产信息更新成功");
}
return list();
} catch (BusinessException e) {
addActionError(e.getMessage());
return INPUT;
}
}
}
资产状态变更服务方法确保了业务规则的执行:
@Service
@Transactional
public class AssetServiceImpl implements AssetService {
public void updateAssetStatus(Long assetId, String status, Long operatorId) {
Asset asset = assetDAO.get(assetId);
if (asset == null) {
throw new BusinessException("资产不存在");
}
// 状态流转验证
if ("报废".equals(status) && !"在库".equals(asset.getStatus())) {
throw new BusinessException("只有库存资产才能报废");
}
String oldStatus = asset.getStatus();
asset.setStatus(status);
asset.setUpdatedTime(new Date());
// 记录状态变更日志
AssetStatusLog statusLog = new AssetStatusLog();
statusLog.setAsset(asset);
statusLog.setOldStatus(oldStatus);
statusLog.setNewStatus(status);
statusLog.setOperator(employeeDAO.get(operatorId));
statusLog.setOperateTime(new Date());
assetStatusLogDAO.save(statusLog);
assetDAO.update(asset);
}
}
2. 资产维修流程管理
维修管理模块实现了从报修登记、维修分配到完成确认的全流程数字化管理。

维修记录的业务逻辑处理:
// RepairAction 处理维修相关业务
public class RepairAction extends BaseAction {
private AssetRepair repair;
private List<Asset> needRepairAssets;
public String needRepairList() {
needRepairAssets = assetService.findAssetsForRepair();
return SUCCESS;
}
public String saveRepair() {
try {
// 验证资产状态
Asset asset = assetService.getAssetById(repair.getAsset().getAssetId());
if (!"使用中".equals(asset.getStatus())) {
addActionError("只有使用中的资产才能报修");
return INPUT;
}
repair.setRepairStatus("待处理");
repair.setCreatedBy(getCurrentUser());
repair.setCreatedTime(new Date());
repairService.saveRepairRecord(repair);
// 更新资产状态
assetService.updateAssetStatus(asset.getAssetId(), "维修中", getCurrentUser().getEmpId());
addActionMessage("维修记录添加成功");
return list();
} catch (Exception e) {
addActionError("保存维修记录失败:" + e.getMessage());
return ERROR;
}
}
}
维修状态更新的服务层实现:
@Service
@Transactional
public class RepairServiceImpl implements RepairService {
public void updateRepairStatus(Long repairId, String status, BigDecimal cost, String notes) {
AssetRepair repair = repairDAO.get(repairId);
if (repair == null) {
throw new BusinessException("维修记录不存在");
}
repair.setRepairStatus(status);
if ("已完成".equals(status)) {
repair.setCompletedDate(new Date());
if (cost != null) {
repair.setRepairCost(cost);
}
}
if (StringUtils.isNotBlank(notes)) {
repair.setRepairNotes(notes);
}
repairDAO.update(repair);
// 如果维修完成,恢复资产状态
if ("已完成".equals(status)) {
Asset asset = repair.getAsset();
assetService.updateAssetStatus(asset.getAssetId(), "在库", getCurrentOperatorId());
}
}
}
3. 员工与部门信息管理
系统通过员工和部门管理模块建立完整的组织架构,为资产分配和责任界定提供基础。

员工信息管理的核心代码:
// EmployeeAction 处理员工相关操作
public class EmployeeAction extends BaseAction {
private Employee employee;
private Long deptId;
private List<Department> departmentList;
public String list() {
try {
Map<String, Object> params = new HashMap<>();
if (deptId != null) {
params.put("departmentId", deptId);
}
pageBean = employeeService.findEmployeeByPage(pageNo, pageSize, params);
departmentList = departmentService.findAllDepartments();
return SUCCESS;
} catch (Exception e) {
addActionError("查询员工信息失败:" + e.getMessage());
return ERROR;
}
}
public String save() {
try {
if (employee.getDepartment() != null && employee.getDepartment().getDeptId() != null) {
Department dept = departmentService.getDepartmentById(employee.getDepartment().getDeptId());
employee.setDepartment(dept);
}
if (employee.getEmpId() == null) {
// 新员工设置默认密码
employee.setPassword(DigestUtils.md5Hex("123456"));
employee.setCreateTime(new Date());
employeeService.saveEmployee(employee);
addActionMessage("员工信息添加成功");
} else {
employee.setUpdateTime(new Date());
employeeService.updateEmployee(employee);
addActionMessage("员工信息更新成功");
}
return list();
} catch (Exception e) {
addActionError("保存员工信息失败:" + e.getMessage());
return INPUT;
}
}
}
4. 资产借还与调拨管理
资产借还管理实现了资产的流动追踪,确保每次资产转移都有明确记录。

借还业务的核心服务逻辑:
@Service
@Transactional
public class BorrowServiceImpl implements BorrowService {
public void borrowAsset(BorrowRecord borrowRecord) {
Asset asset = assetDAO.get(borrowRecord.getAsset().getAssetId());
Employee borrower = employeeDAO.get(borrowRecord.getBorrower().getEmpId());
// 验证资产可借状态
if (!"在库".equals(asset.getStatus())) {
throw new BusinessException("该资产当前不可借出");
}
// 创建借阅记录
borrowRecord.setBorrowDate(new Date());
borrowRecord.setExpectedReturnDate(calculateExpectedReturnDate());
borrowRecord.setActualReturnDate(null);
borrowRecord.setRecordStatus("借出中");
borrowRecord.setCreatedTime(new Date());
borrowDAO.save(borrowRecord);
// 更新资产状态和使用人
asset.setStatus("借出中");
asset.setEmployee(borrower);
asset.setUpdatedTime(new Date());
assetDAO.update(asset);
}
public void returnAsset(Long borrowId, String returnCondition) {
BorrowRecord borrowRecord = borrowDAO.get(borrowId);
if (borrowRecord == null) {
throw new BusinessException("借阅记录不存在");
}
Asset asset = borrowRecord.getAsset();
// 更新借阅记录
borrowRecord.setActualReturnDate(new Date());
borrowRecord.setReturnCondition(returnCondition);
borrowRecord.setRecordStatus("已归还");
// 恢复资产状态
asset.setStatus("在库");
asset.setEmployee(null); // 清空使用人
asset.setUpdatedTime(new Date());
borrowDAO.update(borrowRecord);
assetDAO.update(asset);
}
}
实体域模型设计
系统采用面向对象的设计思想,通过Hibernate实体映射建立完整的领域模型:
// 固定资产实体类
@Entity
@Table(name = "fixed_asset")
public class Asset implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long assetId;
@Column(unique = true, nullable = false, length = 50)
private String assetCode;
@Column(nullable = false, length = 100)
private String assetName;
@Enumerated(EnumType.STRING)
@Column(length = 20)
private AssetStatus status;
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
@ManyToOne
@JoinColumn(name = "employee_id")
private Employee employee;
@Temporal(TemporalType.DATE)
private Date purchaseDate;
@Column(precision = 15, scale = 2)
private BigDecimal purchasePrice;
@OneToMany(mappedBy = "asset", cascade = CascadeType.ALL)
private Set<AssetRepair> repairs = new HashSet<>();
@OneToMany(mappedBy = "asset", cascade = CascadeType.ALL)
private Set<BorrowRecord> borrowRecords = new HashSet<>();
// getter/setter方法
}
// 资产状态枚举定义
public enum AssetStatus {
IN_STOCK("在库"),
IN_USE("使用中"),
UNDER_REPAIR("维修中"),
BORROWED("借出