综合档案管理系统社保版:从零搭建可落地的实操指南

一、系统核心架构与选型

本系统采用前后端分离架构,前端使用Vue 3 + Element Plus,后端使用Spring Boot 2.7,数据库使用MySQL 8.0。此组合成熟稳定,社区资源丰富,适合快速构建企业级应用。

1.1 环境准备清单

在开始前,请确保你的开发环境已安装以下软件:

  • Node.js 16.14.0 或更高版本
  • Java Development Kit (JDK) 11
  • MySQL 8.0.28 或更高版本
  • Maven 3.8.6 或更高版本
  • Git 2.35 或更高版本

你可以通过以下命令验证安装:

``` node --version java -version mysql --version mvn -v git --version ```

二、数据库初始化

社保档案的核心数据模型包括参保人信息、缴费记录、待遇发放记录等。以下是创建数据库和核心表的完整SQL脚本。

2.1 创建数据库与用户

``` CREATE DATABASE IF NOT EXISTS social_archive CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'archive_admin'@'localhost' IDENTIFIED BY 'YourStrongPassword123!'; GRANT ALL PRIVILEGES ON social_archive. TO 'archive_admin'@'localhost'; FLUSH PRIVILEGES; USE social_archive; ```

2.2 创建核心数据表

执行以下SQL创建参保人员主表:

