Files
medical-mall/pages/mall/consumer/home-service/order-detail.uvue

264 lines
6.6 KiB
Plaintext
Raw 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>
<ServicePageScaffold title="服务单详情" fallback-url="/pages/mall/consumer/home-service/index">
<view v-if="detail == null" class="empty-box">
<text class="empty-text">未找到对应服务单</text>
</view>
<view v-else>
<view class="summary-card">
<view class="summary-top-row">
<view>
<text class="summary-title">{{ detail.serviceName }}</text>
<text class="summary-case-no">服务单号:{{ detail.caseNo }}</text>
</view>
<ServiceStatusTag :text="detail.statusText" :tone="detail.statusTone"></ServiceStatusTag>
</view>
<text class="summary-desc">{{ detail.summary }}</text>
<view class="summary-price-row">
<text class="summary-price-prefix">¥</text>
<text class="summary-price">{{ detail.amount }}</text>
<text class="summary-price-unit">服务金额</text>
</view>
<view class="summary-meta-grid">
<view class="summary-meta-item">
<text class="summary-meta-label">上门时间</text>
<text class="summary-meta-value">{{ detail.serviceTime }}</text>
</view>
<view class="summary-meta-item">
<text class="summary-meta-label">当前进度</text>
<text class="summary-meta-value">第 {{ detail.currentStep }} / {{ detail.totalSteps }} 步</text>
</view>
<view class="summary-meta-item">
<text class="summary-meta-label">服务机构 / 人员</text>
<text class="summary-meta-value">{{ detail.staffName }}</text>
</view>
<view class="summary-meta-item">
<text class="summary-meta-label">联系电话</text>
<text class="summary-meta-value">{{ detail.staffPhone }}</text>
</view>
</view>
</view>
<ServicePanel title="预约信息" subtitle="围绕联系人、地址和服务对象展示当前预约信息。">
<ServiceInfoList
:items="[
{ label: '联系人:', value: detail.applicantName },
{ label: '服务对象:', value: detail.elderName + '' + detail.age + ' 岁' },
{ label: '联系电话:', value: detail.phone },
{ label: '服务地址:', value: detail.address },
{ label: '预约备注:', value: detail.summary }
]"
></ServiceInfoList>
</ServicePanel>
<ServicePanel title="服务保障" subtitle="用户在预约后仍可看到平台保障与追溯承诺。">
<view class="guarantee-row">
<text class="guarantee-chip">平台认证</text>
<text class="guarantee-chip">明码标价</text>
<text class="guarantee-chip">服务可追溯</text>
<text class="guarantee-chip">异常可申诉</text>
</view>
</ServicePanel>
<ServicePanel title="服务过程" subtitle="当前以 mock 时间线展示预约受理、派单和上门过程。">
<ServiceTimeline :items="detail.timeline"></ServiceTimeline>
</ServicePanel>
<view class="action-row">
<view class="secondary-btn" @click="bookAgain">再次预约</view>
<view v-if="detail.status == 'pending_acceptance'" class="primary-btn" @click="goFeedback">去验收反馈</view>
<view v-else class="primary-btn" @click="contactService">联系客服</view>
</view>
</view>
</ServicePageScaffold>
</template>
<script setup lang="uts">
import { ref } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import ServicePageScaffold from '@/components/homeService/ServicePageScaffold.uvue'
import ServiceInfoList from '@/components/homeService/ServiceInfoList.uvue'
import ServicePanel from '@/components/homeService/ServicePanel.uvue'
import ServiceStatusTag from '@/components/homeService/ServiceStatusTag.uvue'
import ServiceTimeline from '@/components/homeService/ServiceTimeline.uvue'
import { fetchConsumerHomeServiceCaseDetail } from '@/services/homeServiceService.uts'
import { HomeServiceCaseType } from '@/types/home-service.uts'
const caseId = ref('')
const detail = ref<HomeServiceCaseType | null>(null)
async function loadData() {
if (caseId.value == '') {
return
}
detail.value = await fetchConsumerHomeServiceCaseDetail(caseId.value)
}
function goFeedback() {
if (caseId.value == '') {
return
}
uni.navigateTo({ url: '/pages/mall/consumer/home-service/feedback?id=' + caseId.value })
}
function bookAgain() {
if (detail.value == null) {
return
}
let serviceTargetId = 'svc-001'
if (detail.value.serviceName == '康复训练指导') {
serviceTargetId = 'svc-002'
}
if (detail.value.serviceName == '慢病健康随访') {
serviceTargetId = 'svc-003'
}
uni.navigateTo({ url: '/pages/mall/consumer/home-service/service-detail?id=' + serviceTargetId + '&mode=booking' })
}
function contactService() {
uni.showToast({ title: '即将接入专属客服入口', icon: 'none' })
}
onLoad((options) => {
const id = options['id']
if (id != null) {
caseId.value = id as string
loadData()
}
})
onShow(() => {
loadData()
})
</script>
<style scoped>
.summary-card {
background: #ffffff;
border-radius: 32rpx;
padding: 28rpx;
box-shadow: 0 12rpx 24rpx rgba(15, 23, 42, 0.06);
margin-bottom: 24rpx;
}
.summary-top-row,
.summary-price-row,
.action-row,
.guarantee-row {
flex-direction: row;
align-items: center;
}
.summary-top-row,
.action-row {
justify-content: space-between;
}
.summary-title {
font-size: 34rpx;
font-weight: 700;
color: #16324f;
}
.summary-case-no,
.summary-desc,
.summary-meta-label,
.summary-meta-value,
.empty-text {
margin-top: 10rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #66788a;
}
.summary-desc {
margin-top: 18rpx;
}
.summary-price-row {
margin-top: 18rpx;
align-items: flex-end;
}
.summary-price-prefix,
.summary-price {
font-size: 40rpx;
font-weight: 700;
color: #0f766e;
}
.summary-price-unit {
font-size: 22rpx;
color: #64748b;
margin-left: 10rpx;
margin-bottom: 6rpx;
}
.summary-meta-grid {
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 22rpx;
}
.summary-meta-item {
width: 48%;
padding: 22rpx;
border-radius: 24rpx;
background: #f8fbfd;
box-sizing: border-box;
margin-bottom: 16rpx;
}
.guarantee-row {
flex-wrap: wrap;
}
.guarantee-chip {
padding: 12rpx 18rpx;
border-radius: 999rpx;
background: #eef6ff;
font-size: 22rpx;
color: #476072;
margin-right: 12rpx;
margin-bottom: 12rpx;
}
.action-row {
margin-top: 10rpx;
margin-bottom: 12rpx;
}
.secondary-btn,
.primary-btn {
width: 48%;
height: 78rpx;
border-radius: 999rpx;
font-size: 26rpx;
font-weight: 700;
align-items: center;
justify-content: center;
}
.secondary-btn {
background: #ffffff;
border-width: 2rpx;
border-style: solid;
border-color: #cbd5e1;
color: #476072;
}
.primary-btn {
background: #16a085;
color: #ffffff;
}
.empty-text {
margin-top: 10rpx;
}
.empty-box {
padding: 120rpx 0;
align-items: center;
}
</style>