feat: 初始化
@@ -0,0 +1,4 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.DS_Store
|
||||
*.log
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ['@vue/cli-plugin-babel/preset']
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "supplied-h5",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve --host 0.0.0.0",
|
||||
"build": "vue-cli-service build"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.37.1",
|
||||
"vant": "^2.13.9",
|
||||
"vue": "^2.7.16",
|
||||
"vue-router": "^3.6.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~5.0.8",
|
||||
"@vue/cli-service": "~5.0.8",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^10.2.0",
|
||||
"vue-template-compiler": "^2.7.16"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<title>供货端</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>请启用 JavaScript 后访问本应用。</noscript>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div id="app"><router-view /></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
* { box-sizing: border-box; }
|
||||
body { margin: 0; background: #f7f8fa; color: #323233; }
|
||||
#app { min-height: 100vh; font-family: Arial, sans-serif; }
|
||||
a { color: inherit; text-decoration: none; }
|
||||
</style>
|
||||
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 695 KiB |
|
After Width: | Height: | Size: 674 KiB |
|
After Width: | Height: | Size: 665 KiB |
|
After Width: | Height: | Size: 267 KiB |
|
After Width: | Height: | Size: 268 KiB |
|
After Width: | Height: | Size: 246 KiB |
|
After Width: | Height: | Size: 269 KiB |
|
After Width: | Height: | Size: 220 KiB |
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<main class="shop" :class="`shop--${shop.layout}`" :style="{ '--theme': shop.theme }">
|
||||
<van-nav-bar :title="shop.name" left-arrow @click-left="$router.push('/')" />
|
||||
|
||||
<section class="hero" :style="{ background: shop.gradient }">
|
||||
<div>
|
||||
<span class="hero__eyebrow">官方品质供应商</span>
|
||||
<h1>{{ shop.slogan }}</h1>
|
||||
<p>满 {{ shop.freeShipping }} 元免配送费</p>
|
||||
</div>
|
||||
<van-icon :name="shop.icon" size="64" />
|
||||
</section>
|
||||
|
||||
<van-notice-bar class="notice" left-icon="volume-o" :text="shop.notice" />
|
||||
<van-search v-model="keyword" placeholder="搜索商品" shape="round" />
|
||||
|
||||
<van-tabs v-model="activeCategory" sticky :color="shop.theme" title-active-color="var(--theme)">
|
||||
<van-tab v-for="category in categories" :key="category" :title="category" />
|
||||
</van-tabs>
|
||||
|
||||
<van-empty v-if="filteredProducts.length === 0" description="暂无相关商品" />
|
||||
<section v-else class="goods-list">
|
||||
<van-card
|
||||
v-for="item in filteredProducts"
|
||||
:key="item.id"
|
||||
:price="item.price.toFixed(2)"
|
||||
:desc="item.desc"
|
||||
:title="item.name"
|
||||
:thumb="item.image"
|
||||
:origin-price="item.originPrice.toFixed(2)"
|
||||
>
|
||||
<template #tags>
|
||||
<van-tag round plain :color="shop.theme">{{ item.tag }}</van-tag>
|
||||
</template>
|
||||
<template #footer>
|
||||
<van-stepper v-model="cart[item.id]" theme="round" :button-size="25" :disable-input="true" />
|
||||
</template>
|
||||
</van-card>
|
||||
</section>
|
||||
|
||||
<div class="bottom-space" />
|
||||
<van-submit-bar :price="totalPrice" :button-text="submitText" :disabled="totalCount === 0" @submit="openCheckout">
|
||||
<van-icon name="shopping-cart-o" size="26" :badge="totalCount || ''" class="cart-icon" />
|
||||
<span class="selected">已选 {{ totalCount }} 件</span>
|
||||
</van-submit-bar>
|
||||
|
||||
<van-popup v-model="checkoutVisible" round position="bottom" :style="{ minHeight: '68%' }" closeable>
|
||||
<section class="checkout">
|
||||
<h2>确认订单</h2>
|
||||
<van-contact-card type="add" name="商城收货人" tel="138****8888" @click="Toast('当前使用默认收货地址')" />
|
||||
<van-cell-group inset title="商品清单">
|
||||
<van-cell
|
||||
v-for="item in selectedProducts"
|
||||
:key="item.id"
|
||||
:title="item.name"
|
||||
:label="`¥ ${item.price.toFixed(2)} × ${cart[item.id]}`"
|
||||
:value="`¥ ${(item.price * cart[item.id]).toFixed(2)}`"
|
||||
/>
|
||||
</van-cell-group>
|
||||
<van-cell-group inset>
|
||||
<van-cell title="配送方式" value="供应商配送" />
|
||||
<van-cell title="配送费" :value="freight ? `¥ ${freight.toFixed(2)}` : '免配送费'" />
|
||||
</van-cell-group>
|
||||
<div class="checkout__total">合计 <b>¥ {{ (totalPrice / 100).toFixed(2) }}</b></div>
|
||||
<van-button block round :color="shop.gradient" :loading="submitting" @click="submitOrder">提交订单</van-button>
|
||||
</section>
|
||||
</van-popup>
|
||||
|
||||
<van-popup v-model="successVisible" round closeable class="result-popup">
|
||||
<van-icon name="checked" color="#23b65d" size="62" />
|
||||
<h2>订单提交成功</h2>
|
||||
<p>订单号:{{ submittedOrderId }}</p>
|
||||
<van-button round block type="primary" @click="successVisible = false">继续选购</van-button>
|
||||
</van-popup>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Toast } from 'vant'
|
||||
|
||||
const apiBase = process.env.VUE_APP_API_BASE || 'http://localhost:8050'
|
||||
const formatTime = date => date.toISOString().slice(0, 19).replace('T', ' ')
|
||||
|
||||
export default {
|
||||
props: {
|
||||
shop: { type: Object, required: true }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword: '',
|
||||
activeCategory: 0,
|
||||
cart: this.shop.products.reduce((result, item) => ({ ...result, [item.id]: 0 }), {}),
|
||||
checkoutVisible: false,
|
||||
successVisible: false,
|
||||
submitting: false,
|
||||
submittedOrderId: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
categories() {
|
||||
return ['全部', ...this.shop.categories]
|
||||
},
|
||||
filteredProducts() {
|
||||
const category = this.categories[this.activeCategory]
|
||||
const keyword = this.keyword.trim()
|
||||
return this.shop.products.filter(item => (category === '全部' || item.category === category) && (!keyword || item.name.includes(keyword)))
|
||||
},
|
||||
selectedProducts() {
|
||||
return this.shop.products.filter(item => this.cart[item.id] > 0)
|
||||
},
|
||||
totalCount() {
|
||||
return this.selectedProducts.reduce((sum, item) => sum + this.cart[item.id], 0)
|
||||
},
|
||||
goodsAmount() {
|
||||
return this.selectedProducts.reduce((sum, item) => sum + item.price * this.cart[item.id], 0)
|
||||
},
|
||||
freight() {
|
||||
return this.goodsAmount > 0 && this.goodsAmount < this.shop.freeShipping ? 12 : 0
|
||||
},
|
||||
totalPrice() {
|
||||
return Math.round((this.goodsAmount + this.freight) * 100)
|
||||
},
|
||||
submitText() {
|
||||
return this.totalCount ? `提交订单(${this.totalCount} 件)` : '提交订单'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openCheckout() {
|
||||
this.checkoutVisible = true
|
||||
},
|
||||
createOrderId() {
|
||||
return `SUP${new Date().toISOString().replace(/\D/g, '').slice(0, 14)}${Math.floor(Math.random() * 9000 + 1000)}`
|
||||
},
|
||||
async submitOrder() {
|
||||
const orderId = this.createOrderId()
|
||||
const now = formatTime(new Date())
|
||||
const orderInfo = {
|
||||
orderId,
|
||||
orderNumberId: `TRADE${Date.now()}`,
|
||||
supplierId: this.shop.id,
|
||||
aplName: this.shop.name,
|
||||
createTime: now,
|
||||
updateTime: now,
|
||||
deliveryStatus: '0',
|
||||
orderState: '0',
|
||||
totalPrice: +(this.totalPrice / 100).toFixed(2),
|
||||
pointsPrice: +(this.totalPrice / 100).toFixed(2),
|
||||
wPayOrAPay: 0,
|
||||
freightCost: this.freight,
|
||||
orderProInfos: this.selectedProducts.map(item => ({
|
||||
sku: item.sku,
|
||||
number: this.cart[item.id],
|
||||
price: +(item.price * this.cart[item.id]).toFixed(2),
|
||||
name: item.name,
|
||||
taxRate: 0.13,
|
||||
picInfo: [item.image]
|
||||
}))
|
||||
}
|
||||
|
||||
this.submitting = true
|
||||
try {
|
||||
const response = await fetch(`${apiBase}/general/receive/pending`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ supplierId: this.shop.id, userId: 'h5-demo-user', token: 'h5-demo-token', orderInfo })
|
||||
})
|
||||
const result = await response.json()
|
||||
if (!response.ok || result.resultCode !== 0) throw new Error(result.message || '订单提交失败')
|
||||
|
||||
this.submittedOrderId = result.data && result.data.orderId ? result.data.orderId : orderId
|
||||
this.checkoutVisible = false
|
||||
this.successVisible = true
|
||||
this.selectedProducts.forEach(item => { this.cart[item.id] = 0 })
|
||||
} catch (error) {
|
||||
Toast.fail(error.message || '无法连接订单服务,请确认服务已启动')
|
||||
} finally {
|
||||
this.submitting = false
|
||||
}
|
||||
},
|
||||
Toast
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.shop { min-height: 100vh; background: #f6f7f9; }
|
||||
.hero { display: flex; align-items: center; justify-content: space-between; margin: 12px; padding: 22px; border-radius: 18px; color: #fff; box-shadow: 0 10px 22px rgba(30, 80, 90, .14); }
|
||||
.hero h1 { margin: 7px 0; font-size: 23px; }
|
||||
.hero p, .hero__eyebrow { margin: 0; font-size: 13px; opacity: .9; }
|
||||
.notice { margin: 0 12px 8px; overflow: hidden; border-radius: 9px; }
|
||||
.goods-list { padding: 0 12px; }
|
||||
.van-card { margin: 10px 0; padding: 12px; border-radius: 12px; background: #fff; }
|
||||
.van-card__thumb { overflow: hidden; border-radius: 8px; }
|
||||
.bottom-space { height: 72px; }
|
||||
.cart-icon { margin: 0 10px 0 4px; }
|
||||
.selected { color: #646566; font-size: 13px; }
|
||||
.checkout { padding: 22px 16px 28px; }
|
||||
.checkout h2 { margin: 2px 0 18px; }
|
||||
.checkout__total { padding: 18px 8px; text-align: right; }
|
||||
.checkout__total b { color: #ee0a24; font-size: 22px; }
|
||||
.result-popup { width: 78%; padding: 32px 22px 24px; text-align: center; }
|
||||
.result-popup h2 { margin: 14px 0 8px; }
|
||||
.result-popup p { margin: 0 0 22px; color: #969799; font-size: 12px; }
|
||||
</style>
|
||||
@@ -0,0 +1,13 @@
|
||||
import Vue from 'vue'
|
||||
import Vant from 'vant'
|
||||
import 'vant/lib/index.css'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
Vue.use(Vant)
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
@@ -0,0 +1,43 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import SupplierHome from '@/view/index.vue'
|
||||
import JoyfulSelectionHome from '@/view/joyful-selection/index.vue'
|
||||
import JoyfulSelectionProductList from '@/view/joyful-selection/products/index.vue'
|
||||
import JoyfulSelectionProductDetail from '@/view/joyful-selection/product-detail/index.vue'
|
||||
import JoyfulSelectionCart from '@/view/joyful-selection/cart/index.vue'
|
||||
import JoyfulSelectionCartEdit from '@/view/joyful-selection/cart/edit/index.vue'
|
||||
import JoyfulSelectionCheckout from '@/view/joyful-selection/cart/checkout/index.vue'
|
||||
import JoyfulSelectionPayment from '@/view/joyful-selection/cart/payment/index.vue'
|
||||
import JoyfulSelectionPaymentConfirm from '@/view/joyful-selection/cart/payment-confirm/index.vue'
|
||||
import JoyfulSelectionPaymentSuccess from '@/view/joyful-selection/cart/payment-success/index.vue'
|
||||
import JoyfulSelectionOrders from '@/view/joyful-selection/profile/orders/index.vue'
|
||||
import JoyfulSelectionProfile from '@/view/joyful-selection/profile/index.vue'
|
||||
import JoyfulSelectionPoints from '@/view/joyful-selection/profile/points/index.vue'
|
||||
import HomeLiving from '@/view/home-living/index.vue'
|
||||
import HappyShopping from '@/view/happy-shopping/index.vue'
|
||||
import FreshFruit from '@/view/fresh-fruit/index.vue'
|
||||
import CuteSelection from '@/view/cute-selection/index.vue'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
routes: [
|
||||
{ path: '/', component: SupplierHome },
|
||||
{ path: '/joyful-selection', component: JoyfulSelectionHome },
|
||||
{ path: '/joyful-selection/products', component: JoyfulSelectionProductList },
|
||||
{ path: '/joyful-selection/product-detail', component: JoyfulSelectionProductDetail },
|
||||
{ path: '/joyful-selection/cart', component: JoyfulSelectionCart },
|
||||
{ path: '/joyful-selection/cart/edit', component: JoyfulSelectionCartEdit },
|
||||
{ path: '/joyful-selection/checkout', component: JoyfulSelectionCheckout },
|
||||
{ path: '/joyful-selection/payment', component: JoyfulSelectionPayment },
|
||||
{ path: '/joyful-selection/payment-confirm', component: JoyfulSelectionPaymentConfirm },
|
||||
{ path: '/joyful-selection/payment-success', component: JoyfulSelectionPaymentSuccess },
|
||||
{ path: '/joyful-selection/orders', component: JoyfulSelectionOrders },
|
||||
{ path: '/joyful-selection/profile', component: JoyfulSelectionProfile },
|
||||
{ path: '/joyful-selection/points', component: JoyfulSelectionPoints },
|
||||
{ path: '/home-living', component: HomeLiving },
|
||||
{ path: '/happy-shopping', component: HappyShopping },
|
||||
{ path: '/fresh-fruit', component: FreshFruit },
|
||||
{ path: '/cute-selection', component: CuteSelection }
|
||||
]
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<supplier-shop :shop="shop" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SupplierShop from '@/components/SupplierShop.vue'
|
||||
import { shops } from '../shop-data'
|
||||
|
||||
export default {
|
||||
name: 'CuteSelection',
|
||||
components: { SupplierShop },
|
||||
data: () => ({ shop: shops.cuteSelection })
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<supplier-shop :shop="shop" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SupplierShop from '@/components/SupplierShop.vue'
|
||||
import { shops } from '../shop-data'
|
||||
|
||||
export default {
|
||||
name: 'FreshFruit',
|
||||
components: { SupplierShop },
|
||||
data: () => ({ shop: shops.freshFruit })
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<supplier-shop :shop="shop" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SupplierShop from '@/components/SupplierShop.vue'
|
||||
import { shops } from '../shop-data'
|
||||
|
||||
export default {
|
||||
name: 'HappyShopping',
|
||||
components: { SupplierShop },
|
||||
data: () => ({ shop: shops.happyShopping })
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<supplier-shop :shop="shop" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SupplierShop from '@/components/SupplierShop.vue'
|
||||
import { shops } from '../shop-data'
|
||||
|
||||
export default {
|
||||
name: 'HomeLiving',
|
||||
components: { SupplierShop },
|
||||
data: () => ({ shop: shops.homeLiving })
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,293 @@
|
||||
<template>
|
||||
<main class="page">
|
||||
<van-nav-bar fixed placeholder title="首页" :border="false" />
|
||||
<van-search v-model="keyword" class="fixed-search" shape="round" placeholder="搜索供应商名称或商品" />
|
||||
|
||||
<section class="content">
|
||||
<van-swipe class="banner" :autoplay="3200" :show-indicators="false">
|
||||
<van-swipe-item v-for="banner in banners" :key="banner.id">
|
||||
<van-image class="banner-image" :src="banner.image" :alt="banner.alt" fit="contain" />
|
||||
</van-swipe-item>
|
||||
</van-swipe>
|
||||
|
||||
<section v-if="filteredSuppliers.length" class="list">
|
||||
<article v-for="supplier in filteredSuppliers" :key="supplier.id" class="card">
|
||||
<div class="icon" :style="{ backgroundColor: supplier.backgroundColor }">
|
||||
<van-image :src="supplier.image" :alt="`${supplier.name}图标`" fit="cover" />
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<div class="heading">
|
||||
<h2>{{ supplier.name }}</h2>
|
||||
<van-tag class="head-tag" plain type="warning">官方</van-tag>
|
||||
</div>
|
||||
<p class="description">{{ supplier.description }}</p>
|
||||
<div class="tags">
|
||||
<span v-for="tag in supplier.tags" :key="tag"
|
||||
:style="{ color: supplier.tagColor, backgroundColor: supplier.tagBackground }">
|
||||
{{ tag }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="stats">
|
||||
<span>商品数量 {{ formatCount(supplier.productCount) }}</span><i></i><span>月销 {{ formatCount(supplier.sales)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<van-button class="enter-supplier" round :color="supplier.buttonColor"
|
||||
@click="$router.push(supplier.path)">进入店铺</van-button>
|
||||
</article>
|
||||
</section>
|
||||
<van-empty v-else description="未找到相关供应商" />
|
||||
</section>
|
||||
|
||||
<footer class="services">
|
||||
<div v-for="service in services" :key="service.title" class="service">
|
||||
<van-icon :name="service.icon" :color="service.color" :size="22" />
|
||||
<span><b>{{ service.title }}</b><small>{{ service.description }}</small></span>
|
||||
</div>
|
||||
</footer>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import bannerWelfare from '@/assets/supplier-banner/supplier-banner-welfare.png'
|
||||
import bannerQuality from '@/assets/supplier-banner/supplier-banner-quality.png'
|
||||
import bannerDaily from '@/assets/supplier-banner/supplier-banner-daily.png'
|
||||
import supplierJoy from '@/assets/supplier-icons/joyful-selection.png'
|
||||
import supplierHome from '@/assets/supplier-icons/home-living.png'
|
||||
import supplierHappy from '@/assets/supplier-icons/happy-shopping.png'
|
||||
import supplierFruit from '@/assets/supplier-icons/fresh-fruit.png'
|
||||
import supplierCute from '@/assets/supplier-icons/cute-selection.png'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
keyword: '',
|
||||
banners: [
|
||||
{ id: 'welfare', image: bannerWelfare, alt: '优质供应商精选' },
|
||||
{ id: 'quality', image: bannerQuality, alt: '品质好物精选直供' },
|
||||
{ id: 'daily', image: bannerDaily, alt: '精选商品每日推荐' }
|
||||
],
|
||||
suppliers: [
|
||||
{ id: 'joy', name: '悦享优选', image: supplierJoy, description: '精选好物,悦享品质生活', tags: ['正品保障', '极速发货', '售后无忧'], productCount: 6800, sales: '18万+', backgroundColor: '#f4f7ff', tagColor: '#4e83ef', tagBackground: '#edf3ff', buttonColor: '#ff651d', path: '/joyful-selection' },
|
||||
{ id: 'home', name: '美家生活馆', image: supplierHome, description: '家居好物,点亮品质生活', tags: ['家居日用', '品质精选', '售后保障'], productCount: 5200, sales: '12万+', backgroundColor: '#f1fbf9', tagColor: '#18bfae', tagBackground: '#e9faf7', buttonColor: '#ff651d', path: '/home-living' },
|
||||
{ id: 'happy', name: '乐购甄选', image: supplierHappy, description: '天天低价,乐享购物', tags: ['低价好物', '限时优惠', '极速配送'], productCount: 7600, sales: '22万+', backgroundColor: '#f7f4ff', tagColor: '#7b61ee', tagBackground: '#f0edff', buttonColor: '#ff651d', path: '/happy-shopping' },
|
||||
{ id: 'fruit', name: '鲜果优品', image: supplierFruit, description: '新鲜直达,优选好果', tags: ['产地直采', '新鲜直达', '坏果包赔'], productCount: 3500, sales: '9万+', backgroundColor: '#fff9ed', tagColor: '#f39d16', tagBackground: '#fff5df', buttonColor: '#ff651d', path: '/fresh-fruit' },
|
||||
{ id: 'cute', name: '萌趣优选', image: supplierCute, description: '萌趣好物,快乐购物', tags: ['潮流好物', '品质保障', '贴心服务'], productCount: 4500, sales: '11万+', backgroundColor: '#fff4f7', tagColor: '#f45a7d', tagBackground: '#fff0f3', buttonColor: '#ff651d', path: '/cute-selection' }
|
||||
],
|
||||
services: [
|
||||
{ title: '正品保障', description: '品牌直供,假一赔十', icon: 'shield-o', color: '#3d78ed' },
|
||||
{ title: '极速配送', description: '多仓直发,快速送达', icon: 'logistics', color: '#15b8a3' },
|
||||
{ title: '售后无忧', description: '7天无理由退换货', icon: 'service-o', color: '#725cf2' }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredSuppliers() {
|
||||
const keyword = this.keyword.trim()
|
||||
return keyword ? this.suppliers.filter(item => `${item.name}${item.description}${item.tags.join('')}`.includes(keyword)) : this.suppliers
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatCount(value) {
|
||||
const source = String(value).trim()
|
||||
const explicitPlus = source.endsWith('+')
|
||||
const numeric = Number(source.replace(/\+$/, ''))
|
||||
|
||||
if (!Number.isFinite(numeric) || numeric <= 1000) return source
|
||||
|
||||
const rounded = Math.floor(numeric / 100) / 10
|
||||
const hasRemainder = numeric % 100 !== 0
|
||||
return `${rounded}k${explicitPlus || hasRemainder ? '+' : ''}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 76px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 64px 17px 0;
|
||||
}
|
||||
|
||||
.fixed-search {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
top: 46px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.banner {
|
||||
overflow: hidden;
|
||||
border-radius: 14px;
|
||||
aspect-ratio: 1492 / 315;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 13px;
|
||||
padding: 14px;
|
||||
border-radius: 17px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 74px;
|
||||
height: 74px;
|
||||
flex: none;
|
||||
overflow: hidden;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.icon ::v-deep .van-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.card-info {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.heading,
|
||||
.tags,
|
||||
.stats,
|
||||
.service {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.heading {
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.heading h2 {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
color: #1c1c1c;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.head-tag {
|
||||
flex: none;
|
||||
padding: 0 4px;
|
||||
font-size: 10px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.description {
|
||||
overflow: hidden;
|
||||
margin: 4px 0;
|
||||
color: #777;
|
||||
font-size: 10px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tags {
|
||||
gap: 5px;
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
padding-bottom: 1px;
|
||||
font-size: 9px;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.tags::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tags span {
|
||||
flex: 0 0 auto;
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.stats {
|
||||
gap: 5px;
|
||||
min-width: 0;
|
||||
margin-top: 3px;
|
||||
overflow: hidden;
|
||||
color: #868686;
|
||||
font-size: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.stats span {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.stats i {
|
||||
width: 1px;
|
||||
height: 13px;
|
||||
flex: none;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.enter-supplier {
|
||||
width: 72px;
|
||||
height: 24px;
|
||||
flex: none;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.services {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
height: 58px;
|
||||
background: #fff;
|
||||
border-top: 1px solid #f2f2f2;
|
||||
}
|
||||
|
||||
.service {
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
min-width: 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.service span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.service small {
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
color: rgb(226, 226, 226);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="checkout-page"><van-nav-bar title="确认订单" left-arrow @click-left="$router.back()"/><van-cell-group inset><van-cell title="收货人:张三 138****8888" label="浙江省杭州市余杭区文一西路 888 号 1203 室" is-link/></van-cell-group><van-cell-group inset title="配送方式"><van-cell title="预计送达:5月20日(周二)" value="快速配送 免邮"/></van-cell-group><van-cell-group inset><van-card v-for="item in goods" :key="item" :title="item" price="69.90" :thumb="teaImage" num="1"/></van-cell-group><van-field v-model="remark" label="订单备注" placeholder="选填,给商家留言"/><section class="amount"><p>商品金额 <b>¥287.90</b></p><p>运费 <b>¥0.00</b></p><p>优惠券 <b>暂无优惠券</b></p></section><van-submit-bar :price="28790" button-text="提交订单" @submit="$router.push('/joyful-selection/payment')"/></main></template>
|
||||
<script>import teaImage from '@/assets/joyful-selection/products/tea-set.png';export default{name:'JoyfulSelectionCheckout',data:()=>({teaImage,remark:'',goods:['简约北欧风陶瓷餐具套装','便携式榨汁机 家用小型','智能声波电动牙刷']})}</script>
|
||||
<style scoped>.checkout-page{min-height:100vh;padding-bottom:60px;background:#f7f7f7}.van-cell-group{margin:10px 12px}.amount{margin:10px 12px;padding:10px 16px;border-radius:10px;background:#fff;font-size:13px}.amount p{display:flex;justify-content:space-between}.amount b{font-weight:normal}.van-submit-bar{bottom:0}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="edit-page"><van-nav-bar title="购物车" right-text="完成" @click-right="$router.push('/joyful-selection/cart')"/><section><van-card v-for="item in goods" :key="item" :title="item" price="69.90" :thumb="teaImage"><template #footer><van-stepper v-model="count" theme="round" button-size="22"/></template></van-card></section><van-submit-bar button-text="删除" @submit="remove"><van-checkbox v-model="checked">全选</van-checkbox></van-submit-bar></main></template>
|
||||
<script>import teaImage from '@/assets/joyful-selection/products/tea-set.png';import {Toast} from 'vant';export default{name:'JoyfulSelectionCartEdit',data:()=>({teaImage,checked:false,count:1,goods:['简约北欧风陶瓷餐具套装','便携式榨汁机 家用小型','智能声波电动牙刷','大容量双肩电脑背包']}),methods:{remove(){Toast('请选择要删除的商品')}}}</script>
|
||||
<style scoped>.edit-page{min-height:100vh;padding-bottom:60px;background:#f7f7f7}.edit-page section{padding:0 12px}.edit-page .van-card{margin-top:10px;border-radius:10px;background:#fff}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="cart-page"><van-nav-bar title="购物车" right-text="编辑" @click-right="$router.push('/joyful-selection/cart/edit')"/><van-notice-bar text="满 199 元包邮,快去凑单吧~" left-icon="info-o"/><section class="cart-list"><van-card v-for="item in goods" :key="item.name" :title="item.name" :price="item.price" :thumb="teaImage"><template #tags><van-tag plain type="danger">精选</van-tag></template><template #footer><van-stepper v-model="item.count" theme="round" button-size="22"/></template></van-card></section><van-submit-bar :price="28790" button-text="去结算(3)" @submit="$router.push('/joyful-selection/checkout')"><van-checkbox v-model="checked">全选</van-checkbox></van-submit-bar><van-tabbar route><van-tabbar-item icon="wap-home-o" to="/joyful-selection">首页</van-tabbar-item><van-tabbar-item icon="apps-o" to="/joyful-selection/products">分类</van-tabbar-item><van-tabbar-item icon="cart-o" to="/joyful-selection/cart">购物车</van-tabbar-item><van-tabbar-item icon="user-o" to="/joyful-selection/profile">我的</van-tabbar-item></van-tabbar></main></template>
|
||||
<script>import teaImage from '@/assets/joyful-selection/products/tea-set.png';export default{name:'JoyfulSelectionCart',data:()=>({teaImage,checked:true,goods:[{name:'简约北欧风陶瓷餐具套装',price:'69.90',count:1},{name:'便携式榨汁机 家用小型',price:'89.00',count:1},{name:'智能声波电动牙刷',price:'129.00',count:1}]})}</script>
|
||||
<style scoped lang="less">.cart-page{min-height:100vh;padding-bottom:106px;background:#f7f7f7}.cart-list{padding:0 12px}.cart-list .van-card{margin-top:10px;border-radius:10px;background:#fff}.cart-list ::v-deep .van-card__price{color:#ff5b20;font-weight:bold}.van-submit-bar{bottom:50px}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="confirm-page"><van-nav-bar title="确认支付" left-arrow @click-left="$router.back()"/><section><p>支付金额</p><b>¥ 287.90</b></section><van-popup v-model="show" round position="bottom" :style="{height:'42%'}" :close-on-click-overlay="false"><article><h2>确认支付</h2><p>您即将使用微信支付</p><p>支付金额 <b>¥287.90</b></p><div><van-button round @click="$router.back()">取消</van-button><van-button round type="danger" @click="$router.push('/joyful-selection/payment-success')">确认支付</van-button></div></article></van-popup></main></template>
|
||||
<script>export default{name:'JoyfulSelectionPaymentConfirm',data:()=>({show:true})}</script>
|
||||
<style scoped>.confirm-page{min-height:100vh;background:#f7f7f7;text-align:center}.confirm-page section{margin:15px;padding:30px;border-radius:12px;background:#fff}.confirm-page section b{font-size:26px}.confirm-page article{padding:20px;text-align:center}.confirm-page article p{color:#666;font-size:13px}.confirm-page article div{display:flex;gap:10px;margin-top:40px}.confirm-page article .van-button{flex:1}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="success-page"><van-icon name="checked" color="#20bd58" size="68"/><h2>支付成功</h2><b>¥ 287.90</b><section><p>订单编号 <span>YX2024051812345678</span></p><p>支付方式 <span>微信支付</span></p><p>支付时间 <span>2024-05-18 14:35:28</span></p></section><div><van-button round @click="$router.push('/joyful-selection/orders')">查看订单</van-button><van-button round type="danger" @click="$router.push('/joyful-selection')">继续购物</van-button></div></main></template>
|
||||
<script>export default{name:'JoyfulSelectionPaymentSuccess'}</script>
|
||||
<style scoped>.success-page{min-height:100vh;padding:80px 30px;text-align:center;background:#fff}.success-page h2{margin:15px 0 10px;font-size:17px}.success-page>b{font-size:22px}.success-page section{margin-top:42px;text-align:left;color:#888;font-size:12px}.success-page section p{display:flex;justify-content:space-between}.success-page section span{color:#333}.success-page>div{display:flex;gap:10px;margin-top:35px}.success-page .van-button{flex:1}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="payment-page"><van-nav-bar title="确认支付" left-arrow @click-left="$router.back()"/><section class="pay-total"><p>支付金额</p><b>¥ 287.90</b></section><van-cell-group inset title="订单信息"><van-cell title="订单编号" value="YX2024051812345678"/><van-cell title="收货人" value="张三 138****8888"/></van-cell-group><van-radio-group v-model="payType"><van-cell-group inset title="支付方式"><van-cell title="微信支付" icon="wechat-pay" clickable @click="payType='wechat'"><template #right-icon><van-radio name="wechat"/></template></van-cell><van-cell title="支付宝支付" icon="alipay" clickable @click="payType='alipay'"><template #right-icon><van-radio name="alipay"/></template></van-cell><van-cell title="银联支付" icon="credit-pay" clickable @click="payType='union'"><template #right-icon><van-radio name="union"/></template></van-cell><van-cell title="余额支付(余额:¥32.00)" icon="gold-coin-o" clickable @click="payType='balance'"><template #right-icon><van-radio name="balance"/></template></van-cell></van-cell-group></van-radio-group><van-button class="pay-button" round type="danger" block @click="$router.push('/joyful-selection/payment-confirm')">立即支付 ¥287.90</van-button></main></template>
|
||||
<script>export default{name:'JoyfulSelectionPayment',data:()=>({payType:'wechat'})}</script>
|
||||
<style scoped>.payment-page{min-height:100vh;background:#f7f7f7}.pay-total{padding:25px;text-align:center;background:#fff}.pay-total p{margin:0;color:#666;font-size:13px}.pay-total b{display:block;margin-top:10px;font-size:26px}.van-cell-group{margin:10px 12px}.pay-button{position:fixed;right:16px;bottom:20px;left:16px;width:calc(100% - 32px)}</style>
|
||||
@@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<main class="joy-home">
|
||||
<van-search class="fixed-search" v-model="keyword" shape="round" placeholder="搜索商品名称" />
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-copy">
|
||||
<h1>品质生活 悦享好物</h1>
|
||||
<p>精选好物,悦享品质生活</p>
|
||||
<van-button size="mini" round @click="$router.push('/joyful-selection/products')">立即抢购</van-button>
|
||||
</div>
|
||||
<van-image class="hero-art" :src="supplierImage" fit="contain" />
|
||||
</section>
|
||||
|
||||
<van-grid :column-num="5" :border="false" class="category-grid">
|
||||
<van-grid-item v-for="item in categories" :key="item.name" @click="$router.push('/joyful-selection/products')">
|
||||
<template #icon>
|
||||
<div class="category-icon" :style="{ backgroundColor: item.background }"><van-icon :name="item.icon"
|
||||
:color="item.color" /></div>
|
||||
</template>
|
||||
<template #text><span class="category-title">{{ item.name }}</span></template>
|
||||
</van-grid-item>
|
||||
</van-grid>
|
||||
|
||||
<section class="product-section">
|
||||
<header class="section-head"><b>今日特惠</b><a @click="$router.push('/joyful-selection/products')">更多 ›</a></header>
|
||||
<div class="product-row">
|
||||
<article v-for="item in flashProducts" :key="item.name" @click="goProductDetail(item)">
|
||||
<van-image :src="item.image" fit="cover" />
|
||||
<div class="product-meta">
|
||||
<p>{{ item.name }}</p><b>¥{{ item.price }}</b>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="product-section hot-section">
|
||||
<header class="section-head"><b>爆款推荐</b><a @click="$router.push('/joyful-selection/products')">更多 ›</a></header>
|
||||
<div class="product-row">
|
||||
<article v-for="item in hotProducts" :key="item.name" @click="goProductDetail(item)">
|
||||
<van-image :src="item.image" fit="cover" />
|
||||
<div class="product-meta">
|
||||
<p>{{ item.name }}</p><b>¥{{ item.price }}</b>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<van-tabbar route active-color="#ff5b20" inactive-color="#777">
|
||||
<van-tabbar-item icon="wap-home-o" to="/joyful-selection">首页</van-tabbar-item>
|
||||
<van-tabbar-item icon="apps-o" to="/joyful-selection/products">分类</van-tabbar-item>
|
||||
<van-tabbar-item icon="cart-o" to="/joyful-selection/cart">购物车</van-tabbar-item>
|
||||
<van-tabbar-item icon="user-o" to="/joyful-selection/profile">我的</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import supplierImage from '@/assets/supplier-icons/joyful-selection.png'
|
||||
import teaImage from '@/assets/joyful-selection/products/tea-set.png'
|
||||
|
||||
export default {
|
||||
name: 'JoyfulSelectionHome',
|
||||
data() {
|
||||
const productImages = [teaImage, teaImage, teaImage, teaImage]
|
||||
return {
|
||||
keyword: '',
|
||||
supplierImage,
|
||||
categories: [
|
||||
{ name: '精选推荐', icon: 'like', color: '#ff6e8a', background: '#fff0f3' },
|
||||
{ name: '居家生活', icon: 'shop-o', color: '#54b8e6', background: '#e9f8ff' },
|
||||
{ name: '数码家电', icon: 'photo-o', color: '#7771ee', background: '#efefff' },
|
||||
{ name: '美妆个护', icon: 'gift', color: '#e878c4', background: '#fff0fb' },
|
||||
{ name: '食品饮料', icon: 'bag', color: '#e9a438', background: '#fff5e7' },
|
||||
{ name: '母婴玩具', icon: 'smile', color: '#77b1e7', background: '#eef8ff' },
|
||||
{ name: '服饰鞋包', icon: 'flower-o', color: '#ed769c', background: '#fff0f3' },
|
||||
{ name: '运动户外', icon: 'fire', color: '#32bc91', background: '#eafbf6' },
|
||||
{ name: '超值专区', icon: 'label', color: '#ec8c3d', background: '#fff4e9' },
|
||||
{ name: '全部分类', icon: 'apps-o', color: '#989898', background: '#f5f5f5' }
|
||||
],
|
||||
flashProducts: [
|
||||
{ name: '香氛洗护', price: '59.9', image: productImages[0] },
|
||||
{ name: '品质茶具', price: '99.0', image: productImages[1] },
|
||||
{ name: '绿植盆栽', price: '39.9', image: productImages[2] },
|
||||
{ name: '声波牙刷', price: '129.0', image: productImages[3] }
|
||||
],
|
||||
hotProducts: [
|
||||
{ name: '护颈枕', price: '89.0', image: productImages[2] },
|
||||
{ name: '简约花瓶', price: '59.0', image: productImages[0] },
|
||||
{ name: '香薰礼盒', price: '69.0', image: productImages[1] },
|
||||
{ name: '轻享水杯', price: '49.0', image: productImages[3] }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goProductDetail(item) {
|
||||
this.$router.push({ path: '/joyful-selection/product-detail', query: { title: item.name, price: item.price } })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.joy-home {
|
||||
min-height: 100vh;
|
||||
padding: 54px 0 70px;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.fixed-search {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.joy-home ::v-deep .van-search {
|
||||
padding: 10px 12px 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.joy-home ::v-deep .van-search__content {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
.joy-home ::v-deep .van-field__control {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.hero {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 108px;
|
||||
margin: 10px 10px 0;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(114deg, #8c77fb 0%, #c2b9ff 100%);
|
||||
}
|
||||
|
||||
.hero-copy {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 21px 0 0 18px;
|
||||
color: #26214f;
|
||||
}
|
||||
|
||||
.hero-copy h1 {
|
||||
margin: 0;
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .2px;
|
||||
}
|
||||
|
||||
.hero-copy p {
|
||||
margin: 5px 0 11px;
|
||||
color: #5f579e;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.hero-copy .van-button {
|
||||
min-width: 53px;
|
||||
height: 19px;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
font-size: 9px;
|
||||
background: #6f5ee9;
|
||||
}
|
||||
|
||||
.hero-art {
|
||||
position: absolute;
|
||||
right: 11px;
|
||||
bottom: -8px;
|
||||
width: 119px;
|
||||
height: 119px;
|
||||
filter: drop-shadow(0 10px 8px rgba(72, 58, 176, .2));
|
||||
}
|
||||
|
||||
.category-grid {
|
||||
margin: 8px 10px 9px;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.category-grid ::v-deep .van-grid-item__content {
|
||||
padding: 10px 0 7px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.category-grid ::v-deep .van-grid-item__icon {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.category-icon {
|
||||
display: flex;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.category-icon .van-icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
color: #4d4d4d;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.category-grid ::v-deep .van-grid-item__text {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.product-section {
|
||||
margin: 9px 10px;
|
||||
padding: 10px 8px 9px;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 18px;
|
||||
margin: 0 0 8px 1px;
|
||||
}
|
||||
|
||||
.section-head b {
|
||||
margin-right: 7px;
|
||||
color: #222;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.section-head a {
|
||||
margin-left: auto;
|
||||
color: #888;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.product-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.product-row article {
|
||||
width: calc((100% - 21px) / 4);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.product-row .van-image {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.product-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.product-meta p {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
color: #555;
|
||||
font-size: 9px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.product-meta b {
|
||||
flex: none;
|
||||
color: #ff5b20;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.hot-section {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.joy-home ::v-deep .van-tabbar-item__icon {
|
||||
margin-bottom: 2px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.joy-home ::v-deep .van-tabbar-item__text {
|
||||
font-size: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<main class="detail-page">
|
||||
<van-nav-bar title="商品详情" left-arrow @click-left="$router.back()" />
|
||||
<van-image class="product-image" :src="teaImage" fit="cover" />
|
||||
<section class="product-info">
|
||||
<h1>{{ productTitle }}</h1>
|
||||
<p>精选优质瓷土,简约百搭,为品质生活增添仪式感</p>
|
||||
<div><b>¥{{ productPrice }}</b><del>¥89.90</del><van-tag type="danger" plain>精选</van-tag></div>
|
||||
</section>
|
||||
<van-cell-group inset title="商品服务">
|
||||
<van-cell title="正品保障" value="极速发货 · 售后无忧" />
|
||||
<van-cell title="配送" value="满 99 元免配送费" />
|
||||
</van-cell-group>
|
||||
<section class="detail-content"><h2>商品详情</h2><p>精致器型与温润釉色,适合日常用餐、下午茶与礼赠场景。</p></section>
|
||||
<van-goods-action>
|
||||
<van-goods-action-icon icon="chat-o" text="客服" dot />
|
||||
<van-goods-action-icon icon="cart-o" text="购物车" badge="5" @click="$router.push('/joyful-selection/cart')" />
|
||||
<van-goods-action-icon icon="star" text="已收藏" color="#ff5000" />
|
||||
<van-goods-action-button type="warning" text="加入购物车" @click="$toast('已加入购物车')" />
|
||||
<van-goods-action-button type="danger" text="立即购买" @click="$router.push('/joyful-selection/checkout')" />
|
||||
</van-goods-action>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import teaImage from '@/assets/joyful-selection/products/tea-set.png'
|
||||
export default {
|
||||
name: 'JoyfulSelectionProductDetail',
|
||||
data: () => ({ teaImage }),
|
||||
computed: {
|
||||
productTitle() { return this.$route.query.title || '简约北欧风陶瓷餐具套装' },
|
||||
productPrice() { return this.$route.query.price || '69.90' }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.detail-page { min-height: 100vh; padding-bottom: 56px; background: #f7f7f7; }
|
||||
.product-image { display: block; width: 100%; height: 310px; background: #fff; }
|
||||
.product-info, .detail-content { margin: 10px 12px; padding: 14px; border-radius: 10px; background: #fff; }
|
||||
.product-info h1 { margin: 0 0 8px; font-size: 17px; }
|
||||
.product-info p, .detail-content p { color: #777; font-size: 12px; line-height: 1.6; }
|
||||
.product-info b { margin-right: 8px; color: #ff5b20; font-size: 21px; }
|
||||
.product-info del { margin-right: 9px; color: #aaa; font-size: 11px; }
|
||||
.detail-content h2 { margin: 0; font-size: 15px; }
|
||||
</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="product-page"><van-nav-bar title="商品列表" left-arrow @click-left="$router.back()"/><van-tabs v-model="active" color="#715ef1"><van-tab v-for="tab in tabs" :key="tab" :title="tab"/></van-tabs><section class="layout"><aside><span v-for="category in categories" :key="category" :class="{active: category===selected}" @click="selected=category">{{ category }}</span></aside><div class="goods"><van-card v-for="item in goods" :key="item.name" :title="item.name" :desc="item.desc" :price="item.price" :thumb="teaImage" @click="goProductDetail(item)"><template #tags><van-tag plain type="danger">精选</van-tag></template><template #footer><van-button icon="cart-o" size="mini" round type="danger" @click.stop="$router.push('/joyful-selection/cart')"/></template></van-card></div></section><van-tabbar route><van-tabbar-item icon="wap-home-o" to="/joyful-selection">首页</van-tabbar-item><van-tabbar-item icon="apps-o" to="/joyful-selection/products">分类</van-tabbar-item><van-tabbar-item icon="cart-o" to="/joyful-selection/cart">购物车</van-tabbar-item><van-tabbar-item icon="user-o" to="/joyful-selection/profile">我的</van-tabbar-item></van-tabbar></main></template>
|
||||
<script>import teaImage from '@/assets/joyful-selection/products/tea-set.png';export default{name:'JoyfulSelectionProductList',data:()=>({teaImage,active:0,selected:'推荐',tabs:['综合','销量','价格','筛选'],categories:['推荐','居家生活','数码家电','美妆个护','食品饮料','母婴玩具','服饰鞋包','运动户外'],goods:[{name:'简约北欧风陶瓷餐具套装',desc:'精致实用,悦享生活',price:'69.90'},{name:'便携式榨汁机 家用小型',desc:'鲜榨果汁随时享',price:'89.00'},{name:'100%纯棉舒适四件套',desc:'柔软亲肤,安心睡眠',price:'179.00'},{name:'智能声波电动牙刷',desc:'高频洁净,呵护口腔',price:'129.00'}]}),methods:{goProductDetail(item){this.$router.push({path:'/joyful-selection/product-detail',query:{title:item.name,price:item.price}})}}}</script>
|
||||
<style scoped lang="less">.product-page{min-height:100vh;padding-bottom:56px;background:#fff}.layout{display:flex}.layout aside{width:86px;flex:none;background:#f7f7f7}.layout aside span{display:block;padding:16px 8px;text-align:center;color:#666;font-size:12px}.layout aside .active{background:#fff;color:#ff5b20;font-weight:bold}.goods{flex:1;min-width:0;padding:0 9px}.goods .van-card{margin:10px 0;background:#fff}.goods ::v-deep .van-card__price{color:#ff5b20;font-weight:bold}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="profile-page"><section class="profile-top"><van-image round width="48" height="48" src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"/><div><b>张三</b><p>欢迎来到悦享优选</p></div><van-icon name="ellipsis"/></section><section class="asset"><div><small>我的积分</small><b>2368</b></div><div><small>成长值</small><b>3680</b></div><div><small>优惠券</small><b>5</b></div></section><section class="panel"><div class="panel-title">我的订单 <span @click="$router.push('/joyful-selection/orders')">全部订单 ›</span></div><van-grid :column-num="5" :border="false"><van-grid-item icon="balance-pay" text="待付款"/><van-grid-item icon="logistics" text="待发货"/><van-grid-item icon="send-gift-o" text="待收货"/><van-grid-item icon="todo-list-o" text="已完成"/><van-grid-item icon="after-sale" text="售后"/></van-grid></section><section class="panel"><div class="panel-title">我的服务</div><van-grid :column-num="4" :border="false"><van-grid-item icon="star-o" text="我的收藏"/><van-grid-item icon="clock-o" text="浏览记录"/><van-grid-item icon="location-o" text="收货地址"/><van-grid-item icon="coupon-o" text="优惠券"/><van-grid-item icon="gift-o" text="积分商城" @click="$router.push('/joyful-selection/points')"/><van-grid-item icon="service-o" text="客户服务"/><van-grid-item icon="edit" text="意见反馈"/><van-grid-item icon="setting-o" text="设置"/></van-grid></section><van-tabbar route><van-tabbar-item icon="wap-home-o" to="/joyful-selection">首页</van-tabbar-item><van-tabbar-item icon="apps-o" to="/joyful-selection/products">分类</van-tabbar-item><van-tabbar-item icon="cart-o" to="/joyful-selection/cart">购物车</van-tabbar-item><van-tabbar-item icon="user-o" to="/joyful-selection/profile">我的</van-tabbar-item></van-tabbar></main></template>
|
||||
<script>export default{name:'JoyfulSelectionProfile'}</script>
|
||||
<style scoped>.profile-page{min-height:100vh;padding-bottom:50px;background:#f7f7f7}.profile-top{display:flex;align-items:center;gap:12px;padding:24px 20px;background:linear-gradient(135deg,#dcd8ff,#f9f8ff)}.profile-top div{flex:1}.profile-top b{font-size:17px}.profile-top p{margin:4px 0 0;color:#777;font-size:11px}.asset{display:flex;margin:-3px 12px 12px;padding:14px;border-radius:10px;background:#fff}.asset div{display:grid;flex:1;gap:6px;text-align:center}.asset small{color:#777;font-size:11px}.asset b{color:#ff5b20}.panel{margin:10px 12px;border-radius:10px;background:#fff}.panel-title{padding:13px;font-size:13px;font-weight:bold}.panel-title span{float:right;color:#999;font-size:11px;font-weight:normal}.panel ::v-deep .van-grid-item__text{font-size:10px}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="orders-page"><van-nav-bar title="我的订单" left-arrow @click-left="$router.back()"/><van-tabs v-model="active"><van-tab v-for="tab in tabs" :key="tab" :title="tab"/></van-tabs><section><article v-for="order in orders" :key="order.id"><header><span>订单号:{{ order.id }}</span><b :class="order.status">{{ order.status }}</b></header><van-card title="简约北欧风陶瓷餐具套装" desc="共 3 件商品" price="287.90" :thumb="teaImage"/><footer><span>合计:<b>¥287.90</b></span><van-button size="small" round plain type="danger">查看详情</van-button></footer></article></section></main></template>
|
||||
<script>import teaImage from '@/assets/joyful-selection/products/tea-set.png';export default{name:'JoyfulSelectionOrders',data:()=>({teaImage,active:0,tabs:['全部','待付款','待发货','待收货','已完成','售后'],orders:[{id:'YX2024051812345678',status:'待发货'},{id:'YX2024051509876543',status:'待收货'},{id:'YX2024051211223344',status:'已完成'}]})}</script>
|
||||
<style scoped>.orders-page{min-height:100vh;background:#f7f7f7}.orders-page section{padding:0 12px}.orders-page article{margin-top:10px;border-radius:10px;background:#fff}.orders-page header,.orders-page footer{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;color:#999;font-size:11px}.orders-page header b{color:#ff5b20}.orders-page .已完成{color:#27ae60}.orders-page footer b{color:#222}.orders-page .van-card{background:#fff}</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template><main class="points-page"><van-nav-bar title="我的积分" left-arrow @click-left="$router.back()"/><section class="score"><small>可用积分</small><b>2368</b><van-button size="small" round @click="$router.push('/joyful-selection/products')">积分说明</van-button></section><van-grid :column-num="4" :border="false"><van-grid-item icon="gift-o" text="积分商城"/><van-grid-item icon="gift-card-o" text="积分抽奖"/><van-grid-item icon="balance-list-o" text="积分兑换"/><van-grid-item icon="todo-list-o" text="积分签到"/></van-grid><section class="details"><h3>积分明细</h3><van-cell v-for="item in items" :key="item.title" :title="item.title" :label="item.time" :value="item.value" :value-class="item.value[0] === '+' ? 'income' : 'cost'"/><p>没有更多了~</p></section></main></template>
|
||||
<script>export default{name:'JoyfulSelectionPoints',data:()=>({items:[{title:'签到奖励',time:'2024-05-18 09:30',value:'+10'},{title:'订单完成奖励',time:'2024-05-14 10:20',value:'+88'},{title:'积分兑换',time:'2024-05-08 15:11',value:'-200'},{title:'晒单奖励',time:'2024-05-02 08:30',value:'+20'},{title:'评价奖励',time:'2024-04-28 12:08',value:'+5'}]})}</script>
|
||||
<style scoped>.points-page{min-height:100vh;background:#f7f7f7}.score{position:relative;margin:10px 12px;padding:16px 18px;border-radius:10px;background:linear-gradient(135deg,#ffe0ac,#ffc66e)}.score small,.score b{display:block}.score small{font-size:11px}.score b{margin-top:6px;font-size:22px}.score .van-button{position:absolute;right:14px;top:24px;background:rgba(255,255,255,.6)}.points-page>.van-grid{margin:0 12px;border-radius:10px;background:#fff}.details{margin:10px 12px;padding:2px 0;border-radius:10px;background:#fff}.details h3{margin:14px;font-size:14px}.details p{text-align:center;color:#aaa;font-size:11px}.income{color:#14a44d}.cost{color:#f15b45}</style>
|
||||
@@ -0,0 +1,110 @@
|
||||
import joyfulSelectionIcon from '@/assets/supplier-icons/joyful-selection.png'
|
||||
import homeLivingIcon from '@/assets/supplier-icons/home-living.png'
|
||||
import happyShoppingIcon from '@/assets/supplier-icons/happy-shopping.png'
|
||||
import freshFruitIcon from '@/assets/supplier-icons/fresh-fruit.png'
|
||||
import cuteSelectionIcon from '@/assets/supplier-icons/cute-selection.png'
|
||||
|
||||
const product = (id, name, category, price, desc, tag, image) => ({
|
||||
id,
|
||||
sku: `SKU-${id.toUpperCase()}`,
|
||||
name,
|
||||
category,
|
||||
price,
|
||||
originPrice: +(price * 1.15).toFixed(2),
|
||||
desc,
|
||||
tag,
|
||||
image
|
||||
})
|
||||
|
||||
export const shops = {
|
||||
joyfulSelection: {
|
||||
id: 'SUP-JOY-001',
|
||||
name: '悦享优选',
|
||||
slogan: '精选好物,悦享品质生活',
|
||||
icon: 'shopping-bag-o',
|
||||
theme: '#4e83ef',
|
||||
gradient: 'linear-gradient(135deg, #4b8dff, #8ab9ff)',
|
||||
layout: 'joyful-selection',
|
||||
freeShipping: 99,
|
||||
notice: '精选好物限时直降,满 99 元免配送费',
|
||||
categories: ['人气好物', '居家日用', '数码周边'],
|
||||
products: [
|
||||
product('joy-tumbler', '轻享保温随行杯 500ml', '人气好物', 49.9, '316 不锈钢内胆,长效锁温', '品质精选', joyfulSelectionIcon),
|
||||
product('joy-pillow', '云感护颈记忆枕', '居家日用', 89.9, '慢回弹支撑,舒缓颈部压力', '人气推荐', joyfulSelectionIcon),
|
||||
product('joy-charger', '双口快充充电器 30W', '数码周边', 69, '小巧便携,多设备快速充电', '极速发货', joyfulSelectionIcon),
|
||||
product('joy-tissue', '原木抽纸 24 包', '居家日用', 39.9, '柔韧亲肤,家庭常备', '正品保障', joyfulSelectionIcon)
|
||||
]
|
||||
},
|
||||
homeLiving: {
|
||||
id: 'SUP-HOME-002',
|
||||
name: '美家生活馆',
|
||||
slogan: '家居好物,点亮品质生活',
|
||||
icon: 'home-o',
|
||||
theme: '#18bfae',
|
||||
gradient: 'linear-gradient(135deg, #18c9b6, #7ce3d7)',
|
||||
layout: 'home-living',
|
||||
freeShipping: 129,
|
||||
notice: '居家焕新季,精选商品满 129 元免配送费',
|
||||
categories: ['收纳整理', '家居清洁', '厨房用品'],
|
||||
products: [
|
||||
product('home-box', '可叠加透明收纳箱', '收纳整理', 35.9, '一目了然,轻松整理杂物', '家居日用', homeLivingIcon),
|
||||
product('home-rack', '多层厨房置物架', '厨房用品', 79.9, '稳固承重,释放台面空间', '品质精选', homeLivingIcon),
|
||||
product('home-cleaner', '植物配方地板清洁液', '家居清洁', 29.9, '温和去污,清新留香', '售后保障', homeLivingIcon),
|
||||
product('home-towel', '加厚吸水抹布 6 条装', '家居清洁', 22.9, '不易掉毛,耐用易清洗', '家庭必备', homeLivingIcon)
|
||||
]
|
||||
},
|
||||
happyShopping: {
|
||||
id: 'SUP-HAPPY-003',
|
||||
name: '乐购甄选',
|
||||
slogan: '天天低价,乐享购物',
|
||||
icon: 'bag-o',
|
||||
theme: '#7b61ee',
|
||||
gradient: 'linear-gradient(135deg, #8065ef, #b49bff)',
|
||||
layout: 'happy-shopping',
|
||||
freeShipping: 89,
|
||||
notice: '今日限时优惠,爆款商品低至 7 折',
|
||||
categories: ['限时优惠', '热销榜单', '实惠套装'],
|
||||
products: [
|
||||
product('happy-snack', '休闲零食大礼包', '限时优惠', 59.9, '多种风味,一次满足', '低价好物', happyShoppingIcon),
|
||||
product('happy-cup', '简约马克杯 2 只装', '热销榜单', 29.9, '高温烧制,圆润易清洗', '限时优惠', happyShoppingIcon),
|
||||
product('happy-bath', '柔软浴巾家庭装', '实惠套装', 69.9, '亲肤蓬松,吸水更快', '爆款直降', happyShoppingIcon),
|
||||
product('happy-lamp', '护眼阅读台灯', '热销榜单', 99, '多档调光,柔和不刺眼', '极速配送', happyShoppingIcon)
|
||||
]
|
||||
},
|
||||
freshFruit: {
|
||||
id: 'SUP-FRUIT-004',
|
||||
name: '鲜果优品',
|
||||
slogan: '新鲜直达,优选好果',
|
||||
icon: 'flower-o',
|
||||
theme: '#f39d16',
|
||||
gradient: 'linear-gradient(135deg, #f6a51c, #ffd45d)',
|
||||
layout: 'fresh-fruit',
|
||||
freeShipping: 99,
|
||||
notice: '产地直采,今日 16:00 前下单次日上午送达',
|
||||
categories: ['当季鲜果', '水果礼盒', '果切轻食'],
|
||||
products: [
|
||||
product('fruit-orange', '赣南脐橙 5 斤装', '当季鲜果', 45.9, '汁水丰盈,酸甜适口', '产地直采', freshFruitIcon),
|
||||
product('fruit-grape', '阳光玫瑰葡萄 1 斤装', '当季鲜果', 39.9, '清甜脆爽,颗粒饱满', '新鲜直达', freshFruitIcon),
|
||||
product('fruit-box', '精选鲜果礼盒', '水果礼盒', 99, '多品组合,送礼体面', '优选好果', freshFruitIcon),
|
||||
product('fruit-cut', '每日果切组合', '果切轻食', 25.9, '即开即食,轻松补充维 C', '冷链配送', freshFruitIcon)
|
||||
]
|
||||
},
|
||||
cuteSelection: {
|
||||
id: 'SUP-CUTE-005',
|
||||
name: '萌趣优选',
|
||||
slogan: '萌趣好物,快乐购物',
|
||||
icon: 'smile-o',
|
||||
theme: '#f45a7d',
|
||||
gradient: 'linear-gradient(135deg, #f45d80, #ff9db1)',
|
||||
layout: 'cute-selection',
|
||||
freeShipping: 99,
|
||||
notice: '萌趣新品上架,满 99 元享免配送费服务',
|
||||
categories: ['潮流好物', '萌趣文创', '贴心礼物'],
|
||||
products: [
|
||||
product('cute-doll', '兔兔抱枕玩偶', '萌趣文创', 59.9, '柔软亲肤,陪伴感满满', '潮流好物', cuteSelectionIcon),
|
||||
product('cute-notebook', '插画手账本礼盒', '萌趣文创', 39.9, '治愈插画,记录每一天', '品质保障', cuteSelectionIcon),
|
||||
product('cute-bag', '可爱帆布托特包', '潮流好物', 49.9, '轻巧百搭,日常实用', '贴心服务', cuteSelectionIcon),
|
||||
product('cute-gift', '萌趣生日礼物套装', '贴心礼物', 89.9, '精致包装,送礼更有心意', '快乐购物', cuteSelectionIcon)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 228 KiB |
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
publicPath: './',
|
||||
outputDir: 'dist',
|
||||
lintOnSave: false,
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
port: 3001,
|
||||
open: false
|
||||
}
|
||||
}
|
||||