``` CREATE TABLE `insured_person` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `personal_id` varchar(18) NOT NULL COMMENT '公民身份号码', `name` varchar(50) NOT NULL COMMENT '姓名', `gender` tinyint NOT NULL COMMENT '性别:1-男,2-女', `birth_date` date NOT NULL COMMENT '出生日期', `insured_type` varchar(20) NOT NULL COMMENT '参保类型:城镇职工、城乡居民等', `insured_status` tinyint NOT NULL DEFAULT '1' COMMENT '参保状态:1-正常,2-暂停,3-终止', `first_insured_date` date NOT NULL COMMENT '首次参保日期', `current_unit_id` bigint DEFAULT NULL COMMENT '当前参保单位ID', `archive_location` varchar(200) DEFAULT NULL COMMENT '纸质档案存放位置', `contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_personal_id` (`personal_id`), KEY `idx_name` (`name`), KEY `idx_insured_status` (`insured_status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='参保人员主档案表'; ```

执行以下SQL创建缴费记录明细表:

``` CREATE TABLE `payment_record` ( `id` bigint NOT NULL AUTO_INCREMENT, `person_id` bigint NOT NULL COMMENT '关联参保人ID', `payment_month` date NOT NULL COMMENT '缴费所属月份', `payment_base` decimal(10,2) NOT NULL COMMENT '缴费基数', `personal_payment` decimal(10,2) NOT NULL COMMENT '个人缴纳金额', `unit_payment` decimal(10,2) NOT NULL COMMENT '单位缴纳金额', `total_payment` decimal(10,2) NOT NULL COMMENT '缴费总额', `payment_status` tinyint NOT NULL DEFAULT '1' COMMENT '缴费状态:1-已缴,2-欠缴,3-补缴', `actual_payment_date` date DEFAULT NULL COMMENT '实际缴费日期', `operator_id` bigint DEFAULT NULL COMMENT '操作员ID', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_person_month` (`person_id`,`payment_month`), KEY `idx_payment_status` (`payment_status`), CONSTRAINT `fk_payment_person` FOREIGN KEY (`person_id`) REFERENCES `insured_person` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='社保缴费记录表'; ```

三、后端服务搭建

3.1 创建Spring Boot项目

综合档案管理系统社保版:从零搭建可落地的实操指南

使用Spring Initializr快速生成项目,执行以下命令或直接访问 https://start.spring.io/ 生成项目:

``` curl https://start.spring.io/starter.zip \ -d type=maven-project \ -d language=java \ -d bootVersion=2.7.14 \ -d baseDir=social-archive-backend \ -d groupId=com.example \ -d artifactId=archive \ -d name=social-archive \ -d description="Social Archive Management System" \ -d packageName=com.example.archive \ -d packaging=jar \ -d javaVersion=11 \ -d dependencies=web,data-jpa,mysql,lombok \ -o social-archive-backend.zip unzip social-archive-backend.zip ```

3.2 配置数据库连接

编辑 src/main/resources/application.yml 文件,配置数据库连接:

``` spring: datasource: url: jdbc:mysql://localhost:3306/social_archive?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false username: archive_admin password: YourStrongPassword123! driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect format_sql: true server: port: 8080 ```

3.3 实现参保人档案管理API

创建实体类 src/main/java/com/example/archive/entity/InsuredPerson.java

``` package com.example.archive.entity; import lombok.Data; import javax.persistence.; import java.time.LocalDate; import java.time.LocalDateTime; @Entity @Table(name = "insured_person") @Data public class InsuredPerson { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "personal_id", nullable = false, unique = true, length = 18) private String personalId; @Column(nullable = false, length = 50) private String name; @Column(nullable = false) private Integer gender; @Column(name = "birth_date", nullable = false) private LocalDate birthDate; @Column(name = "insured_type", nullable = false, length = 20) private String insuredType; @Column(name = "insured_status", nullable = false) private Integer insuredStatus = 1; @Column(name = "first_insured_date", nullable = false) private LocalDate firstInsuredDate; @Column(name = "archive_location", length = 200) private String archiveLocation; @Column(name = "contact_phone", length = 20) private String contactPhone; @Column(name = "create_time", nullable = false, updatable = false) private LocalDateTime createTime; @Column(name = "update_time", nullable = false) private LocalDateTime updateTime; @PrePersist protected void onCreate() { createTime = LocalDateTime.now(); updateTime = LocalDateTime.now(); } @PreUpdate protected void onUpdate() { updateTime = LocalDateTime.now(); } } ```

创建Repository接口 src/main/java/com/example/archive/repository/InsuredPersonRepository.java

``` package com.example.archive.repository; import com.example.archive.entity.InsuredPerson; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import java.util.Optional; public interface InsuredPersonRepository extends JpaRepository, JpaSpecificationExecutor { Optional findByPersonalId(String personalId); boolean existsByPersonalId(String personalId); } ```

创建服务类 src/main/java/com/example/archive/service/InsuredPersonService.java

``` package com.example.archive.service; import com.example.archive.entity.InsuredPerson; import com.example.archive.repository.InsuredPersonRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.persistence.criteria.Predicate; import java.util.ArrayList; import java.util.List; import java.util.Optional; @Service @RequiredArgsConstructor public class InsuredPersonService { private final InsuredPersonRepository repository; public InsuredPerson create(InsuredPerson person) { if (repository.existsByPersonalId(person.getPersonalId())) { throw new RuntimeException("该身份证号已存在"); } return repository.save(person); } public Optional findById(Long id) { return repository.findById(id); } public Page search(String name, String personalId, Integer insuredStatus, Pageable pageable) { Specification spec = (root, query, cb) -> { List predicates = new ArrayList<>(); if (StringUtils.hasText(name)) { predicates.add(cb.like(root.get("name"), "%" + name + "%")); } if (StringUtils.hasText(personalId)) { predicates.add(cb.equal(root.get("personalId"), personalId)); } if (insuredStatus != null) { predicates.add(cb.equal(root.get("insuredStatus"), insuredStatus)); } return cb.and(predicates.toArray(new Predicate[0])); }; return repository.findAll(spec, pageable); } public InsuredPerson update(Long id, InsuredPerson updates) { return repository.findById(id).map(existing -> { if (updates.getName() != null) existing.setName(updates.getName()); if (updates.getGender() != null) existing.setGender(updates.getGender()); if (updates.getInsuredType() != null) existing.setInsuredType(updates.getInsuredType()); if (updates.getInsuredStatus() != null) existing.setInsuredStatus(updates.getInsuredStatus()); if (updates.getArchiveLocation() != null) existing.setArchiveLocation(updates.getArchiveLocation()); if (updates.getContactPhone() != null) existing.setContactPhone(updates.getContactPhone()); return repository.save(existing); }).orElseThrow(() -> new RuntimeException("参保人不存在")); } } ```

四、前端界面开发

4.1 创建Vue项目

``` npm create vue@latest social-archive-frontend cd social-archive-frontend npm install npm install element-plus axios ```

4.2 配置Element Plus和Axios

编辑 src/main.js

``` import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import axios from 'axios' const app = createApp(App) // 配置axios axios.defaults.baseURL = 'http://localhost:8080/api' axios.defaults.timeout = 10000 app.config.globalProperties.$axios = axios app.use(ElementPlus) app.mount('app') ```

4.3 实现参保人管理页面

创建 src/views/InsuredPersonList.vue

```