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

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
+116 -1
View File
@@ -27,10 +27,11 @@ Implemented scaffold tables:
- `book_categories`: category names and descriptions for catalog grouping.
- `books`: book information, category reference, inventory counts, and catalog
status.
- `readers`: reader profiles, optional login-account linkage, borrowing
eligibility, contact information, and management status.
Planned module tables:
- `readers`: reader profiles, borrowing eligibility, contact information.
- `borrow_records`: book-reader borrowing, return, renew, and overdue data.
Record new schema changes in `src/main/resources/db/schema.sql` and update this
@@ -78,6 +79,11 @@ spec with exact table names, key columns, and DAO/service contracts.
- `role_permissions.permission_code` must reference `permissions.code`.
- `books.status` must match `BookStatus` enum codes: `available`,
`unavailable`, and `archived`.
- `readers.user_id` may reference `users.id` when a reader profile is linked to
a login account.
- `readers.status` must match `ReaderStatus` enum codes: `active`,
`suspended`, and `inactive`.
- `readers.max_borrow_count` must stay between 1 and 50.
## Scenario: Book Catalog And Management Slice
@@ -187,6 +193,115 @@ books/form.jsp -> JDBC -> INSERT INTO books using request parameters
books/form.jsp -> BookManagementServlet -> BookService -> BookDao -> books
```
## Scenario: Reader Information Management Slice
### 1. Scope / Trigger
- Trigger: the reader profile foundation was implemented after login,
permissions, catalog search, and book management.
- Schema path: `src/main/resources/db/schema.sql`.
- JSP paths: `WEB-INF/jsp/readers/manage.jsp` and `readers/form.jsp`.
### 2. Signatures
- DAO signatures: `ReaderDao.search(ReaderSearchCriteria criteria)`,
`findById(long id)`, `findByIdentifier(String identifier)`,
`findByUserId(long userId)`, `create(Reader reader)`,
`update(Reader reader)`, and `deactivate(long id)`.
- Entity/search signatures: `Reader` fields are `id`, `identifier`,
nullable `userId`, nullable `username`, `fullName`, `phone`, `email`,
`status`, `maxBorrowCount`, `createdAt`, and `updatedAt`;
`ReaderSearchCriteria` fields are `identifier`, `name`, `contact`, and
`statusCode`.
- Status signature: `ReaderStatus` enum codes are `active`, `suspended`, and
`inactive`.
- Service signatures: `ReaderService.searchReaders(ReaderSearchCriteria)`,
`findReader(long id)`, `createReader(AuthenticatedUser actor, Reader reader)`,
`updateReader(AuthenticatedUser actor, Reader reader)`, and
`deactivateReader(AuthenticatedUser actor, long id)`, all returning
`ServiceResult<T>`.
- Management routes: `GET /readers`, `GET /readers/new`,
`GET /readers/edit?id=...`, `POST /readers`, `POST /readers/update`, and
`POST /readers/delete`.
- Protected permission: `/readers*` requires `MANAGE_READERS`.
- DB signature: `readers(id, reader_identifier, user_id, full_name, phone,
email, status, max_borrow_count, created_at, updated_at)`, with unique keys
on `reader_identifier` and nullable `user_id`, indexes on name/contact/status,
a foreign key to `users(id)`, and checks for supported status values and
borrow-limit range.
### 3. Contracts
- `readers.reader_identifier` is the unique user-facing reader ID.
- `readers.user_id` is optional; when present, only one reader profile may link
to the same login account.
- `readers.status` stores the Java `ReaderStatus` code exactly. Soft-delete
behavior deactivates the profile by setting status to `inactive`.
- Reader searches support partial identifier, full-name, and phone/email
contact matching plus exact status filtering.
- Servlet controllers parse request fields and set JSP attributes such as
`criteria`, `readers`, `reader`, `statuses`, `formValues`, `errors`,
`errorMessage`, and `successMessage`.
- JSP pages render JavaBean properties only; they must not call DAOs or embed
SQL.
- Navigation should expose reader management to administrator/librarian users,
matching the current `MANAGE_READERS` policy.
### 4. Validation & Error Matrix
- Missing identifier or full name -> return to `readers/form.jsp` with field
errors.
- Missing both phone and email -> return a field error on `phone`.
- Invalid phone or email format -> return field errors on `phone` or `email`.
- Unsupported status -> return a field error on `status`.
- Max borrow count outside 1 to 50 -> return a field error on
`maxBorrowCount`.
- Non-positive linked `user_id` -> return a field error on `userId`.
- Duplicate `reader_identifier` -> return a field error on `identifier`.
- Duplicate linked `user_id` -> return a field error on `userId`.
- Reader or unauthenticated actor attempts write -> HTTP 403 through
authorization filter or service denial.
- DAO failure during list/search/write -> log server-side details and return
`Reader service is temporarily unavailable. Please try again later.`
- Successful create/update/deactivate -> redirect to `/readers` with a short
flash message.
### 5. Good/Base/Bad Cases
- Good: a librarian creates `RD-1003`, searches by email, edits the borrow
limit, and can later deactivate the profile without deleting future borrowing
history.
- Base: `/readers` with no filters lists reader records ordered by full name
and reader identifier.
- Bad: normal readers access `/readers`, a JSP opens JDBC, or deleting a reader
profile removes rows that future borrow records need to reference.
### 6. Tests Required
- Run `ReaderServiceCheck` or equivalent assertions for invalid contact,
invalid borrow limit, duplicate identifiers, duplicate linked users, reader
write denial, successful librarian CRUD-like operations, search, deactivate,
and DAO failure fallback.
- Run `PermissionPolicyCheck` to confirm librarians have `MANAGE_READERS` and
readers do not.
- Scan reader JSPs for scriptlets and SQL/JDBC references.
- When Maven/Tomcat dependencies are installed, run `mvn clean package` to
compile Servlets and package JSP resources.
### 7. Wrong vs Correct
#### Wrong
```text
readers/form.jsp -> JDBC -> DELETE FROM readers using request parameters
```
#### Correct
```text
readers/form.jsp -> ReaderManagementServlet -> ReaderService -> ReaderDao -> readers.status = inactive
```
## Scenario: Login And Permission Scaffold Schema
### 1. Scope / Trigger