672 lines
25 KiB
Vue
672 lines
25 KiB
Vue
<template>
|
|
<view class="content">
|
|
<!-- 顶部导航栏 -->
|
|
<view class="header">
|
|
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
|
<view class="header-content">
|
|
<view class="back-button" @click="goBack">
|
|
<image src="/static/ic_back.png" class="back-icon"></image>
|
|
</view>
|
|
<text class="header-title">{{ $t('myAppointment.title') || '我的预约单' }}</text>
|
|
<view class="header-placeholder"></view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- Tab 区域 -->
|
|
<view class="tab-container">
|
|
<view class="tab-item" :class="{ active: activeTab === 'all' }" @click="switchTab('all')">
|
|
<text class="tab-text" :class="{ active: activeTab === 'all' }">{{ $t('myAppointment.all') || '全部' }}</text>
|
|
</view>
|
|
<view class="tab-item" :class="{ active: activeTab === 'inProgress' }" @click="switchTab('inProgress')">
|
|
<text class="tab-text" :class="{ active: activeTab === 'inProgress' }">{{ $t('myAppointment.inProgress') || '进行中' }}</text>
|
|
</view>
|
|
<view class="tab-item" :class="{ active: activeTab === 'completed' }" @click="switchTab('completed')">
|
|
<text class="tab-text" :class="{ active: activeTab === 'completed' }">{{ $t('myAppointment.completed') || '已结束' }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 预约列表 -->
|
|
<scroll-view class="appointment-list" scroll-y @scrolltolower="loadMore" :show-scrollbar="false">
|
|
<view class="appointment-item" v-for="item in appointmentList" :key="item.id" @click="showDetail(item)">
|
|
<view class="item-title">{{ getServiceTitle(item) }}</view>
|
|
|
|
<view class="item-row">
|
|
<image src="/static/me_tiem.png" class="item-icon"></image>
|
|
<text class="item-text">{{ formatDate(item.createdAt) }}</text>
|
|
</view>
|
|
|
|
<view class="item-row">
|
|
<image src="/static/me_name.png" class="item-icon"></image>
|
|
<text class="item-text">{{ item.realName || '-' }}</text>
|
|
</view>
|
|
|
|
<view class="item-row">
|
|
<image src="/static/me_phone.png" class="item-icon"></image>
|
|
<text class="item-text">{{ getContactInfo(item) }}</text>
|
|
</view>
|
|
|
|
<view class="item-footer">
|
|
<text class="view-detail" @click.stop="showDetail(item)">{{ $t('myAppointment.viewDetail') || '查看详情' }}</text>
|
|
<text class="status-text" :class="getStatusClass(item.status)">{{ getStatusText(item.status) }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="loading" class="loading-more">
|
|
<text class="loading-text">{{ $t('common.loading') }}</text>
|
|
</view>
|
|
|
|
<view v-if="!loading && !hasMore && appointmentList.length > 0" class="loading-more">
|
|
<text class="loading-text">{{ $t('common.noMore') || '没有更多了' }}</text>
|
|
</view>
|
|
|
|
<view v-if="appointmentList.length === 0 && !loading" class="empty-state">
|
|
<text class="empty-icon">📋</text>
|
|
<text class="no-data">{{ $t('myAppointment.noAppointment') || '暂无预约记录' }}</text>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 详情弹窗 -->
|
|
<view class="detail-mask" v-if="showDetailPopup" @click="closeDetail">
|
|
<view class="detail-popup" @click.stop>
|
|
<view class="popup-header">
|
|
<text class="popup-title">{{ $t('myAppointment.serviceDetail') || '服务详情' }}</text>
|
|
<view class="popup-close" @click="closeDetail">
|
|
<image src="/static/ic_colse.png" class="close-icon"></image>
|
|
</view>
|
|
</view>
|
|
<scroll-view class="popup-content" scroll-y>
|
|
<!-- 服务类型 -->
|
|
<view class="detail-item">
|
|
<text class="detail-label">服务类型</text>
|
|
<text class="detail-value">{{ getServiceTitle(currentDetail) }}</text>
|
|
</view>
|
|
|
|
<!-- 姓名 -->
|
|
<view class="detail-item">
|
|
<text class="detail-label">姓名</text>
|
|
<text class="detail-value">{{ currentDetail.realName || '-' }}</text>
|
|
</view>
|
|
|
|
<!-- 提交时间 -->
|
|
<view class="detail-item">
|
|
<text class="detail-label">提交时间</text>
|
|
<text class="detail-value">{{ formatDate(currentDetail.createdAt) }}</text>
|
|
</view>
|
|
|
|
<!-- 联系方式 -->
|
|
<view class="detail-item">
|
|
<text class="detail-label">联系方式</text>
|
|
<text class="detail-value">{{ getAllContactInfo(currentDetail) }}</text>
|
|
</view>
|
|
|
|
<!-- 预约日期(通用字段) -->
|
|
<view class="detail-item" v-if="currentDetail.appointmentDate">
|
|
<text class="detail-label">预约日期</text>
|
|
<text class="detail-value">{{ currentDetail.appointmentDate }}</text>
|
|
</view>
|
|
|
|
<!-- 机票相关字段 -->
|
|
<view class="detail-item" v-if="currentDetail.tripType">
|
|
<text class="detail-label">行程类型</text>
|
|
<text class="detail-value">{{ currentDetail.tripType === 'single' ? '单程' : '往返' }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.departureCity">
|
|
<text class="detail-label">出发城市</text>
|
|
<text class="detail-value">{{ currentDetail.departureCity }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.arrivalCity">
|
|
<text class="detail-label">到达城市</text>
|
|
<text class="detail-value">{{ currentDetail.arrivalCity }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.departureDate">
|
|
<text class="detail-label">出发日期</text>
|
|
<text class="detail-value">{{ currentDetail.departureDate }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.returnDate">
|
|
<text class="detail-label">返程日期</text>
|
|
<text class="detail-value">{{ currentDetail.returnDate }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.cabinType">
|
|
<text class="detail-label">舱位类型</text>
|
|
<text class="detail-value">{{ getCabinTypeText(currentDetail.cabinType) }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.luggageCount">
|
|
<text class="detail-label">行李件数</text>
|
|
<text class="detail-value">{{ currentDetail.luggageCount }}件</text>
|
|
</view>
|
|
|
|
<!-- 酒店相关字段 -->
|
|
<view class="detail-item" v-if="currentDetail.countryCity">
|
|
<text class="detail-label">国家/城市</text>
|
|
<text class="detail-value">{{ currentDetail.countryCity }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.hotelName">
|
|
<text class="detail-label">酒店名称</text>
|
|
<text class="detail-value">{{ currentDetail.hotelName }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.checkInDate">
|
|
<text class="detail-label">入住日期</text>
|
|
<text class="detail-value">{{ currentDetail.checkInDate }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.checkOutDate">
|
|
<text class="detail-label">退房日期</text>
|
|
<text class="detail-value">{{ currentDetail.checkOutDate }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.roomCount">
|
|
<text class="detail-label">房间数量</text>
|
|
<text class="detail-value">{{ currentDetail.roomCount }}间</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.roomType">
|
|
<text class="detail-label">房间类型</text>
|
|
<text class="detail-value">{{ currentDetail.roomType }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.needMeal !== null && currentDetail.needMeal !== undefined">
|
|
<text class="detail-label">是否需要餐食</text>
|
|
<text class="detail-value">{{ currentDetail.needMeal ? '是' : '否' }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.mealPlan">
|
|
<text class="detail-label">餐食计划</text>
|
|
<text class="detail-value">{{ getMealPlanText(currentDetail.mealPlan) }}</text>
|
|
</view>
|
|
|
|
<!-- 人数相关 -->
|
|
<view class="detail-item" v-if="currentDetail.adultCount">
|
|
<text class="detail-label">成人人数</text>
|
|
<text class="detail-value">{{ currentDetail.adultCount }}人</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.childCount">
|
|
<text class="detail-label">儿童人数</text>
|
|
<text class="detail-value">{{ currentDetail.childCount }}人</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.infantCount">
|
|
<text class="detail-label">婴儿人数</text>
|
|
<text class="detail-value">{{ currentDetail.infantCount }}人</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.passengerCount">
|
|
<text class="detail-label">乘客数量</text>
|
|
<text class="detail-value">{{ currentDetail.passengerCount }}人</text>
|
|
</view>
|
|
|
|
<!-- 机场/航班相关 -->
|
|
<view class="detail-item" v-if="currentDetail.airportTerminal">
|
|
<text class="detail-label">机场/航站楼</text>
|
|
<text class="detail-value">{{ currentDetail.airportTerminal }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.arrivalFlightNo">
|
|
<text class="detail-label">到达航班号</text>
|
|
<text class="detail-value">{{ currentDetail.arrivalFlightNo }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.departureFlightNo">
|
|
<text class="detail-label">出发航班号</text>
|
|
<text class="detail-value">{{ currentDetail.departureFlightNo }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.flightNo">
|
|
<text class="detail-label">航班号</text>
|
|
<text class="detail-value">{{ currentDetail.flightNo }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.deliveryAddress">
|
|
<text class="detail-label">送达地址</text>
|
|
<text class="detail-value">{{ currentDetail.deliveryAddress }}</text>
|
|
</view>
|
|
|
|
<!-- 高铁相关 -->
|
|
<view class="detail-item" v-if="currentDetail.originStation">
|
|
<text class="detail-label">出发站</text>
|
|
<text class="detail-value">{{ currentDetail.originStation }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.destinationStation">
|
|
<text class="detail-label">到达站</text>
|
|
<text class="detail-value">{{ currentDetail.destinationStation }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.seatClass">
|
|
<text class="detail-label">座位等级</text>
|
|
<text class="detail-value">{{ getSeatClassText(currentDetail.seatClass) }}</text>
|
|
</view>
|
|
|
|
<!-- 儿童相关 -->
|
|
<view class="detail-item" v-if="currentDetail.itinerary">
|
|
<text class="detail-label">行程</text>
|
|
<text class="detail-value">{{ currentDetail.itinerary }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.childAge">
|
|
<text class="detail-label">儿童年龄</text>
|
|
<text class="detail-value">{{ currentDetail.childAge }}岁</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.boyCount">
|
|
<text class="detail-label">男孩数量</text>
|
|
<text class="detail-value">{{ currentDetail.boyCount }}人</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.girlCount">
|
|
<text class="detail-label">女孩数量</text>
|
|
<text class="detail-value">{{ currentDetail.girlCount }}人</text>
|
|
</view>
|
|
|
|
<!-- 医疗相关 -->
|
|
<view class="detail-item" v-if="currentDetail.hospitalName">
|
|
<text class="detail-label">医院名称</text>
|
|
<text class="detail-value">{{ currentDetail.hospitalName }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.conditionDescription">
|
|
<text class="detail-label">病情描述</text>
|
|
<text class="detail-value">{{ currentDetail.conditionDescription }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.specialAssistanceReason">
|
|
<text class="detail-label">特殊协助原因</text>
|
|
<text class="detail-value">{{ currentDetail.specialAssistanceReason }}</text>
|
|
</view>
|
|
|
|
<!-- 宠物相关 -->
|
|
<view class="detail-item" v-if="currentDetail.origin">
|
|
<text class="detail-label">出发地</text>
|
|
<text class="detail-value">{{ currentDetail.origin }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.destination">
|
|
<text class="detail-label">目的地</text>
|
|
<text class="detail-value">{{ currentDetail.destination }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.petType">
|
|
<text class="detail-label">宠物类型</text>
|
|
<text class="detail-value">{{ currentDetail.petType }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.petName">
|
|
<text class="detail-label">宠物名称</text>
|
|
<text class="detail-value">{{ currentDetail.petName }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.hasQuarantineCert !== null && currentDetail.hasQuarantineCert !== undefined">
|
|
<text class="detail-label">检疫证明</text>
|
|
<text class="detail-value">{{ currentDetail.hasQuarantineCert ? '有' : '无' }}</text>
|
|
</view>
|
|
|
|
<!-- 导游/翻译相关 -->
|
|
<view class="detail-item" v-if="currentDetail.serviceDays">
|
|
<text class="detail-label">服务天数</text>
|
|
<text class="detail-value">{{ currentDetail.serviceDays }}天</text>
|
|
</view>
|
|
|
|
<!-- 物流相关 -->
|
|
<view class="detail-item" v-if="currentDetail.originPort">
|
|
<text class="detail-label">起运港</text>
|
|
<text class="detail-value">{{ currentDetail.originPort }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.destinationPort">
|
|
<text class="detail-label">目的港</text>
|
|
<text class="detail-value">{{ currentDetail.destinationPort }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.itemName">
|
|
<text class="detail-label">物品名称</text>
|
|
<text class="detail-value">{{ currentDetail.itemName }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.itemQuantity">
|
|
<text class="detail-label">物品数量</text>
|
|
<text class="detail-value">{{ currentDetail.itemQuantity }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.cargoName">
|
|
<text class="detail-label">货物名称</text>
|
|
<text class="detail-value">{{ currentDetail.cargoName }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.cargoQuantity">
|
|
<text class="detail-label">货物数量</text>
|
|
<text class="detail-value">{{ currentDetail.cargoQuantity }}</text>
|
|
</view>
|
|
|
|
<!-- 旅游相关 -->
|
|
<view class="detail-item" v-if="currentDetail.travelDestination">
|
|
<text class="detail-label">旅游目的地</text>
|
|
<text class="detail-value">{{ currentDetail.travelDestination }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.travelDate">
|
|
<text class="detail-label">出行日期</text>
|
|
<text class="detail-value">{{ currentDetail.travelDate }}</text>
|
|
</view>
|
|
<view class="detail-item" v-if="currentDetail.travelDays">
|
|
<text class="detail-label">旅游天数</text>
|
|
<text class="detail-value">{{ currentDetail.travelDays }}天</text>
|
|
</view>
|
|
|
|
<!-- 咨询相关 -->
|
|
<view class="detail-item" v-if="currentDetail.specificRequirements">
|
|
<text class="detail-label">具体需求</text>
|
|
<text class="detail-value">{{ currentDetail.specificRequirements }}</text>
|
|
</view>
|
|
|
|
<!-- 备注 -->
|
|
<view class="detail-item" v-if="currentDetail.notes">
|
|
<text class="detail-label">备注</text>
|
|
<text class="detail-value">{{ currentDetail.notes }}</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { AppServer } from '@/modules/api/AppServer.js'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
statusBarHeight: 0,
|
|
activeTab: 'all',
|
|
loading: false,
|
|
appointmentList: [],
|
|
pagination: { page: 1, limit: 10, total: 0 },
|
|
hasMore: true,
|
|
showDetailPopup: false,
|
|
currentDetail: {}
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
const systemInfo = uni.getSystemInfoSync()
|
|
this.statusBarHeight = systemInfo.statusBarHeight || 0
|
|
if (options.tab) this.activeTab = options.tab
|
|
this.fetchAppointments()
|
|
},
|
|
methods: {
|
|
goBack() {
|
|
uni.navigateBack({ delta: 1 })
|
|
},
|
|
switchTab(tab) {
|
|
if (this.activeTab === tab) return
|
|
this.activeTab = tab
|
|
this.pagination.page = 1
|
|
this.appointmentList = []
|
|
this.hasMore = true
|
|
this.fetchAppointments()
|
|
},
|
|
async fetchAppointments() {
|
|
if (this.loading) return
|
|
this.loading = true
|
|
try {
|
|
const appserver = new AppServer()
|
|
const params = { page: this.pagination.page, limit: this.pagination.limit }
|
|
if (this.activeTab === 'inProgress') params.status = 'in-progress'
|
|
else if (this.activeTab === 'completed') params.status = 'completed'
|
|
|
|
const res = await appserver.GetAppointments(params)
|
|
if (res.success || res.code === 0) {
|
|
const newList = res.data || []
|
|
if (this.pagination.page === 1) this.appointmentList = newList
|
|
else this.appointmentList = [...this.appointmentList, ...newList]
|
|
this.pagination.total = res.pagination?.total || 0
|
|
this.hasMore = newList.length >= this.pagination.limit
|
|
}
|
|
} catch (e) {
|
|
console.error('获取预约列表失败:', e)
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
loadMore() {
|
|
if (!this.hasMore || this.loading) return
|
|
this.pagination.page++
|
|
this.fetchAppointments()
|
|
},
|
|
showDetail(item) {
|
|
this.currentDetail = item
|
|
this.showDetailPopup = true
|
|
},
|
|
closeDetail() {
|
|
this.showDetailPopup = false
|
|
},
|
|
getServiceTitle(item) {
|
|
if (!item) return '-'
|
|
const locale = this.$i18n.locale
|
|
if (item.service) {
|
|
if (locale === 'zh') return item.service.titleZh || item.service.titleEn || '-'
|
|
else if (locale === 'es') return item.service.titleEs || item.service.titleEn || '-'
|
|
else return item.service.titleEn || item.service.titleZh || '-'
|
|
}
|
|
if (item.hotService) {
|
|
if (locale === 'zh') return item.hotService.name_zh || item.hotService.name_en || '-'
|
|
else if (locale === 'es') return item.hotService.name_es || item.hotService.name_en || '-'
|
|
else return item.hotService.name_en || item.hotService.name_zh || '-'
|
|
}
|
|
return this.getServiceTypeText(item.serviceType) || '-'
|
|
},
|
|
getServiceTypeText(type) {
|
|
const typeMap = {
|
|
'travel': '全球机票代理',
|
|
'flight': '全球机票代理',
|
|
'hotel': '全球酒店预定',
|
|
'vip_lounge': '全球机场贵宾室服务',
|
|
'lounge': '全球机场贵宾室服务',
|
|
'airport_transfer': '机场接/送机服务',
|
|
'unaccompanied_minor': '无成人陪伴儿童代办',
|
|
'rail_ticket': '高铁票代订',
|
|
'train': '高铁票代订',
|
|
'medical_consultation': '远程医疗问诊代理服务',
|
|
'telemedicine': '远程医疗问诊代理服务',
|
|
'special_needs': '特殊旅客定制服务代办',
|
|
'special_passenger': '特殊旅客定制服务代办',
|
|
'pet_transportation': '宠物托运代理',
|
|
'pet_transport': '宠物托运代理',
|
|
'guide_translation': '西班牙语专业导游/翻译服务',
|
|
'visa_consultation': '签证咨询',
|
|
'visa': '签证咨询',
|
|
'exhibition_service': '墨西哥展会咨询与协办服务',
|
|
'exhibition': '墨西哥展会咨询与协办服务',
|
|
'air_logistics': '跨境航空物流/快递一站式服务',
|
|
'sea_freight': '海运/清关一站式服务',
|
|
'travel_planning': '旅游线路规划/咨询',
|
|
'insurance_consultation': '跨境出行意外保险/国际财产保险咨询',
|
|
'insurance': '跨境出行意外保险/国际财产保险咨询'
|
|
}
|
|
return typeMap[type] || type
|
|
},
|
|
getContactInfo(item) {
|
|
if (!item) return '-'
|
|
return item.phone || item.wechatId || item.whatsapp || item.contactValue || '-'
|
|
},
|
|
getAllContactInfo(item) {
|
|
if (!item) return '-'
|
|
const contacts = []
|
|
if (item.phone) contacts.push((item.phoneCountryCode || '') + ' ' + item.phone)
|
|
if (item.wechatId) contacts.push('微信: ' + item.wechatId)
|
|
if (item.whatsapp) contacts.push('WhatsApp: ' + item.whatsapp)
|
|
return contacts.length > 0 ? contacts.join('\n') : '-'
|
|
},
|
|
formatDate(dateStr) {
|
|
if (!dateStr) return '-'
|
|
const date = new Date(dateStr)
|
|
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
|
|
},
|
|
getStatusText(status) {
|
|
const statusMap = {
|
|
'pending': this.$t('myAppointment.statusPending') || '待处理',
|
|
'confirmed': this.$t('myAppointment.statusConfirmed') || '已确认',
|
|
'in-progress': this.$t('myAppointment.statusInProgress') || '进行中',
|
|
'completed': this.$t('myAppointment.statusCompleted') || '已结束',
|
|
'cancelled': this.$t('myAppointment.statusCancelled') || '已取消'
|
|
}
|
|
return statusMap[status] || status
|
|
},
|
|
getStatusClass(status) {
|
|
return {
|
|
'status-in-progress': status === 'in-progress' || status === 'pending' || status === 'confirmed',
|
|
'status-completed': status === 'completed',
|
|
'status-cancelled': status === 'cancelled'
|
|
}
|
|
},
|
|
getCabinTypeText(type) {
|
|
const map = { 'economy': '经济舱', 'premium_economy': '超级经济舱', 'business': '商务舱' }
|
|
return map[type] || type
|
|
},
|
|
getMealPlanText(plan) {
|
|
const map = { 'breakfast': '早餐', 'three_meals': '三餐', 'all_inclusive': '全包' }
|
|
return map[plan] || plan
|
|
},
|
|
getSeatClassText(seatClass) {
|
|
const map = { 'first': '一等座', 'second': '二等座', 'third': '三等座' }
|
|
return map[seatClass] || seatClass
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.content {
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: #F5F7FA;
|
|
}
|
|
|
|
.header {
|
|
background-color: #fff;
|
|
.status-bar { width: 100%; background-color: #fff; }
|
|
.header-content {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 20rpx 32rpx;
|
|
}
|
|
.back-button { width: 60rpx; height: 60rpx; display: flex; align-items: center; justify-content: center; }
|
|
.back-icon { width: 40rpx; height: 40rpx; }
|
|
.header-title { font-size: 34rpx; font-weight: 600; color: #333; flex: 1; text-align: center; }
|
|
.header-placeholder { width: 60rpx; }
|
|
}
|
|
|
|
.tab-container {
|
|
display: flex;
|
|
flex-direction: row;
|
|
padding: 24rpx 32rpx;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.tab-item {
|
|
padding: 14rpx 36rpx;
|
|
margin-right: 24rpx;
|
|
border-radius: 36rpx;
|
|
border: 2rpx solid #E0E0E0;
|
|
background-color: #fff;
|
|
&.active { background-color: #E5FBFF; border-color: #00A0BC; }
|
|
}
|
|
|
|
.tab-text {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
&.active { color: #00A0BC; font-weight: 500; }
|
|
}
|
|
|
|
.appointment-list {
|
|
flex: 1;
|
|
height: 0;
|
|
width: 686rpx;
|
|
margin: 24rpx auto 24rpx;
|
|
}
|
|
|
|
.appointment-item {
|
|
background-color: #fff;
|
|
border-radius: 24rpx;
|
|
padding: 32rpx;
|
|
margin-bottom: 24rpx;
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.item-title { font-size: 32rpx; font-weight: 600; color: #333; margin-bottom: 24rpx; }
|
|
.item-row { display: flex; align-items: center; margin-bottom: 16rpx; }
|
|
.item-icon { width: 36rpx; height: 36rpx; margin-right: 20rpx; }
|
|
.item-text { font-size: 28rpx; color: #666; }
|
|
|
|
.item-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-top: 24rpx;
|
|
padding-top: 24rpx;
|
|
border-top: 1rpx solid #F0F0F0;
|
|
}
|
|
|
|
.view-detail { font-size: 28rpx; color: #00A0BC; }
|
|
.status-text { font-size: 28rpx; font-weight: 500; }
|
|
.status-in-progress { color: #00A0BC; }
|
|
.status-completed { color: #FF6B6B; }
|
|
.status-cancelled { color: #999; }
|
|
|
|
.loading-more { padding: 40rpx; display: flex; justify-content: center; }
|
|
.loading-text { font-size: 26rpx; color: #999; }
|
|
|
|
.empty-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding-top: 200rpx;
|
|
}
|
|
.empty-icon { font-size: 120rpx; opacity: 0.3; margin-bottom: 30rpx; }
|
|
.no-data { font-size: 28rpx; color: #999; }
|
|
|
|
// 详情弹窗 - 居中显示
|
|
.detail-mask {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 999;
|
|
}
|
|
|
|
.detail-popup {
|
|
width: 85%;
|
|
max-height: 70vh;
|
|
background-color: #fff;
|
|
border-radius: 24rpx;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.popup-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 36rpx 32rpx;
|
|
border-bottom: 1rpx solid #F0F0F0;
|
|
background-color: #fff;
|
|
position: relative;
|
|
}
|
|
|
|
.popup-title { font-size: 34rpx; font-weight: 600; color: #333; }
|
|
.popup-close {
|
|
position: absolute;
|
|
right: 32rpx;
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.close-icon { width: 36rpx; height: 36rpx; }
|
|
|
|
.popup-content {
|
|
max-height: 60vh;
|
|
padding: 0 40rpx 40rpx;
|
|
}
|
|
|
|
.detail-item {
|
|
padding: 28rpx 0;
|
|
border-bottom: 1rpx solid #F5F5F5;
|
|
&:last-child { border-bottom: none; }
|
|
}
|
|
|
|
.detail-label {
|
|
font-size: 30rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
display: block;
|
|
margin-bottom: 12rpx;
|
|
}
|
|
|
|
.detail-value {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
display: block;
|
|
line-height: 1.6;
|
|
word-break: break-all;
|
|
white-space: pre-wrap;
|
|
}
|
|
</style>
|