更新 2026-04-18 21:54

This commit is contained in:
MaDaLei 2026-04-18 21:54:48 +08:00
parent a6bd72f0d4
commit b486dd313a

View File

@ -8,24 +8,20 @@
<view class="c-hero">
<text class="c-hero-title">服务预约</text>
<text class="c-hero-sub">一键预约洗美到店与进度随时可查</text>
<text class="c-hero-sub">在线选时段到店更省心</text>
<button class="app-btn-main app-btn-primary c-hero-cta" hover-class="c-hero-cta--hover" @click="openCustCreateAppt">
预约服务
</button>
</view>
<view class="home-dash">
<view
v-for="card in dashCards"
:key="card.key"
class="dash-card"
:class="{ 'dash-card--active': activeDashKey === card.key }"
@click="onDashCardClick(card.key)"
>
<text class="dash-card-value">{{ card.value }}</text>
<text class="dash-card-label">{{ card.label }}</text>
<text class="dash-card-hint">{{ card.hint }}</text>
</view>
<view class="c-cust-section">
<text class="c-cust-section-title">我的预约</text>
<text v-if="listMode === 'tab'" class="c-cust-section-hint">以下可查看已提交的预约按状态筛选</text>
</view>
<!-- 宠主不做门店 KPI 看板仅在有与我相关的进行态时给一行轻量提示§2 -->
<view v-if="petOwnerMeSummaryLine && listMode === 'tab'" class="c-cust-me-line">
<text class="c-cust-me-line-text">{{ petOwnerMeSummaryLine }}</text>
</view>
<view v-if="listMode === 'today'" class="list-mode-bar">
@ -67,13 +63,12 @@
:empty-hint="listEmptyHint"
@retry="fetchAppointments"
>
<template v-if="custEmptyProminent" #empty>
<text class="c-empty-emoji">📅</text>
<text class="c-empty-title">还没有预约</text>
<text class="c-empty-hint">创建预约后待开始与进行中的单会出现在下方列表</text>
<button class="app-btn-main app-btn-primary c-empty-cta" @click="openCustCreateAppt">立即预约</button>
<template v-if="custEmptyGuidance" #empty>
<text class="c-empty-emoji">📋</text>
<text class="c-empty-title">当前没有可展示的预约</text>
<text class="c-empty-hint">请使用上方预约服务创建提交后会在本列表显示进度</text>
</template>
<view class="order-list">
<view class="order-list order-list--cust">
<view
v-for="item in ordersForList"
:key="item.id"
@ -94,10 +89,6 @@
</view>
</view>
</AppPageState>
<view class="fab-appt fab-appt--cust-secondary" @click="openCustCreateAppt" hover-class="fab-appt--hover">
<text class="fab-appt-icon">+</text>
</view>
</view>
<!-- B端看板新建预约改为右下角悬浮按钮避免与小程序胶囊重叠 -->
@ -355,6 +346,17 @@ const dashCards = computed(() => {
const newApptCount = computed(() => orders.value.filter(o => o.status === 'new').length)
const doingApptCount = computed(() => orders.value.filter(o => o.status === 'doing').length)
/** 宠主:与我相关的轻量一句(非门店经营看板,见产品说明 §2 */
const petOwnerMeSummaryLine = computed(() => {
if (userInfo.role !== 'customer') return ''
const n = newApptCount.value
const d = doingApptCount.value
if (!n && !d) return ''
if (n && d) return `你有 ${n} 个待开始、${d} 个进行中的预约`
if (n) return `你有 ${n} 个待开始的预约`
return `你有 ${d} 个进行中的预约`
})
const serviceTypes = ref([])
const showNewAppt = ref(false)
const creatingAppt = ref(false)
@ -446,8 +448,8 @@ const showListPlaceholder = computed(
() => !appointmentsLoading.value && !appointmentsError.value && ordersForList.value.length === 0
)
/** 宠主 Tab 列表为空:用自定义空态突出主按钮(与首屏 CTA 一致) */
const custEmptyProminent = computed(
/** 宠主 Tab 列表为空:仅文案引导,避免与首屏「立即预约」重复入口 */
const custEmptyGuidance = computed(
() => userInfo.role === 'customer' && listMode.value === 'tab' && showListPlaceholder.value
)
@ -462,7 +464,7 @@ const listEmptyHint = computed(() => {
return '可返回列表切换日期或 Tab'
}
if (userInfo.role === 'customer') {
return '切换上方 Tab 查看不同状态,或新建预约'
return '切换上方状态查看不同进度'
}
return '切换上方状态或新建预约'
})
@ -736,24 +738,29 @@ onShow(() => {
font-weight: 700;
}
.c-hero {
padding: 24px 20px 32px;
margin: 8px 16px 0;
padding: 22px 20px 20px;
background: #fff;
border-radius: 16px;
box-shadow: 0 1px 8px rgba(15, 23, 42, 0.06);
}
.c-hero-title {
display: block;
font-size: 26px;
font-size: 22px;
font-weight: 800;
color: #1a1a1a;
letter-spacing: -0.5px;
letter-spacing: -0.3px;
}
.c-hero-sub {
display: block;
font-size: 14px;
color: #999993;
margin-top: 4px;
color: #6b6b65;
margin-top: 8px;
line-height: 1.45;
}
.c-hero-cta {
width: 100%;
margin-top: 20px;
margin-top: 18px;
border-radius: 14px !important;
font-size: 16px !important;
font-weight: 700 !important;
@ -761,40 +768,56 @@ onShow(() => {
.c-hero-cta--hover {
opacity: 0.94;
}
.c-cust-section {
margin: 18px 16px 8px;
}
.c-cust-section-title {
display: block;
font-size: 15px;
font-weight: 700;
color: #1a1a1a;
}
.c-cust-section-hint {
display: block;
font-size: 12px;
color: #a8a89f;
margin-top: 4px;
line-height: 1.4;
}
.c-cust-me-line {
margin: 0 16px 10px;
padding: 10px 14px;
background: #f7faf8;
border-radius: 12px;
border: 1px solid #e8f5ee;
}
.c-cust-me-line-text {
font-size: 13px;
color: #3d5a4a;
line-height: 1.45;
}
.c-empty-emoji {
display: block;
font-size: 40px;
font-size: 36px;
text-align: center;
margin-bottom: 12px;
margin-bottom: 10px;
opacity: 0.9;
}
.c-empty-title {
display: block;
font-size: 17px;
font-size: 16px;
font-weight: 700;
color: #1a1a1a;
color: #3f3f3a;
text-align: center;
}
.c-empty-hint {
display: block;
font-size: 13px;
color: #999993;
color: #a8a89f;
text-align: center;
margin-top: 8px;
line-height: 1.5;
padding: 0 8px;
}
.c-empty-cta {
width: 100%;
max-width: 280px;
margin: 24px auto 0;
border-radius: 14px !important;
}
.fab-appt--cust-secondary {
background: #e8f8ef;
box-shadow: 0 4px 14px rgba(45, 185, 109, 0.22);
}
.fab-appt--cust-secondary .fab-appt-icon {
color: #2db96d;
line-height: 1.55;
padding: 0 12px;
}
.c-form-card {
margin: 0 16px;
@ -944,6 +967,9 @@ onShow(() => {
/* B端列表底部留白避免最后一条被悬浮钮挡住 */
.order-list { padding: 12px 16px 88px; }
.order-list--cust {
padding: 12px 16px 28px;
}
.order-card {
background: #fff;
border-radius: 14px;