基于SSH框架的国土资源审批管理系统 - 源码深度解析

JavaScriptSSH框架HTMLCSSMySQL
2026-03-093 浏览

文章摘要

本项目是基于SSH(Struts2 + Spring + Hibernate)框架构建的国土资源审批管理系统,旨在解决传统国土资源审批流程中存在的效率低下、数据分散、监管困难等核心痛点。系统通过集成化的审批流程与资源管理模块,实现了国土业务从申请、受理、审核到批复的全生命周期线上化管理,显著提升了政...

随着政府数字化转型的深入推进,传统国土资源审批流程面临着效率低下、数据分散、监管困难等核心挑战。基于SSH(Struts2 + Spring + Hibernate)框架构建的"国土政务智能审批平台"应运而生,该系统通过集成化的审批流程与资源管理模块,实现了国土业务从申请、受理、审核到批复的全生命周期线上化管理。

系统采用经典的三层架构设计,表现层使用Struts2框架处理用户请求与页面跳转,通过拦截器机制实现统一的权限校验与日志记录。业务层依托Spring框架的IoC容器进行Bean的生命周期管理,并利用声明式事务控制保证审批流程中数据操作的一致性。持久层采用Hibernate作为ORM工具,通过对象关系映射将国土资源的空间数据与属性数据统一管理。

数据库架构设计

系统数据库包含8个核心表,其中土地资源表(land_resources)和审批记录表(approval_records)的设计尤为关键。

土地资源表采用层次化分类设计,通过land_use_type字段与用地类型表建立外键关联,确保数据规范性:

