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:
@@ -0,0 +1,139 @@
|
||||
# PC buyer mall reference digest
|
||||
|
||||
## 1. Home route table
|
||||
|
||||
`resources/js/plugins/routes/index.js` defines one parent `path: '/'` component `Home/index` (the global buyer shell). Its children are:
|
||||
|
||||
| Path | Page file | Purpose / mock data boundary |
|
||||
|---|---|---|
|
||||
| `/` | `Home/default.vue` | Home landing page: hero/banner, quick links and category product floors. `/home` response supplies `goods` groups; each group has `name`, `goods[]`, and each product has `id`, `goods_master_image`, `goods_name`, `goods_subname`, `goods_price`, `goods_market_price`. |
|
||||
| `/login` | `Home/auth/login.vue` | Username/password login plus WeChat login. |
|
||||
| `/register` | `Home/auth/register.vue` | Phone registration, password confirmation and SMS code. |
|
||||
| `/forget_password` | `Home/auth/forget_password.vue` | Phone, new password/confirmation and SMS code reset. |
|
||||
| `/stores` | `Home/stores/list.vue` | Store directory, default/distance sort, pagination. |
|
||||
| `/store/:id` | `Home/stores/info.vue` | Store profile/rating, store sales rail, product listing/sort. |
|
||||
| `/store/join` | `Home/stores/index.vue` | Merchant onboarding landing; links into join steps. |
|
||||
| `/store/step_1`, `/store/step_2`, `/store/step_3` | corresponding `Home/stores/step_*.vue` | Join agreement/data/review state steps. |
|
||||
| `/s/:params?` | `Home/goods/index.vue` | Product search/list; optional base64 JSON query (`keywords`, `pid/sid/tid`, `class_id`, `brand_id`, `sort_type`, `sort_order`). |
|
||||
| `/goods/:id` | `Home/goods/info.vue` | Product detail, gallery/zoom, SKU, buy/cart, store, detail/comments/service. |
|
||||
| `/carts` | `Home/carts/index.vue` | Cart grouped by store, selection/quantity/removal and checkout. |
|
||||
| `/integral` | `Home/integral/index.vue` | Points-mall home (banner, account panel, recommendations/category rails). |
|
||||
| `/integral/search/:params?` | `Home/integral/goods.vue` | Points product search/category/sort list. |
|
||||
| `/integral/goods/:id` | `Home/integral/info.vue` | Points product detail and quantity selection. |
|
||||
| `/integral/order/:id/:buy_num` | `Home/integral/orders/index.vue` | Address + points redemption order. |
|
||||
| `/seckills` | `Home/seckills/index.vue` | Timed seckill sessions/products. |
|
||||
| `/collectives/:params?` | `Home/collectives/index.vue` | Group-buy product list, using ordinary goods filters with `is_collective: 1`. |
|
||||
| `/user` | `Home/users/index.vue` with child `Home/users/default.vue` | Buyer center shell and dashboard. |
|
||||
| `/user/address` (+ `/form/:id?`) | `Home/users/address/index.vue` (+ `form.vue`) | Address list and add/edit. |
|
||||
| `/user/comments`, `/user/comment/add/:id` | comments pages | Buyer comments and add-comment flow. |
|
||||
| `/user/info`, `/user/safe/**`, `/user/oauth`, `/user/cashes` | user subpages | Profile, safety/password/phone, OAuth binding and withdrawal. |
|
||||
| `/user/favorites` | `Home/users/favorites/index.vue` | Toggle product favorites/store follows. |
|
||||
| `/user/money`, `/user/integral`, `/user/frozen_money` | money-log pages | Balance, points and frozen-funds records. |
|
||||
| `/user/orders`, `/user/order/:id`, `/user/order/comment/:id`, `/user/order/refund/**` | order subpages | Order list/detail/comment/refund flows. |
|
||||
| `/user/integral_order` | integral-order page | User’s points orders. |
|
||||
| `/user/coupons` | `Home/users/coupons/index.vue` | Coupon table. |
|
||||
| `/user/distribution/**` | distribution pages | Distribution profile/members/commissions. |
|
||||
| `/user/article/:name` | article page | Named announcement/help/about content. |
|
||||
| `/order/before/:params` | `Home/orders/before.vue` | Address/coupon/remark and order preview. |
|
||||
| `/order/pay/:params` | `Home/orders/pay.vue` | Payment selection and generated order summary. |
|
||||
| `/order/success` | `Home/orders/success.vue` | Completed payment result. |
|
||||
|
||||
`views/App.vue` is only `<router-view/>`; `/Admin/login` and `/Seller/login` are separate non-buyer routes (Admin/Seller areas exist but are out of this survey). `router.js` creates a history router, installs `baseRoute`, and has global progress/auth navigation logic.
|
||||
|
||||
## 2. Global layout anatomy
|
||||
|
||||
The naming is slightly split: `views/Home/index.vue` is the shell, `views/Home/default.vue` is the actual home landing page, and `components/home/base.vue` is the shared outer layout.
|
||||
|
||||
1. **`components/home/top.vue` fixed top bar (`.head`, 30px):** 1200px `.head_in`; left links in order: 平台官网, separator, 商城官网, separator, 联系方式, separator, 关于我们, separator, city/location (default 北京市, optionally IP/AMap-resolved). Right side conditionally shows 登录/注册 or `欢迎您,nickname`, 个人中心, 注销账号; then 商家入驻, 手机端, APP下载. Uses `#ca151e` for login/location/merchant links.
|
||||
2. **`components/home/head.vue` fixed header (`top:30px`, white):** `.center_top center1200` logo (`.shop_logo`, 242x74), then `.shop_top_seach` with 434px text input (`data.keywords`), search icon button and `.index_my_car` “我的商城/我的购物车” with cart count badge `.shop_car_dot`. Below is 40px dark `.shop_top_nav`: 240px red `.shop_top_nav_left` “全部商品” (hover mounts `leftbar`), then links 首页, 店铺街, 秒杀, 拼团, 积分商城, 帮助中心. Header collapses logo/search area after scroll >200; home category menu can collapse after scroll. Search pushes `/s/` + base64 JSON `{keywords}`.
|
||||
3. **`components/home/leftbar.vue` category mega-menu:** 240px x 450px `.leftbar` (white) or `.leftbar2` (black translucent when over hero). Each top-level `goodsClass` renders `.left_bar_block`: `.class_1` top category name, `.class_2` up to three child names, and hidden hover `.subbar` 960px wide. Mega menu contains optional top tags, right brand tiles from `goodsBrand[]` (`thumb`), optional advert, and `.subbar_subnav` rows: child heading `name`, grandchildren `{id,pid,name}`. Navigation encodes `pid/sid/tid/class_id` into `/s/:params`.
|
||||
4. **`components/home/base.vue`:** `<div class="home_default"><top/><div class="padding_content"/><slot name="main"/><foot/></div>`. `.padding_content` is 228px to offset fixed top + header. On mount dispatches `init/loadCommon` (common config, classes, brands, cart, etc.). In `Home/index.vue`, the main slot is `<head-view/><router-view/>`; therefore every buyer page receives the top/header/footer shell. Home `default.vue` itself is just the route content under that shell.
|
||||
5. **`components/home/foot.vue`:** centered 1200px `.shop_foot`; four value propositions in order (“500强企业 品质保证”, “7天退货 15天换货”, “99元起免运费”, “448家维修网点 全国联保”), then copyright/ICP/security text interpolating `common.web_name` and `common.icp`, plus Element `el-backtop`. Replace `el-backtop` with a small fixed scroll-to-top control in Nuxt.
|
||||
|
||||
Element Plus pieces to replace in this shell: `el-icon`/icons (search, cart, etc.), `el-image` (native img with lazy loading), `el-carousel`/transition (CSS/Headless carousel), `el-backtop`, and any `el-breadcrumb` used by child pages.
|
||||
|
||||
## 3. Homepage sections and mock data
|
||||
|
||||
`views/Home/default.vue` is intentionally simpler than the nav labels suggest—there are no dedicated seckill/collective/brand sections in this file. Those are quick links in `banner_adv`; product floors are generic category groups.
|
||||
|
||||
1. **Hero carousel (`components/home/banner.vue`, first child):** `<el-carousel height=450>` → each `<el-carousel-item>` → `.shop_banner` background image (`background-position:center; background-size:cover`) → full 1200x450 router link. `banner` shape: `[{image:string, url?:string, name?:string}]`; default landing mock is one `default_banner.jpg` item. Nuxt replacement: regular CSS/JS carousel.
|
||||
2. **Below-hero promo/quick-link strip (`components/home/banner_adv.vue`):** `.banner_bottom_adv center1200`; left 240px six 78x80 cells in order: 实名认证 (`/user/safe`), 积分商城, 优惠团购, 秒杀活动, 公告 (`/user`), 入驻商家. Each icon is an image; right side has up to three 312x160 linked promo images. `index_adv` shape: `[{image:string, url?:string, name?:string}]`. Uses `el-image` (replace with img).
|
||||
3. **Floor background:** `.index_bg` gray `#f5f5f5`, top margin 40px and 20px/60px padding. For every `data.goods` category group, render `.goods_class_list w1200`; if `v.goods.length > 0`, first `adv-view` full-width placeholder (`adv:{image,url?}`), then `.title` group name + “查看更多”.
|
||||
4. **Floor body:** left `.index_adv_goods_left` 234x614 image from `data.classLeftAdv[k].image_url` or fallback `pc_class_btadv.jpg`; right `.index_class_goods_right` 966px with product cards in `<ul>`. Product cards are 220x300 white `.product_act_in` with 140x140 image, title, subtitle, red sale price and struck market price. Floor product shape: `{id, goods_master_image, goods_name, goods_subname, goods_price, goods_market_price}`; floor group shape: `{name, goods:[product...]}`. Note `classLeftAdv` is initialized but not assigned from `/home` in the shown code, so a mock can supply it separately.
|
||||
5. **`components/home/adv.vue`:** a linked lazy image, default `width/height:'100%'`, margin top/bottom 40px; `adv:{image,url?}`.
|
||||
|
||||
Visual card behavior: hover lifts cards by 3px and adds `0 2px 12px rgba(0,0,0,.1)`. A Nuxt mock module should include `home {goods: Floor[], classLeftAdv: Adv[]}`, `banner`, and `index_adv` even though the current banner/floor images are hardcoded assets.
|
||||
|
||||
## 4. Goods list (`views/Home/goods/index.vue`)
|
||||
|
||||
- Breadcrumb `.w1200 breadcrumb`: 首页, then either `搜索 "..." 结果列表` (decoded `keywords`) or 商品列表.
|
||||
- **Filter block `.goods_where w1200`:** three `.item` rows: 商品分类, 品牌筛选, 筛选排序. Category has “全部”, top-level `common.classes`, selected second-level and third-level children; each class is `{id,name,children:[...]}`. Brand options are `{id,name}`. The route state/query shape is `{keywords?,pid?,sid?,tid?,class_id?:number[],brand_id?,sort_type?,sort_order?}` encoded in base64 path.
|
||||
- **Important reference limitation:** despite a request to survey “attrs/brands/price”, this template has no attribute facet row and no price-range controls. It exposes category + brands + sort only. Do not infer an attrs/price UI from this file; if the new app adds them, it is an intentional enhancement rather than parity.
|
||||
- Sort choices are default, 价格 (`goods_price`), 销量 (`goods_sale`), 评论 (`order_comment_count`), each toggling `sort_order` asc/desc. In the shown template the sort controls are also in `.goods_where`, not a separate bar.
|
||||
- **Results:** `.s_goods_content`; `.s_goods_list` five cards/row (`.item` 224x364). Each card `<dl>` has 176x176 image, title, red price, footer “立即购买” and `{order_comment_count} 人评论`; links `/goods/{id}`. Product list shape: `{id,goods_master_image,goods_name,goods_price,order_comment_count}` (market/subname are not rendered here).
|
||||
- **Pagination:** `.fy` Element `el-pagination` total/prev/pager/next; response fields are `data`, `total`, `per_page`, `last_page`, `current_page`; empty state is `el-empty`. Replace with plain button/page-number pagination, empty state, and native img.
|
||||
|
||||
## 5. Goods detail (`views/Home/goods/info.vue`)
|
||||
|
||||
- **Breadcrumb:** `.mbx w1200`: 首页 → every `goods_info.classList[{name}]` → product name.
|
||||
- **Gallery:** `.goods_info_top_left` has `.goods_image_item` containing custom `components/home/vue-piczoom.vue`, then thumbnail rail `.pic_zoom_list` with previous/next controls and `goods_images_thumb_150[]`; selected index `chose_img_pos`, display image `goods_images_thumb_400[]`, zoom source `goods_images[]`. Mock fields: `goods_images`, `goods_images_thumb_400`, `goods_images_thumb_150` arrays of URLs.
|
||||
- **Product summary:** `.goods_info_top_right` title/subtitle, favorite toggle, sale/market prices, sale count, QR hint, coupon cards, optional seckill and group-buy activity, full-reduction messages. Core `goods_info`: `id,goods_name,goods_subname,goods_price,goods_market_price,goods_sale,goods_stock,goods_content,classList,attrList,skuList,sale_list`; `coupons[]` entries `{id,money,use_money}`, `full_reductions[]` `{money,use_money}`, `seckills` `{discount,end_time,format_time}`, `collectives` `{discount,need}`, `collective_list[]` `{id,avatar,nickname,orders_count,need}`.
|
||||
- **SKU/quantity:** `attrList[]` each `{name,specs:[{id,name,is_chose?}]}`; `skuList[]` each `{id,spec_id:number[],goods_price,goods_market_price,goods_stock}`. Chosen `sku_id`, `buy_num`, current stock; “立即购买”, “加入购物车” (regular goods) or “立即抢购” (seckill). Group buy adds `collective_id`.
|
||||
- **Store card / left rail:** `.goods_info_content` left `.left_item` store card with `store_info.store_name`, `store_company_name`, `area_info`, `store_address`, `id`, `user_id`; four scores in `rate_info` (`scoreAll`, `agreeAll`, `serviceAll`, `speedAll`); buttons enter store/customer service. Below, 销售排行 from `goods_info.sale_list[]` product `{id,goods_master_image,goods_name,goods_price}`.
|
||||
- **Tabs:** right `.right_item` Element tabs: 商品详情 renders sanitized `goods_content`; 用户评价 renders statistics `{all,good,commonly,bad,rate}`, comment filters, paginated `comments[]` where `{avatar,nickname,score,content,image:string[],reply}`; 售后服务 renders `store_info.after_sale_service`. Replace `el-tabs`, `el-rate`, `el-pagination`, `el-image` with native tabs, stars and controls. `Chat` is a separate common component and may be replaced with a simple contact CTA if chat is not in scope.
|
||||
|
||||
## 6. Cart and order flow
|
||||
|
||||
**Cart (`views/Home/carts/index.vue`):** `.create_order_1 w1200` begins a four-step `.step_bar` (cart active, address, payment, success). If nonempty, `.cart_th` header columns are 商品, 规格, 单价(元), 数量, 小计, 操作. `.cart_table` groups `data.list` by store: store group `{store_id,store_name,checked,css,cart_list[]}`, item `{cart_id,goods_id,goods_image,goods_name,sku_name,goods_price,buy_num,checked}`. Each item has checkbox, 40px thumb/name link, SKU, +/- quantity controls, subtotal and 移除. Bottom select-all summarizes `allCount`, `allPrice` and 结算; empty `el-empty`. Pagination response state exists (`data.params={page,per_page,last_page,total}`) but no pager is rendered. Replace Element checkboxes/empty/icons.
|
||||
|
||||
**Order before (`orders/before.vue`):** same step bar with cart/address active. Address selection list entries `{id,receive_name,receive_tel,area_info,address,is_default}`; then order preview grouped by store. Order group includes `store_info:{id,store_logo,store_name}`, `coupon_id`, `coupons[]:{id,money}`, `is_coupon`, `goods_list[]:{goods_master_image,goods_name,sku_name,goods_price,buy_num,total}`. Shows remark textarea (`data.remark`), total, create-order button. Submit payload uses encoded route `params`, `address_id`, comma-joined `coupon_id`, `remark`.
|
||||
|
||||
**Order pay (`orders/pay.vue`):** step bar through payment; balance panel `userInfo.money`; payment options are balance/password, WeChat and Alipay. Displays generated `order[]` groups `{order_no,coupon_money,order_goods[]:{goods_image,goods_name,sku_name,goods_price,buy_num,total_price}}`, `total`, `freight_money`; balance password and QR modal state `{pay_password,qr_code}`. Replace `el-dialog`, QR Vue and Element grid with Tailwind modal/grid and a QR library.
|
||||
|
||||
**Order success (`orders/success.vue`):** all four steps active, success result (“订单支付成功!”), link to `/user`; replace Element `el-result` with a simple success panel.
|
||||
|
||||
## 7. User center
|
||||
|
||||
`Home/users/index.vue` is a two-column `.user_default` shell: 234px `.user_left` + 20px gap, 946px `.user_right` with nested `<router-view>`. Profile card has avatar, `nickname`, edit link, account-profile progress (`check`) and safety indicators (`phone`, `check`). Nav menu groups/items, in order:
|
||||
|
||||
- **订单中心:** 我的订单 `/user/orders`, 收货地址 `/user/address`, 评论列表 `/user/comments`.
|
||||
- **会员中心:** 个人中心 `/user`, 用户资料 `/user/info`, 账户安全 `/user/safe`, 账号绑定 `/user/oauth`, 资金提现 `/user/cashes`, 收藏/关注 `/user/favorites`, 我的优惠券 `/user/coupons`.
|
||||
- **积分商城:** 积分订单 `/user/integral_order`.
|
||||
- **资产记录:** 平台余额 `/user/money`, 冻结资金 `/user/frozen_money`, 平台积分 `/user/integral`.
|
||||
- **分销分佣:** 分销信息 `/user/distribution`, 分销会员 `/user/distribution_users`, 分销佣金 `/user/distribution_logs`.
|
||||
- **帮助中心:** 网站公告、其他合作、帮助中心、关于我们 at `/user/article/:name`.
|
||||
|
||||
`users/default.vue` dashboard data shape: `user_info:{money,integral,frozen_money}`, `count[5]` for pending payment/shipping/receipt/comment/after-sale, `order[]` with `{id,created_at,order_no,order_status,order_status_cn,order_goods[]:{goods_image,goods_name,sku_name,buy_num,total_price}}`, `fav[]` with `{out_id,goods_master_image,goods_name,goods_price}`, and local `history[]` with `{id,image,goods_name,goods_price}`. It renders balance cards, five status links/badges, recent orders, recent favorites and browsing history, all in `.user_main` cards.
|
||||
|
||||
Focused page shapes:
|
||||
- **Address:** `addresses[]:{id,receive_name,receive_tel,area_info,address,is_default}`; add/edit fields are `receive_name`, `receive_tel`, `area` (cascader), `address`, `is_default`; paginated response. Uses `el-dialog`, `el-form`, `el-pagination`.
|
||||
- **Orders:** filter `{order_status,order_no,created_at:[start,end],is_type}`; statuses -1/0/1/2/3/4/5/6 = all/cancelled/wait-pay/wait-ship/wait-receive/wait-comment/after-sale/completed. Cards use the same order/item shape above and action buttons; logistics modal expects `order_info.delivery_list[]:{context,time}`.
|
||||
- **Favorites:** toggle `isGoods`; product table fields `goods_master_image,goods_name,goods_price,created_at`, store table fields `store_logo,store_name,created_at`, records carry `is_type,out_id`.
|
||||
- **Coupons:** generic table columns `name,money,use_money,end_time,created_at`; no custom card UI. `table-view` is a large Element-based shared component and should be replaced with a plain responsive table in Nuxt.
|
||||
|
||||
## 8. Stores, seckill, collective and integral pages
|
||||
|
||||
- **Stores list (`stores/list.vue`):** breadcrumb + one sort row (default/distance), then store rows with 80px logo and `{id,store_logo,store_name,store_company_name,area_info,store_address,distance}`; center hardcodes 好评率 100%, right shows distance and 进入店铺; 30/page pagination. Location comes from local `lonlat`. Replace `el-breadcrumb`, icons, image and pagination.
|
||||
- **Store info (`stores/info.vue`):** 350px banner from `store_info.store_slide[]`, left store profile/rates/company/address/favorite/contact and sales ranking; right store-scoped sort (default/price/sales/comments) plus 220x300 product cards with `{id,goods_master_image,goods_name,goods_subname,goods_price,goods_market_price}` and pagination. Store payload adds `id,user_id,store_verify,store_status,store_logo,sale_list[]`, `rate:{scoreAll,agreeAll,serviceAll,speedAll}`, and `after_sale_service` where relevant.
|
||||
- **Seckills (`seckills/index.vue`):** breadcrumb, four equal timed session selectors (`timeList` hours, `timeIndex`, `timeFormat` countdown), then a 4-column product grid using `{id,goods_master_image,goods_name,goods_subname,goods_price,goods_market_price}`, paginated by `{page,per_page,last_page,total,start_time}`. Countdown refreshes the page when the hour expires.
|
||||
- **Collectives (`collectives/index.vue`):** 350px collective banner, then the same 3-row category/brand/sort filter and 5-column standard goods cards as `/s`; API query adds `is_collective:1`. Mock the same class/brand/filter/product/page shapes as goods list.
|
||||
- **Integral home (`integral/index.vue`):** 350px banner, four info blocks (login/register or avatar + `userInfo.integral`, plus private customization/24H/priority cards), then “热门推荐” and category rails. Data is `{store_slide?,userInfo:{avatar,integral},recommend:[{id,goods_master_image,goods_name,goods_price,goods_market_price}],list:[{name,integral_goods:[same product shape]}]}`.
|
||||
- **Integral goods/detail/order:** `integral/goods.vue` is a category/sort-only list (`class[]:{id,name}`, product card uses “立即兑换”); `integral/info.vue` is zoom gallery + points price/market price, sale/stock and quantity, “立即兑换”, with `goods_content`; `integral/orders/index.vue` reuses address/remark four-step checkout but has one points product `{goods_master_image,goods_name,sku_name,goods_price,buy_num}`, and submits `{id,buy_num,address_id,remark}` to points pay.
|
||||
|
||||
## 9. Auth pages
|
||||
|
||||
All three use `.home_login` with `user_login__bgs.png`, a 1200px `.login_block`, and right-floating white `.login_item` 400x450, 40px padding, 50px top margin. Inputs are 320px wide, 35px high; submit is full-width red `#ca151e`; no shared top/header is rendered inside the auth template (they still are routed beneath the Home shell in the current route tree).
|
||||
|
||||
- **Login:** title tabs “帐号登录 | 扫码登录”; `username`, `password`; 登录 button; links 注册 and 忘记密码; Element divider and WeChat icon/click. Mock `{username,password,provider:'users'}`.
|
||||
- **Register:** title “注册账号 | 账号登录”; `username` (phone), `password`, `re_password`, SMS `code`, send-code countdown (`code_text`, `math`); 注册 + forgot-password link. Optional inviter id from query/session. Mock `{username,password,re_password,code,code_text,math}`.
|
||||
- **Forgot password:** title “忘记密码 | 账号登录”; `username`, new `password`, `re_password`, SMS `code`, send-code state; 确定 + 立即登录. Same `{username,password,re_password,code,code_text,math}`.
|
||||
|
||||
Element replacements here: `el-divider` → border/label, `el-message` → toast, and ordinary inputs/buttons can be native/Tailwind.
|
||||
|
||||
## 10. Theme and visual language
|
||||
|
||||
- `plugins/css/style.css` resets body/common block margins and list styles, sets `html,body,#app` height 100%, base `font-size:14px`, color `#333`, no explicit `font-family` (browser/system font applies). Links default `#333` with no decoration; hover `#000`. `body` margin is zero.
|
||||
- Fixed desktop container is `.center1200` and `.w1200`, both `width:1200px;margin:0 auto`; floats are `.float_left/.float_right`; `.clear` clears floats. Other recurring utility classes: `.breadcrumb` (30px vertical margin), `.shadow` (`0 2px 12px rgba(0,0,0,.1)`), `.x20` 1px gray divider with 20px margin, `.user_main` white padded card, `.table_lists` min-height 600px, `.block_title` 16px with 3px red left border.
|
||||
- `base.scss` has `$admin_background:#f4f4f4`; `.home` Element primary CSS vars are `--el-color-primary:#e50e19` and light variants, but storefront source consistently uses `#ca151e` for active links, red prices, buttons, selected filters, nav, and borders. Preserve both: `#ca151e` is the visual brand red; `#e50e19` is Element theme fallback. Status colors are green `#67c23a`, gray `#909399`, yellow `#e6a23c`, red `#f56c6c` (round utility classes).
|
||||
- Button language: white bordered `.default_btn`, red `.error_btn`, yellow `.warn_btn`, green `.success_btn`, gray `.gray_btn`; all compact 12px, 3px radius, 6px/15px padding. Cards/rows are mostly white with `#efefef` 1px rules, subtle hover lift/shadow, restrained 12–16px text, and red price emphasis. Home/floor backgrounds use `#f5f5f5`; user center uses `#f1f1f1`; header nav is `#333` with a red category block.
|
||||
- Replication recommendation: keep 1200px desktop grid, 20–30px section rhythm, 20px card gaps, 40px header/nav spacing, 220–224px product cards, gray separators, low-radius 3px controls, red active states and strikethrough market prices. Since the reference relies heavily on Element Plus (`el-carousel`, `el-image`, `el-breadcrumb`, `el-pagination`, `el-empty`, `el-checkbox`, `el-select`, `el-dialog`, `el-form`, `el-tabs`, `el-rate`, `el-result`, `el-badge`, `el-progress`, `el-timeline`, `el-icon`), a fresh Nuxt 3/Tailwind build should provide plain semantic replacements rather than porting Element’s runtime.
|
||||
Reference in New Issue
Block a user