11.14 完成项目计划管理系统(idea中使用Mysql(9.4)Tomcat(11)jdk(21.0.8))
一.
创建项目
注意:项目属性选择java 构建系统选择Maven 演示图片所用jdk版本为21.0.8

二.
连接数据库
注意:演示图片Mysql版本为9.4 确保数据库已经打开
(1)首先检查Mysql是否已经打开
同时按住win+R,显示如下界面,输入services.msc

进入后找到Mysql 显示如下界面则已经成功打开

(2)在idea中接入Mysql
在项目右侧找到DataBase按键,打开后显示如下

点击左上角加号,选择Data Source,选择其中的Mysql

打开后可以选择更改名字,然后填入User(一般为root),再输入Password(你的Mysql密码)

填完后点击下方的Test Connection,若显示如下图所示,则连接成功,点击Applay和OK后返回即可

三.
部署Tomcat
注意:演示图片所用Tomcat版本为11版
选择Project Structure创建Artifact

选择From moudles后选择此项目

上方选择Edit configurations

进入后点击左上角加号,进去后寻找Tomcat Server

application server选择你的Tomcat安装的位置

点击Deployment,选择加号添加Artifact,选择之前创建好的Artifact

四.
搭建项目结构
如下图所示

文件说明:
1.配置文件:
pom.xml :项目的Maven配置文件 定义项目的基本信息和依赖库(Servlet API、Mysql驱动 )
db.properties:数据库连接配置文件 存储数据库中的URL、用户名和密码,用于DBUtil类加载,建立和管理数据库连接
2.实体类(Bean)
Project.java:项目实体类,封装项目所有属性(项目ID、名称、位置等),提供构造方法,getter和setter方法
DBUtil.java:数据库工具类,负责数据库的创建,通过静态代码加载db.properties配置,提供getConnection()方法获取数据库连接,提供close()方法关闭数据库
3.数据访问层(DAO):
ProjectDao.java:项目数据访问对象,封装与项目相关的数据库操作,主要方法addProject():项目立项(插入数据)、getProjectByNo()根据项目编号查询项、updateProject():修改项目信息、deleteProject()删除项目、auditProject():审核项目、fuzzyQuery():多条件模糊查询项目
4.过滤器(Filter)
主要用于解决中文乱码问题,确保系统能够正确处理中文数据
5.控制器层(servlet)
MainServlet:系统的入口控制器,负责将用户请求转发到主页面
ProjectCreateServlet:处理项目立项功能,包括显示表单和提交数据
ProjectAuditServlet:处理项目审核功能,包括项目查询和审核操作
ProjectUpdateServlet:处理项目信息修改功能
ProjectDeleteServlet:处理项目删除功能
6. 视图层(JSP页面)
main.jsp:系统的主页面,提供功能菜单入口,包含四个主要功能模块的导航链接:项目立项、修改项目、删除项目、项目审核
createProject.jsp:项目立项信息录入页面
auditProject.jsp:项目审核管理页面
updateProject.jsp:项目信息更新页面
deleteProject.jsp:项目删除页面
五. 文件内容
1.bean
(1.DBUtil)
`package com.project.bean;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class DBUtil {
private static String driver;
private static String url;
private static String username;
private static String password;
static {
try (InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties")) {
Properties prop = new Properties();
prop.load(is);
driver = prop.getProperty("driver");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
Class.forName(driver);
} catch (Exception e) {
throw new RuntimeException("数据库配置加载失败", e);
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}(2.Project)package com.project.bean;
import java.sql.Date;
public class Project {
private String projectId;
private String projectName;
private String projectLocation;
private String projectType;
private int totalInvestment;
private int currentInvestment;
private Date startDate;
private Date endDate;
private String constructionContent;
private int auditStatus;
private String auditOpinion;
// 构造方法
public Project(String projectId, String projectName, String projectLocation, String projectType,
int totalInvestment, int currentInvestment, Date startDate, Date endDate,
String constructionContent) {
this.projectId = projectId;
this.projectName = projectName;
this.projectLocation = projectLocation;
this.projectType = projectType;
this.totalInvestment = totalInvestment;
this.currentInvestment = currentInvestment;
this.startDate = startDate;
this.endDate = endDate;
this.constructionContent = constructionContent;
this.auditStatus = 0;
this.auditOpinion = null;
}
// 所有字段的 Getter/Setter 方法
public String getProjectId() { return projectId; }
public void setProjectId(String projectId) { this.projectId = projectId; }
public String getProjectName() { return projectName; }
public void setProjectName(String projectName) { this.projectName = projectName; }
public String getProjectLocation() { return projectLocation; }
public void setProjectLocation(String projectLocation) { this.projectLocation = projectLocation; }
public String getProjectType() { return projectType; }
public void setProjectType(String projectType) { this.projectType = projectType; }
public int getTotalInvestment() { return totalInvestment; }
public void setTotalInvestment(int totalInvestment) { this.totalInvestment = totalInvestment; }
public int getCurrentInvestment() { return currentInvestment; }
public void setCurrentInvestment(int currentInvestment) { this.currentInvestment = currentInvestment; }
public Date getStartDate() { return startDate; }
public void setStartDate(Date startDate) { this.startDate = startDate; }
public Date getEndDate() { return endDate; }
public void setEndDate(Date endDate) { this.endDate = endDate; }
public String getConstructionContent() { return constructionContent; }
public void setConstructionContent(String constructionContent) { this.constructionContent = constructionContent; }
public int getAuditStatus() { return auditStatus; }
public void setAuditStatus(int auditStatus) { this.auditStatus = auditStatus; }
public String getAuditOpinion() { return auditOpinion; }
public void setAuditOpinion(String auditOpinion) { this.auditOpinion = auditOpinion; }
}`
2.dao
(ProjectDao)
`package com.project.dao;
import com.project.bean.DBUtil;
import com.project.bean.Project;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class ProjectDao {
// 项目立项(插入数据)
public boolean addProject(Project project) throws SQLException {
String sql = "INSERT INTO project (project_id, project_name, project_location, project_type, " +
"total_investment, current_investment, start_date, end_date, construction_content, " +
"audit_status, audit_opinion) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, project.getProjectId());
pstmt.setString(2, project.getProjectName());
pstmt.setString(3, project.getProjectLocation());
pstmt.setString(4, project.getProjectType());
pstmt.setInt(5, project.getTotalInvestment());
pstmt.setInt(6, project.getCurrentInvestment());
pstmt.setDate(7, project.getStartDate());
pstmt.setDate(8, project.getEndDate());
pstmt.setString(9, project.getConstructionContent());
pstmt.setInt(10, project.getAuditStatus());
pstmt.setString(11, project.getAuditOpinion());
return pstmt.executeUpdate() > 0;
} finally {
DBUtil.close(conn, pstmt, null);
}
}
// 根据项目编号查询项目
public Project getProjectByNo(String projectId) throws SQLException {
String sql = "SELECT * FROM project WHERE project_id = ?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, projectId);
rs = pstmt.executeQuery();
if (rs.next()) {
Project project = new Project(
rs.getString("project_id"),
rs.getString("project_name"),
rs.getString("project_location"),
rs.getString("project_type"),
rs.getInt("total_investment"),
rs.getInt("current_investment"),
rs.getDate("start_date"),
rs.getDate("end_date"),
rs.getString("construction_content")
);
project.setAuditStatus(rs.getInt("audit_status"));
project.setAuditOpinion(rs.getString("audit_opinion"));
return project;
}
return null;
} finally {
DBUtil.close(conn, pstmt, rs);
}
}
// 修改项目(仅更新未审核项目的非关键字段)
public boolean updateProject(Project project) throws SQLException {
String sql = "UPDATE project SET current_investment = ?, start_date = ?, end_date = ?, " +
"construction_content = ? WHERE project_id = ? AND audit_status = 0";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, project.getCurrentInvestment());
pstmt.setDate(2, project.getStartDate());
pstmt.setDate(3, project.getEndDate());
pstmt.setString(4, project.getConstructionContent());
pstmt.setString(5, project.getProjectId());
return pstmt.executeUpdate() > 0;
} finally {
DBUtil.close(conn, pstmt, null);
}
}
// 删除项目(仅删除未审核项目)
public boolean deleteProject(String projectId) throws SQLException {
String sql = "DELETE FROM project WHERE project_id = ? AND audit_status = 0";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, projectId);
return pstmt.executeUpdate() > 0;
} finally {
DBUtil.close(conn, pstmt, null);
}
}
// 审核项目(更新审核状态与意见)
public boolean auditProject(String projectId, int auditStatus, String auditOpinion) throws SQLException {
String sql = "UPDATE project SET audit_status = ?, audit_opinion = ? WHERE project_id = ?";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, auditStatus);
pstmt.setString(2, auditOpinion);
pstmt.setString(3, projectId);
return pstmt.executeUpdate() > 0;
} finally {
DBUtil.close(conn, pstmt, null);
}
}
// 多条件模糊查询项目
public List<Project> fuzzyQuery(String projectId, String projectName) throws SQLException {
String sql = "SELECT * FROM project WHERE 1=1";
List<Object> params = new ArrayList<>();
if (projectId != null && !projectId.isEmpty()) {
sql += " AND project_id LIKE ?";
params.add("%" + projectId + "%");
}
if (projectName != null && !projectName.isEmpty()) {
sql += " AND project_name LIKE ?";
params.add("%" + projectName + "%");
}
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<Project> projectList = new ArrayList<>();
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < params.size(); i++) {
pstmt.setObject(i + 1, params.get(i));
}
rs = pstmt.executeQuery();
while (rs.next()) {
Project project = new Project(
rs.getString("project_id"),
rs.getString("project_name"),
rs.getString("project_location"),
rs.getString("project_type"),
rs.getInt("total_investment"),
rs.getInt("current_investment"),
rs.getDate("start_date"),
rs.getDate("end_date"),
rs.getString("construction_content")
);
project.setAuditStatus(rs.getInt("audit_status"));
project.setAuditOpinion(rs.getString("audit_opinion"));
projectList.add(project);
}
return projectList;
} finally {
DBUtil.close(conn, pstmt, rs);
}
}
}`
3.filter
(CharacterEncodingFilter)
`package com.project.filter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import java.io.IOException;
/**
-
自定义字符编码过滤器
-
用于解决中文乱码问题
*/
public class CharacterEncodingFilter implements Filter {
private String encoding = "UTF-8";@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 从web.xml中获取编码参数
String encodingParam = filterConfig.getInitParameter("encoding");
if (encodingParam != null && !encodingParam.trim().isEmpty()) {
this.encoding = encodingParam;
}
}@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 设置请求和响应的字符编码
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
response.setContentType("text/html;charset=" + encoding);// 继续执行过滤器链 chain.doFilter(request, response);}
@Override
public void destroy() {
// 过滤器销毁时的清理工作
}
}`
4.servlet
(1.MainServlet)
`package com.project.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/main")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("main.jsp").forward(req, resp);
}
}`
(2.ProjectAuditServlet)
`package com.project.servlet;
import com.project.bean.Project;
import com.project.dao.ProjectDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
@WebServlet("/auditProject")
public class ProjectAuditServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(ProjectAuditServlet.class);
private final ProjectDao projectDao = new ProjectDao();
// 处理GET请求:显示审核页面,支持多条件模糊查询
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
// 获取查询条件(项目编号、项目名称,支持模糊查询)
String projectId = req.getParameter("projectId");
String projectName = req.getParameter("projectName");
List<Project> projectList = null;
String errorMsg = "";
try {
// 调用DAO执行模糊查询(无条件时查询所有项目)
projectList = projectDao.fuzzyQuery(projectId, projectName);
} catch (SQLException e) {
logger.error("项目查询异常", e);
errorMsg = "查询失败:系统错误,请重试";
}
// 回显查询条件和结果到页面
req.setAttribute("projectList", projectList);
req.setAttribute("errorMsg", errorMsg);
req.setAttribute("echoProjectId", projectId);
req.setAttribute("echoProjectName", projectName);
req.getRequestDispatcher("auditProject.jsp").forward(req, resp);
}
// 处理POST请求:执行审核操作(同意/不同意)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 获取审核参数
String projectId = req.getParameter("projectId");
String auditStatusStr = req.getParameter("auditStatus"); // 1-同意,2-不同意
String auditOpinion = req.getParameter("auditOpinion");
String errorMsg = "";
String successMsg = "";
// 参数校验
if (projectId == null || projectId.isEmpty() || auditStatusStr == null) {
errorMsg = "参数错误:未指定项目或审核状态";
} else {
try {
int auditStatus = "1".equals(auditStatusStr) ? 1 : 0; // 1-已审核(同意),0-未审核(逻辑保留,实际用状态区分)
// 不同意时必须填写审核意见
if ("2".equals(auditStatusStr) && (auditOpinion == null || auditOpinion.trim().isEmpty())) {
errorMsg = "审核不同意时,必须填写审核意见";
} else {
// 执行审核(更新审核状态为1,无论同意/不同意均标记为“已审核”)
boolean isAudited = projectDao.auditProject(
projectId,
1, // 审核状态:1-已审核(区分于0-未审核)
"1".equals(auditStatusStr) ? "同意" : auditOpinion // 同意时意见为“同意”,不同意时为用户输入
);
if (isAudited) {
successMsg = "项目【" + projectId + "】审核成功";
} else {
errorMsg = "审核失败:项目不存在或已被删除";
}
}
} catch (SQLException e) {
logger.error("项目审核异常", e);
errorMsg = "审核失败:系统错误,请重试";
}
}
// 审核后重新查询并跳转回审核页面,显示结果
req.setAttribute("successMsg", successMsg);
req.setAttribute("errorMsg", errorMsg);
// 回显查询条件(保持用户之前的查询状态)
req.setAttribute("echoProjectId", req.getParameter("echoProjectId"));
req.setAttribute("echoProjectName", req.getParameter("echoProjectName"));
doGet(req, resp); // 复用GET方法的查询逻辑
}
}`
(3.ProjectCreateServlet)
`package com.project.servlet;
import com.project.bean.Project;
import com.project.dao.ProjectDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;
@WebServlet("/createProject")
public class ProjectCreateServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(ProjectCreateServlet.class);
private final ProjectDao projectDao = new ProjectDao();
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 项目编号规则:8位数字(前4位“年+月”,如2410代表2024年10月,后4位序号)
private final Pattern projectIdPattern = Pattern.compile("^\d{4}\d{4}$");
// 项目位置规则:省市区三级(如“河北省石家庄市长安区XX路”)
private final Pattern locationPattern = Pattern.compile("^.{2,}省.{2,}市.{2,}区.*$");
// 处理GET请求:显示立项表单页面
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("createProject.jsp").forward(req, resp);
}
// 处理POST请求:提交立项数据并入库
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 1. 获取表单参数
String projectId = req.getParameter("projectId");
String projectName = req.getParameter("projectName");
String projectLocation = req.getParameter("projectLocation");
String projectType = req.getParameter("projectType");
String totalInvestmentStr = req.getParameter("totalInvestment");
String currentInvestmentStr = req.getParameter("currentInvestment");
String startDateStr = req.getParameter("startDate");
String endDateStr = req.getParameter("endDate");
String constructionContent = req.getParameter("constructionContent");
// 2. 参数校验(格式+逻辑)
String errorMsg = "";
// 项目编号校验
if (projectId == null || !projectIdPattern.matcher(projectId).matches()) {
errorMsg = "项目编号格式错误(8位数字,前4位年+月,后4位序号,如24100130)";
}
// 项目名称校验(非空+长度≤50字)
else if (projectName == null || projectName.trim().isEmpty() || projectName.length() > 50) {
errorMsg = "项目名称不能为空且长度不超过50个汉字";
}
// 项目位置校验(符合省市区格式)
else if (projectLocation == null || !locationPattern.matcher(projectLocation).matches()) {
errorMsg = "项目位置格式错误(需包含省、市、区,如“河北省石家庄市长安区XX路”)";
}
// 项目属性校验(必选)
else if (projectType == null || projectType.trim().isEmpty()) {
errorMsg = "请选择项目属性";
}
// 投资金额转换与校验(正整数)
Integer totalInvestment = null, currentInvestment = null;
try {
totalInvestment = Integer.parseInt(totalInvestmentStr);
currentInvestment = Integer.parseInt(currentInvestmentStr);
if (totalInvestment <= 0 || currentInvestment < 0 || currentInvestment > totalInvestment) {
errorMsg = "总投资需为正数,已投资需≥0且≤总投资";
}
} catch (NumberFormatException e) {
errorMsg = "总投资和已投资需为整数";
}
// 日期转换与校验(开工日期≤竣工日期)
Date startDate = null, endDate = null;
try {
startDate = new Date(sdf.parse(startDateStr).getTime());
endDate = new Date(sdf.parse(endDateStr).getTime());
if (startDate.after(endDate)) {
errorMsg = "开工日期不能晚于竣工日期";
}
} catch (ParseException e) {
logger.error("日期解析异常", e);
errorMsg = "日期格式错误(需yyyy-MM-dd)";
}
// 建设内容校验(非空+长度≤500字)
if (errorMsg.isEmpty() && (constructionContent == null || constructionContent.trim().isEmpty() || constructionContent.length() > 500)) {
errorMsg = "建设内容不能为空且长度不超过500个汉字";
}
// 3. 校验失败:返回表单页面并显示错误
if (!errorMsg.isEmpty()) {
req.setAttribute("errorMsg", errorMsg);
// 回显表单数据(避免用户重新输入)
req.setAttribute("echoProjectId", projectId);
req.setAttribute("echoProjectName", projectName);
req.setAttribute("echoProjectLocation", projectLocation);
req.setAttribute("echoProjectType", projectType);
req.setAttribute("echoTotalInvestment", totalInvestmentStr);
req.setAttribute("echoCurrentInvestment", currentInvestmentStr);
req.setAttribute("echoStartDate", startDateStr);
req.setAttribute("echoEndDate", endDateStr);
req.setAttribute("echoConstructionContent", constructionContent);
req.getRequestDispatcher("createProject.jsp").forward(req, resp);
return;
}
// 4. 校验成功:封装实体并入库
try {
Project project = new Project(
projectId,
projectName,
projectLocation,
projectType,
totalInvestment,
currentInvestment,
startDate,
endDate,
constructionContent
);
// 检查项目编号是否已存在
if (projectDao.getProjectByNo(projectId) != null) {
errorMsg = "项目编号已存在,请更换";
req.setAttribute("errorMsg", errorMsg);
req.getRequestDispatcher("createProject.jsp").forward(req, resp);
return;
}
// 执行插入
boolean isSuccess = projectDao.addProject(project);
if (isSuccess) {
// 立项成功后跳转审核页面,默认查询当前项目
resp.sendRedirect(req.getContextPath() + "/auditProject?projectId=" + projectId);
} else {
errorMsg = "立项失败,请重试";
req.setAttribute("errorMsg", errorMsg);
req.getRequestDispatcher("createProject.jsp").forward(req, resp);
}
} catch (Exception e) {
logger.error("项目立项异常", e);
errorMsg = "系统错误,立项失败";
req.setAttribute("errorMsg", errorMsg);
req.getRequestDispatcher("createProject.jsp").forward(req, resp);
}
}
}`
(4.ProjectDeleteServlet)
`package com.project.servlet;
import com.project.bean.Project;
import com.project.dao.ProjectDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
@WebServlet("/deleteProject")
public class ProjectDeleteServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(ProjectDeleteServlet.class);
private final ProjectDao projectDao = new ProjectDao();
// 项目编号规则:8位数字(与立项功能保持一致)
private final String PROJECT_ID_PATTERN = "^\d{8}$";
// 处理GET请求:显示删除页面,支持根据项目编号查询
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String projectId = req.getParameter("projectId");
Project project = null;
String errorMsg = "";
// 如果传入项目编号,则查询项目信息
if (projectId != null && !projectId.trim().isEmpty()) {
// 校验项目编号格式
if (!projectId.matches(PROJECT_ID_PATTERN)) {
errorMsg = "项目编号格式错误(需8位数字)";
} else {
try {
project = projectDao.getProjectByNo(projectId);
if (project == null) {
errorMsg = "未查询到编号为【" + projectId + "】的项目";
}
} catch (SQLException e) {
logger.error("项目查询异常", e);
errorMsg = "查询失败:系统错误,请重试";
}
}
}
// 传递数据到页面
req.setAttribute("project", project);
req.setAttribute("errorMsg", errorMsg);
req.setAttribute("echoProjectId", projectId); // 回显查询的项目编号
req.getRequestDispatcher("deleteProject.jsp").forward(req, resp);
}
// 处理POST请求:执行删除操作(仅允许删除未审核项目)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
String projectId = req.getParameter("projectId");
String errorMsg = "";
String successMsg = "";
// 参数校验
if (projectId == null || !projectId.matches(PROJECT_ID_PATTERN)) {
errorMsg = "参数错误:项目编号格式不正确";
} else {
try {
// 1. 查询项目是否存在及审核状态
Project project = projectDao.getProjectByNo(projectId);
if (project == null) {
errorMsg = "删除失败:未查询到编号为【" + projectId + "】的项目";
} else if (project.getAuditStatus() == 1) {
// 已审核项目不允许删除
errorMsg = "删除失败:项目【" + projectId + "】已审核,不能删除";
} else {
// 2. 执行删除(仅删除未审核项目)
boolean isDeleted = projectDao.deleteProject(projectId);
if (isDeleted) {
successMsg = "项目【" + projectId + "】删除成功";
} else {
errorMsg = "删除失败:系统异常,请重试";
}
}
} catch (SQLException e) {
logger.error("项目删除异常", e);
errorMsg = "删除失败:系统错误,请重试";
}
}
// 传递结果到页面,复用GET方法的查询逻辑
req.setAttribute("successMsg", successMsg);
req.setAttribute("errorMsg", errorMsg);
req.setAttribute("echoProjectId", projectId); // 回显项目编号
doGet(req, resp);
}
}`
(5.ProjectUpdateServlet)
`package com.project.servlet;
import com.project.bean.Project;
import com.project.dao.ProjectDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;
@WebServlet("/updateProject")
public class ProjectUpdateServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(ProjectUpdateServlet.class);
private final ProjectDao projectDao = new ProjectDao();
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
private final Pattern projectIdPattern = Pattern.compile("^\d{8}$");
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String projectId = req.getParameter("projectId");
Project project = null;
String errorMsg = "";
if (projectId != null && !projectId.trim().isEmpty()) {
if (!projectIdPattern.matcher(projectId).matches()) {
errorMsg = "项目编号格式错误(需8位数字)";
} else {
try {
project = projectDao.getProjectByNo(projectId);
if (project == null) {
errorMsg = "未查询到编号为【" + projectId + "】的项目";
} else if (project.getAuditStatus() == 1) {
errorMsg = "项目【" + projectId + "】已审核,不允许修改";
}
} catch (Exception e) {
logger.error("项目查询异常", e);
errorMsg = "查询失败:系统错误,请重试";
}
}
}
req.setAttribute("project", project);
req.setAttribute("errorMsg", errorMsg);
req.setAttribute("echoProjectId", projectId);
req.getRequestDispatcher("updateProject.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
String projectId = req.getParameter("projectId");
String currentInvestmentStr = req.getParameter("currentInvestment");
String startDateStr = req.getParameter("startDate");
String endDateStr = req.getParameter("endDate");
String constructionContent = req.getParameter("constructionContent");
String errorMsg = "";
Project project = null;
if (projectId == null || !projectIdPattern.matcher(projectId).matches()) {
errorMsg = "参数错误:项目编号格式不正确";
} else {
try {
project = projectDao.getProjectByNo(projectId);
if (project == null) {
errorMsg = "修改失败:未查询到编号为【" + projectId + "】的项目";
} else if (project.getAuditStatus() == 1) {
errorMsg = "修改失败:项目【" + projectId + "】已审核,不允许修改";
}
} catch (Exception e) {
logger.error("项目查询异常", e);
errorMsg = "查询失败:系统错误,请重试";
}
}
if (errorMsg.isEmpty()) {
Integer currentInvestment = null;
try {
currentInvestment = Integer.parseInt(currentInvestmentStr);
if (currentInvestment < 0 || currentInvestment > project.getTotalInvestment()) {
errorMsg = "已投资需≥0且≤总投资(" + project.getTotalInvestment() + "万元)";
}
} catch (NumberFormatException e) {
errorMsg = "已投资需为整数";
}
Date startDate = null, endDate = null;
try {
startDate = new Date(sdf.parse(startDateStr).getTime());
endDate = new Date(sdf.parse(endDateStr).getTime());
if (startDate.after(endDate)) {
errorMsg = "开工日期不能晚于竣工日期";
}
} catch (ParseException e) {
logger.error("日期解析异常", e);
errorMsg = "日期格式错误(需yyyy-MM-dd)";
}
if (errorMsg.isEmpty() && (constructionContent == null || constructionContent.trim().isEmpty() || constructionContent.length() > 500)) {
errorMsg = "建设内容不能为空且长度不超过500个汉字";
}
}
if (!errorMsg.isEmpty()) {
req.setAttribute("errorMsg", errorMsg);
req.setAttribute("project", project);
req.setAttribute("echoProjectId", projectId);
req.getRequestDispatcher("updateProject.jsp").forward(req, resp);
return;
}
try {
Project updatedProject = new Project(
project.getProjectId(),
project.getProjectName(),
project.getProjectLocation(),
project.getProjectType(),
project.getTotalInvestment(),
Integer.parseInt(currentInvestmentStr),
new Date(sdf.parse(startDateStr).getTime()),
new Date(sdf.parse(endDateStr).getTime()),
constructionContent
);
updatedProject.setAuditStatus(project.getAuditStatus());
boolean isUpdated = projectDao.updateProject(updatedProject);
if (isUpdated) {
req.setAttribute("successMsg", "项目【" + projectId + "】修改成功");
} else {
errorMsg = "修改失败:系统异常,请重试";
req.setAttribute("errorMsg", errorMsg);
}
} catch (Exception e) {
logger.error("项目修改异常", e);
errorMsg = "修改失败:系统错误,请重试";
req.setAttribute("errorMsg", errorMsg);
}
req.setAttribute("project", project);
req.setAttribute("echoProjectId", projectId);
req.getRequestDispatcher("updateProject.jsp").forward(req, resp);
}
}`
5.resources
(db.properties)
url=jdbc:mysql://localhost:3306/project_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username=root password=#你的密码 driver=com.mysql.cj.jdbc.Driver
6.jsp
(1.auditProject)
`<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.project.bean.Project" %>
<%@ page import="java.util.List" %>
<%
// 从请求域获取数据
List
String errorMsg = (String) request.getAttribute("errorMsg");
String successMsg = (String) request.getAttribute("successMsg");
// 回显查询条件
String echoProjectId = (String) request.getAttribute("echoProjectId");
String echoProjectName = (String) request.getAttribute("echoProjectName");
// 处理空值
if (echoProjectId == null) echoProjectId = "";
if (echoProjectName == null) echoProjectName = "";
%>
项目审核管理
<!-- 消息提示区域 -->
<% if (errorMsg != null && !errorMsg.isEmpty()) { %>
<div class="msg error"><%= errorMsg %></div>
<% } %>
<% if (successMsg != null && !successMsg.isEmpty()) { %>
<div class="msg success"><%= successMsg %></div>
<% } %>
<!-- 1. 多条件模糊查询表单 -->
<form action="${pageContext.request.contextPath}/auditProject" method="get" class="query-form">
<div class="form-item">
<label>项目编号:</label>
<input type="text" name="projectId" value="<%= echoProjectId %>" placeholder="支持模糊查询,如2410">
</div>
<div class="form-item">
<label>项目名称:</label>
<input type="text" name="projectName" value="<%= echoProjectName %>" placeholder="支持模糊查询,如道路">
</div>
<button type="submit" class="btn query-btn">查询项目</button>
</form>
<!-- 2. 项目列表与审核操作 -->
<% if (projectList != null && !projectList.isEmpty()) { %>
<table class="data-table">
<thead>
<tr>
<th>项目编号</th>
<th>项目名称</th>
<th>项目位置</th>
<th>项目属性</th>
<th>总投资(万元)</th>
<th>开工日期</th>
<th>竣工日期</th>
<th>审核状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<% for (Project project : projectList) { %>
<tr>
<td><%= project.getProjectId() %></td>
<td><%= project.getProjectName() %></td>
<td><%= project.getProjectLocation() %></td>
<td><%= project.getProjectType() %></td>
<td><%= project.getTotalInvestment() %></td>
<td><%= project.getStartDate() %></td>
<td><%= project.getEndDate() %></td>
<td><%= project.getAuditStatus() == 0 ? "未审核" :
(project.getAuditOpinion().startsWith("同意") ? "已同意" : "已拒绝") %></td>
<td>
<% if (project.getAuditStatus() == 0) { %>
<!-- 未审核项目显示审核按钮 -->
<button type="button" class="btn audit-btn"
onclick="showAuditModal('<%= project.getProjectId() %>')">
审核
</button>
<% } else { %>
<!-- 已审核项目显示审核结果 -->
<span><%= project.getAuditOpinion() %></span>
<% } %>
</td>
</tr>
<% } %>
</tbody>
</table>
<% } else if (echoProjectId != null || echoProjectName != null) { %>
<div class="msg error">未查询到符合条件的项目</div>
<% } %>
<!-- 3. 返回主页面按钮 -->
<div style="margin-top: 30px; text-align: center;">
<a href="${pageContext.request.contextPath}/main">
<button type="button" class="btn">返回主页面</button>
</a>
</div>
(2.createProject)
`<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 获取回显数据和错误信息
String errorMsg = (String) request.getAttribute("errorMsg");
String echoProjectId = (String) request.getAttribute("echoProjectId");
String echoProjectName = (String) request.getAttribute("echoProjectName");
String echoProjectLocation = (String) request.getAttribute("echoProjectLocation");
String echoProjectType = (String) request.getAttribute("echoProjectType");
String echoTotalInvestment = (String) request.getAttribute("echoTotalInvestment");
String echoCurrentInvestment = (String) request.getAttribute("echoCurrentInvestment");
String echoStartDate = (String) request.getAttribute("echoStartDate");
String echoEndDate = (String) request.getAttribute("echoEndDate");
String echoConstructionContent = (String) request.getAttribute("echoConstructionContent");
// 处理空值,避免页面显示null
if (echoProjectId == null) echoProjectId = "";
if (echoProjectName == null) echoProjectName = "";
if (echoProjectLocation == null) echoProjectLocation = "";
if (echoProjectType == null) echoProjectType = "";
if (echoTotalInvestment == null) echoTotalInvestment = "";
if (echoCurrentInvestment == null) echoCurrentInvestment = "";
if (echoStartDate == null) echoStartDate = "";
if (echoEndDate == null) echoEndDate = "";
if (echoConstructionContent == null) echoConstructionContent = "";
%>
项目立项信息录入
<!-- 错误提示 -->
<% if (errorMsg != null && !errorMsg.isEmpty()) { %>
<div class="error"><%= errorMsg %></div>
<% } %>
<!-- 立项表单 -->
<form action="${pageContext.request.contextPath}/createProject" method="post">
<div class="form-item">
<label>项目编号:</label>
<div>
<input type="text" name="projectId" value="<%= echoProjectId %>"
placeholder="8位数字(前4位年+月,后4位序号,如24100130)" required>
<div class="tips">示例:24100130(2024年10月第130个项目)</div>
</div>
</div>
<div class="form-item">
<label>项目名称:</label>
<div>
<input type="text" name="projectName" value="<%= echoProjectName %>"
placeholder="不超过50个汉字" required>
<div class="tips">例如:石家庄市长安区XX道路改造工程</div>
</div>
</div>
<div class="form-item">
<label>项目位置:</label>
<div>
<input type="text" name="projectLocation" value="<%= echoProjectLocation %>"
placeholder="需包含省、市、区,如“河北省石家庄市长安区XX路”" required>
<div class="tips">必须包含三级行政区划(省/市/区)</div>
</div>
</div>
<div class="form-item">
<label>项目属性:</label>
<select name="projectType" required>
<option value="">--请选择项目属性--</option>
<option value="道路" <%= "道路".equals(echoProjectType) ? "selected" : "" %>>道路</option>
<option value="管廊" <%= "管廊".equals(echoProjectType) ? "selected" : "" %>>管廊</option>
<option value="住宅" <%= "住宅".equals(echoProjectType) ? "selected" : "" %>>住宅</option>
<option value="商业" <%= "商业".equals(echoProjectType) ? "selected" : "" %>>商业</option>
<option value="公建" <%= "公建".equals(echoProjectType) ? "selected" : "" %>>公建</option>
<option value="园林绿化" <%= "园林绿化".equals(echoProjectType) ? "selected" : "" %>>园林绿化</option>
<option value="产业类" <%= "产业类".equals(echoProjectType) ? "selected" : "" %>>产业类</option>
</select>
</div>
<div class="form-item">
<label>总投资(万元):</label>
<div>
<input type="number" name="totalInvestment" value="<%= echoTotalInvestment %>"
min="1" placeholder="正整数" required>
<div class="tips">单位:万元,需为正数</div>
</div>
</div>
<div class="form-item">
<label>已投资(万元):</label>
<div>
<input type="number" name="currentInvestment" value="<%= echoCurrentInvestment %>"
min="0" placeholder="≥0且≤总投资" required>
<div class="tips">单位:万元,不能超过总投资</div>
</div>
</div>
<div class="form-item">
<label>开工日期:</label>
<input type="date" name="startDate" value="<%= echoStartDate %>" required>
</div>
<div class="form-item">
<label>竣工日期:</label>
<input type="date" name="endDate" value="<%= echoEndDate %>" required>
</div>
<div class="form-item">
<label>建设内容:</label>
<div>
<textarea name="constructionContent" placeholder="不超过500个汉字,描述项目主要建设内容" required><%= echoConstructionContent %></textarea>
<div class="tips">例如:道路全长XX米,宽XX米,包含XX等配套设施...</div>
</div>
</div>
<button type="submit" class="btn">提交立项</button>
</form>
<!-- 返回主页面链接 -->
<a href="${pageContext.request.contextPath}/main" class="back-link">返回主页面</a>
(3.deleteProject)
`<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.project.bean.Project" %>
<%
// 从请求域获取数据
Project project = (Project) request.getAttribute("project");
String errorMsg = (String) request.getAttribute("errorMsg");
String successMsg = (String) request.getAttribute("successMsg");
String echoProjectId = (String) request.getAttribute("echoProjectId");
if (echoProjectId == null) echoProjectId = "";
%>
项目删除管理
<!-- 消息提示区域 -->
<% if (errorMsg != null && !errorMsg.isEmpty()) { %>
<div class="msg error"><%= errorMsg %></div>
<% } %>
<% if (successMsg != null && !successMsg.isEmpty()) { %>
<div class="msg success"><%= successMsg %></div>
<% } %>
<!-- 1. 查询项目表单 -->
<form action="${pageContext.request.contextPath}/deleteProject" method="get" class="query-form">
<div class="form-item">
<label>项目编号:</label>
<input type="text" name="projectId" value="<%= echoProjectId %>"
placeholder="8位数字,如24100130" required>
<button type="submit" class="btn query-btn">查询项目</button>
</div>
</form>
<!-- 2. 项目信息与删除操作(查询到项目时显示) -->
<% if (project != null) { %>
<div class="project-info">
<h3>项目信息(编号:<%= project.getProjectId() %>)</h3>
<table class="data-table">
<thead>
<tr>
<th>项目名称</th>
<th>项目位置</th>
<th>项目属性</th>
<th>总投资(万元)</th>
<th>审核状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= project.getProjectName() %></td>
<td><%= project.getProjectLocation() %></td>
<td><%= project.getProjectType() %></td>
<td><%= project.getTotalInvestment() %></td>
<td><%= project.getAuditStatus() == 0 ? "未审核" : "已审核" %></td>
<td>
<% if (project.getAuditStatus() == 0) { %>
<!-- 未审核项目显示删除按钮 -->
<button type="button" class="btn delete-btn"
onclick="showDeleteModal('<%= project.getProjectId() %>')">
删除项目
</button>
<% } else { %>
<!-- 已审核项目禁用删除按钮 -->
<button type="button" class="btn delete-btn" disabled>
已审核,不可删除
</button>
<% } %>
</td>
</tr>
</tbody>
</table>
</div>
<% } %>
<!-- 3. 返回主页面按钮 -->
<div style="margin-top: 30px; text-align: center;">
<a href="${pageContext.request.contextPath}/main">
<button type="button" class="btn back-btn">返回主页面</button>
</a>
</div>
(4.main)
`<%@ page contentType="text/html;charset=UTF-8" language="java" %>
项目计划管理系统
(5.updateProject)
`<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.project.bean.Project" %>
<%@ page import="java.sql.Date" %>
<%
// 从请求域获取数据
Project project = (Project) request.getAttribute("project");
String errorMsg = (String) request.getAttribute("errorMsg");
String successMsg = (String) request.getAttribute("successMsg");
String echoProjectId = (String) request.getAttribute("echoProjectId");
if (echoProjectId == null) echoProjectId = "";
%>
项目信息修改
<!-- 消息提示区域 -->
<% if (errorMsg != null && !errorMsg.isEmpty()) { %>
<div class="msg error"><%= errorMsg %></div>
<% } %>
<% if (successMsg != null && !successMsg.isEmpty()) { %>
<div class="msg success"><%= successMsg %></div>
<% } %>
<!-- 1. 查询项目表单 -->
<form action="${pageContext.request.contextPath}/updateProject" method="get" class="query-form">
<div class="form-item">
<label>项目编号:</label>
<input type="text" name="projectId" value="<%= echoProjectId %>"
placeholder="8位数字,如24100130" required>
<button type="submit" class="btn query-btn">查询项目</button>
</div>
</form>
<!-- 2. 修改表单(查询到未审核项目时显示) -->
<% if (project != null && project.getAuditStatus() == 0) { %>
<form action="${pageContext.request.contextPath}/updateProject" method="post">
<!-- 隐藏字段:项目编号(关键字段,不允许修改) -->
<input type="hidden" name="projectId" value="<%= project.getProjectId() %>">
<div class="form-item">
<label>项目编号:</label>
<div>
<input type="text" value="<%= project.getProjectId() %>" readonly>
<div class="readonly-tip">关键字段,不允许修改</div>
</div>
</div>
<div class="form-item">
<label>项目名称:</label>
<div>
<input type="text" value="<%= project.getProjectName() %>" readonly>
<div class="readonly-tip">关键字段,不允许修改</div>
</div>
</div>
<div class="form-item">
<label>项目位置:</label>
<div>
<input type="text" value="<%= project.getProjectLocation() %>" readonly>
<div class="readonly-tip">关键字段,不允许修改</div>
</div>
</div>
<div class="form-item">
<label>项目属性:</label>
<div>
<input type="text" value="<%= project.getProjectType() %>" readonly>
<div class="readonly-tip">关键字段,不允许修改</div>
</div>
</div>
<div class="form-item">
<label>总投资(万元):</label>
<div>
<input type="number" value="<%= project.getTotalInvestment() %>" readonly>
<div class="readonly-tip">关键字段,不允许修改</div>
</div>
</div>
<div class="form-item">
<label>已投资(万元):</label>
<div>
<input type="number" name="currentInvestment"
value="<%= project.getCurrentInvestment() %>"
min="0" max="<%= project.getTotalInvestment() %>" required>
<div class="tips">≤总投资(<%= project.getTotalInvestment() %>万元)</div>
</div>
</div>
<div class="form-item">
<label>开工日期:</label>
<input type="date" name="startDate"
value="<%= project.getStartDate() != null ? project.getStartDate() : "" %>" required>
</div>
<div class="form-item">
<label>竣工日期:</label>
<input type="date" name="endDate"
value="<%= project.getEndDate() != null ? project.getEndDate() : "" %>" required>
</div>
<div class="form-item">
<label>建设内容:</label>
<div>
<textarea name="constructionContent"
placeholder="不超过500个汉字" required><%= project.getConstructionContent() %></textarea>
<div class="tips">描述项目主要建设内容,不超过500个汉字</div>
</div>
</div>
<button type="submit" class="btn update-btn">保存修改</button>
<a href="${pageContext.request.contextPath}/main">
<button type="button" class="btn back-btn">返回主页面</button>
</a>
</form>
<% } %>
(web.xml)
`
<!-- 欢迎文件列表 -->
<welcome-file-list>
<welcome-file>main.jsp</welcome-file>
</welcome-file-list>
<!-- 配置字符编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
`
(pom.xml)
`
<!-- 依赖配置需直接在 project 下 -->
<dependencies>
<!-- Servlet 依赖 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<!-- MySQL 驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
<scope>runtime</scope>
</dependency>
<!-- SLF4J 日志依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
</dependencies>
<build>
<!-- 编译插件等配置 -->
</build>
`
六.
文件填写完后,从右侧Maven中点击Reload

完成上述操作后,项目管理系统完成

浙公网安备 33010602011771号