4.09
项目结构
复制
src/
├── main/
│ ├── java/com/hebei/techpolicy/
│ │ ├── config/
│ │ ├── controller/
│ │ │ └── PolicyController.java
│ │ ├── entity/
│ │ │ ├── Policy.java
│ │ │ └── PolicyType.java
│ │ ├── repository/
│ │ │ ├── PolicyRepository.java
│ │ │ └── PolicyTypeRepository.java
│ │ ├── service/
│ │ │ ├── PolicyService.java
│ │ │ └── impl/
│ │ │ └── PolicyServiceImpl.java
│ │ └── TechPolicyApplication.java
│ ├── resources/
│ │ ├── static/
│ │ ├── templates/
│ │ │ └── index.html
│ │ ├── application.properties
│ │ └── data.sql
├── test/
代码实现
- 实体类
Policy.java
java
复制
package com.hebei.techpolicy.entity;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "policy")
public class Policy {
@Id
@Column(name = "unique_code")
private String uniqueCode;
@Column(name = "policy_index")
private String policyIndex;
@Column(name = "policy_name")
private String policyName;
@Column(name = "policy_number")
private String policyNumber;
@Column(name = "policy_type")
private String policyType;
@Column(name = "implementation_scope")
private String implementationScope;
@Column(name = "issuing_agency")
private String issuingAgency;
@Column(name = "release_date")
private Date releaseDate;
@Column(name = "input_date")
private Date inputDate;
@Column(name = "implementation_date")
private Date implementationDate;
@Column(name = "subject_words")
private String subjectWords;
@Column(name = "keywords")
private String keywords;
@Column(name = "upper_policy")
private String upperPolicy;
@Column(name = "predecessor_policy")
private String predecessorPolicy;
@Column(name = "successor_policy")
private String successorPolicy;
@Column(name = "status")
private String status;
@Column(name = "content", columnDefinition = "TEXT")
private String content;
// Getters and Setters
// 省略getter和setter方法,实际项目中需要添加
}
PolicyType.java
java
复制
package com.hebei.techpolicy.entity;
import javax.persistence.*;
@Entity
@Table(name = "policy_type")
public class PolicyType {
@Id
@Column(name = "type_id")
private String typeId;
@Column(name = "type_name")
private String typeName;
// Getters and Setters
// 省略getter和setter方法,实际项目中需要添加
}
2. Repository接口
PolicyRepository.java
java
复制
package com.hebei.techpolicy.repository;
import com.hebei.techpolicy.entity.Policy;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface PolicyRepository extends JpaRepository<Policy, String>, JpaSpecificationExecutor
}
PolicyTypeRepository.java
java
复制
package com.hebei.techpolicy.repository;
import com.hebei.techpolicy.entity.PolicyType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PolicyTypeRepository extends JpaRepository<PolicyType, String> {
}
3. Service层
PolicyService.java
java
复制
package com.hebei.techpolicy.service;
import com.hebei.techpolicy.entity.Policy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import java.util.List;
public interface PolicyService {
Page
List
}
PolicyServiceImpl.java
java
复制
package com.hebei.techpolicy.service.impl;
import com.hebei.techpolicy.entity.Policy;
import com.hebei.techpolicy.repository.PolicyRepository;
import com.hebei.techpolicy.service.PolicyService;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.List;
@Service
public class PolicyServiceImpl implements PolicyService {
@Autowired
private PolicyRepository policyRepository;
@Override
public Page<Policy> findAll(Specification<Policy> spec, Pageable pageable) {
return policyRepository.findAll(spec, pageable);
}
@Override
public List<Policy> findAll(Specification<Policy> spec) {
return policyRepository.findAll(spec);
}
}
4. Controller层
PolicyController.java
java
复制
package com.hebei.techpolicy.controller;
import com.hebei.techpolicy.entity.Policy;
import com.hebei.techpolicy.entity.PolicyType;
import com.hebei.techpolicy.repository.PolicyTypeRepository;
import com.hebei.techpolicy.service.PolicyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
@Controller
public class PolicyController {
@Autowired
private PolicyService policyService;
@Autowired
private PolicyTypeRepository policyTypeRepository;
@GetMapping("/")
public String index(Model model) {
List<PolicyType> policyTypes = policyTypeRepository.findAll();
model.addAttribute("policyTypes", policyTypes);
return "index";
}
@GetMapping("/search")
public String search(
@RequestParam(value = "policyName", required = false) String policyName,
@RequestParam(value = "content", required = false) String content,
@RequestParam(value = "issuingAgency", required = false) String issuingAgency,
@RequestParam(value = "policyType", required = false) String policyType,
@RequestParam(value = "policyNumber", required = false) String policyNumber,
@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "10") int size,
Model model) {
// 构建查询条件
Specification<Policy> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (policyName != null && !policyName.isEmpty()) {
predicates.add(cb.like(root.get("policyName"), "%" + policyName + "%"));
}
if (content != null && !content.isEmpty()) {
predicates.add(cb.like(root.get("content"), "%" + content + "%"));
}
if (issuingAgency != null && !issuingAgency.isEmpty()) {
predicates.add(cb.like(root.get("issuingAgency"), "%" + issuingAgency + "%"));
}
if (policyType != null && !policyType.isEmpty()) {
predicates.add(cb.equal(root.get("policyType"), policyType));
}
if (policyNumber != null && !policyNumber.isEmpty()) {
predicates.add(cb.like(root.get("policyNumber"), "%" + policyNumber + "%"));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
Pageable pageable = PageRequest.of(page, size);
Page<Policy> policyPage = policyService.findAll(spec, pageable);
List<PolicyType> policyTypes = policyTypeRepository.findAll();
model.addAttribute("policyTypes", policyTypes);
model.addAttribute("policyPage", policyPage);
model.addAttribute("policyName", policyName);
model.addAttribute("content", content);
model.addAttribute("issuingAgency", issuingAgency);
model.addAttribute("policyType", policyType);
model.addAttribute("policyNumber", policyNumber);
return "index";
}
}
5. 主应用类
TechPolicyApplication.java
java
复制
package com.hebei.techpolicy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TechPolicyApplication {
public static void main(String[] args) {
SpringApplication.run(TechPolicyApplication.class, args);
}
}
6. 配置文件
application.properties
properties
复制
数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/root?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
JPA配置
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
视图配置
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
7. 初始化数据脚本
data.sql
sql
复制
-- 政策分类数据
INSERT INTO policy_type (type_id, type_name) VALUES
('0100', '综合'),
('0200', '科研机构改革'),
('0300', '科技计划管理'),
('0400', '科技经费与财务'),
('0500', '基础研究与科研基地'),
('0501', '基础研究'),
('0502', '平台基地'),
('0600', '企业技术进步与高新技术产业化'),
('0601', '企业'),
('0602', '产业'),
('0603', '创新载体'),
('0700', '农村科技与社会发展'),
('0800', '科技人才'),
('0900', '科技中介服务'),
('1000', '科技条件与标准'),
('1100', '科技金融与税收'),
('1200', '科技成果与知识产权'),
('1300', '科技奖励'),
('1400', '科学技术普及');
8. 前端页面
index.html (简化版)
html
复制
河北省科技政策综合查询系统
<div class="row">
<div class="col-md-3">
<div class="card">
<div class="card-header">政策分类</div>
<div class="card-body">
<ul class="tree-menu">
<li th:each="type : ${policyTypes}" th:if="${#strings.length(type.typeId) == 4}">
<a th:href="@{/search(policyType=${type.typeId})}" th:text="${type.typeName}"></a>
<ul th:if="${#lists.size(#lists.filter(policyTypes, t -> t.typeId.startsWith(type.typeId.substring(0,2)))} > 1">
<li th:each="subType : ${policyTypes}"
th:if="${#strings.length(subType.typeId) == 6 and subType.typeId.startsWith(type.typeId.substring(0,2))}">
<a th:href="@{/search(policyType=${subType.typeId})}" th:text="${subType.typeName}"></a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="col-md-9">
<div class="card">
<div class="card-header">高级检索</div>
<div class="card-body">
<form th:action="@{/search}" method="get">
<div class="row mb-3">
<div class="col-md-6">
<label for="policyName" class="form-label">政策标题</label>
<input type="text" class="form-control" id="policyName" name="policyName" th:value="${policyName}">
</div>
<div class="col-md-6">
<label for="content" class="form-label">政策内容</label>
<input type="text" class="form-control" id="content" name="content" th:value="${content}">
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="issuingAgency" class="form-label">发文机构</label>
<input type="text" class="form-control" id="issuingAgency" name="issuingAgency" th:value="${issuingAgency}">
</div>
<div class="col-md-6">
<label for="policyType" class="form-label">政策分类</label>
<select class="form-select" id="policyType" name="policyType">
<option value="">全部</option>
<option th:each="type : ${policyTypes}"
th:value="${type.typeId}"
th:text="${type.typeName}"
th:selected="${policyType == type.typeId}"></option>
</select>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="policyNumber" class="form-label">政策文号</label>
<input type="text" class="form-control" id="policyNumber" name="policyNumber" th:value="${policyNumber}">
</div>
<div class="col-md-6 d-flex align-items-end">
<button type="submit" class="btn btn-primary">检索</button>
</div>
</div>
</form>
</div>
</div>
<div class="card mt-4">
<div class="card-header">查询结果</div>
<div class="card-body">
<table class="table table-striped">
<thead>
<tr>
<th>政策名称</th>
<th>发文机构</th>
<th>文号</th>
<th>发布日期</th>
</tr>
</thead>
<tbody>
<tr th:each="policy : ${policyPage.content}">
<td><a th:href="@{/detail/{id}(id=${policy.uniqueCode})}" th:text="${policy.policyName}"></a></td>
<td th:text="${policy.issuingAgency}"></td>
<td th:text="${policy.policyNumber}"></td>
<td th:text="${#dates.format(policy.releaseDate, 'yyyy-MM-dd')}"></td>
</tr>
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination">
<li class="page-item" th:classappend="${policyPage.number == 0} ? 'disabled'">
<a class="page-link" th:href="@{/search(policyName=${policyName}, content=${content}, issuingAgency=${issuingAgency}, policyType=${policyType}, policyNumber=${policyNumber}, page=0)}">首页</a>
</li>
<li class="page-item" th:classappend="${policyPage.number == 0} ? 'disabled'">
<a class="page-link" th:href="@{/search(policyName=${policyName}, content=${content}, issuingAgency=${issuingAgency}, policyType=${policyType}, policyNumber=${policyNumber}, page=${policyPage.number-1})}">上一页</a>
</li>
<li class="page-item" th:each="i : ${#numbers.sequence(1, policyPage.totalPages)}" th:if="${i-1 >= policyPage.number-2 and i-1 <= policyPage.number+2}">
<a class="page-link" th:href="@{/search(policyName=${policyName}, content=${content}, issuingAgency=${issuingAgency}, policyType=${policyType}, policyNumber=${policyNumber}, page=${i-1})}" th:text="${i}" th:classappend="${i-1 == policyPage.number} ? 'active'"></a>
</li>
<li class="page-item" th:classappend="${policyPage.number == policyPage.totalPages-1} ? 'disabled'">
<a class="page-link" th:href="@{/search(policyName=${policyName}, content=${content}, issuingAgency=${issuingAgency}, policyType=${policyType}, policyNumber=${policyNumber}, page=${policyPage.number+1})}">下一页</a>
</li>
<li class="page-item" th:classappend="${policyPage.number == policyPage.totalPages-1} ? 'disabled'">
<a class="page-link" th:href="@{/search(policyName=${policyName}, content=${content}, issuingAgency=${issuingAgency}, policyType=${policyType}, policyNumber=${policyNumber}, page=${policyPage.totalPages-1})}">尾页</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<groupId>com.hebei</groupId>
<artifactId>tech-policy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>tech-policy</name>
<description>河北省科技政策综合查询系统</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Boot Starter Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
浙公网安备 33010602011771号