This commit is contained in:
Zzzz
2026-04-28 10:53:09 +08:00
parent 5dc91a4e8e
commit ff044e6aab
58 changed files with 793 additions and 635 deletions
@@ -17,9 +17,9 @@ import java.util.logging.Logger;
public class AuthServiceImpl implements AuthService {
private static final Logger LOGGER = Logger.getLogger(AuthServiceImpl.class.getName());
private static final String REQUIRED_MESSAGE = "Username and password are required.";
private static final String INVALID_MESSAGE = "Invalid username or password.";
private static final String UNAVAILABLE_MESSAGE = "Login service is temporarily unavailable. Please try again later.";
private static final String REQUIRED_MESSAGE = "请输入用户名和密码。";
private static final String INVALID_MESSAGE = "用户名或密码不正确。";
private static final String UNAVAILABLE_MESSAGE = "登录服务暂时不可用,请稍后重试。";
private final UserDao userDao;
private final PermissionPolicy permissionPolicy;
@@ -21,10 +21,10 @@ import java.util.logging.Logger;
public class BookServiceImpl implements BookService {
private static final Logger LOGGER = Logger.getLogger(BookServiceImpl.class.getName());
private static final String UNAVAILABLE_MESSAGE =
"Book service is temporarily unavailable. Please try again later.";
private static final String VALIDATION_MESSAGE = "Please correct the highlighted book fields.";
private static final String CATEGORY_VALIDATION_MESSAGE = "Please correct the highlighted category fields.";
private static final String DENIED_MESSAGE = "You do not have permission to manage books.";
"图书服务暂时不可用,请稍后重试。";
private static final String VALIDATION_MESSAGE = "请修正高亮的图书字段。";
private static final String CATEGORY_VALIDATION_MESSAGE = "请修正高亮的分类字段。";
private static final String DENIED_MESSAGE = "您无权管理图书。";
private final BookDao bookDao;
private final PermissionPolicy permissionPolicy;
@@ -51,7 +51,7 @@ public class BookServiceImpl implements BookService {
@Override
public ServiceResult<Optional<BookCategory>> findCategory(long id) {
if (id <= 0) {
return ServiceResult.failure("Select a valid category.");
return ServiceResult.failure("请选择有效的分类。");
}
try {
@@ -76,13 +76,13 @@ public class BookServiceImpl implements BookService {
try {
if (bookDao.findCategoryByName(category.getName()).isPresent()) {
errors.put("name", "Category name is already in use.");
errors.put("name", "分类名称已被使用。");
return ServiceResult.validationFailure(CATEGORY_VALIDATION_MESSAGE, errors);
}
long id = bookDao.createCategory(category);
LOGGER.info("Created book category id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(id, "Category created.");
return ServiceResult.success(id, "分类已创建。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to create book category actorId=" + actor.getId()
+ " name=" + safeCategoryName(category), ex);
@@ -105,16 +105,16 @@ public class BookServiceImpl implements BookService {
try {
Optional<BookCategory> existingWithName = bookDao.findCategoryByName(category.getName());
if (existingWithName.isPresent() && existingWithName.get().getId() != category.getId()) {
errors.put("name", "Category name is already in use.");
errors.put("name", "分类名称已被使用。");
return ServiceResult.validationFailure(CATEGORY_VALIDATION_MESSAGE, errors);
}
if (!bookDao.updateCategory(category)) {
return ServiceResult.failure("Category was not found.");
return ServiceResult.failure("未找到分类。");
}
LOGGER.info("Updated book category id=" + category.getId() + " actorId=" + actor.getId());
return ServiceResult.success(null, "Category updated.");
return ServiceResult.success(null, "分类已更新。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to update book category id=" + category.getId()
+ " actorId=" + actor.getId(), ex);
@@ -128,25 +128,25 @@ public class BookServiceImpl implements BookService {
return ServiceResult.failure(DENIED_MESSAGE);
}
if (id <= 0) {
return ServiceResult.failure("Select a valid category.");
return ServiceResult.failure("请选择有效的分类。");
}
try {
if (!bookDao.findCategoryById(id).isPresent()) {
return ServiceResult.failure("Category was not found.");
return ServiceResult.failure("未找到分类。");
}
if (bookDao.countBooksByCategoryId(id) > 0) {
Map<String, String> errors = new LinkedHashMap<>();
errors.put("category", "Category is used by existing books and cannot be deleted.");
return ServiceResult.validationFailure("Category is used by existing books and cannot be deleted.",
errors.put("category", "该分类已被现有图书使用,不能删除。");
return ServiceResult.validationFailure("该分类已被现有图书使用,不能删除。",
errors);
}
if (!bookDao.deleteCategory(id)) {
return ServiceResult.failure("Category was not found.");
return ServiceResult.failure("未找到分类。");
}
LOGGER.info("Deleted book category id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(null, "Category deleted.");
return ServiceResult.success(null, "分类已删除。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to delete book category id=" + id + " actorId=" + actor.getId(), ex);
return ServiceResult.failure(UNAVAILABLE_MESSAGE);
@@ -158,8 +158,8 @@ public class BookServiceImpl implements BookService {
BookSearchCriteria normalized = criteria == null ? new BookSearchCriteria() : criteria;
if (normalized.getCategoryId() != null && normalized.getCategoryId() <= 0) {
Map<String, String> errors = new LinkedHashMap<>();
errors.put("categoryId", "Select a valid category.");
return ServiceResult.validationFailure("Please correct the catalog search filters.", errors);
errors.put("categoryId", "请选择有效的分类。");
return ServiceResult.validationFailure("请修正馆藏检索筛选条件。", errors);
}
try {
@@ -173,7 +173,7 @@ public class BookServiceImpl implements BookService {
@Override
public ServiceResult<Optional<Book>> findBook(long id) {
if (id <= 0) {
return ServiceResult.failure("Select a valid book.");
return ServiceResult.failure("请选择有效的图书。");
}
try {
@@ -198,13 +198,13 @@ public class BookServiceImpl implements BookService {
try {
if (bookDao.findByIdentifier(book.getIdentifier()).isPresent()) {
errors.put("identifier", "Book identifier is already in use.");
errors.put("identifier", "图书编号已被使用。");
return ServiceResult.validationFailure(VALIDATION_MESSAGE, errors);
}
long id = bookDao.create(book);
LOGGER.info("Created book id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(id, "Book created.");
return ServiceResult.success(id, "图书已创建。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to create book actorId=" + actor.getId(), ex);
return ServiceResult.failure(UNAVAILABLE_MESSAGE);
@@ -226,16 +226,16 @@ public class BookServiceImpl implements BookService {
try {
Optional<Book> existingWithIdentifier = bookDao.findByIdentifier(book.getIdentifier());
if (existingWithIdentifier.isPresent() && existingWithIdentifier.get().getId() != book.getId()) {
errors.put("identifier", "Book identifier is already in use.");
errors.put("identifier", "图书编号已被使用。");
return ServiceResult.validationFailure(VALIDATION_MESSAGE, errors);
}
if (!bookDao.update(book)) {
return ServiceResult.failure("Book was not found.");
return ServiceResult.failure("未找到图书。");
}
LOGGER.info("Updated book id=" + book.getId() + " actorId=" + actor.getId());
return ServiceResult.success(null, "Book updated.");
return ServiceResult.success(null, "图书已更新。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to update book id=" + book.getId() + " actorId=" + actor.getId(), ex);
return ServiceResult.failure(UNAVAILABLE_MESSAGE);
@@ -248,16 +248,16 @@ public class BookServiceImpl implements BookService {
return ServiceResult.failure(DENIED_MESSAGE);
}
if (id <= 0) {
return ServiceResult.failure("Select a valid book.");
return ServiceResult.failure("请选择有效的图书。");
}
try {
if (!bookDao.delete(id)) {
return ServiceResult.failure("Book was not found.");
return ServiceResult.failure("未找到图书。");
}
LOGGER.info("Deleted book id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(null, "Book deleted.");
return ServiceResult.success(null, "图书已删除。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to delete book id=" + id + " actorId=" + actor.getId(), ex);
return ServiceResult.failure(UNAVAILABLE_MESSAGE);
@@ -288,30 +288,30 @@ public class BookServiceImpl implements BookService {
private Map<String, String> validate(Book book, boolean requireId) {
Map<String, String> errors = new LinkedHashMap<>();
if (book == null) {
errors.put("book", "Book details are required.");
errors.put("book", "请填写图书详情。");
return errors;
}
if (requireId && book.getId() <= 0) {
errors.put("id", "Select a valid book.");
errors.put("id", "请选择有效的图书。");
}
requireLength(errors, "identifier", book.getIdentifier(), "Book identifier", 64);
requireLength(errors, "title", book.getTitle(), "Title", 200);
requireLength(errors, "author", book.getAuthor(), "Author", 120);
requireLength(errors, "identifier", book.getIdentifier(), "图书编号", 64);
requireLength(errors, "title", book.getTitle(), "书名", 200);
requireLength(errors, "author", book.getAuthor(), "作者", 120);
if (book.getCategoryId() <= 0) {
errors.put("categoryId", "Select a category.");
errors.put("categoryId", "请选择分类。");
}
if (book.getTotalCopies() < 0) {
errors.put("totalCopies", "Total copies cannot be negative.");
errors.put("totalCopies", "馆藏总数不能为负数。");
}
if (book.getAvailableCopies() < 0) {
errors.put("availableCopies", "Available copies cannot be negative.");
errors.put("availableCopies", "可借数量不能为负数。");
}
if (book.getAvailableCopies() > book.getTotalCopies()) {
errors.put("availableCopies", "Available copies cannot exceed total copies.");
errors.put("availableCopies", "可借数量不能超过馆藏总数。");
}
if (book.getStatus() == null) {
errors.put("status", "Select a status.");
errors.put("status", "请选择状态。");
}
return errors;
}
@@ -319,16 +319,16 @@ public class BookServiceImpl implements BookService {
private Map<String, String> validate(BookCategory category, boolean requireId) {
Map<String, String> errors = new LinkedHashMap<>();
if (category == null) {
errors.put("category", "Category details are required.");
errors.put("category", "请填写分类详情。");
return errors;
}
if (requireId && category.getId() <= 0) {
errors.put("id", "Select a valid category.");
errors.put("id", "请选择有效的分类。");
}
requireLength(errors, "name", category.getName(), "Category name", 96);
requireLength(errors, "name", category.getName(), "分类名称", 96);
if (category.getDescription() != null && category.getDescription().length() > 255) {
errors.put("description", "Description must be 255 characters or fewer.");
errors.put("description", "说明不能超过 255 个字符。");
}
return errors;
}
@@ -339,11 +339,11 @@ public class BookServiceImpl implements BookService {
private void requireLength(Map<String, String> errors, String field, String value, String label, int maxLength) {
if (value == null || value.isEmpty()) {
errors.put(field, label + " is required.");
errors.put(field, "请填写" + label + "");
return;
}
if (value.length() > maxLength) {
errors.put(field, label + " must be " + maxLength + " characters or fewer.");
errors.put(field, label + "不能超过 " + maxLength + " 个字符。");
}
}
@@ -35,10 +35,10 @@ public class BorrowingServiceImpl implements BorrowingService {
private static final Logger LOGGER = Logger.getLogger(BorrowingServiceImpl.class.getName());
private static final String UNAVAILABLE_MESSAGE =
"Borrowing service is temporarily unavailable. Please try again later.";
private static final String VALIDATION_MESSAGE = "Please correct the highlighted borrowing fields.";
private static final String DENIED_MESSAGE = "You do not have permission to manage borrowing.";
private static final String HISTORY_DENIED_MESSAGE = "You do not have permission to view loan history.";
"借阅服务暂时不可用,请稍后重试。";
private static final String VALIDATION_MESSAGE = "请修正高亮的借阅字段。";
private static final String DENIED_MESSAGE = "您无权管理借阅。";
private static final String HISTORY_DENIED_MESSAGE = "您无权查看借阅历史。";
private static final int LOAN_DAYS = 14;
private static final int MAX_RENEWALS = 1;
@@ -68,7 +68,7 @@ public class BorrowingServiceImpl implements BorrowingService {
BorrowRecordSearchCriteria normalized = criteria == null ? new BorrowRecordSearchCriteria() : criteria;
Map<String, String> errors = validateSearch(normalized);
if (!errors.isEmpty()) {
return ServiceResult.validationFailure("Please correct the borrowing search filters.", errors);
return ServiceResult.validationFailure("请修正借阅检索筛选条件。", errors);
}
try {
@@ -98,13 +98,13 @@ public class BorrowingServiceImpl implements BorrowingService {
Optional<Reader> readerResult = borrowRecordDao.findReaderByIdentifierForUpdate(connection,
normalizedReaderIdentifier);
if (!readerResult.isPresent()) {
transactionErrors.put("readerIdentifier", "Reader was not found.");
transactionErrors.put("readerIdentifier", "未找到读者。");
}
Optional<Book> bookResult = borrowRecordDao.findBookByIdentifierForUpdate(connection,
normalizedBookIdentifier);
if (!bookResult.isPresent()) {
transactionErrors.put("bookIdentifier", "Book was not found.");
transactionErrors.put("bookIdentifier", "未找到图书。");
}
if (!transactionErrors.isEmpty()) {
@@ -134,7 +134,7 @@ public class BorrowingServiceImpl implements BorrowingService {
LOGGER.info("Borrowed book recordId=" + id + " readerId=" + reader.getId()
+ " bookId=" + book.getId() + " actorId=" + actor.getId());
return ServiceResult.success(id, "Book borrowed.");
return ServiceResult.success(id, "图书已借出。");
});
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to borrow book actorId=" + actor.getId()
@@ -150,20 +150,20 @@ public class BorrowingServiceImpl implements BorrowingService {
return ServiceResult.failure(DENIED_MESSAGE);
}
if (recordId <= 0) {
return ServiceResult.failure("Select a valid borrowing record.");
return ServiceResult.failure("请选择有效的借阅记录。");
}
try {
return transactionExecutor.execute(connection -> {
Optional<BorrowRecord> recordResult = borrowRecordDao.findByIdForUpdate(connection, recordId);
if (!recordResult.isPresent()) {
return ServiceResult.failure("Borrowing record was not found.");
return ServiceResult.failure("未找到借阅记录。");
}
BorrowRecord record = recordResult.get();
Map<String, String> errors = validateActiveLoan(record);
if (!errors.isEmpty()) {
return ServiceResult.validationFailure("Borrowing record cannot be returned.", errors);
return ServiceResult.validationFailure("借阅记录不能归还。", errors);
}
if (!borrowRecordDao.markReturned(connection, recordId, now())) {
@@ -172,7 +172,7 @@ public class BorrowingServiceImpl implements BorrowingService {
borrowRecordDao.incrementAvailableCopies(connection, record.getBookId());
LOGGER.info("Returned borrow recordId=" + recordId + " actorId=" + actor.getId());
return ServiceResult.success(null, "Book returned.");
return ServiceResult.success(null, "图书已归还。");
});
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to return borrow record id=" + recordId + " actorId=" + actor.getId(), ex);
@@ -186,23 +186,23 @@ public class BorrowingServiceImpl implements BorrowingService {
return ServiceResult.failure(DENIED_MESSAGE);
}
if (recordId <= 0) {
return ServiceResult.failure("Select a valid borrowing record.");
return ServiceResult.failure("请选择有效的借阅记录。");
}
try {
return transactionExecutor.execute(connection -> {
Optional<BorrowRecord> recordResult = borrowRecordDao.findByIdForUpdate(connection, recordId);
if (!recordResult.isPresent()) {
return ServiceResult.failure("Borrowing record was not found.");
return ServiceResult.failure("未找到借阅记录。");
}
BorrowRecord record = recordResult.get();
Map<String, String> errors = validateActiveLoan(record);
if (record.getRenewalCount() >= MAX_RENEWALS) {
errors.put("renewalCount", "This loan has already reached the renewal limit.");
errors.put("renewalCount", "该借阅已达到续借次数上限。");
}
if (!errors.isEmpty()) {
return ServiceResult.validationFailure("Borrowing record cannot be renewed.", errors);
return ServiceResult.validationFailure("借阅记录不能续借。", errors);
}
LocalDateTime currentDueAt = record.getDueAt() == null ? now() : record.getDueAt();
@@ -212,7 +212,7 @@ public class BorrowingServiceImpl implements BorrowingService {
}
LOGGER.info("Renewed borrow recordId=" + recordId + " actorId=" + actor.getId());
return ServiceResult.success(null, "Loan renewed.");
return ServiceResult.success(null, "借阅已续借。");
});
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to renew borrow record id=" + recordId + " actorId=" + actor.getId(), ex);
@@ -229,7 +229,7 @@ public class BorrowingServiceImpl implements BorrowingService {
try {
Optional<Reader> readerResult = borrowRecordDao.findReaderByUserId(actor.getId());
if (!readerResult.isPresent()) {
return ServiceResult.success(Collections.emptyList(), "No reader profile is linked to your account.");
return ServiceResult.success(Collections.emptyList(), "您的账户未关联读者档案。");
}
return ServiceResult.success(borrowRecordDao.findByReaderId(readerResult.get().getId()));
@@ -246,16 +246,16 @@ public class BorrowingServiceImpl implements BorrowingService {
private void validateBorrowEligibility(Map<String, String> errors, Reader reader, Book book,
java.sql.Connection connection) {
if (reader.getStatus() != ReaderStatus.ACTIVE) {
errors.put("readerIdentifier", "Reader must be active to borrow books.");
errors.put("readerIdentifier", "读者状态必须为正常才能借阅图书。");
}
int activeLoans = borrowRecordDao.countActiveByReaderId(connection, reader.getId());
if (activeLoans >= reader.getMaxBorrowCount()) {
errors.put("readerIdentifier", "Reader has reached the active borrowing limit.");
errors.put("readerIdentifier", "读者已达到在借数量上限。");
}
if (book.getStatus() != BookStatus.AVAILABLE) {
errors.put("bookIdentifier", "Book status does not allow borrowing.");
errors.put("bookIdentifier", "图书状态不允许借阅。");
} else if (book.getAvailableCopies() <= 0) {
errors.put("bookIdentifier", "No available copies remain for this book.");
errors.put("bookIdentifier", "该图书没有可借副本。");
}
}
@@ -270,7 +270,7 @@ public class BorrowingServiceImpl implements BorrowingService {
try {
BorrowRecordStatus.fromCode(statusCode);
} catch (IllegalArgumentException ex) {
errors.put("status", "Select a valid borrowing status.");
errors.put("status", "请选择有效的借阅状态。");
}
}
return errors;
@@ -278,26 +278,26 @@ public class BorrowingServiceImpl implements BorrowingService {
private Map<String, String> validateBorrowIdentifiers(String readerIdentifier, String bookIdentifier) {
Map<String, String> errors = new LinkedHashMap<>();
requireLength(errors, "readerIdentifier", readerIdentifier, "Reader ID", 64);
requireLength(errors, "bookIdentifier", bookIdentifier, "Book ID", 64);
requireLength(errors, "readerIdentifier", readerIdentifier, "读者编号", 64);
requireLength(errors, "bookIdentifier", bookIdentifier, "图书编号", 64);
return errors;
}
private Map<String, String> validateActiveLoan(BorrowRecord record) {
Map<String, String> errors = new LinkedHashMap<>();
if (record.getStatus() != BorrowRecordStatus.ACTIVE || record.getReturnedAt() != null) {
errors.put("status", "Only active loans can use this action.");
errors.put("status", "只有借阅中的记录可以执行此操作。");
}
return errors;
}
private void requireLength(Map<String, String> errors, String field, String value, String label, int maxLength) {
if (value == null || value.isEmpty()) {
errors.put(field, label + " is required.");
errors.put(field, "请填写" + label + "");
return;
}
if (value.length() > maxLength) {
errors.put(field, label + " must be " + maxLength + " characters or fewer.");
errors.put(field, label + "不能超过 " + maxLength + " 个字符。");
}
}
@@ -22,10 +22,10 @@ import java.util.logging.Logger;
public class ReaderServiceImpl implements ReaderService {
private static final Logger LOGGER = Logger.getLogger(ReaderServiceImpl.class.getName());
private static final String UNAVAILABLE_MESSAGE =
"Reader service is temporarily unavailable. Please try again later.";
private static final String VALIDATION_MESSAGE = "Please correct the highlighted reader fields.";
private static final String SEARCH_VALIDATION_MESSAGE = "Please correct the reader search filters.";
private static final String DENIED_MESSAGE = "You do not have permission to manage readers.";
"读者服务暂时不可用,请稍后重试。";
private static final String VALIDATION_MESSAGE = "请修正高亮的读者字段。";
private static final String SEARCH_VALIDATION_MESSAGE = "请修正读者检索筛选条件。";
private static final String DENIED_MESSAGE = "您无权管理读者。";
private static final int MAX_BORROW_LIMIT = 50;
private static final Pattern PHONE_PATTERN = Pattern.compile("(?=.*\\d)[0-9+()\\-\\s]{6,32}");
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$");
@@ -61,7 +61,7 @@ public class ReaderServiceImpl implements ReaderService {
@Override
public ServiceResult<Optional<Reader>> findReader(long id) {
if (id <= 0) {
return ServiceResult.failure("Select a valid reader.");
return ServiceResult.failure("请选择有效的读者。");
}
try {
@@ -86,17 +86,17 @@ public class ReaderServiceImpl implements ReaderService {
try {
if (readerDao.findByIdentifier(reader.getIdentifier()).isPresent()) {
errors.put("identifier", "Reader identifier is already in use.");
errors.put("identifier", "读者编号已被使用。");
return ServiceResult.validationFailure(VALIDATION_MESSAGE, errors);
}
if (reader.getUserId() != null && readerDao.findByUserId(reader.getUserId()).isPresent()) {
errors.put("userId", "Linked account is already assigned to a reader profile.");
errors.put("userId", "关联账户已绑定到其他读者档案。");
return ServiceResult.validationFailure(VALIDATION_MESSAGE, errors);
}
long id = readerDao.create(reader);
LOGGER.info("Created reader id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(id, "Reader profile created.");
return ServiceResult.success(id, "读者档案已创建。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to create reader actorId=" + actor.getId(), ex);
return ServiceResult.failure(UNAVAILABLE_MESSAGE);
@@ -118,23 +118,23 @@ public class ReaderServiceImpl implements ReaderService {
try {
Optional<Reader> existingWithIdentifier = readerDao.findByIdentifier(reader.getIdentifier());
if (existingWithIdentifier.isPresent() && existingWithIdentifier.get().getId() != reader.getId()) {
errors.put("identifier", "Reader identifier is already in use.");
errors.put("identifier", "读者编号已被使用。");
return ServiceResult.validationFailure(VALIDATION_MESSAGE, errors);
}
if (reader.getUserId() != null) {
Optional<Reader> existingWithUser = readerDao.findByUserId(reader.getUserId());
if (existingWithUser.isPresent() && existingWithUser.get().getId() != reader.getId()) {
errors.put("userId", "Linked account is already assigned to a reader profile.");
errors.put("userId", "关联账户已绑定到其他读者档案。");
return ServiceResult.validationFailure(VALIDATION_MESSAGE, errors);
}
}
if (!readerDao.update(reader)) {
return ServiceResult.failure("Reader profile was not found.");
return ServiceResult.failure("未找到读者档案。");
}
LOGGER.info("Updated reader id=" + reader.getId() + " actorId=" + actor.getId());
return ServiceResult.success(null, "Reader profile updated.");
return ServiceResult.success(null, "读者档案已更新。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to update reader id=" + reader.getId() + " actorId=" + actor.getId(), ex);
return ServiceResult.failure(UNAVAILABLE_MESSAGE);
@@ -147,16 +147,16 @@ public class ReaderServiceImpl implements ReaderService {
return ServiceResult.failure(DENIED_MESSAGE);
}
if (id <= 0) {
return ServiceResult.failure("Select a valid reader.");
return ServiceResult.failure("请选择有效的读者。");
}
try {
if (!readerDao.deactivate(id)) {
return ServiceResult.failure("Reader profile was not found.");
return ServiceResult.failure("未找到读者档案。");
}
LOGGER.info("Deactivated reader id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(null, "Reader profile deactivated.");
return ServiceResult.success(null, "读者档案已停用。");
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to deactivate reader id=" + id + " actorId=" + actor.getId(), ex);
return ServiceResult.failure(UNAVAILABLE_MESSAGE);
@@ -183,7 +183,7 @@ public class ReaderServiceImpl implements ReaderService {
try {
criteria.setStatusCode(ReaderStatus.fromCode(criteria.getStatusCode()).getCode());
} catch (IllegalArgumentException ex) {
errors.put("status", "Select a valid status.");
errors.put("status", "请选择有效的状态。");
}
}
return errors;
@@ -192,24 +192,24 @@ public class ReaderServiceImpl implements ReaderService {
private Map<String, String> validate(Reader reader, boolean requireId) {
Map<String, String> errors = new LinkedHashMap<>();
if (reader == null) {
errors.put("reader", "Reader details are required.");
errors.put("reader", "请填写读者详情。");
return errors;
}
if (requireId && reader.getId() <= 0) {
errors.put("id", "Select a valid reader.");
errors.put("id", "请选择有效的读者。");
}
requireLength(errors, "identifier", reader.getIdentifier(), "Reader identifier", 64);
requireLength(errors, "fullName", reader.getFullName(), "Full name", 100);
requireLength(errors, "identifier", reader.getIdentifier(), "读者编号", 64);
requireLength(errors, "fullName", reader.getFullName(), "姓名", 100);
if (reader.getUserId() != null && reader.getUserId() <= 0) {
errors.put("userId", "Linked account ID must be positive.");
errors.put("userId", "关联账户 ID 必须为正数。");
}
validateContact(errors, reader);
if (reader.getStatus() == null) {
errors.put("status", "Select a status.");
errors.put("status", "请选择状态。");
}
if (reader.getMaxBorrowCount() < 1 || reader.getMaxBorrowCount() > MAX_BORROW_LIMIT) {
errors.put("maxBorrowCount", "Max borrow count must be between 1 and " + MAX_BORROW_LIMIT + ".");
errors.put("maxBorrowCount", "最大借阅数量必须在 1 到 " + MAX_BORROW_LIMIT + " 之间。");
}
return errors;
}
@@ -218,24 +218,24 @@ public class ReaderServiceImpl implements ReaderService {
String phone = reader.getPhone();
String email = reader.getEmail();
if ((phone == null || phone.isEmpty()) && (email == null || email.isEmpty())) {
errors.put("phone", "Phone or email is required.");
errors.put("phone", "请填写电话或邮箱。");
return;
}
if (phone != null && !phone.isEmpty() && !PHONE_PATTERN.matcher(phone).matches()) {
errors.put("phone", "Phone must include a digit and use 6 to 32 digits or common phone symbols.");
errors.put("phone", "电话必须包含数字,并使用 6 32 位数字或常见电话符号。");
}
if (email != null && !email.isEmpty() && !EMAIL_PATTERN.matcher(email).matches()) {
errors.put("email", "Email must be a valid address.");
errors.put("email", "邮箱格式不正确。");
}
}
private void requireLength(Map<String, String> errors, String field, String value, String label, int maxLength) {
if (value == null || value.isEmpty()) {
errors.put(field, label + " is required.");
errors.put(field, "请填写" + label + "");
return;
}
if (value.length() > maxLength) {
errors.put(field, label + " must be " + maxLength + " characters or fewer.");
errors.put(field, label + "不能超过 " + maxLength + " 个字符。");
}
}
@@ -15,8 +15,8 @@ import java.util.logging.Logger;
public class ReportServiceImpl implements ReportService {
private static final Logger LOGGER = Logger.getLogger(ReportServiceImpl.class.getName());
private static final String UNAVAILABLE_MESSAGE =
"Report service is temporarily unavailable. Please try again later.";
private static final String DENIED_MESSAGE = "You do not have permission to view reports.";
"报表服务暂时不可用,请稍后重试。";
private static final String DENIED_MESSAGE = "您无权查看报表。";
private static final int POPULAR_BOOK_LIMIT = 10;
private final ReportDao reportDao;
@@ -20,9 +20,9 @@ import java.util.logging.Logger;
public class SystemLogServiceImpl implements SystemLogService {
private static final Logger LOGGER = Logger.getLogger(SystemLogServiceImpl.class.getName());
private static final String UNAVAILABLE_MESSAGE =
"System log service is temporarily unavailable. Please try again later.";
private static final String DENIED_MESSAGE = "You do not have permission to view system logs.";
private static final String VALIDATION_MESSAGE = "Please correct the system log search filters.";
"系统日志服务暂时不可用,请稍后重试。";
private static final String DENIED_MESSAGE = "您无权查看系统日志。";
private static final String VALIDATION_MESSAGE = "请修正系统日志检索筛选条件。";
private final SystemLogDao systemLogDao;
private final PermissionPolicy permissionPolicy;
@@ -62,18 +62,18 @@ public class SystemLogServiceImpl implements SystemLogService {
private Map<String, String> validate(SystemLogSearchCriteria criteria) {
Map<String, String> errors = new LinkedHashMap<>();
if (criteria.getOperationType().length() > 64) {
errors.put("operationType", "Operation type must be 64 characters or fewer.");
errors.put("operationType", "操作类型不能超过 64 个字符。");
}
if (criteria.getKeyword().length() > 120) {
errors.put("keyword", "Keyword must be 120 characters or fewer.");
errors.put("keyword", "关键词不能超过 120 个字符。");
}
parseDate(criteria.getCreatedFromText(), "createdFrom", "Start date", errors, criteria, true);
parseDate(criteria.getCreatedToText(), "createdTo", "End date", errors, criteria, false);
parseDate(criteria.getCreatedFromText(), "createdFrom", "开始日期", errors, criteria, true);
parseDate(criteria.getCreatedToText(), "createdTo", "结束日期", errors, criteria, false);
if (criteria.getCreatedFrom() != null
&& criteria.getCreatedTo() != null
&& criteria.getCreatedFrom().isAfter(criteria.getCreatedTo())) {
errors.put("createdTo", "End date must be on or after start date.");
errors.put("createdTo", "结束日期必须晚于或等于开始日期。");
}
return errors;
}
@@ -91,7 +91,7 @@ public class SystemLogServiceImpl implements SystemLogService {
criteria.setCreatedTo(parsed);
}
} catch (DateTimeParseException ex) {
errors.put(field, label + " must use YYYY-MM-DD.");
errors.put(field, label + "必须使用 YYYY-MM-DD 格式。");
}
}
@@ -30,12 +30,12 @@ public class UserAccountServiceImpl implements UserAccountService {
private static final Logger LOGGER = Logger.getLogger(UserAccountServiceImpl.class.getName());
private static final String UNAVAILABLE_MESSAGE =
"User management service is temporarily unavailable. Please try again later.";
private static final String VALIDATION_MESSAGE = "Please correct the highlighted account fields.";
private static final String SEARCH_VALIDATION_MESSAGE = "Please correct the account search filters.";
private static final String DENIED_MESSAGE = "You do not have permission to manage users.";
private static final String SELF_DEACTIVATE_MESSAGE = "You cannot deactivate your own administrator account.";
private static final String SELF_ROLE_MESSAGE = "You cannot change your own administrator role.";
"用户管理服务暂时不可用,请稍后重试。";
private static final String VALIDATION_MESSAGE = "请修正高亮的账户字段。";
private static final String SEARCH_VALIDATION_MESSAGE = "请修正账户检索筛选条件。";
private static final String DENIED_MESSAGE = "您无权管理用户。";
private static final String SELF_DEACTIVATE_MESSAGE = "不能停用您自己的管理员账户。";
private static final String SELF_ROLE_MESSAGE = "不能修改您自己的管理员角色。";
private final UserAccountDao userAccountDao;
private final SystemLogDao systemLogDao;
@@ -80,7 +80,7 @@ public class UserAccountServiceImpl implements UserAccountService {
return ServiceResult.failure(DENIED_MESSAGE);
}
if (id <= 0) {
return ServiceResult.failure("Select a valid user account.");
return ServiceResult.failure("请选择有效的用户账户。");
}
try {
@@ -105,7 +105,7 @@ public class UserAccountServiceImpl implements UserAccountService {
try {
if (userAccountDao.findByUsername(user.getUsername()).isPresent()) {
errors.put("username", "Username is already in use.");
errors.put("username", "用户名已被使用。");
return ServiceResult.validationFailure(VALIDATION_MESSAGE, errors);
}
@@ -113,10 +113,10 @@ public class UserAccountServiceImpl implements UserAccountService {
return transactionExecutor.execute(connection -> {
long id = userAccountDao.create(connection, user);
systemLogDao.create(connection, auditLog(actor, "user.create", id,
"Created account username=" + user.getUsername() + " role=" + user.getRole().getCode(),
"创建账户:用户名=" + user.getUsername() + ",角色=" + user.getRole().getDisplayName(),
requestIp));
LOGGER.info("Created user id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(id, "User account created.");
return ServiceResult.success(id, "用户账户已创建。");
});
} catch (DaoException | IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "Unable to create user actorId=" + actor.getId()
@@ -140,7 +140,7 @@ public class UserAccountServiceImpl implements UserAccountService {
try {
Optional<User> existingResult = userAccountDao.findById(user.getId());
if (!existingResult.isPresent()) {
return ServiceResult.failure("User account was not found.");
return ServiceResult.failure("未找到用户账户。");
}
protectCurrentAdministrator(actor, user, errors);
@@ -158,15 +158,15 @@ public class UserAccountServiceImpl implements UserAccountService {
final boolean passwordChanged = updatePassword;
return transactionExecutor.execute(connection -> {
if (!userAccountDao.update(connection, user, passwordChanged)) {
return ServiceResult.failure("User account was not found.");
return ServiceResult.failure("未找到用户账户。");
}
systemLogDao.create(connection, auditLog(actor, "user.update", user.getId(),
"Updated account username=" + user.getUsername() + " role=" + user.getRole().getCode()
+ " active=" + user.isActive()
+ (passwordChanged ? " passwordReset=true" : ""),
"更新账户:用户名=" + user.getUsername() + ",角色=" + user.getRole().getDisplayName()
+ ",状态=" + (user.isActive() ? "启用" : "停用")
+ (passwordChanged ? ",已重置密码" : ""),
requestIp));
LOGGER.info("Updated user id=" + user.getId() + " actorId=" + actor.getId());
return ServiceResult.success(null, "User account updated.");
return ServiceResult.success(null, "用户账户已更新。");
});
} catch (DaoException | IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "Unable to update user id=" + user.getId() + " actorId=" + actor.getId(), ex);
@@ -180,7 +180,7 @@ public class UserAccountServiceImpl implements UserAccountService {
return ServiceResult.failure(DENIED_MESSAGE);
}
if (id <= 0) {
return ServiceResult.failure("Select a valid user account.");
return ServiceResult.failure("请选择有效的用户账户。");
}
if (actor.getId() == id) {
Map<String, String> errors = new LinkedHashMap<>();
@@ -191,20 +191,20 @@ public class UserAccountServiceImpl implements UserAccountService {
try {
Optional<User> existingResult = userAccountDao.findById(id);
if (!existingResult.isPresent()) {
return ServiceResult.failure("User account was not found.");
return ServiceResult.failure("未找到用户账户。");
}
User user = existingResult.get();
user.setActive(false);
return transactionExecutor.execute(connection -> {
if (!userAccountDao.update(connection, user, false)) {
return ServiceResult.failure("User account was not found.");
return ServiceResult.failure("未找到用户账户。");
}
systemLogDao.create(connection, auditLog(actor, "user.deactivate", id,
"Deactivated account username=" + user.getUsername(),
"停用账户:用户名=" + user.getUsername(),
requestIp));
LOGGER.info("Deactivated user id=" + id + " actorId=" + actor.getId());
return ServiceResult.success(null, "User account deactivated.");
return ServiceResult.success(null, "用户账户已停用。");
});
} catch (DaoException ex) {
LOGGER.log(Level.SEVERE, "Unable to deactivate user id=" + id + " actorId=" + actor.getId(), ex);
@@ -218,7 +218,7 @@ public class UserAccountServiceImpl implements UserAccountService {
try {
criteria.setRoleCode(Role.fromCode(criteria.getRoleCode()).getCode());
} catch (IllegalArgumentException ex) {
errors.put("role", "Select a valid role.");
errors.put("role", "请选择有效的角色。");
}
}
@@ -226,7 +226,7 @@ public class UserAccountServiceImpl implements UserAccountService {
if (!activeStatus.isEmpty()
&& !UserSearchCriteria.ACTIVE_STATUS.equals(activeStatus)
&& !UserSearchCriteria.INACTIVE_STATUS.equals(activeStatus)) {
errors.put("active", "Select a valid active state.");
errors.put("active", "请选择有效的启用状态。");
}
return errors;
}
@@ -234,19 +234,19 @@ public class UserAccountServiceImpl implements UserAccountService {
private Map<String, String> validateUser(User user, boolean requireId, String password, boolean requirePassword) {
Map<String, String> errors = new LinkedHashMap<>();
if (user == null) {
errors.put("user", "User account details are required.");
errors.put("user", "请填写用户账户详情。");
return errors;
}
if (requireId && user.getId() <= 0) {
errors.put("id", "Select a valid user account.");
errors.put("id", "请选择有效的用户账户。");
}
if (!requireId) {
requireLength(errors, "username", user.getUsername(), "Username", 64);
requireLength(errors, "username", user.getUsername(), "用户名", 64);
}
requireLength(errors, "displayName", user.getDisplayName(), "Display name", 100);
requireLength(errors, "displayName", user.getDisplayName(), "显示名称", 100);
if (user.getRole() == null) {
errors.put("role", "Select a role.");
errors.put("role", "请选择角色。");
}
validatePassword(errors, password, requirePassword);
return errors;
@@ -256,12 +256,12 @@ public class UserAccountServiceImpl implements UserAccountService {
String trimmed = password == null ? "" : password.trim();
if (trimmed.isEmpty()) {
if (required) {
errors.put("password", "Password is required.");
errors.put("password", "请填写密码。");
}
return;
}
if (password.length() > 128) {
errors.put("password", "Password must be 128 characters or fewer.");
errors.put("password", "密码不能超过 128 个字符。");
}
}
@@ -279,11 +279,11 @@ public class UserAccountServiceImpl implements UserAccountService {
private void requireLength(Map<String, String> errors, String field, String value, String label, int maxLength) {
if (value == null || value.isEmpty()) {
errors.put(field, label + " is required.");
errors.put(field, "请填写" + label + "");
return;
}
if (value.length() > maxLength) {
errors.put(field, label + " must be " + maxLength + " characters or fewer.");
errors.put(field, label + "不能超过 " + maxLength + " 个字符。");
}
}