汽车制造部门数字档案馆系统搭建实操指南
一、系统架构与核心组件选型
本系统采用微服务架构,确保高可用性与可扩展性。核心由文档管理、元数据索引、全文搜索引擎、安全审计四大模块构成。以下是生产环境推荐的最小化技术栈:
1.1 基础服务选型
直接使用以下成熟开源方案,避免重复造轮子:
- 文档存储与版本控制: MinIO (对象存储) + GitLab (用于CAD图纸等设计文件的版本管理)。
- 元数据与索引数据库: PostgreSQL 13+, 利用其JSONB字段高效存储非结构化元数据。
- 全文搜索引擎: Elasticsearch 8.x, 用于对技术文档、报告进行全文检索。
- 业务流程引擎: Camunda 7, 驱动文档的审批、归档、借阅流程。
1.2 部署环境说明
假设初始环境为CentOS 7.9, 已安装Docker 20.10+和Docker Compose 2.0+。所有服务将通过Docker Compose编排。
二、基础设施快速部署
在部署应用前,先搭建好底层服务。在服务器上创建`infra/`目录,并编写`docker-compose-infra.yml`。
2.1 编排文件部署
将以下完整配置保存为`docker-compose-infra.yml`:
```yaml version: '3.8' services: postgres: image: postgres:13-alpine container_name: archive-postgres environment: POSTGRES_DB: digital_archive POSTGRES_USER: archive_admin POSTGRES_PASSWORD: YourStrong@Passw0rd volumes: - postgres_data:/var/lib/postgresql/data - ./init-scripts:/docker-entrypoint-initdb.d ports: - "5432:5432" restart: unless-stopped minio: image: minio/minio:latest container_name: archive-minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: YourMinioPassw0rd volumes: - minio_data:/data ports: - "9000:9000" - "9001:9001" restart: unless-stopped elasticsearch: image: elasticsearch:8.6.2 container_name: archive-es environment: - discovery.type=single-node - xpack.security.enabled=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 volumes: - es_data:/usr/share/elasticsearch/data ports: - "9200:9200" restart: unless-stopped camunda: image: camunda/camunda-bpm-platform:run-7.18.0 container_name: archive-camunda environment: DB_DRIVER: org.postgresql.Driver DB_URL: jdbc:postgresql://postgres:5432/digital_archive DB_USERNAME: archive_admin DB_PASSWORD: YourStrong@Passw0rd WAIT_FOR: postgres:5432 ports: - "8080:8080" depends_on: - postgres restart: unless-stopped volumes: postgres_data: minio_data: es_data: ```执行部署命令:在终端中进入该文件所在目录,运行:
```bash docker-compose -f docker-compose-infra.yml up -d ```等待所有容器状态变为“Up”后,访问以下地址验证:
- MinIO控制台: http://你的服务器IP:9001 (账号: minioadmin, 密码: YourMinioPassw0rd)
- Camunda: http://你的服务器IP:8080/camunda (默认账号: demo, 密码: demo)
- Elasticsearch: http://你的服务器IP:9200
三、核心业务应用开发与配置
我们将构建一个简单的Spring Boot应用作为系统核心,处理业务逻辑。
3.1 项目初始化与依赖
使用Spring Initializr (https://start.spring.io) 生成项目,依赖选择:Spring Web, Spring Data JPA, Spring Data Elasticsearch, Camunda Spring Boot Starter。
下载后,在`pom.xml`中补充MinIO Java SDK依赖:
```xml3.2 核心配置文件
在`src/main/resources/application.yml`中配置全部连接信息:
```yaml server: port: 8081 spring: datasource: url: jdbc:postgresql://你的服务器IP:5432/digital_archive username: archive_admin password: YourStrong@Passw0rd driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update show-sql: true elasticsearch: uris: http://你的服务器IP:9200 minio: endpoint: http://你的服务器IP:9000 accessKey: minioadmin secretKey: YourMinioPassw0rd bucket: car-archive-docs camunda: bpm: database: schema-update: true ```3.3 文档上传服务实现
创建`DocumentService.java`,实现文档上传至MinIO并记录元数据至PostgreSQL和Elasticsearch。
第一步:初始化MinIO客户端。
```java import io.minio.; import org.springframework.beans.factory.annotation.Value; import javax.annotation.PostConstruct; @Component public class MinioService { private MinioClient minioClient; @Value("${minio.endpoint}") private String endpoint; @Value("${minio.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; @Value("${minio.bucket}") private String bucketName; @PostConstruct public void init() throws Exception { minioClient = MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); // 确保存储桶存在 boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); if (!found) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); } } public String uploadFile(MultipartFile file, String department, String docType) throws Exception { String objectName = department + "/" + UUID.randomUUID() + "_" + file.getOriginalFilename(); minioClient.putObject( PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build() ); return objectName; // 返回对象存储路径 } } ```
第二步:创建JPA实体和ES文档模型。
```java // JPA实体 (PostgreSQL) @Entity @Table(name = "archive_document") @Data public class ArchiveDocument { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String fileName; private String filePath; // MinIO中的路径 private String department; // 部门:冲压、焊装、涂装、总装 private String docType; // 类型:设计图纸、工艺文件、质检报告、供应商文档 private String uploadUser; private LocalDateTime uploadTime; @Column(columnDefinition = "jsonb") private String extraMetadata; // 扩展元数据,JSON格式 } // ES文档模型 @Document(indexName = "archive_docs") @Data public class EsDocument { @Id private String id; @Field(type = FieldType.Text, analyzer = "ik_max_word") private String fileName; @Field(type = FieldType.Keyword) private String department; @Field(type = FieldType.Keyword) private String docType; private String content; // 从文件中提取的文本内容,用于全文检索 } ```第三步:实现上传控制器。
```java @RestController @RequestMapping("/api/document") public class DocumentController { @Autowired private MinioService minioService; @Autowired private ArchiveDocumentRepository docRepository; @Autowired private ElasticsearchRestTemplate esTemplate; @PostMapping("/upload") public ResponseEntity四、核心业务流程自动化
使用Camunda实现“技术文档变更审批流程”。
4.1 流程定义
在`src/main/resources/processes/`目录下创建BPMN文件`document-change-approval.bpmn`。核心节点包括:
- Start Event: 文档上传/变更申请。
- User Task (提交人直属领导审批): 分配候选人组为`dept_leader`。
- Exclusive Gateway: 判断审批结果。
- User Task (技术部门负责人审批): 仅当上一步通过,分配给`tech_leader`。
- Service Task (更新文档状态): 调用Spring Bean方法。
- End Event: 流程结束。
4.2 流程服务实现
创建`DocumentApprovalService.java`,作为Camunda服务任务(Service Task)的委托类。
```java @Component("documentUpdateService") public class DocumentApprovalService { @Autowired private ArchiveDocumentRepository repository; public void updateDocumentStatus(DelegateExecution execution) { Long documentId = (Long) execution.getVariable("documentId"); Boolean finalApproval = (Boolean) execution.getVariable("finalApproved"); ArchiveDocument doc = repository.findById(documentId).orElseThrow(); if (Boolean.TRUE.equals(finalApproval)) { doc.setStatus("APPROVED"); // 可在此触发通知或后续系统集成 } else { doc.setStatus("REJECTED"); } repository.save(doc); } } ```在流程BPMN的Service Task中,设置`Delegate Expression`为`${documentUpdateService}`。
五、系统对接与数据初始化
5.1 与现有系统对接
若需从现有PLM/ERP系统同步数据,创建定时任务或使用消息队列。以下为从数据库视图同步的Spring Scheduler示例:
```java @Scheduled(cron = "0 0 2 ?") // 每天凌晨2点执行 @Transactional public void syncFromPLM() { // 1. 从PLM系统视图查询新增或变更文档 // jdbcTemplate.query("SELECT FROM plm_doc_view WHERE update_time > ?", ...) // 2. 循环处理,调用本系统的upload逻辑或直接写入数据库 } ```5.2 基础数据初始化
在PostgreSQL容器初始化脚本`infra/init-scripts/01-init.sql`中,插入部门、文档类型等基础数据:
```sql INSERT INTO department (code, name) VALUES ('STAMPING', '冲压车间'), ('WELDING', '焊装车间'), ('PAINTING', '涂装车间'), ('ASSEMBLY', '总装车间'); INSERT INTO document_type (code, name) VALUES ('DESIGN_DWG', '设计图纸'), ('PROCESS_FILE', '工艺文件'), ('QC_REPORT', '质检报告'), ('SUPPLIER_DOC', '供应商文档'); ```六、安全与权限配置
集成Spring Security实现基于角色的访问控制。
6.1 基础安全配置
创建`SecurityConfig.java`,配置内存用户(生产环境应连接LDAP或统一用户中心)。
```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("engineer").password("{noop}engineer123").roles("USER") .and() .withUser("dept_leader").password("{noop}leader123").roles("USER", "DEPT_LEADER") .and() .withUser("tech_leader").password("{noop}tech123").roles("USER", "TECH_LEADER"); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/api/document/upload").hasAnyRole("DEPT_LEADER", "TECH_LEADER") .antMatchers("/api/document/search").hasRole("USER") .anyRequest().authenticated() .and() .httpBasic(); } } ```6.2 MinIO存储桶策略
通过MinIO控制台或mc命令,为存储桶设置细粒度访问策略,例如只允许特定部门前缀路径的读写。
七、部署上线与验证
7.1 应用打包与部署
在项目根目录执行`mvn clean package`生成JAR包。创建应用层的`docker-compose-app.yml`:
```yaml version: '3.8' services: archive-core-app: build: . 假设已编写Dockerfile container_name: archive-core-app ports: - "8081:8081" environment: SPRING_PROFILES_ACTIVE: prod depends_on: - postgres - minio - elasticsearch - camunda restart: unless-stopped 注意:这里需要能访问到之前部署的基础设施服务,可通过network配置联通。 ```执行最终部署:
```bash docker-compose -f docker-compose-app.yml up -d ```7.2 功能验证清单
- 访问 http://服务器IP:8081/api/document/upload (使用Basic Auth: dept_leader/leader123),上传一个测试PDF文件,观察返回成功信息。
- 登录PostgreSQL,查询`archive_document`表,确认记录已插入。
- 访问Elasticsearch: http://服务器IP:9200/archive_docs/_search, 确认文档已被索引。
- 登录MinIO控制台,在`car-archive-docs`桶中查看上传的文件。
- 登录Camunda (demo/demo),启动一个“Document Change Approval”流程,完成审批任务,观察文档状态是否更新。