做读者档案、联系方式、借阅资格功能

This commit is contained in:
Zzzz
2026-04-27 20:32:46 +08:00
parent 78c649b6d1
commit eff118e6fa
25 changed files with 1997 additions and 5 deletions
@@ -0,0 +1,375 @@
package com.mzh.library.controller;
import com.mzh.library.dao.impl.JdbcReaderDao;
import com.mzh.library.entity.AuthenticatedUser;
import com.mzh.library.entity.Reader;
import com.mzh.library.entity.ReaderSearchCriteria;
import com.mzh.library.entity.ReaderStatus;
import com.mzh.library.service.ReaderService;
import com.mzh.library.service.ServiceResult;
import com.mzh.library.service.impl.ReaderServiceImpl;
import com.mzh.library.util.SessionAttributes;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ReaderManagementServlet extends HttpServlet {
private static final String MANAGE_JSP = "/WEB-INF/jsp/readers/manage.jsp";
private static final String FORM_JSP = "/WEB-INF/jsp/readers/form.jsp";
private static final String UNAUTHORIZED_JSP = "/WEB-INF/jsp/auth/unauthorized.jsp";
private static final String FLASH_SUCCESS = "flashSuccess";
private static final String FLASH_ERROR = "flashError";
private ReaderService readerService;
@Override
public void init() {
this.readerService = new ReaderServiceImpl(new JdbcReaderDao());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getServletPath();
if ("/readers/new".equals(path)) {
renderForm(request, response, "Create reader", "/readers", defaultReader(), Collections.emptyMap(),
Collections.emptyMap(), null);
return;
}
if ("/readers/edit".equals(path)) {
showEditForm(request, response);
return;
}
if (!"/readers".equals(path)) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
showManagementList(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getServletPath();
if ("/readers".equals(path)) {
createReader(request, response);
return;
}
if ("/readers/update".equals(path)) {
updateReader(request, response);
return;
}
if ("/readers/delete".equals(path)) {
deactivateReader(request, response);
return;
}
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
private void showManagementList(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ReaderSearchCriteria criteria = searchCriteria(request);
request.setAttribute("criteria", criteria);
request.setAttribute("statuses", ReaderStatus.values());
applyFlash(request);
ServiceResult<List<Reader>> searchResult = readerService.searchReaders(criteria);
request.setAttribute("readers", searchResult.isSuccessful()
? searchResult.getData()
: Collections.emptyList());
if (!searchResult.isSuccessful()) {
request.setAttribute("errorMessage", searchResult.getMessage());
request.setAttribute("errors", searchResult.getErrors());
}
request.getRequestDispatcher(MANAGE_JSP).forward(request, response);
}
private void showEditForm(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
long id = requiredLong(request.getParameter("id"), -1L);
ServiceResult<Optional<Reader>> result = readerService.findReader(id);
if (!result.isSuccessful() || !result.getData().isPresent()) {
flashError(request, result.isSuccessful() ? "Reader profile was not found." : result.getMessage());
response.sendRedirect(request.getContextPath() + "/readers");
return;
}
renderForm(request, response, "Edit reader", "/readers/update", result.getData().get(),
Collections.emptyMap(), Collections.emptyMap(), null);
}
private void createReader(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ReaderForm form = readReaderForm(request, false);
if (!form.getErrors().isEmpty()) {
renderForm(request, response, "Create reader", "/readers", form.getReader(), form.getValues(),
form.getErrors(), "Please correct the highlighted reader fields.");
return;
}
ServiceResult<Long> result = readerService.createReader(currentUser(request), form.getReader());
if (!result.isSuccessful()) {
handleFormFailure(request, response, "Create reader", "/readers", form, result);
return;
}
flashSuccess(request, result.getMessage());
response.sendRedirect(request.getContextPath() + "/readers");
}
private void updateReader(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ReaderForm form = readReaderForm(request, true);
if (!form.getErrors().isEmpty()) {
renderForm(request, response, "Edit reader", "/readers/update", form.getReader(), form.getValues(),
form.getErrors(), "Please correct the highlighted reader fields.");
return;
}
ServiceResult<Void> result = readerService.updateReader(currentUser(request), form.getReader());
if (!result.isSuccessful()) {
handleFormFailure(request, response, "Edit reader", "/readers/update", form, result);
return;
}
flashSuccess(request, result.getMessage());
response.sendRedirect(request.getContextPath() + "/readers");
}
private void deactivateReader(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
long id = requiredLong(request.getParameter("id"), -1L);
ServiceResult<Void> result = readerService.deactivateReader(currentUser(request), id);
if (isPermissionDenied(result)) {
forwardDenied(request, response, result.getMessage());
return;
}
if (result.isSuccessful()) {
flashSuccess(request, result.getMessage());
} else {
flashError(request, result.getMessage());
}
response.sendRedirect(request.getContextPath() + "/readers");
}
private void handleFormFailure(HttpServletRequest request, HttpServletResponse response, String title,
String action, ReaderForm form, ServiceResult<?> result)
throws ServletException, IOException {
if (isPermissionDenied(result)) {
forwardDenied(request, response, result.getMessage());
return;
}
renderForm(request, response, title, action, form.getReader(), form.getValues(), result.getErrors(),
result.getMessage());
}
private void renderForm(HttpServletRequest request, HttpServletResponse response, String title, String action,
Reader reader, Map<String, String> formValues, Map<String, String> errors,
String errorMessage)
throws ServletException, IOException {
request.setAttribute("statuses", ReaderStatus.values());
request.setAttribute("formTitle", title);
request.setAttribute("formAction", action);
request.setAttribute("reader", reader);
request.setAttribute("formValues", formValues);
request.setAttribute("errors", errors);
if (errorMessage != null && !errorMessage.isEmpty()) {
request.setAttribute("errorMessage", errorMessage);
}
request.getRequestDispatcher(FORM_JSP).forward(request, response);
}
private ReaderForm readReaderForm(HttpServletRequest request, boolean requireId) {
Map<String, String> values = formValues(request);
Map<String, String> errors = new LinkedHashMap<>();
Reader reader = new Reader();
if (requireId) {
reader.setId(parseLong(values.get("id"), "id", "Select a valid reader.", errors));
}
reader.setIdentifier(values.get("identifier"));
reader.setUserId(optionalPositiveLong(values.get("userId"), "userId",
"Enter a valid linked account ID.", errors));
reader.setFullName(values.get("fullName"));
reader.setPhone(values.get("phone"));
reader.setEmail(values.get("email"));
reader.setMaxBorrowCount(parseInt(values.get("maxBorrowCount"), "maxBorrowCount",
"Enter a valid max borrow count.", errors));
try {
reader.setStatus(ReaderStatus.fromCode(values.get("status")));
} catch (IllegalArgumentException ex) {
errors.put("status", "Select a status.");
}
return new ReaderForm(reader, values, errors);
}
private Map<String, String> formValues(HttpServletRequest request) {
Map<String, String> values = new LinkedHashMap<>();
values.put("id", trim(request.getParameter("id")));
values.put("identifier", trim(request.getParameter("identifier")));
values.put("userId", trim(request.getParameter("userId")));
values.put("fullName", trim(request.getParameter("fullName")));
values.put("phone", trim(request.getParameter("phone")));
values.put("email", trim(request.getParameter("email")));
values.put("status", trim(request.getParameter("status")));
values.put("maxBorrowCount", trim(request.getParameter("maxBorrowCount")));
return values;
}
private ReaderSearchCriteria searchCriteria(HttpServletRequest request) {
return new ReaderSearchCriteria(
request.getParameter("identifier"),
request.getParameter("name"),
request.getParameter("contact"),
request.getParameter("status")
);
}
private Reader defaultReader() {
Reader reader = new Reader();
reader.setStatus(ReaderStatus.ACTIVE);
reader.setMaxBorrowCount(5);
return reader;
}
private Long optionalPositiveLong(String value, String field, String message, Map<String, String> errors) {
String trimmed = trim(value);
if (trimmed.isEmpty()) {
return null;
}
try {
long parsed = Long.parseLong(trimmed);
if (parsed <= 0) {
errors.put(field, message);
return null;
}
return parsed;
} catch (NumberFormatException ex) {
errors.put(field, message);
return null;
}
}
private long parseLong(String value, String field, String message, Map<String, String> errors) {
String trimmed = trim(value);
if (trimmed.isEmpty()) {
errors.put(field, message);
return 0L;
}
try {
long parsed = Long.parseLong(trimmed);
if (parsed <= 0) {
errors.put(field, message);
}
return parsed;
} catch (NumberFormatException ex) {
errors.put(field, message);
return 0L;
}
}
private int parseInt(String value, String field, String message, Map<String, String> errors) {
String trimmed = trim(value);
if (trimmed.isEmpty()) {
errors.put(field, message);
return -1;
}
try {
return Integer.parseInt(trimmed);
} catch (NumberFormatException ex) {
errors.put(field, message);
return -1;
}
}
private long requiredLong(String value, long fallback) {
try {
long parsed = Long.parseLong(trim(value));
return parsed > 0 ? parsed : fallback;
} catch (NumberFormatException ex) {
return fallback;
}
}
private boolean isPermissionDenied(ServiceResult<?> result) {
return !result.isSuccessful() && "You do not have permission to manage readers.".equals(result.getMessage());
}
private void forwardDenied(HttpServletRequest request, HttpServletResponse response, String message)
throws ServletException, IOException {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
request.setAttribute("errorMessage", message);
request.getRequestDispatcher(UNAUTHORIZED_JSP).forward(request, response);
}
private AuthenticatedUser currentUser(HttpServletRequest request) {
HttpSession session = request.getSession(false);
Object value = session == null ? null : session.getAttribute(SessionAttributes.AUTHENTICATED_USER);
return value instanceof AuthenticatedUser ? (AuthenticatedUser) value : null;
}
private void applyFlash(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
moveFlash(session, request, FLASH_SUCCESS, "successMessage");
moveFlash(session, request, FLASH_ERROR, "errorMessage");
}
private void moveFlash(HttpSession session, HttpServletRequest request, String sessionKey, String requestKey) {
Object value = session.getAttribute(sessionKey);
if (value != null) {
request.setAttribute(requestKey, value);
session.removeAttribute(sessionKey);
}
}
private void flashSuccess(HttpServletRequest request, String message) {
request.getSession().setAttribute(FLASH_SUCCESS, message);
}
private void flashError(HttpServletRequest request, String message) {
request.getSession().setAttribute(FLASH_ERROR, message);
}
private String trim(String value) {
return value == null ? "" : value.trim();
}
private static final class ReaderForm {
private final Reader reader;
private final Map<String, String> values;
private final Map<String, String> errors;
private ReaderForm(Reader reader, Map<String, String> values, Map<String, String> errors) {
this.reader = reader;
this.values = values;
this.errors = errors;
}
private Reader getReader() {
return reader;
}
private Map<String, String> getValues() {
return values;
}
private Map<String, String> getErrors() {
return errors;
}
}
}