1. 项目概述
固定资产转移管理系统是企业资产管理中的重要一环,它解决了传统纸质审批流程效率低下、资产状态更新不及时、历史记录难以追溯等痛点。我们基于SpringBoot和Vue框架开发了一套完整的解决方案,实现了从资产信息录入、转移申请、多级审批到报表统计的全流程数字化管理。
这个系统特别适合中大型企业、事业单位和高校等拥有大量固定资产的机构使用。通过前后端分离的架构设计,后端提供稳定可靠的业务逻辑处理,前端则带来流畅的用户体验。我在实际开发过程中发现,这种技术组合既能保证系统性能,又能快速响应业务需求的变化。
2. 技术选型与架构设计
2.1 后端技术栈
我们选择SpringBoot 2.7.18作为后端框架,主要考虑因素包括:
- 自动配置特性大幅减少了XML配置
- 内嵌Tomcat服务器简化了部署流程
- 丰富的Starter依赖可以快速集成常用组件
- 社区活跃度高,遇到问题容易找到解决方案
数据库选用MySQL 8.0,主要基于以下考量:
- 事务支持完善,确保资产转移过程中的数据一致性
- 对JSON类型的良好支持,便于存储动态字段
- 成熟的备份和恢复机制
权限控制采用Spring Security + JWT方案,实现了:
- 基于角色的访问控制(RBAC)
- 无状态的认证机制
- 细粒度的接口权限控制
2.2 前端技术栈
Vue 3的组合式API让我们能够更灵活地组织前端代码逻辑。配合Vite构建工具,开发体验和构建速度都有显著提升。实际开发中,我们特别看重:
- 响应式系统的性能优化
- Composition API带来的更好代码组织
- 更小的打包体积
UI组件库选择了Element Plus,因为它:
- 提供了丰富的企业级组件
- 主题定制方便
- 文档完善,社区资源丰富
2.3 系统架构图
整个系统采用经典的三层架构:
code复制表现层(Vue) ↔ 业务逻辑层(SpringBoot) ↔ 数据访问层(MySQL)
↑
缓存层(Redis)
这种架构的优点是各层职责明确,便于团队协作和维护。我们在实际开发中还加入了以下优化:
- 使用Redis缓存高频访问的资产分类数据
- 采用Nginx作为静态资源服务器和反向代理
- 通过Docker容器化部署保证环境一致性
3. 核心功能实现
3.1 资产管理模块
资产信息管理是系统的基础功能,我们实现了:
- 资产信息CRUD操作
- 批量导入导出
- 资产状态追踪
在数据库设计上,asset表的关键字段包括:
sql复制CREATE TABLE `asset` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`category_id` int NOT NULL COMMENT '资产分类',
`specification` json DEFAULT NULL COMMENT '规格参数',
`purchase_date` date DEFAULT NULL,
`price` decimal(12,2) DEFAULT NULL,
`status` enum('IDLE','IN_USE','SCRAPPED') DEFAULT 'IDLE',
`current_department` varchar(50) DEFAULT NULL,
`current_keeper` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
注意:json类型的specification字段可以灵活存储不同类别资产的特有属性,避免了过度设计表结构。
3.2 转移流程模块
转移流程是系统的核心业务,我们设计了状态机来管理流程:
code复制申请提交 → 部门审批 → 财务审批 → 转移执行 → 完成
↘ 拒绝 ↗
关键实现代码片段:
java复制@Transactional
public void approveTransfer(Long requestId, boolean approved, String remark) {
TransferRequest request = requestRepository.findById(requestId)
.orElseThrow(() -> new BusinessException("转移申请不存在"));
if (!"PENDING".equals(request.getStatus())) {
throw new BusinessException("当前状态不允许审批");
}
if (approved) {
request.setStatus("APPROVED");
// 更新资产所属部门
assetService.updateAssetDepartment(
request.getAssetId(),
request.getToDepartment()
);
} else {
request.setStatus("REJECTED");
}
// 记录审批日志
ApprovalLog log = new ApprovalLog();
log.setRequestId(requestId);
log.setApprover(SecurityUtils.getCurrentUsername());
log.setDecision(approved ? "APPROVE" : "REJECT");
log.setRemark(remark);
approvalLogRepository.save(log);
}
3.3 统计报表模块
使用ECharts实现了多种可视化图表:
- 资产分类分布饼图
- 月度转移趋势折线图
- 部门资产对比柱状图
报表导出功能支持:
- Excel导出:使用Apache POI实现
- PDF导出:使用iText库生成
- 定时邮件发送:集成Spring Mail
4. 关键技术实现细节
4.1 权限控制实现
我们采用RBAC模型,数据库设计如下:
sql复制CREATE TABLE `role` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`description` varchar(200) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `permission` (
`id` int NOT NULL AUTO_INCREMENT,
`code` varchar(50) NOT NULL,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `user_role` (
`user_id` bigint NOT NULL,
`role_id` int NOT NULL,
PRIMARY KEY (`user_id`,`role_id`)
);
CREATE TABLE `role_permission` (
`role_id` int NOT NULL,
`permission_id` int NOT NULL,
PRIMARY KEY (`role_id`,`permission_id`)
);
Spring Security配置核心代码:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/transfer/approve").hasAnyRole("DEPARTMENT_MANAGER", "FINANCE")
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
4.2 前后端数据交互
前端使用axios封装了统一的请求处理:
javascript复制const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 10000
})
// 请求拦截器
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['Authorization'] = 'Bearer ' + store.getters.token
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
const res = response.data
if (res.code !== 200) {
if (res.code === 401) {
MessageBox.confirm('登录状态已过期,请重新登录', '提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
return Promise.reject(error)
}
)
4.3 性能优化实践
- 缓存优化:
java复制@Cacheable(value = "assetCategory", key = "#root.methodName")
public List<AssetCategory> getAllCategories() {
return categoryRepository.findAll();
}
- 批量操作优化:
java复制@Transactional
public void batchImport(List<Asset> assets) {
int batchSize = 100;
for (int i = 0; i < assets.size(); i += batchSize) {
List<Asset> subList = assets.subList(i, Math.min(i + batchSize, assets.size()));
assetRepository.saveAll(subList);
}
}
- 前端懒加载:
javascript复制const routes = [
{
path: '/asset',
component: () => import('../views/asset/index.vue'),
meta: { requiresAuth: true }
}
]
5. 开发与部署实践
5.1 开发环境搭建
后端开发环境:
- JDK 11
- IntelliJ IDEA
- Maven 3.8+
- MySQL 8.0
- Redis 6.2
前端开发环境:
- Node.js 16.x
- Visual Studio Code
- Vue CLI 5.x
提示:建议使用nvm管理Node.js版本,避免全局安装带来的冲突问题。
5.2 测试策略
我们采用了分层测试策略:
- 单元测试:JUnit 5 + Mockito
- 集成测试:SpringBootTest + Testcontainers
- API测试:Postman + Newman
- 前端测试:Jest + Vue Test Utils
测试覆盖率要求:
- 业务逻辑层:≥80%
- 控制器层:≥60%
- 工具类:100%
5.3 部署方案
使用Docker Compose编排服务:
yaml复制version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: asset_db
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:6.2-alpine
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
volumes:
mysql_data:
CI/CD流程:
- 代码提交触发GitHub Actions
- 运行单元测试和构建
- 构建Docker镜像并推送到Registry
- 部署到测试环境进行验收
- 人工确认后发布到生产环境
6. 常见问题与解决方案
6.1 跨域问题
解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
6.2 文件上传大小限制
SpringBoot配置:
properties复制spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
6.3 Vue路由刷新404
Nginx配置:
nginx复制location / {
try_files $uri $uri/ /index.html;
}
6.4 性能问题排查
常用工具:
- Arthas:Java诊断工具
- Chrome DevTools:前端性能分析
- VisualVM:JVM监控
- Slow Query Log:MySQL慢查询日志
7. 项目扩展方向
在实际使用过程中,我们发现还可以进一步扩展以下功能:
- 移动端支持:开发微信小程序或H5版本,方便现场扫码盘点
- 物联网集成:通过RFID技术实现资产自动识别
- 智能预测:基于历史数据预测资产报废周期
- 工作流引擎:集成Activiti实现更复杂的审批流程
- 多租户支持:SAAS化改造,服务更多中小客户
在技术架构上,未来可以考虑:
- 微服务化拆分
- 引入消息队列处理异步任务
- 使用分布式文件存储
- 实现灰度发布能力
