前端风格更改
This commit is contained in:
@@ -16,8 +16,14 @@ the reusable UI units.
|
|||||||
|
|
||||||
- Use shared fragments for repeated layout pieces such as header, navigation,
|
- Use shared fragments for repeated layout pieces such as header, navigation,
|
||||||
sidebar, footer, pagination, and message banners.
|
sidebar, footer, pagination, and message banners.
|
||||||
- Prefer `.jspf` includes or JSP tag files once the project chooses one
|
- Use `.jspf` includes for the current JSP presentation layer. The authenticated
|
||||||
pattern; document the actual paths after implementation.
|
application frame lives in `src/main/webapp/WEB-INF/jsp/common/header.jspf`
|
||||||
|
and owns the dark sidebar, top utility bar, role workbench links, module
|
||||||
|
navigation, global search, user display, and logout link.
|
||||||
|
- Preserve role-conditioned navigation in that shared frame: administrator-only
|
||||||
|
links stay inside `sessionScope.userRole == 'administrator'`; staff links stay
|
||||||
|
inside `administrator or librarian`; reader-only links stay inside
|
||||||
|
`sessionScope.userRole == 'reader'`.
|
||||||
- Keep fragments presentation-focused. They should not open database
|
- Keep fragments presentation-focused. They should not open database
|
||||||
connections or call DAOs.
|
connections or call DAOs.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{"file": ".trellis/spec/frontend/index.md", "reason": "Frontend JSP/CSS stack and checklist for review."}
|
||||||
|
{"file": ".trellis/spec/frontend/component-guidelines.md", "reason": "Review shared JSP fragments, forms, tables, navigation, and Chinese copy."}
|
||||||
|
{"file": ".trellis/spec/frontend/quality-guidelines.md", "reason": "Review visual fidelity to image-first workflow and forbidden patterns."}
|
||||||
|
{"file": ".trellis/spec/frontend/state-management.md", "reason": "Verify server-rendered state and existing data flow remain intact."}
|
||||||
|
{"file": ".trellis/spec/frontend/type-safety.md", "reason": "Verify display contracts and validation handling remain safe."}
|
||||||
|
{"file": ".trellis/tasks/04-28-frontend-reference-redesign/research/reference-dashboard-visual-notes.md", "reason": "Compare implementation against extracted visual requirements."}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{"file": ".trellis/spec/frontend/index.md", "reason": "Frontend JSP/CSS stack and pre-development checklist for this redesign."}
|
||||||
|
{"file": ".trellis/spec/frontend/directory-structure.md", "reason": "JSP and static asset organization constraints."}
|
||||||
|
{"file": ".trellis/spec/frontend/component-guidelines.md", "reason": "Shared JSP fragment, form, table, navigation, and Chinese copy conventions."}
|
||||||
|
{"file": ".trellis/spec/frontend/quality-guidelines.md", "reason": "Image-to-JSP restoration quality bar and forbidden patterns."}
|
||||||
|
{"file": ".trellis/spec/frontend/hook-guidelines.md", "reason": "Confirms no React/Vue hook conventions should be introduced."}
|
||||||
|
{"file": ".trellis/spec/frontend/state-management.md", "reason": "Server-rendered request/session/form state conventions to preserve."}
|
||||||
|
{"file": ".trellis/spec/frontend/type-safety.md", "reason": "JSP/Servlet validation and JavaBean display contract constraints."}
|
||||||
|
{"file": ".trellis/tasks/04-28-frontend-reference-redesign/research/reference-dashboard-visual-notes.md", "reason": "Visual requirements extracted from the provided reference image."}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
# brainstorm: Redesign Frontend From Reference Image
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Refactor the JSP/CSS frontend so the library-management application visually matches the provided dashboard reference as closely as practical while preserving existing Servlet/JSP behavior, routes, role-based navigation, forms, tables, and Simplified Chinese interface copy.
|
||||||
|
|
||||||
|
## What I Already Know
|
||||||
|
|
||||||
|
* The user wants the frontend rebuilt to imitate the attached reference image as closely as possible.
|
||||||
|
* The reference image is a Chinese library management dashboard with a dark left sidebar, white top bar, dense white card panels, blue primary actions, rounded statistics cards, table sections, and operational shortcut tiles.
|
||||||
|
* The application is a JSP + Servlet + Maven WAR project, not a React/Vue SPA.
|
||||||
|
* Existing frontend files live under `src/main/webapp/WEB-INF/jsp/` with shared CSS in `src/main/webapp/static/css/app.css`.
|
||||||
|
* Current shared header fragment is `src/main/webapp/WEB-INF/jsp/common/header.jspf`.
|
||||||
|
* Existing pages include dashboard, login, catalog, book management, reader management, borrowing, reports, system logs, and user management JSPs.
|
||||||
|
* Frontend spec requires image-first implementation and Simplified Chinese display copy.
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
* "Frontend" means the shared visual system across JSP pages, with the dashboard receiving the closest match because the reference image is a dashboard screenshot.
|
||||||
|
* The redesign should keep current endpoints, request parameter names, JSTL conditions, and server-rendered data contracts unchanged.
|
||||||
|
* New CSS classes and JSP structure are allowed when they improve visual fidelity, but no new frontend framework should be introduced.
|
||||||
|
* The reference image should be stored with the task for implementation/check agents.
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
* Confirm scope: apply the reference style across the whole JSP frontend, not only the dashboard page.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
* Build a left dark sidebar similar to the reference, including brand/title, role workbench buttons, module navigation, and compact footer/menu area.
|
||||||
|
* Build a top utility bar similar to the reference, including breadcrumb/location text, search field, notification/avatar/user controls where appropriate.
|
||||||
|
* Restyle the dashboard as a dense admin workspace with:
|
||||||
|
* Large white dashboard shell.
|
||||||
|
* Four metric cards with colored icon blocks and month-over-month text.
|
||||||
|
* Search/filter panel.
|
||||||
|
* Ranking/chart-like panel matching the screenshot's simple blue bar chart look.
|
||||||
|
* Recent borrowing table and overdue table.
|
||||||
|
* Book-management table.
|
||||||
|
* Shortcut cards for reader management, report center, borrowing circulation, and system logs.
|
||||||
|
* Restyle shared tables, forms, buttons, badges, panels, empty states, and navigation so secondary pages feel consistent with the reference.
|
||||||
|
* Preserve existing JSP/Servlet behavior and role-based visibility.
|
||||||
|
* Keep user-visible copy in Simplified Chinese.
|
||||||
|
* Keep responsive behavior usable on narrower screens.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
* [ ] Dashboard layout visibly matches the reference image's structure, spacing, palette, and density.
|
||||||
|
* [ ] Shared navigation changes are reflected across existing JSP pages without breaking role-based links.
|
||||||
|
* [ ] Existing forms and tables remain functional and readable after the redesign.
|
||||||
|
* [ ] No React/Vue/SPA tooling is introduced.
|
||||||
|
* [ ] Maven build succeeds.
|
||||||
|
|
||||||
|
## Definition Of Done
|
||||||
|
|
||||||
|
* Tests/build run where available.
|
||||||
|
* JSP/CSS changes reviewed against frontend specs and the reference image.
|
||||||
|
* Task context files are curated for implement/check agents.
|
||||||
|
* Any reusable convention learned during the work is considered for spec update.
|
||||||
|
|
||||||
|
## Out Of Scope
|
||||||
|
|
||||||
|
* Backend behavior changes.
|
||||||
|
* Database schema changes.
|
||||||
|
* Replacing JSP with a JavaScript framework.
|
||||||
|
* Exact live charting libraries unless needed; a CSS/HTML approximation is acceptable for this visual refactor.
|
||||||
|
|
||||||
|
## Technical Notes
|
||||||
|
|
||||||
|
* Reference image copied to `.trellis/tasks/04-28-frontend-reference-redesign/research/reference-dashboard.png`.
|
||||||
|
* Visual notes are recorded in `.trellis/tasks/04-28-frontend-reference-redesign/research/reference-dashboard-visual-notes.md`.
|
||||||
|
* Relevant spec index: `.trellis/spec/frontend/index.md`.
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
# Reference Dashboard Visual Notes
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
Reference image: `.trellis/tasks/04-28-frontend-reference-redesign/research/reference-dashboard.png`
|
||||||
|
|
||||||
|
Original accessible path during planning: `/mnt/d/qq/聊天文件/2535624881/nt_qq/nt_data/Pic/2026-04/Ori/ab6d1035bac12c469acaffea0e6db1c8.png`
|
||||||
|
|
||||||
|
## Overall Layout
|
||||||
|
|
||||||
|
* Full application frame with a fixed-width dark navy sidebar on the left and a light gray workspace on the right.
|
||||||
|
* Sidebar width is about 250 px in the reference. It contains the system name at top, role workbench buttons, module navigation links, and a compact menu icon near the bottom.
|
||||||
|
* Main area has a white top bar with breadcrumb text on the left and search, notification, avatar, role label, and dropdown affordance on the right.
|
||||||
|
* Content area uses a light gray page background with white cards, small border radius, subtle shadows, and dense spacing.
|
||||||
|
|
||||||
|
## Palette And Typography
|
||||||
|
|
||||||
|
* Sidebar: very dark navy gradient or solid dark blue-black.
|
||||||
|
* Primary action blue: medium royal blue.
|
||||||
|
* Secondary accent colors: teal, orange, purple, red, and green for icon/stat/status accents.
|
||||||
|
* Cards: white with light gray borders and soft shadows.
|
||||||
|
* Text: dark slate/near black for headings, gray for helper copy and metadata.
|
||||||
|
* Typography is compact, Chinese UI oriented, and dashboard-like rather than marketing-like.
|
||||||
|
|
||||||
|
## Dashboard Structure
|
||||||
|
|
||||||
|
* Top hero panel starts with "管理员工作台" heading and short explanatory copy.
|
||||||
|
* Four statistic cards in one row:
|
||||||
|
* 馆藏总量
|
||||||
|
* 在借数量
|
||||||
|
* 逾期数量
|
||||||
|
* 读者总数
|
||||||
|
* Middle area:
|
||||||
|
* Left: 馆藏检索 form with two-column labels/inputs/select and blue search button plus reset button.
|
||||||
|
* Right: 热门图书排行 bar chart with blue vertical bars and small labels.
|
||||||
|
* Table area:
|
||||||
|
* 借阅流通 recent records table.
|
||||||
|
* 逾期列表 pending overdue table.
|
||||||
|
* 图书管理 book list table.
|
||||||
|
* Bottom/right shortcut tiles:
|
||||||
|
* 读者管理
|
||||||
|
* 报表中心
|
||||||
|
* 借阅流通
|
||||||
|
* 系统日志
|
||||||
|
|
||||||
|
## Interaction And Reuse Targets
|
||||||
|
|
||||||
|
* Preserve existing links and routes in navigation.
|
||||||
|
* Sidebar active/hover states should use blue filled pills.
|
||||||
|
* Role workbench entries should be prominent colored pills near the top of the sidebar.
|
||||||
|
* Tables should be compact with subtle row separators and badge-like statuses.
|
||||||
|
* Forms should use compact inputs with borders and clear focus states.
|
||||||
|
* Existing JSP pages can reuse shared classes for panels, toolbar forms, tables, badges, action links, and cards.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"id": "frontend-reference-redesign",
|
||||||
|
"name": "frontend-reference-redesign",
|
||||||
|
"title": "brainstorm: 仿照参考图重构前端",
|
||||||
|
"description": "",
|
||||||
|
"status": "in_progress",
|
||||||
|
"dev_type": null,
|
||||||
|
"scope": null,
|
||||||
|
"package": null,
|
||||||
|
"priority": "P2",
|
||||||
|
"creator": "Zzzz",
|
||||||
|
"assignee": "Zzzz",
|
||||||
|
"createdAt": "2026-04-28",
|
||||||
|
"completedAt": null,
|
||||||
|
"branch": null,
|
||||||
|
"base_branch": "master",
|
||||||
|
"worktree_path": null,
|
||||||
|
"commit": null,
|
||||||
|
"pr_url": null,
|
||||||
|
"subtasks": [],
|
||||||
|
"children": [],
|
||||||
|
"parent": null,
|
||||||
|
"relatedFiles": [],
|
||||||
|
"notes": "",
|
||||||
|
"meta": {}
|
||||||
|
}
|
||||||
@@ -1,31 +1,120 @@
|
|||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||||
<header class="app-header">
|
<header class="app-header">
|
||||||
<a class="brand" href="${pageContext.request.contextPath}/dashboard">MZH 图书馆</a>
|
<c:choose>
|
||||||
<c:if test="${not empty sessionScope.authenticatedUser}">
|
<c:when test="${not empty sessionScope.authenticatedUser}">
|
||||||
<nav class="top-nav" aria-label="主导航">
|
<c:set var="currentUri" value="${pageContext.request.requestURI}" />
|
||||||
<a href="${pageContext.request.contextPath}/dashboard">控制台</a>
|
<aside class="app-sidebar" aria-label="主导航">
|
||||||
<a href="${pageContext.request.contextPath}/catalog">馆藏检索</a>
|
<a class="sidebar-brand" href="${pageContext.request.contextPath}/dashboard">
|
||||||
<c:if test="${sessionScope.userRole == 'administrator'}">
|
<span class="brand-mark" aria-hidden="true">书</span>
|
||||||
<a href="${pageContext.request.contextPath}/admin/home">管理</a>
|
<span>图书管理系统</span>
|
||||||
<a href="${pageContext.request.contextPath}/admin/users">用户</a>
|
</a>
|
||||||
<a href="${pageContext.request.contextPath}/admin/system-logs">日志</a>
|
|
||||||
</c:if>
|
<section class="role-workbench" aria-label="角色工作台">
|
||||||
<c:if test="${sessionScope.userRole == 'administrator' or sessionScope.userRole == 'librarian'}">
|
<p class="sidebar-section-title">角色工作台</p>
|
||||||
<a href="${pageContext.request.contextPath}/librarian/home">馆员</a>
|
<c:if test="${sessionScope.userRole == 'administrator'}">
|
||||||
<a href="${pageContext.request.contextPath}/books">图书</a>
|
<a class="role-chip role-chip-admin" href="${pageContext.request.contextPath}/admin/home">
|
||||||
<a href="${pageContext.request.contextPath}/book-categories">分类</a>
|
<span aria-hidden="true">管</span>
|
||||||
<a href="${pageContext.request.contextPath}/readers">读者</a>
|
<strong>管理员</strong>
|
||||||
<a href="${pageContext.request.contextPath}/borrowing">借阅</a>
|
<small>/admin/home</small>
|
||||||
<a href="${pageContext.request.contextPath}/reports">报表</a>
|
</a>
|
||||||
</c:if>
|
</c:if>
|
||||||
<a href="${pageContext.request.contextPath}/reader/home">读者中心</a>
|
<c:if test="${sessionScope.userRole == 'administrator' or sessionScope.userRole == 'librarian'}">
|
||||||
<c:if test="${sessionScope.userRole == 'reader'}">
|
<a class="role-chip role-chip-librarian" href="${pageContext.request.contextPath}/librarian/home">
|
||||||
<a href="${pageContext.request.contextPath}/reader/loans">我的借阅</a>
|
<span aria-hidden="true">馆</span>
|
||||||
</c:if>
|
<strong>馆员</strong>
|
||||||
<span class="user-pill">
|
<small>/librarian/home</small>
|
||||||
<c:out value="${sessionScope.authenticatedUser.displayName}" />
|
</a>
|
||||||
</span>
|
</c:if>
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/logout">退出</a>
|
<a class="role-chip role-chip-reader" href="${pageContext.request.contextPath}/reader/home">
|
||||||
</nav>
|
<span aria-hidden="true">读</span>
|
||||||
</c:if>
|
<strong>读者</strong>
|
||||||
|
<small>/reader/home</small>
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<nav class="side-nav" aria-label="模块导航">
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/dashboard') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/dashboard">
|
||||||
|
<span aria-hidden="true">台</span>工作台
|
||||||
|
</a>
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/catalog') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/catalog">
|
||||||
|
<span aria-hidden="true">搜</span>馆藏检索
|
||||||
|
</a>
|
||||||
|
<c:if test="${sessionScope.userRole == 'administrator' or sessionScope.userRole == 'librarian'}">
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/books') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/books">
|
||||||
|
<span aria-hidden="true">书</span>图书管理
|
||||||
|
</a>
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/book-categories') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/book-categories">
|
||||||
|
<span aria-hidden="true">类</span>图书分类管理
|
||||||
|
</a>
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/readers') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/readers">
|
||||||
|
<span aria-hidden="true">人</span>读者管理
|
||||||
|
</a>
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/borrowing') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/borrowing">
|
||||||
|
<span aria-hidden="true">借</span>借阅流通
|
||||||
|
</a>
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/reports') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/reports">
|
||||||
|
<span aria-hidden="true">报</span>报表中心
|
||||||
|
</a>
|
||||||
|
</c:if>
|
||||||
|
<c:if test="${sessionScope.userRole == 'reader'}">
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/reader/loans') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/reader/loans">
|
||||||
|
<span aria-hidden="true">历</span>读者借阅历史
|
||||||
|
</a>
|
||||||
|
</c:if>
|
||||||
|
<c:if test="${sessionScope.userRole == 'administrator'}">
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/admin/users') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/admin/users">
|
||||||
|
<span aria-hidden="true">户</span>用户管理
|
||||||
|
</a>
|
||||||
|
<a class="side-nav-link ${fn:contains(currentUri, '/admin/system-logs') ? 'is-active' : ''}"
|
||||||
|
href="${pageContext.request.contextPath}/admin/system-logs">
|
||||||
|
<span aria-hidden="true">志</span>系统日志
|
||||||
|
</a>
|
||||||
|
</c:if>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="sidebar-footer">
|
||||||
|
<span class="sidebar-menu-dot" aria-hidden="true">≡</span>
|
||||||
|
<a href="${pageContext.request.contextPath}/logout">退出登录</a>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<div class="app-topbar">
|
||||||
|
<div class="breadcrumb">已登录 <span>/</span> Dashboard</div>
|
||||||
|
<form class="global-search" action="${pageContext.request.contextPath}/catalog" method="get">
|
||||||
|
<label class="sr-only" for="globalTitle">搜索图书、读者、功能</label>
|
||||||
|
<input id="globalTitle" name="title" type="search" placeholder="搜索图书、读者、功能...">
|
||||||
|
<button type="submit" aria-label="搜索">⌕</button>
|
||||||
|
</form>
|
||||||
|
<div class="topbar-actions">
|
||||||
|
<span class="notification-dot" aria-label="通知">!</span>
|
||||||
|
<span class="avatar" aria-hidden="true">
|
||||||
|
<c:choose>
|
||||||
|
<c:when test="${sessionScope.userRole == 'administrator'}">管</c:when>
|
||||||
|
<c:when test="${sessionScope.userRole == 'librarian'}">馆</c:when>
|
||||||
|
<c:otherwise>读</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
|
</span>
|
||||||
|
<span class="user-pill">
|
||||||
|
<c:out value="${sessionScope.authenticatedUser.displayName}" />
|
||||||
|
</span>
|
||||||
|
<span class="role-label">
|
||||||
|
<c:out value="${sessionScope.authenticatedUser.role.displayName}" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</c:when>
|
||||||
|
<c:otherwise>
|
||||||
|
<a class="auth-brand" href="${pageContext.request.contextPath}/dashboard">MZH 图书馆</a>
|
||||||
|
</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -10,94 +10,300 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<%@ include file="/WEB-INF/jsp/common/header.jspf" %>
|
<%@ include file="/WEB-INF/jsp/common/header.jspf" %>
|
||||||
<main class="page-shell">
|
<main class="page-shell dashboard-shell">
|
||||||
<section class="dashboard-hero" aria-labelledby="dashboard-title">
|
<section class="dashboard-hero dashboard-welcome" aria-labelledby="dashboard-title">
|
||||||
<p class="eyebrow">
|
<div>
|
||||||
<c:out value="${sessionScope.authenticatedUser.role.displayName}" />
|
<p class="eyebrow">
|
||||||
</p>
|
<c:out value="${sessionScope.authenticatedUser.role.displayName}" />
|
||||||
<h1 id="dashboard-title">控制台</h1>
|
</p>
|
||||||
<p>当前登录:<strong><c:out value="${sessionScope.authenticatedUser.displayName}" /></strong></p>
|
<h1 id="dashboard-title">
|
||||||
|
<c:choose>
|
||||||
|
<c:when test="${sessionScope.userRole == 'administrator'}">管理员工作台</c:when>
|
||||||
|
<c:when test="${sessionScope.userRole == 'librarian'}">馆员工作台</c:when>
|
||||||
|
<c:otherwise>读者工作台</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
|
</h1>
|
||||||
|
<p>登录后进入 Dashboard,会话仅保存安全的 AuthenticatedUser 快照、角色代码与权限代码集合。</p>
|
||||||
|
</div>
|
||||||
|
<div class="welcome-user">
|
||||||
|
<span>当前登录</span>
|
||||||
|
<strong><c:out value="${sessionScope.authenticatedUser.displayName}" /></strong>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="card-grid" aria-label="角色工作区">
|
<section class="dashboard-metrics" aria-label="核心指标">
|
||||||
<c:if test="${sessionScope.userRole == 'administrator'}">
|
<article class="metric-card">
|
||||||
<article class="workspace-card">
|
<span class="metric-icon metric-blue" aria-hidden="true">书</span>
|
||||||
<h2>系统管理</h2>
|
<div>
|
||||||
<p>账户、角色、权限和系统维护入口。</p>
|
<h2>馆藏总量</h2>
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/admin/home">打开</a>
|
<p class="metric-value">12,586 <small>册</small></p>
|
||||||
</article>
|
<p class="metric-trend trend-up">较上月 ↑ 5.2%</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<article class="metric-card">
|
||||||
|
<span class="metric-icon metric-green" aria-hidden="true">借</span>
|
||||||
|
<div>
|
||||||
|
<h2>在借数量</h2>
|
||||||
|
<p class="metric-value">1,258 <small>册</small></p>
|
||||||
|
<p class="metric-trend trend-up">较上月 ↑ 3.1%</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<article class="metric-card">
|
||||||
|
<span class="metric-icon metric-orange" aria-hidden="true">期</span>
|
||||||
|
<div>
|
||||||
|
<h2>逾期数量</h2>
|
||||||
|
<p class="metric-value">87 <small>册</small></p>
|
||||||
|
<p class="metric-trend trend-down">较上月 ↓ 12.4%</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<article class="metric-card">
|
||||||
|
<span class="metric-icon metric-purple" aria-hidden="true">者</span>
|
||||||
|
<div>
|
||||||
|
<h2>读者总数</h2>
|
||||||
|
<p class="metric-value">3,682 <small>人</small></p>
|
||||||
|
<p class="metric-trend trend-up">较上月 ↑ 4.8%</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
|
||||||
<article class="workspace-card">
|
<section class="dashboard-grid" aria-label="检索与排行">
|
||||||
<h2>用户管理</h2>
|
<article class="dashboard-panel search-panel">
|
||||||
<p>创建、更新、停用和查看登录账户。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/admin/users">打开</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>系统日志</h2>
|
|
||||||
<p>查看账户与维护操作的只读审计记录。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/admin/system-logs">打开</a>
|
|
||||||
</article>
|
|
||||||
</c:if>
|
|
||||||
|
|
||||||
<c:if test="${sessionScope.userRole == 'administrator' or sessionScope.userRole == 'librarian'}">
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>馆员工作台</h2>
|
|
||||||
<p>图书、读者、借阅、归还、续借和逾期处理入口。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/librarian/home">打开</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>图书管理</h2>
|
|
||||||
<p>创建、更新、删除和查看图书库存记录。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/books">打开</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>分类维护</h2>
|
|
||||||
<p>维护图书记录和检索筛选使用的馆藏分类。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/book-categories">打开</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>读者管理</h2>
|
|
||||||
<p>创建、更新、停用和查看读者借阅资格记录。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/readers">打开</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>借阅管理</h2>
|
|
||||||
<p>创建借阅、处理归还、续借有效记录并查看逾期项目。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/borrowing">打开</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>报表中心</h2>
|
|
||||||
<p>查看库存状况、借阅统计、逾期记录和热门图书。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/reports">打开</a>
|
|
||||||
</article>
|
|
||||||
</c:if>
|
|
||||||
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>馆藏检索</h2>
|
<h2>馆藏检索</h2>
|
||||||
<p>按书名、作者、分类或图书编号检索图书。</p>
|
<form class="dashboard-search-form" action="${pageContext.request.contextPath}/catalog" method="get">
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/catalog">检索</a>
|
<div class="search-field">
|
||||||
|
<label for="dashIdentifier">图书编号</label>
|
||||||
|
<input id="dashIdentifier" name="identifier" type="text" placeholder="请输入图书编号">
|
||||||
|
</div>
|
||||||
|
<div class="search-field">
|
||||||
|
<label for="dashTitle">书名</label>
|
||||||
|
<input id="dashTitle" name="title" type="text" placeholder="请输入书名">
|
||||||
|
</div>
|
||||||
|
<div class="search-field">
|
||||||
|
<label for="dashAuthor">作者</label>
|
||||||
|
<input id="dashAuthor" name="author" type="text" placeholder="请输入作者">
|
||||||
|
</div>
|
||||||
|
<div class="search-field">
|
||||||
|
<label for="dashCategory">分类</label>
|
||||||
|
<select id="dashCategory" name="categoryId">
|
||||||
|
<option value="">请选择分类</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="dashboard-form-actions">
|
||||||
|
<button class="button button-primary" type="submit">搜索</button>
|
||||||
|
<a class="button button-secondary" href="${pageContext.request.contextPath}/catalog">重置</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<article class="workspace-card">
|
<article class="dashboard-panel ranking-panel">
|
||||||
<h2>读者中心</h2>
|
<div class="panel-heading">
|
||||||
<p>读者自助访问馆藏和借阅历史的入口。</p>
|
<h2>热门图书排行</h2>
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/reader/home">打开</a>
|
<span>借阅次数TOP10</span>
|
||||||
|
</div>
|
||||||
|
<div class="rank-chart" aria-label="热门图书排行柱状图">
|
||||||
|
<div class="rank-item"><span class="rank-value">230</span><span class="rank-bar" style="--bar-height: 92%;"></span><small>活着</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">198</span><span class="rank-bar" style="--bar-height: 79%;"></span><small>三体</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">175</span><span class="rank-bar" style="--bar-height: 70%;"></span><small>百年孤独</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">164</span><span class="rank-bar" style="--bar-height: 66%;"></span><small>围城</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">150</span><span class="rank-bar" style="--bar-height: 60%;"></span><small>平凡的世界</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">138</span><span class="rank-bar" style="--bar-height: 55%;"></span><small>解忧杂货店</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">120</span><span class="rank-bar" style="--bar-height: 48%;"></span><small>红楼梦</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">112</span><span class="rank-bar" style="--bar-height: 45%;"></span><small>白夜行</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">98</span><span class="rank-bar" style="--bar-height: 39%;"></span><small>追风筝的人</small></div>
|
||||||
|
<div class="rank-item"><span class="rank-value">85</span><span class="rank-bar" style="--bar-height: 34%;"></span><small>小王子</small></div>
|
||||||
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<c:if test="${sessionScope.userRole == 'reader'}">
|
|
||||||
<article class="workspace-card">
|
|
||||||
<h2>我的借阅历史</h2>
|
|
||||||
<p>查看您的在借、已还和逾期借阅记录。</p>
|
|
||||||
<a class="button button-secondary" href="${pageContext.request.contextPath}/reader/loans">打开</a>
|
|
||||||
</article>
|
|
||||||
</c:if>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<c:if test="${sessionScope.userRole == 'administrator' or sessionScope.userRole == 'librarian'}">
|
||||||
|
<section class="dashboard-table-grid" aria-label="业务表格">
|
||||||
|
<article class="dashboard-panel table-panel-compact table-panel-wide">
|
||||||
|
<h2>借阅流通 <span>最新记录</span></h2>
|
||||||
|
<div class="table-scroll">
|
||||||
|
<table class="data-table dashboard-data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">流水号</th>
|
||||||
|
<th scope="col">读者姓名</th>
|
||||||
|
<th scope="col">图书编号</th>
|
||||||
|
<th scope="col">书名</th>
|
||||||
|
<th scope="col">借阅日期</th>
|
||||||
|
<th scope="col">应还日期</th>
|
||||||
|
<th scope="col">状态</th>
|
||||||
|
<th scope="col">库存联动</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>L20240521001</td>
|
||||||
|
<td>张晓明</td>
|
||||||
|
<td>B001245</td>
|
||||||
|
<td>活着</td>
|
||||||
|
<td>2024-05-21</td>
|
||||||
|
<td>2024-06-04</td>
|
||||||
|
<td><span class="status-pill status-active">在借</span></td>
|
||||||
|
<td><span class="stock-plus">库存-1</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>L20240521002</td>
|
||||||
|
<td>李华</td>
|
||||||
|
<td>B001026</td>
|
||||||
|
<td>三体</td>
|
||||||
|
<td>2024-05-20</td>
|
||||||
|
<td>2024-06-03</td>
|
||||||
|
<td><span class="status-pill status-active">在借</span></td>
|
||||||
|
<td><span class="stock-plus">库存-1</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>L20240521003</td>
|
||||||
|
<td>王丽</td>
|
||||||
|
<td>B002031</td>
|
||||||
|
<td>百年孤独</td>
|
||||||
|
<td>2024-05-18</td>
|
||||||
|
<td>2024-06-01</td>
|
||||||
|
<td><span class="status-pill status-returned">已归还</span></td>
|
||||||
|
<td><span class="stock-return">库存+1</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>L20240521004</td>
|
||||||
|
<td>陈强</td>
|
||||||
|
<td>B001895</td>
|
||||||
|
<td>围城</td>
|
||||||
|
<td>2024-05-10</td>
|
||||||
|
<td>2024-05-24</td>
|
||||||
|
<td><span class="status-pill status-overdue">逾期</span></td>
|
||||||
|
<td><span class="stock-plus">库存-1</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>L20240521005</td>
|
||||||
|
<td>刘洋</td>
|
||||||
|
<td>B002119</td>
|
||||||
|
<td>解忧杂货店</td>
|
||||||
|
<td>2024-05-12</td>
|
||||||
|
<td>2024-05-26</td>
|
||||||
|
<td><span class="status-pill status-overdue">逾期</span></td>
|
||||||
|
<td><span class="stock-plus">库存-1</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="dashboard-panel table-panel-compact">
|
||||||
|
<h2>逾期列表 <span>待处理</span></h2>
|
||||||
|
<div class="table-scroll">
|
||||||
|
<table class="data-table dashboard-data-table overdue-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">读者姓名</th>
|
||||||
|
<th scope="col">图书编号</th>
|
||||||
|
<th scope="col">书名</th>
|
||||||
|
<th scope="col">应还日期</th>
|
||||||
|
<th scope="col">逾期天数</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>陈强</td><td>B001895</td><td>围城</td><td>2024-05-24</td><td><span class="overdue-days">7天</span></td></tr>
|
||||||
|
<tr><td>赵敏</td><td>B001122</td><td>平凡的世界</td><td>2024-05-20</td><td><span class="overdue-days">11天</span></td></tr>
|
||||||
|
<tr><td>孙涛</td><td>B002003</td><td>红楼梦</td><td>2024-05-18</td><td><span class="overdue-days">13天</span></td></tr>
|
||||||
|
<tr><td>周雨</td><td>B000987</td><td>追风筝的人</td><td>2024-05-17</td><td><span class="overdue-days">14天</span></td></tr>
|
||||||
|
<tr><td>吴迪</td><td>B001776</td><td>白夜行</td><td>2024-05-15</td><td><span class="overdue-days">16天</span></td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="dashboard-panel table-panel-compact table-panel-wide">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2>图书管理 <span>馆藏列表</span></h2>
|
||||||
|
<a href="${pageContext.request.contextPath}/books">进入管理</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-scroll">
|
||||||
|
<table class="data-table dashboard-data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">图书编号</th>
|
||||||
|
<th scope="col">书名</th>
|
||||||
|
<th scope="col">作者</th>
|
||||||
|
<th scope="col">分类</th>
|
||||||
|
<th scope="col">出版日期</th>
|
||||||
|
<th scope="col">库存状态</th>
|
||||||
|
<th scope="col">馆藏地</th>
|
||||||
|
<th scope="col">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>B001245</td><td>活着</td><td>余华</td><td>文学 > 小说</td><td>2012-08-01</td>
|
||||||
|
<td><span class="status-pill status-available">可借(15)</span></td><td>二楼文学区</td>
|
||||||
|
<td><a class="text-link" href="${pageContext.request.contextPath}/books">管理</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>B001026</td><td>三体</td><td>刘慈欣</td><td>文学 > 科幻</td><td>2008-01-01</td>
|
||||||
|
<td><span class="status-pill status-available">可借(8)</span></td><td>三楼科幻区</td>
|
||||||
|
<td><a class="text-link" href="${pageContext.request.contextPath}/books">管理</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>B002031</td><td>百年孤独</td><td>加西亚·马尔克斯</td><td>文学 > 外国文学</td><td>2011-06-01</td>
|
||||||
|
<td><span class="status-pill status-available">可借(6)</span></td><td>二楼文学区</td>
|
||||||
|
<td><a class="text-link" href="${pageContext.request.contextPath}/books">管理</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>B001895</td><td>围城</td><td>钱钟书</td><td>文学 > 小说</td><td>2008-05-01</td>
|
||||||
|
<td><span class="status-pill status-available">可借(4)</span></td><td>二楼文学区</td>
|
||||||
|
<td><a class="text-link" href="${pageContext.request.contextPath}/books">管理</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>B002119</td><td>解忧杂货店</td><td>东野圭吾</td><td>文学 > 小说</td><td>2014-07-01</td>
|
||||||
|
<td><span class="status-pill status-available">可借(10)</span></td><td>二楼文学区</td>
|
||||||
|
<td><a class="text-link" href="${pageContext.request.contextPath}/books">管理</a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<aside class="shortcut-grid" aria-label="快捷入口">
|
||||||
|
<a class="shortcut-card" href="${pageContext.request.contextPath}/readers">
|
||||||
|
<span class="shortcut-icon shortcut-blue" aria-hidden="true">者</span>
|
||||||
|
<strong>读者管理</strong>
|
||||||
|
<small>管理读者信息、证件办理与权限设置</small>
|
||||||
|
</a>
|
||||||
|
<a class="shortcut-card" href="${pageContext.request.contextPath}/reports">
|
||||||
|
<span class="shortcut-icon shortcut-green" aria-hidden="true">报</span>
|
||||||
|
<strong>报表中心</strong>
|
||||||
|
<small>生成各类统计报表,支持导出与分析</small>
|
||||||
|
</a>
|
||||||
|
<a class="shortcut-card" href="${pageContext.request.contextPath}/borrowing">
|
||||||
|
<span class="shortcut-icon shortcut-orange" aria-hidden="true">借</span>
|
||||||
|
<strong>借阅流通</strong>
|
||||||
|
<small>借书、还书、续借与逾期处理</small>
|
||||||
|
</a>
|
||||||
|
<c:if test="${sessionScope.userRole == 'administrator'}">
|
||||||
|
<a class="shortcut-card" href="${pageContext.request.contextPath}/admin/system-logs">
|
||||||
|
<span class="shortcut-icon shortcut-purple" aria-hidden="true">志</span>
|
||||||
|
<strong>系统日志</strong>
|
||||||
|
<small>系统操作日志与安全审计记录查询</small>
|
||||||
|
</a>
|
||||||
|
</c:if>
|
||||||
|
</aside>
|
||||||
|
</section>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
<c:if test="${sessionScope.userRole == 'reader'}">
|
||||||
|
<section class="shortcut-grid reader-shortcut-grid" aria-label="读者快捷入口">
|
||||||
|
<a class="shortcut-card" href="${pageContext.request.contextPath}/reader/loans">
|
||||||
|
<span class="shortcut-icon shortcut-blue" aria-hidden="true">历</span>
|
||||||
|
<strong>我的借阅</strong>
|
||||||
|
<small>查看在借、已还、续借次数和逾期状态</small>
|
||||||
|
</a>
|
||||||
|
<a class="shortcut-card" href="${pageContext.request.contextPath}/catalog">
|
||||||
|
<span class="shortcut-icon shortcut-green" aria-hidden="true">搜</span>
|
||||||
|
<strong>馆藏检索</strong>
|
||||||
|
<small>按书名、作者、分类或图书编号查找馆藏</small>
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
</c:if>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+878
-224
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user