Files

580 lines
14 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<layout>
<view class="index-page">
<uv-navbar
:fixed="false"
:safeAreaInsetTop="true"
height="0"
bgColor="transparent"
leftIcon=""
/>
<!-- 顶部问候 -->
<view class="index-header">
<view class="index-header__greet">
你好,{{ isLogin && member.nickname ? member.nickname : '游客' }}
</view>
<view class="index-header__sub">欢迎来到米糖烘焙点单</view>
</view>
<!-- 品牌 Banner / 广告轮播 -->
<view class="index-banner">
<view v-if="listAds.length" class="index-banner__swiper-wrap">
<uv-swiper
class="index-banner__swiper"
height="320"
radius="24"
imgMode="aspectFill"
keyName="image"
:list="listAds"
indicator
indicatorMode="dot"
indicatorActiveColor="#F28C38"
indicatorInactiveColor="rgba(255,255,255,.75)"
/>
</view>
<view v-else class="index-banner__brand">
<view class="index-banner__brand-left">
<view class="index-banner__logo">
<text class="index-banner__logo-en">Maitre</text>
<text class="index-banner__logo-zh">米糖</text>
</view>
<view class="index-banner__divider"></view>
<view class="index-banner__slogan">你的烘焙材料管家</view>
<view class="index-banner__features">
<view
v-for="item in brandFeatures"
:key="item.label"
class="index-banner__feature"
>
<view class="index-banner__feature-icon">
<uv-icon :name="item.icon" size="14" color="#8B5A2B" />
</view>
<text class="index-banner__feature-label">{{ item.label }}</text>
</view>
</view>
</view>
<view class="index-banner__brand-right">
<view class="index-banner__cupcake">
<view class="index-banner__cupcake-cherry"></view>
<view class="index-banner__cupcake-frost"></view>
<view class="index-banner__cupcake-body"></view>
<view class="index-banner__cupcake-wrap"></view>
</view>
</view>
<view class="index-banner__dots">
<view class="index-banner__dot index-banner__dot--active"></view>
<view class="index-banner__dot"></view>
<view class="index-banner__dot"></view>
</view>
</view>
</view>
<!-- 自取 / 外卖 -->
<view class="index-services">
<view class="index-service" @tap="takein">
<view class="index-service__info">
<view class="index-service__title">自取</view>
<view class="index-service__desc">下单免排队</view>
<view class="index-service__btn index-service__btn--orange">
去下单 >
</view>
</view>
<image
class="index-service__img"
src="/static/images/index002.png"
mode="aspectFit"
/>
</view>
<view class="index-service" @tap="takeout">
<view class="index-service__info">
<view class="index-service__title">外卖</view>
<view class="index-service__desc">美食送到家</view>
<view class="index-service__btn index-service__btn--gold">
去下单 >
</view>
</view>
<image
class="index-service__img"
src="/static/images/index003.png"
mode="aspectFit"
/>
</view>
</view>
<!-- 卡券 / 积分 -->
<view class="index-extras">
<view class="index-extra" @tap="coupons">
<view class="index-extra__icon index-extra__icon--coupon">
<uv-icon name="coupon-fill" size="22" color="#ffffff" />
</view>
<view class="index-extra__main">
<view class="index-extra__title-row">
<text class="index-extra__title">我的卡券</text>
<text class="index-extra__value">{{ member.couponCount || 0 }}</text>
</view>
<view class="index-extra__desc">可抵扣商品价格哦</view>
</view>
<view class="index-extra__link">去领个券 ></view>
</view>
<view class="index-extra index-extra--last" @tap="goScore">
<view class="index-extra__icon index-extra__icon--score">
<uv-icon name="bag" size="22" color="#ffffff" />
</view>
<view class="index-extra__main">
<view class="index-extra__title-row">
<text class="index-extra__title">积分商城</text>
</view>
<view class="index-extra__desc">进入积分商城兑换优惠券</view>
</view>
<view class="index-extra__link">逛一逛 ></view>
</view>
</view>
</view>
</layout>
</template>
<script setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { menuAds } from '@/api/market'
import { storeToRefs } from 'pinia'
import { useMainStore } from '@/store/store'
const main = useMainStore()
const { member, store, isLogin } = storeToRefs(main)
const listAds = ref([])
const brandFeatures = [
{ icon: 'thumb-up', label: '优质原料' },
{ icon: 'grid', label: '品类丰富' },
{ icon: 'gift', label: '新鲜烘焙' },
{ icon: 'heart', label: '贴心服务' }
]
const handGetListAds = async () => {
const shop_id = store.value?.id ? store.value.id : 0
const data = await menuAds({ shop_id })
if (data) {
listAds.value = data.list || []
uni.setStorage({
key: 'isActive',
data: data.isActive
})
if (data.list && data.list.length > 0) {
uni.setStorage({
key: 'shopAd',
data: data.list[0].image
})
}
}
}
const takein = () => {
main.SET_ORDER_TYPE('takein')
uni.switchTab({ url: '/pages/menu/menu' })
}
const takeout = () => {
main.SET_ORDER_TYPE('takeout')
uni.switchTab({ url: '/pages/menu/menu' })
}
const coupons = () => {
if (!main.isLogin) {
uni.navigateTo({ url: '/pages/components/pages/login/login' })
return
}
uni.navigateTo({ url: '/pages/components/pages/coupons/coupons' })
}
const goScore = () => {
uni.navigateTo({ url: '/pages/components/pages/scoreproduct/list' })
}
onLoad(() => {
handGetListAds()
})
</script>
<style lang="scss">
$page-bg-top: #fff3e6;
$page-bg-mid: #fff8f0;
$page-bg-bottom: #ffffff;
$card-radius: 28rpx;
$accent-orange: #f28c38;
$accent-gold: #f5ba42;
$text-main: #2b2b2b;
$text-sub: #9a9590;
/* #ifdef H5 */
page {
height: auto;
min-height: 100%;
}
/* #endif */
.index-page {
min-height: 100vh;
padding: 8rpx 28rpx 40rpx;
box-sizing: border-box;
background: linear-gradient(
180deg,
$page-bg-top 0%,
$page-bg-mid 42%,
$page-bg-bottom 100%
);
}
.index-header {
padding: 8rpx 8rpx 28rpx;
&__greet {
font-size: 40rpx;
font-weight: 700;
color: $text-main;
line-height: 1.3;
}
&__sub {
margin-top: 10rpx;
font-size: 26rpx;
color: $text-sub;
}
}
.index-banner {
margin-bottom: 24rpx;
&__swiper-wrap {
overflow: hidden;
border-radius: $card-radius;
border: 3rpx solid #ffffff;
box-shadow: 0 12rpx 28rpx rgba(180, 120, 60, 0.12);
}
&__brand {
position: relative;
display: flex;
align-items: stretch;
min-height: 320rpx;
padding: 36rpx 28rpx 48rpx;
border-radius: $card-radius;
border: 3rpx solid #ffffff;
overflow: hidden;
background:
radial-gradient(ellipse at 85% 40%, rgba(255, 255, 255, 0.55) 0%, transparent 55%),
linear-gradient(135deg, #f7e8d4 0%, #f0d7b8 45%, #e8c9a0 100%);
box-shadow: 0 12rpx 28rpx rgba(180, 120, 60, 0.12);
}
&__brand-left {
flex: 1;
z-index: 2;
min-width: 0;
}
&__logo {
display: flex;
align-items: baseline;
gap: 12rpx;
}
&__logo-en {
font-size: 48rpx;
font-weight: 600;
font-style: italic;
color: #6b3f1f;
font-family: 'Times New Roman', Georgia, serif;
letter-spacing: 1rpx;
}
&__logo-zh {
font-size: 40rpx;
font-weight: 700;
color: #5a3418;
}
&__divider {
width: 72rpx;
height: 4rpx;
margin: 16rpx 0 12rpx;
border-radius: 4rpx;
background: linear-gradient(90deg, #d4a45a, transparent);
}
&__slogan {
font-size: 24rpx;
color: #8a6a4a;
margin-bottom: 28rpx;
}
&__features {
display: flex;
flex-wrap: wrap;
gap: 16rpx 20rpx;
}
&__feature {
display: flex;
align-items: center;
gap: 6rpx;
}
&__feature-icon {
width: 32rpx;
height: 32rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.55);
color: #8b5a2b;
font-size: 18rpx;
display: flex;
align-items: center;
justify-content: center;
}
&__feature-label {
font-size: 20rpx;
color: #7a5a3a;
}
&__brand-right {
width: 220rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
&__cupcake {
position: relative;
width: 140rpx;
height: 180rpx;
}
&__cupcake-cherry {
position: absolute;
top: 8rpx;
left: 58rpx;
width: 28rpx;
height: 28rpx;
border-radius: 50%;
background: #e4572e;
box-shadow: 0 4rpx 8rpx rgba(180, 40, 20, 0.25);
z-index: 4;
&::after {
content: '';
position: absolute;
top: -10rpx;
left: 10rpx;
width: 4rpx;
height: 14rpx;
border-radius: 4rpx;
background: #3d6b3d;
transform: rotate(-20deg);
}
}
&__cupcake-frost {
position: absolute;
top: 28rpx;
left: 18rpx;
width: 104rpx;
height: 72rpx;
border-radius: 52rpx 52rpx 40rpx 40rpx;
background: linear-gradient(180deg, #fff 0%, #f5f0ea 100%);
box-shadow: inset 0 -8rpx 12rpx rgba(200, 180, 160, 0.35);
z-index: 3;
}
&__cupcake-body {
position: absolute;
top: 84rpx;
left: 28rpx;
width: 84rpx;
height: 52rpx;
border-radius: 8rpx 8rpx 4rpx 4rpx;
background: linear-gradient(180deg, #6b3a22 0%, #4a2414 100%);
z-index: 2;
}
&__cupcake-wrap {
position: absolute;
top: 128rpx;
left: 24rpx;
width: 92rpx;
height: 44rpx;
background: repeating-linear-gradient(
90deg,
#f4e6d4 0 10rpx,
#e8d2b8 10rpx 20rpx
);
clip-path: polygon(8% 0, 92% 0, 100% 100%, 0 100%);
z-index: 1;
}
&__dots {
position: absolute;
left: 0;
right: 0;
bottom: 16rpx;
display: flex;
justify-content: center;
gap: 10rpx;
z-index: 3;
}
&__dot {
width: 10rpx;
height: 10rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.7);
&--active {
background: $accent-orange;
}
}
}
.index-services {
display: flex;
gap: 20rpx;
margin-bottom: 24rpx;
}
.index-service {
flex: 1;
position: relative;
display: flex;
flex-direction: column;
min-height: 260rpx;
padding: 28rpx 24rpx;
border-radius: $card-radius;
background: #fff;
box-shadow: 0 8rpx 24rpx rgba(180, 120, 60, 0.08);
overflow: hidden;
&__info {
position: relative;
z-index: 2;
display: flex;
flex-direction: column;
}
&__title {
font-size: 40rpx;
font-weight: 700;
color: $text-main;
line-height: 1.2;
}
&__desc {
margin-top: 8rpx;
font-size: 24rpx;
color: $text-sub;
}
&__btn {
display: inline-flex;
align-items: center;
align-self: flex-start;
margin-top: 20rpx;
padding: 10rpx 22rpx;
border-radius: 999rpx;
font-size: 22rpx;
color: #fff;
&--orange {
background: $accent-orange;
}
&--gold {
background: $accent-gold;
}
}
&__img {
position: absolute;
right: -8rpx;
bottom: -8rpx;
width: 150rpx;
height: 150rpx;
z-index: 1;
}
}
.index-extras {
padding: 8rpx 8rpx 8rpx 4rpx;
border-radius: $card-radius;
background: #fff;
box-shadow: 0 8rpx 24rpx rgba(180, 120, 60, 0.08);
}
.index-extra {
display: flex;
align-items: center;
padding: 28rpx 24rpx;
border-bottom: 1rpx solid #f3ebe3;
&--last {
border-bottom: none;
}
&__icon {
width: 72rpx;
height: 72rpx;
border-radius: 18rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-right: 20rpx;
&--coupon {
background: linear-gradient(145deg, #ffb347, #f28c38);
}
&--score {
background: linear-gradient(145deg, #ff9a4d, #ff7417);
}
}
&__main {
flex: 1;
min-width: 0;
}
&__title-row {
display: flex;
align-items: baseline;
gap: 10rpx;
}
&__title {
font-size: 30rpx;
font-weight: 700;
color: $text-main;
}
&__value {
font-size: 34rpx;
font-weight: 700;
color: $text-main;
}
&__desc {
margin-top: 6rpx;
font-size: 22rpx;
color: $text-sub;
}
&__link {
flex-shrink: 0;
margin-left: 12rpx;
font-size: 24rpx;
color: $accent-orange;
}
}
</style>