CREATE TABLE land_resources (
    id INT PRIMARY KEY AUTO_INCREMENT,
    land_name VARCHAR(100) NOT NULL COMMENT '地块名称',
    land_location VARCHAR(200) NOT NULL COMMENT '具体位置',
    land_area DECIMAL(10,2) NOT NULL COMMENT '面积(公顷)',
    land_use_type INT NOT NULL COMMENT '用地类型ID',
    current_status ENUM('待审批','审批中','已批准','已驳回') DEFAULT '待审批',
    geographic_coordinates POLYGON COMMENT '地理坐标范围',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    update_time DATETIME ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (land_use_type) REFERENCES land_use_types(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

审批记录表采用状态机模式设计,通过current_status字段跟踪审批流程的完整生命周期:

CREATE TABLE approval_records (
    id INT PRIMARY KEY AUTO_INCREMENT,
    land_id INT NOT NULL COMMENT '关联土地ID',
    applicant_id INT NOT NULL COMMENT '申请人ID',
    approval_flow JSON NOT NULL COMMENT '审批流程定义',
    current_status VARCHAR(50) NOT NULL COMMENT '当前审批环节',
    approval_opinion TEXT COMMENT '审批意见',
    attachment_path VARCHAR(500) COMMENT '附件路径',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    complete_time DATETIME COMMENT '完成时间',
    FOREIGN KEY (land_id) REFERENCES land_resources(id),
    FOREIGN KEY (applicant_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

用地类型表采用树形结构设计,支持多级分类管理:

CREATE TABLE land_use_types (
    id INT PRIMARY KEY AUTO_INCREMENT,
    type_name VARCHAR(50) NOT NULL UNIQUE COMMENT '类型名称',
    parent_id INT DEFAULT NULL COMMENT '父类型ID',
    description TEXT COMMENT '类型描述',
    level INT NOT NULL DEFAULT 1 COMMENT '分类层级',
    is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
    FOREIGN KEY (parent_id) REFERENCES land_use_types(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

核心功能实现

1. 智能审批工作流引擎

系统实现了可配置的审批工作流引擎,通过JSON格式存储审批流程定义,支持动态调整审批环节。审批服务接口采用策略模式设计,不同审批类型可灵活配置不同的审批路径。

public interface ApprovalService {
    ApprovalResult submitApproval(ApprovalRequest request);
    ApprovalResult approveStep(ApprovalStep step);
    ApprovalResult rejectApproval(RejectionReason reason);
    List<ApprovalRecord> getApprovalHistory(String resourceId);
}

@Service
@Transactional
public class LandApprovalService implements ApprovalService {
    
    @Autowired
    private ApprovalRecordDAO approvalRecordDAO;
    
    @Autowired
    private WorkflowEngine workflowEngine;
    
    @Override
    public ApprovalResult submitApproval(ApprovalRequest request) {
        // 验证申请数据完整性
        validateRequest(request);
        
        // 初始化审批流程
        WorkflowDefinition workflow = workflowEngine.getWorkflow(request.getApprovalType());
        ApprovalRecord record = new ApprovalRecord();
        record.setLandId(request.getLandId());
        record.setApplicantId(request.getApplicantId());
        record.setApprovalFlow(workflow.toJSON());
        record.setCurrentStatus(workflow.getFirstStep());
        
        // 保存审批记录
        approvalRecordDAO.save(record);
        
        // 发送通知给第一审批人
        notifyApprover(workflow.getFirstApprover(), record);
        
        return ApprovalResult.success(record.getId());
    }
    
    private void validateRequest(ApprovalRequest request) {
        if (request.getLandId() == null) {
            throw new ValidationException("土地资源ID不能为空");
        }
        // 更多验证逻辑...
    }
}

审批流程管理

2. 土地资源空间数据管理

系统集成地理信息系统能力,通过Hibernate Spatial扩展支持空间数据存储和查询。土地资源实体类使用JTS几何对象表示地理坐标范围。

@Entity
@Table(name = "land_resources")
public class LandResource {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "land_name", nullable = false)
    private String landName;
    
    @Column(name = "land_location", nullable = false)
    private String landLocation;
    
    @Column(name = "land_area", nullable = false)
    private BigDecimal landArea;
    
    @ManyToOne
    @JoinColumn(name = "land_use_type", nullable = false)
    private LandUseType landUseType;
    
    @Column(name = "current_status")
    @Enumerated(EnumType.STRING)
    private ApprovalStatus currentStatus;
    
    @Column(name = "geographic_coordinates")
    private Polygon geographicCoordinates;
    
    @Column(name = "create_time")
    private Date createTime;
    
    @Column(name = "update_time")
    private Date updateTime;
    
    // 空间查询方法
    public boolean contains(Point point) {
        return geographicCoordinates != null && geographicCoordinates.contains(point);
    }
    
    public double calculateDistance(LandResource other) {
        if (this.geographicCoordinates == null || other.geographicCoordinates == null) {
            return -1;
        }
        return this.geographicCoordinates.getCentroid()
               .distance(other.geographicCoordinates.getCentroid());
    }
}

@Repository
public class LandResourceDAOImpl implements LandResourceDAO {
    
    @Autowired
    private SessionFactory sessionFactory;
    
    @Override
    public List<LandResource> findWithinRadius(Point center, double radius) {
        String hql = "FROM LandResource l WHERE within(l.geographicCoordinates, :circle) = true";
        return sessionFactory.getCurrentSession()
                .createQuery(hql, LandResource.class)
                .setParameter("circle", createCircle(center, radius))
                .getResultList();
    }
    
    @Override
    public List<LandResource> findByLandUseTypeAndStatus(LandUseType type, ApprovalStatus status) {
        CriteriaBuilder cb = sessionFactory.getCriteriaBuilder();
        CriteriaQuery<LandResource> query = cb.createQuery(LandResource.class);
        Root<LandResource> root = query.from(LandResource.class);
        
        Predicate typePredicate = cb.equal(root.get("landUseType"), type);
        Predicate statusPredicate = cb.equal(root.get("currentStatus"), status);
        
        query.where(cb.and(typePredicate, statusPredicate));
        
        return sessionFactory.getCurrentSession()
                .createQuery(query)
                .getResultList();
    }
}

土地资源监控

3. 统一身份认证与权限控制

系统基于Struts2拦截器实现细粒度的权限控制,支持RBAC(基于角色的访问控制)模型。用户权限在登录时加载并缓存,后续操作通过注解方式进行权限验证。

public class AuthenticationInterceptor extends AbstractInterceptor {
    
    private static final long serialVersionUID = 1L;
    
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext context = invocation.getInvocationContext();
        HttpSession session = context.getSession();
        
        // 检查用户是否登录
        User user = (User) session.getAttribute("currentUser");
        if (user == null) {
            return "login"; // 跳转到登录页面
        }
        
        // 检查权限
        Action action = (Action) invocation.getAction();
        RequiredPermission permission = action.getClass()
                .getAnnotation(RequiredPermission.class);
        
        if (permission != null && !hasPermission(user, permission.value())) {
            throw new AuthorizationException("权限不足");
        }
        
        return invocation.invoke();
    }
    
    private boolean hasPermission(User user, String permission) {
        return user.getRoles().stream()
                .flatMap(role -> role.getPermissions().stream())
                .anyMatch(p -> p.getCode().equals(permission));
    }
}

@Controller
@RequiredPermission("LAND_APPROVAL_VIEW")
public class LandApprovalAction extends ActionSupport {
    
    private List<LandResource> landResources;
    private Pagination pagination;
    
    @Autowired
    private LandResourceService landResourceService;
    
    public String execute() {
        landResources = landResourceService.getApprovalResources(pagination);
        return SUCCESS;
    }
    
    // Getter和Setter方法
    public List<LandResource> getLandResources() { return landResources; }
    public void setPagination(Pagination pagination) { this.pagination = pagination; }
}

用户登录界面

4. 公告管理与信息发布

系统提供完整的公告管理模块,支持富文本编辑、定时发布和定向推送功能。公告实体采用状态模式管理生命周期。

@Entity
@Table(name = "announcements")
public class Announcement {
    
    public enum AnnouncementStatus {
        DRAFT, PUBLISHED, EXPIRED, ARCHIVED
    }
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false)
    private String title;
    
    @Lob
    @Column(nullable = false)
    private String content;
    
    @Enumerated(EnumType.STRING)
    private AnnouncementStatus status = AnnouncementStatus.DRAFT;
    
    @ManyToOne
    @JoinColumn(name = "publisher_id")
    private User publisher;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date publishTime;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date expireTime;
    
    @ElementCollection
    @CollectionTable(name = "announcement_attachments")
    private List<String> attachments = new ArrayList<>();
    
    public void publish() {
        if (this.status != AnnouncementStatus.DRAFT) {
            throw new IllegalStateException("只有草稿状态的公告可以发布");
        }
        this.status = AnnouncementStatus.PUBLISHED;
        this.publishTime = new Date();
    }
    
    public boolean isActive() {
        return this.status == AnnouncementStatus.PUBLISHED &&
               (expireTime == null || expireTime.after(new Date()));
    }
}

@Service
public class AnnouncementService {
    
    @Autowired
    private AnnouncementDAO announcementDAO;
    
    @Transactional
    public void publishAnnouncement(Long announcementId) {
        Announcement announcement = announcementDAO.findById(announcementId);
        announcement.publish();
        announcementDAO.update(announcement);
        
        // 记录发布日志
        logPublishEvent(announcement);
    }
    
    public List<Announcement> getActiveAnnouncements(User user) {
        return announcementDAO.findByStatusAndDepartment(
            Announcement.AnnouncementStatus.PUBLISHED, 
            user.getDepartment()
        ).stream()
        .filter(Announcement::isActive)
        .sorted(Comparator.comparing(Announcement::getPublishTime).reversed())
        .collect(Collectors.toList());
    }
}

公告管理界面

实体关系模型

系统采用面向对象的领域模型设计,核心实体之间的关系通过Hibernate映射精确表达:

// 用户与角色的多对多关系
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(unique = true, nullable = false)
    private String username;
    
    @Column(nullable = false)
    private String password;
    
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles = new HashSet<>();
    
    @OneToMany(mappedBy = "applicant", cascade = CascadeType.ALL)
    private List<ApprovalRecord> approvalRecords = new ArrayList<>();
}

// 用地类型的自引用树形结构
@Entity
@Table(name = "land_use_types")
public class LandUseType {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false, unique = true)
    private String typeName;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private LandUseType parent;
    
    @OneToMany(mappedBy = "parent")
    private Set<LandUseType> children = new HashSet<>();
    
    @OneToMany(mappedBy = "landUseType")
    private Set<LandResource> landResources = new HashSet<>();
    
    public boolean isLeaf() {
        return children == null || children.isEmpty();
    }
}

性能优化策略

系统在数据访问层实现了多级缓存策略,显著提升查询性能:

@Repository
@CacheConfig(cacheNames = "landResources")
public class LandResourceDAOImpl implements LandResourceDAO {
    
    @Autowired
    private SessionFactory sessionFactory;
    
    @Cacheable(key = "#id")
    @Override
    public LandResource findById(Long id) {
        return sessionFactory.getCurrentSession()
                .get(LandResource.class, id);
    }
    
    @CacheEvict(allEntries = true)
    @Override
    public void update(LandResource resource) {
        sessionFactory.getCurrentSession()
                .update(resource);
    }
    
    @Cacheable(key = "T(org.springframework.util.StringUtils).collectionToDelimitedString(#args, '-')")
    @Override
    public List<LandResource> findByCriteria(LandSearchCriteria criteria) {
        CriteriaBuilder cb = sessionFactory.getCriteriaBuilder();
        CriteriaQuery<LandResource> query = cb.createQuery(LandResource.class);
        Root<LandResource> root = query.from(LandResource.class);
        
        List<Predicate> predicates = buildPredicates(criteria, cb, root);
        query.where(predicates.toArray(new Predicate[0]));
        
        return sessionFactory.getCurrentSession()
                .createQuery(query)
                .setFirstResult(criteria.getOffset())
                .setMaxResults(criteria.getPageSize())
                .getResultList();
    }
}

未来优化方向

  1. 微服务架构迁移:将单体应用拆分为审批服务、资源管理服务、用户服务等微服务,提升系统可扩展性和部署灵活性。可采用Spring Cloud框架实现服务治理。

  2. 大数据分析集成:引入Apache Spark或Flink进行审批数据实时分析,构建国土资源利用趋势预测模型,为决策提供数据支持。

  3. 移动端适配:开发React Native或Flutter移动应用,支持现场勘查数据采集、移动审批等场景,提升工作效率。

  4. 区块链存证:利用Hyperledger Fabric等区块链平台对重要审批结果进行存证,确保数据不可篡改,增强审批公信力。

  5. 智能OCR识别:集成光学字符识别技术,自动提取扫描文档中的关键信息,减少人工录入工作量,提高数据准确性。

该系统通过严谨的架构设计和深入的技术实现,为国土资源管理部门提供了高效、可靠的审批管理解决方案。其模块化设计和可扩展性为后续功能升级和技术演进奠定了坚实基础。

本文关键词
SSH框架国土资源审批管理系统源码解析数据库设计

上下篇

上一篇
没有更多文章
下一篇
没有更多文章