feat(mall): classic B2B2C PC storefront with fixed mock API layer

- Mock adapter implementing @vmall/shared ApiClient (localStorage-persisted
  cart/orders/invoices), runtime switch via mockApi flag (default on)
- Fixed bilingual mock catalog: 3-level categories, 24 products w/ SKUs,
  stores, brands, banners, floors, seckill/collective/integral, comments,
  coupons, addresses, seeded orders/shipments/invoices
- B2B2C mall shell: top bar, logo/search/cart header, dark nav + category
  mega-menu, value-prop footer, back-to-top; 1200px grid, #ca151e theme
- UI primitives replacing element-plus: carousel, pagination, breadcrumb,
  qty stepper, rating stars, modal, tabs, step bar, product card
- Pages: home floors, search (filters/sort/paging), goods detail (SKU
  picker, store rail, review tabs), cart -> checkout -> pay -> success,
  auth pages, user center (dashboard/orders/addresses/favorites/coupons/
  invoices), stores, seckill, collective, integral
- i18n split into per-domain locale modules (en+zh)
- OpenSpec change mall-pc-storefront-replica archived; all specs green
This commit is contained in:
Chengdong Zhang
2026-09-17 19:13:29 +08:00
parent 997c312cda
commit 21e99bb52b
111 changed files with 9458 additions and 1035 deletions
+161
View File
@@ -0,0 +1,161 @@
/* B2B2C mall-style PC mall theme: 1200px grid, #ca151e brand red, compact controls. */
:root {
--mall-red: #ca151e;
--mall-red-dark: #a8111a;
--mall-ink: #333;
--mall-muted: #666;
--mall-faint: #999;
--mall-line: #efefef;
--mall-line-dark: #d9d9d9;
--mall-bg: #f5f5f5;
--mall-panel: #fff;
--mall-green: #67c23a;
--mall-yellow: #e6a23c;
--mall-nav: #333;
--mall-radius: 3px;
--mall-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}
body {
background: #fff;
color: var(--mall-ink);
font-size: 14px;
}
.w1200 {
width: 1200px;
margin: 0 auto;
}
.mall-main {
min-height: 60vh;
}
/* buttons */
.mbtn {
display: inline-block;
box-sizing: border-box;
padding: 6px 15px;
border: 1px solid var(--mall-line-dark);
border-radius: var(--mall-radius);
background: #fff;
color: var(--mall-muted);
font-size: 12px;
line-height: 1.6;
cursor: pointer;
text-decoration: none;
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
}
.mbtn:hover {
color: var(--mall-red);
border-color: var(--mall-red);
}
.mbtn.red {
background: var(--mall-red);
border-color: var(--mall-red);
color: #fff;
}
.mbtn.red:hover {
background: var(--mall-red-dark);
}
.mbtn.gray {
background: #909399;
border-color: #909399;
color: #fff;
}
.mbtn.block {
display: block;
width: 100%;
text-align: center;
padding: 10px 15px;
font-size: 14px;
}
.mbtn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* white content panel (user center etc.) */
.mpanel {
background: var(--mall-panel);
padding: 20px;
margin-bottom: 20px;
}
.mpanel-title {
font-size: 16px;
border-left: 3px solid var(--mall-red);
padding-left: 12px;
margin: 0 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.mpanel-title .more {
font-size: 12px;
color: var(--mall-muted);
text-decoration: none;
}
.mpanel-title .more:hover {
color: var(--mall-red);
}
.hr20 {
height: 1px;
background: var(--mall-line);
margin: 20px 0;
border: 0;
}
/* form controls */
.minput {
box-sizing: border-box;
width: 100%;
height: 38px;
padding: 8px 12px;
border: 1px solid var(--mall-line-dark);
border-radius: var(--mall-radius);
font-size: 13px;
outline: none;
}
.minput:focus {
border-color: var(--mall-red);
}
/* gray page section background (home floors) */
.section-bg {
background: var(--mall-bg);
padding: 20px 0 60px;
}
/* simple table */
.mtable {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.mtable th {
background: #fafafa;
border-bottom: 1px solid var(--mall-line);
padding: 10px 12px;
text-align: left;
color: var(--mall-muted);
font-weight: normal;
}
.mtable td {
border-bottom: 1px solid var(--mall-line);
padding: 12px;
vertical-align: middle;
}
.mtable tr:hover td {
background: #fcfcfc;
}
/* product card hover lift */
.hover-lift {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.hover-lift:hover {
transform: translateY(-3px);
box-shadow: var(--mall-shadow);
}