船舶监造行业正经历从传统纸质化向数字化管理的转型浪潮。这个基于SpringBoot+Vue的船舶监造系统,正是为解决造船企业生产进度不透明、质量追溯困难、多方协作效率低下等痛点而生。我在参与某船厂信息化改造时发现,传统监造模式下,设计变更平均需要3-5天才能同步到生产端,而现在通过这套系统可以实现实时协同。
系统采用前后端分离架构,前端用Vue3+Element Plus构建响应式界面,后端基于SpringBoot提供RESTful API,数据库选用MySQL 8.0。特别针对船舶行业特性,设计了分段建造进度看板、焊接质量追溯、设备安装电子档案等特色模块。实测数据显示,使用该系统后监造文档传递效率提升70%,质量问题闭环周期缩短60%。
前端采用Vue3+TypeScript技术栈,通过Vite构建工具实现秒级热更新。项目结构清晰划分:
code复制src/
├── api/ # 封装Axios请求
├── assets/ # 静态资源
├── components/ # 通用组件
├── router/ # 路由配置
├── stores/ # Pinia状态管理
├── utils/ # 工具函数
└── views/ # 页面组件
特别优化了大型表单处理性能,针对船舶设备清单这类包含500+字段的复杂表单,采用虚拟滚动技术使渲染性能提升3倍。通过动态路由和按需加载,首屏加载时间控制在1.2秒内。
SpringBoot后端采用多模块设计:
code复制com.shipbuilding
├── common # 通用工具
├── config # 配置中心
├── controller # 接口层
├── dao # 数据访问
├── entity # 实体类
├── service # 业务逻辑
└── ShipBuildingApplication.java
针对船舶行业特殊需求,实现了以下核心功能:
数据库设计时特别考虑了船舶行业数据特性,例如:
sql复制CREATE TABLE `ship_section` (
`id` bigint NOT NULL AUTO_INCREMENT,
`section_code` varchar(32) COLLATE utf8mb4_bin NOT NULL COMMENT '分段编号',
`build_status` enum('DESIGN','CUTTING','ASSEMBLY','PAINTING','COMPLETED') COLLATE utf8mb4_bin DEFAULT 'DESIGN',
`quality_check` json DEFAULT NULL COMMENT '质检报告JSON',
`parent_id` bigint DEFAULT NULL COMMENT '父分段ID',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_section_code` (`section_code`),
KEY `idx_parent` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
推荐使用Docker Compose部署,需特别注意:
innodb_buffer_pool_size=4G(物理内存的50-70%)完整docker-compose.yml示例:
yaml复制version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ship@1234
MYSQL_DATABASE: shipbuilding
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
ports:
- "3306:3306"
redis:
image: redis:6-alpine
command: redis-server --appendonly yes
volumes:
- ./redis/data:/data
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
nginx复制location /api/ {
proxy_pass http://backend:8080;
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
}
java复制@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint("https://minio.example.com")
.credentials("accessKey", "secretKey")
.region("us-east-1")
.build();
}
采用状态机模式管理建造流程:
java复制public enum BuildState {
DESIGN {
@Override
public BuildState next() { return CUTTING; }
},
CUTTING {
@Override
public BuildState next() { return ASSEMBLY; }
},
// ...其他状态
}
@Service
public class SectionService {
@Transactional
public void changeSectionState(Long sectionId, BuildState newState) {
ShipSection section = sectionRepository.findById(sectionId)
.orElseThrow(() -> new BusinessException("分段不存在"));
if (!section.getBuildStatus().canTransferTo(newState)) {
throw new BusinessException("状态转换非法");
}
section.setBuildStatus(newState);
sectionRepository.save(section);
// 触发相关事件
eventPublisher.publishEvent(new SectionStateEvent(this, section));
}
}
利用MySQL事务和MD5校验确保数据完整性:
java复制@Transactional
public QualityCheck addQualityCheck(QualityCheckDTO dto) {
// 1. 保存检验记录
QualityCheck check = convertToEntity(dto);
check = qualityRepository.save(check);
// 2. 生成数据指纹
String fingerprint = DigestUtils.md5Hex(
check.getSectionCode() +
check.getCheckTime().getTime() +
check.getInspectorId());
// 3. 保存到区块链表
BlockChainRecord record = new BlockChainRecord();
record.setRecordType("QUALITY_CHECK");
record.setRecordId(check.getId());
record.setFingerprint(fingerprint);
blockChainRepository.save(record);
return check;
}
针对船舶行业数据特点,建议:
MySQL查询优化:
sql复制-- 为常用查询添加覆盖索引
ALTER TABLE ship_component
ADD INDEX idx_section_status (section_id, install_status);
-- 大表分片策略
CREATE TABLE quality_check_2023 (
CHECK (YEAR(check_time) = 2023)
) INHERITS (quality_check);
前端渲染优化:
vue复制<template>
<VirtualScroll :items="largeList" :item-size="50">
<template #default="{ item }">
<ComponentItem :data="item" />
</template>
</VirtualScroll>
</template>
接口权限校验:
java复制@PreAuthorize("@ss.hasPermission('section:progress:update')")
@PostMapping("/progress/update")
public Result updateProgress(@RequestBody ProgressDTO dto) {
// ...
}
敏感数据加密:
java复制@Column(columnDefinition = "VARBINARY(255)")
@Convert(converter = AesEncryptor.class)
private String clientContact;
操作日志审计:
java复制@Aspect
@Component
public class OperLogAspect {
@AfterReturning(pointcut = "@annotation(operLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint point, OperLog operLog, Object jsonResult) {
// 记录操作日志
}
}
需求分析阶段:
前端适配改造:
javascript复制// 扩展船舶类型枚举
export const ShipTypeEnum = {
...originalEnum,
LNG_CARRIER: { value: 5, label: 'LNG运输船' }
}
后端业务扩展:
java复制@Service
@RequiredArgsConstructor
public class CustomSectionService {
private final SectionRepository sectionRepo;
private final QualityCheckRepository qualityRepo;
public void customMethod(Long sectionId) {
// 实现定制逻辑
}
}
ERP系统对接方案:
java复制@FeignClient(name = "erp-service", url = "${erp.service.url}")
public interface ErpClient {
@PostMapping("/material/requisition")
ErpResult createRequisition(@RequestBody MaterialDTO dto);
}
钉钉通知集成:
java复制public class DingTalkNotifier {
public void sendProgressAlert(SectionProgress progress) {
// 调用钉钉机器人API
}
}
海图服务接入:
vue复制<template>
<div class="chart-container">
<BaiduMap :center="mapCenter" :zoom="12">
<ShipMarker v-for="ship in ships" :key="ship.id" :position="ship.position" />
</BaiduMap>
</div>
</template>