feat: harden phase one workflows
This commit is contained in:
@@ -1,57 +1,126 @@
|
||||
<view class="page">
|
||||
<view class="section">
|
||||
<view class="section-title">邻小帮</view>
|
||||
<view class="muted">社区服务 30 分钟到家</view>
|
||||
<view class="home-hero">
|
||||
<view>
|
||||
<view class="hero-eyebrow">社区生活服务</view>
|
||||
<view class="hero-title">邻小帮</view>
|
||||
<view class="hero-subtitle">商品预定、快递代取、团购闲置都在这里</view>
|
||||
</view>
|
||||
<view class="hero-badge">30 分钟到家</view>
|
||||
</view>
|
||||
|
||||
<view class="grid section">
|
||||
<view class="shortcut" bindtap="go" data-url="/pages/products/index">商品预定</view>
|
||||
<view class="shortcut" bindtap="go" data-url="/pages/express/create">代取快递</view>
|
||||
<view class="shortcut" bindtap="goTab" data-url="/pages/group-buy/index">今日团购</view>
|
||||
<view class="shortcut" bindtap="goTab" data-url="/pages/second-hand/index">二手闲置</view>
|
||||
<view class="shortcut" bindtap="go" data-url="/pages/notices/index">社区公告</view>
|
||||
<view class="shortcut" bindtap="go" data-url="/pages/orders/index">我的订单</view>
|
||||
<view class="home-search" bindtap="go" data-url="/pages/products/index">
|
||||
<text>搜索社区商品、团购、闲置</text>
|
||||
<text class="search-action">去看看</text>
|
||||
</view>
|
||||
|
||||
<swiper wx:if="{{banners.length}}" class="banner-swiper" indicator-dots autoplay circular>
|
||||
<swiper-item wx:for="{{banners}}" wx:key="id">
|
||||
<view class="banner-card">
|
||||
<image wx:if="{{item.imageUrl}}" src="{{item.imageUrl}}" mode="aspectFill" />
|
||||
<view wx:else class="banner-fallback">邻小帮</view>
|
||||
<view class="banner-mask">
|
||||
<view class="banner-title">{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<view class="service-grid section">
|
||||
<view class="shortcut service-card service-product" bindtap="go" data-url="/pages/products/index">
|
||||
<view class="service-icon">货</view>
|
||||
<view class="service-name">商品预定</view>
|
||||
</view>
|
||||
<view class="shortcut service-card service-express" bindtap="go" data-url="/pages/express/create">
|
||||
<view class="service-icon">快</view>
|
||||
<view class="service-name">代取快递</view>
|
||||
</view>
|
||||
<view class="shortcut service-card service-group" bindtap="goTab" data-url="/pages/group-buy/index">
|
||||
<view class="service-icon">团</view>
|
||||
<view class="service-name">今日团购</view>
|
||||
</view>
|
||||
<view class="shortcut service-card service-second" bindtap="goTab" data-url="/pages/second-hand/index">
|
||||
<view class="service-icon">闲</view>
|
||||
<view class="service-name">二手闲置</view>
|
||||
</view>
|
||||
<view class="shortcut service-card service-notice" bindtap="go" data-url="/pages/notices/index">
|
||||
<view class="service-icon">告</view>
|
||||
<view class="service-name">社区公告</view>
|
||||
</view>
|
||||
<view class="shortcut service-card service-order" bindtap="go" data-url="/pages/orders/index">
|
||||
<view class="service-icon">单</view>
|
||||
<view class="service-name">我的订单</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<view class="section-title">公告</view>
|
||||
<view wx:for="{{notices}}" wx:key="id" class="card" bindtap="go" data-url="/pages/notices/index">
|
||||
<view>{{item.title}}</view>
|
||||
<view class="section-header">
|
||||
<view class="section-title">公告</view>
|
||||
<view class="pill" bindtap="go" data-url="/pages/notices/index">全部</view>
|
||||
</view>
|
||||
<view wx:for="{{notices}}" wx:key="id" class="content-card notice-brief" bindtap="go" data-url="/pages/notices/index">
|
||||
<view class="card-title">{{item.title}}</view>
|
||||
<view class="muted">{{item.category}}</view>
|
||||
</view>
|
||||
<view wx:if="{{!notices.length}}" class="card muted">暂无公告</view>
|
||||
<view wx:if="{{!notices.length}}" class="empty-state">暂无公告</view>
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<view class="section-title">热门商品</view>
|
||||
<view wx:for="{{products}}" wx:key="id" class="card" bindtap="go" data-url="/pages/products/detail?id={{item.id}}">
|
||||
<view class="row between">
|
||||
<view>{{item.name}}</view>
|
||||
<view class="section-header">
|
||||
<view class="section-title">热门商品</view>
|
||||
<view class="pill" bindtap="go" data-url="/pages/products/index">去选购</view>
|
||||
</view>
|
||||
<view wx:for="{{products}}" wx:key="id" class="content-card product-brief" bindtap="go" data-url="/pages/products/detail?id={{item.id}}">
|
||||
<view class="brief-main">
|
||||
<image wx:if="{{item.coverUrl}}" class="brief-cover" src="{{item.coverUrl}}" mode="aspectFill" />
|
||||
<view wx:else class="brief-cover media-placeholder">货</view>
|
||||
<view class="brief-body">
|
||||
<view class="card-title">{{item.name}}</view>
|
||||
<view class="muted">{{item.description || '社区精选商品'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="brief-side">
|
||||
<view class="tag">{{item.status}}</view>
|
||||
<view wx:if="{{item.skus.length}}" class="price">¥{{item.skus[0].priceCent / 100}} 起</view>
|
||||
</view>
|
||||
<view class="muted">{{item.description || '社区商品'}}</view>
|
||||
</view>
|
||||
<view wx:if="{{!products.length}}" class="empty-state">暂无热门商品</view>
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<view class="section-title">今日团购</view>
|
||||
<view wx:for="{{groupBuys}}" wx:key="id" class="card" bindtap="go" data-url="/pages/group-buy/detail?id={{item.id}}">
|
||||
<view class="row between">
|
||||
<view>{{item.title}}</view>
|
||||
<view class="price">¥{{item.priceCent / 100}}</view>
|
||||
</view>
|
||||
<view class="muted">已售 {{item.soldCount}} / 库存 {{item.stock}}</view>
|
||||
<view class="section-header">
|
||||
<view class="section-title">今日团购</view>
|
||||
<view class="pill" bindtap="goTab" data-url="/pages/group-buy/index">更多</view>
|
||||
</view>
|
||||
<view wx:for="{{groupBuys}}" wx:key="id" class="content-card group-brief" bindtap="go" data-url="/pages/group-buy/detail?id={{item.id}}">
|
||||
<view class="brief-main">
|
||||
<image wx:if="{{item.coverUrl}}" class="brief-cover" src="{{item.coverUrl}}" mode="aspectFill" />
|
||||
<view wx:else class="brief-cover media-placeholder">团</view>
|
||||
<view class="brief-body">
|
||||
<view class="card-title">{{item.title}}</view>
|
||||
<view class="muted">已售 {{item.soldCount}} / 库存 {{item.stock}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="price">¥{{item.priceCent / 100}}</view>
|
||||
</view>
|
||||
<view wx:if="{{!groupBuys.length}}" class="empty-state">暂无团购</view>
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<view class="section-title">最新闲置</view>
|
||||
<view wx:for="{{secondGoods}}" wx:key="id" class="card">
|
||||
<view class="row between">
|
||||
<view>{{item.title}}</view>
|
||||
<view class="price">¥{{item.priceCent / 100}}</view>
|
||||
</view>
|
||||
<view class="muted">{{item.category}}</view>
|
||||
<view class="section-header">
|
||||
<view class="section-title">最新闲置</view>
|
||||
<view class="pill" bindtap="goTab" data-url="/pages/second-hand/index">逛闲置</view>
|
||||
</view>
|
||||
<view wx:for="{{secondGoods}}" wx:key="id" class="content-card second-brief">
|
||||
<view class="brief-main">
|
||||
<image wx:if="{{item.imageUrls.length}}" class="brief-cover" src="{{item.imageUrls[0]}}" mode="aspectFill" />
|
||||
<view wx:else class="brief-cover media-placeholder">闲</view>
|
||||
<view class="brief-body">
|
||||
<view class="card-title">{{item.title}}</view>
|
||||
<view class="muted">{{item.category}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="price">¥{{item.priceCent / 100}}</view>
|
||||
</view>
|
||||
<view wx:if="{{!secondGoods.length}}" class="empty-state">暂无闲置</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -1,3 +1,218 @@
|
||||
.page {
|
||||
padding-bottom: 40rpx;
|
||||
padding-bottom: 56rpx;
|
||||
}
|
||||
|
||||
.home-hero {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
min-height: 220rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
color: #ffffff;
|
||||
background: #0f766e;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 14rpx 34rpx rgba(15, 118, 110, 0.22);
|
||||
}
|
||||
|
||||
.hero-eyebrow {
|
||||
display: inline-flex;
|
||||
height: 42rpx;
|
||||
align-items: center;
|
||||
padding: 0 14rpx;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
margin-top: 22rpx;
|
||||
font-size: 48rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
margin-top: 14rpx;
|
||||
color: rgba(255, 255, 255, 0.86);
|
||||
font-size: 25rpx;
|
||||
}
|
||||
|
||||
.hero-badge {
|
||||
flex-shrink: 0;
|
||||
padding: 10rpx 16rpx;
|
||||
color: #854d0e;
|
||||
background: #fef3c7;
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.home-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 82rpx;
|
||||
padding: 0 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
color: #64748b;
|
||||
background: #ffffff;
|
||||
border: 1rpx solid #dfe7ee;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.search-action {
|
||||
color: #0f766e;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.banner-swiper {
|
||||
height: 220rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.banner-card {
|
||||
position: relative;
|
||||
height: 220rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 16rpx;
|
||||
background: #33536f;
|
||||
}
|
||||
|
||||
.banner-card image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.banner-fallback {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 32rpx;
|
||||
color: #ffffff;
|
||||
background: #33536f;
|
||||
font-size: 36rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.banner-mask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 34rpx 28rpx 24rpx;
|
||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(17, 24, 39, 0.68));
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
color: #ffffff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.service-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
width: 100%;
|
||||
height: 150rpx;
|
||||
align-items: flex-start;
|
||||
padding: 20rpx;
|
||||
border: 1rpx solid #e2e8f0;
|
||||
box-shadow: 0 8rpx 20rpx rgba(20, 36, 58, 0.05);
|
||||
}
|
||||
|
||||
.service-icon {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 14rpx;
|
||||
color: #ffffff;
|
||||
border-radius: 14rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
color: #111827;
|
||||
font-size: 26rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.service-product .service-icon {
|
||||
background: #0f766e;
|
||||
}
|
||||
|
||||
.service-express .service-icon {
|
||||
background: #2563eb;
|
||||
}
|
||||
|
||||
.service-group .service-icon {
|
||||
background: #c2410c;
|
||||
}
|
||||
|
||||
.service-second .service-icon {
|
||||
background: #7c3aed;
|
||||
}
|
||||
|
||||
.service-notice .service-icon {
|
||||
background: #33536f;
|
||||
}
|
||||
|
||||
.service-order .service-icon {
|
||||
background: #be123c;
|
||||
}
|
||||
|
||||
.content-card {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 18rpx;
|
||||
padding: 22rpx;
|
||||
margin-bottom: 16rpx;
|
||||
background: #ffffff;
|
||||
border: 1rpx solid #e4eaf0;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 8rpx 24rpx rgba(20, 36, 58, 0.05);
|
||||
}
|
||||
|
||||
.notice-brief {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.brief-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
gap: 18rpx;
|
||||
}
|
||||
|
||||
.brief-cover {
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.brief-body {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.brief-side {
|
||||
min-width: 112rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
gap: 14rpx;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user