訂單列表頁是用戶查看歷史消費記錄的核心界面,本文詳細剖析 orderList.jsp 的數據模型、交互設計、分頁策略、狀態機展示與性能優化方案。
User (1) ─────< (N) Order (1) ─────< (N) OrderBook (N) ─────> (1) Book
單次查詢需聚合:訂單基礎信息 + 每訂單商品快照 (書名、封面、單價、數量) + 狀態標籤。
方案一:兩次查詢 + 內存組裝 (推薦中小數據量)
-- 1. 查詢訂單主表 (分頁)
SELECT id, user_id, amount, datetime, note, status, shipping_status
FROM t_order WHERE user_id = ? ORDER BY datetime DESC LIMIT ?, ?;
-- 2. 批量查詢訂單明細
SELECT ob.order_id, ob.book_id, ob.quantity, b.name, b.price, b.cover_url
FROM t_orderbook ob JOIN t_book b ON ob.book_id = b.id
WHERE ob.order_id IN (訂單ID列表);
Java 端用 Map<Long, List<OrderItem>> 組裝,避免 N+1 問題。
方案二:單查詢 + 結果集分組 (大數據量)
SELECT o.id, o.amount, o.datetime, o.status, o.shipping_status,
b.id as book_id, b.name, b.price, b.cover_url, ob.quantity
FROM t_order o
JOIN t_orderbook ob ON o.id = ob.order_id
JOIN t_book b ON ob.book_id = b.id
WHERE o.user_id = ?
ORDER BY o.datetime DESC, o.id;
配合 ResultSetExtractor 或 MyBatis resultMap 的 collection 映射自動分組。
| 業務狀態 | 顯示標籤 | 顏色 | 可用操作 |
|---|---|---|---|
| UNPAID | 待付款 | 橙色警告 | 去付款、取消訂單 |
| PAID | 已付款 | 藍色信息 | 查看物流、申請退款 |
| SHIPPED | 已發貨 | 紫色處理中 | 查看物流、確認收貨 |
| COMPLETED | 已完成 | 綠色成功 | 評價、再次購買 |
| CANCELLED | 已取消 | 灰色禁用 | 刪除、再次購買 |
| REFUNDED | 已退款 | 紅色異常 | 查看退款詳情 |
前端使用 <span class="badge badge-{color}"> 語義化渲染。
<!-- JSTL 分頁標籤 -->
<c:url var="pageUrl" value="/orderList">
<c:param name="status" value="${param.status}"/>
<c:param name="startDate" value="${param.startDate}"/>
<c:param name="endDate" value="${param.endDate}"/>
</c:url>
<nav aria-label="Order pagination">
<ul class="pagination">
<c:if test="${page.currentPage > 1}">
<li><a href="${pageUrl}&page=${page.currentPage-1}">上一頁</a></li>
</c:if>
<c:forEach begin="${page.startPage}" end="${page.endPage}" var="p">
<li class="${p == page.currentPage ? 'active' : ''}">
<a href="${pageUrl}&page=${p}">${p}</a></li>
</li>
</c:forEach>
<c:if test="${page.currentPage < page.totalPages}">
<li><a href="${pageUrl}&page=${page.currentPage+1}">下一頁</a></li>
</c:if>
</ul>
</nav>
保持篩選參數在分頁鏈接中傳遞,用戶體驗無縫銜接。
fetch() 返回 HTML 片段替換列表容器/orderDetail?id=xxx 渲染 Modal,避免跳轉| 優化點 | 方案 | 收益 |
|---|---|---|
| 查詢緩存 | Redis 緩存用戶最近 20 條訂單 (TTL 5min) | 首屏極速加載 |
| 索引優化 | t_order(user_id, datetime DESC) 聯合索引 | 分頁查詢毫秒級 |
| 圖片懶加載 | 書封面 loading="lazy" + 佔位圖 | 節省帶寬 |
| 虛擬滾動 | 單頁超 50 條啟用 IntersectionObserver | 長列表流暢 |
| CDN 靜態資源 | 封面圖、CSS/JS 走 CDN | 全球加速 |
<c:if test="${empty orderList}">
<div class="empty-state text-center py-5">
<i class="icon-box-empty display-1 text-muted"></i>
<h4 class="mt-3">暫無訂單記錄</h4>
<p class="text-muted">去挑選幾本好書充實書架吧</p>
<a href="${pageContext.request.contextPath}/bookList" class="btn btn-primary">
<i class="icon-book"></i> 立即選購
</a>
</div>
</c:if>
session.getAttribute("user") != nullWHERE user_id = ? 防止越權訪問UPDATE t_order SET deleted=1 WHERE id=? AND user_id=?orderList.jsp 作為用戶核心資產頁面,兼顧信息密度、交互流暢度與系統性能,是電商系統用戶體驗的關鍵觸點之一。