alipay-emulator/pages/other/air-tickets/qunar-air-tickets/qunar-air-tickets.vue

1016 lines
22 KiB
Vue
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>
<view class="page-container">
<!-- Main Content Wrapper (Standard Flow) -->
<view class="main-content">
<!-- Header Background (Inside scroll flow) -->
<view class="header-bg">
<navBar isBack :title="data.navBar.title" :bgColor="data.navBar.bgColor"
:textColor="data.navBar.textColor" />
<view class="status-section">
<view class="status-row">
<text class="status-title">出票完成</text>
<view class="price-box">
<text class="price-label">体验价</text>
<text class="price-symbol">¥</text>
<text class="price-val">714</text>
<uni-icons type="right" size="14" color="#fff"></uni-icons>
</view>
</view>
<view class="order-no-row">
<text class="order-no-text">订单号:203012348597</text>
<uni-icons type="paperclip" size="14" color="#fff" style="margin-left: 8rpx;"></uni-icons>
</view>
<text class="status-desc">出票成功请按时关注航班变更信息</text>
</view>
<view class="image-box">
<image src="/static/image/other/air-tickets/qunar/banner.png" mode="widthFix" style="width: 100%;">
</image>
</view>
</view>
<view class="gradient-bg"></view>
<!-- Content Area -->
<view class="content-area">
<!-- Unified Ticket Card -->
<view class="ticket-wrapper">
<view class="ticket-card">
<!-- Flight Section -->
<view class="flight-section">
<view class="section-title-row">
<text class="section-title">旅行套餐·航班信息</text>
</view>
<view class="flight-header">
<view class="tag">直飞</view>
<image class="airline-icon" src="/static/airline.png" mode="aspectFit"
style="width: 28rpx; height: 28rpx; margin-right: 8rpx;"></image>
<text class="flight-name">南航 CZ2355 03-04 武汉-北京</text>
</view>
<view class="flight-time-row">
<view class="time-col">
<text class="time-big">08:00</text>
<text class="airport-text">天河机场T3 <uni-icons type="location-filled" size="10"
color="#666"></uni-icons></text>
</view>
<view class="arrow-col">
<image class="plane-line" src="/static/plane-line.png"
style="width: 140rpx; height: 20rpx; margin-bottom: 4rpx;" mode="aspectFit">
</image>
<text class="duration-text">2时5分</text>
</view>
<view class="time-col align-right">
<text class="time-big">10:00</text>
<text class="airport-text">北京大兴机场 <uni-icons type="location-filled" size="10"
color="#666"></uni-icons></text>
</view>
</view>
<view class="flight-detail-row">
<uni-icons type="paperplane" size="12" color="#999"></uni-icons>
<text class="detail-item">737-800</text>
<text class="detail-divider">|</text>
<uni-icons type="smallcircle" size="12" color="#999"></uni-icons>
<text class="detail-item">经济舱</text>
<text class="detail-divider">|</text>
<uni-icons type="info" size="12" color="#999"></uni-icons>
<text class="detail-item">准点率--</text>
<text class="detail-divider">|</text>
<uni-icons type="shop" size="12" color="#999"></uni-icons>
<text class="detail-item">小食</text>
</view>
<view class="flight-actions">
<view class="action-btn">
<uni-icons type="info-filled" size="14" color="#00B5E0"></uni-icons>
<text class="btn-text">退改说明</text>
</view>
<view class="action-btn">
<uni-icons type="bag-filled" size="14" color="#00B5E0"></uni-icons>
<view class="btn-right">
<text class="btn-text">行李规定</text>
<text class="sub-text">含20kg免费托运行李</text>
</view>
</view>
</view>
</view>
<!-- Divider -->
<view class="ticket-divider">
<view class="half-circle left"></view>
<view class="dashed-line"></view>
<view class="half-circle right"></view>
</view>
<!-- Passenger Section -->
<view class="passenger-section">
<view class="section-title-row">
<text class="section-title">旅行套餐·出票信息</text>
<view class="link-right">
<text>查看隐藏信息</text>
<uni-icons type="right" size="12" color="#999"></uni-icons>
</view>
</view>
<view class="passenger-list">
<view class="passenger-row" v-for="(p, i) in passengerList" :key="i">
<view class="row-label" v-if="i === 0">乘机人</view>
<view class="row-label-placeholder" v-else></view>
<view class="row-content">
<view class="p-name">{{ p.name }}</view>
<view class="p-sub">身份证: {{ p.id }}</view>
<view class="p-sub">
票号: {{ p.ticketNo }}
<uni-icons type="paperclip" size="12" color="#666"
style="margin-left: 6rpx;"></uni-icons>
</view>
</view>
</view>
<view class="contact-row">
<text class="row-label">联系手机</text>
<text class="contact-val">+86 187****5555</text>
</view>
</view>
</view>
</view>
</view>
<!-- Alerts -->
<view class="combined-alert-box">
<view class="alert-row">
<view class="alert-tag">防诈提示</view>
<text class="alert-content">凡以航班变动、取消为由主动提供经济赔偿可能是诈骗,请登录去哪儿网核实或咨询客服 95117。</text>
</view>
<view class="alert-divider"></view>
<view class="alert-row">
<view class="alert-tag">乘机提示</view>
<text class="alert-content">禁止旅客携带没有3C标识、3C标识不清、已经被召回型号或批次的充电宝乘坐境内航班。</text>
</view>
</view>
<!-- Services Card -->
<view class="card service-card">
<view class="service-header-row">
<text class="section-title">出行服务</text>
</view>
<view class="service-list-header">
<uni-icons type="wallet-filled" size="16" color="#FFC107"
style="margin-right: 8rpx;"></uni-icons>
<text class="sl-title">旅行套餐·其他产品</text>
</view>
<view class="product-grid">
<!-- Item 1 -->
<view class="product-item">
<view class="pi-top">
<text class="pi-title">接送机立减券 (8... x2</text>
<uni-icons type="right" size="12" color="#ccc"></uni-icons>
</view>
</view>
<!-- Item 2 -->
<view class="product-item">
<view class="pi-top">
<text class="pi-title">度假券 x2</text>
<uni-icons type="right" size="12" color="#ccc"></uni-icons>
</view>
<text class="pi-sub">跟团游享9.7折</text>
</view>
<!-- Item 3 -->
<view class="product-item">
<view class="pi-top">
<text class="pi-title">租车券 x1</text>
<uni-icons type="right" size="12" color="#ccc"></uni-icons>
</view>
<text class="pi-sub">租车享85折</text>
</view>
</view>
<view class="show-more-row">
<text>收起</text>
<uni-icons type="top" size="12" color="#666"></uni-icons>
</view>
</view>
<!-- FAQ Card -->
<view class="card faq-card">
<view class="section-title-row">
<text class="section-title">快速解决问题</text>
<view class="link-right">
<text>联系客服</text>
<uni-icons type="right" size="12" color="#666"></uni-icons>
</view>
</view>
<view class="faq-tags">
<view class="faq-tag">补开发票</view>
<view class="faq-tag">发票打印时效</view>
<view class="faq-tag">联系航空公司</view>
<view class="faq-tag">需要电子发票</view>
<view class="faq-tag">合并寄零发票</view>
<view class="faq-tag">行程单打印</view>
</view>
</view>
<!-- Terms Section -->
<view class="card terms-card">
<view class="section-title-row">
<text class="section-title">协议条款</text>
</view>
<view class="terms-content">
<text class="t-gray">本次预定涉及及条款:</text>
<text
class="t-blue">内容声明、锂电池及危险品乘机须知、去哪儿网电子商务平台服务合同、个人信息授权声明、赠险免责声明、机票价格变动说明、安心飞政策2024年8月8日更新、南航锂电池运输规定、重庆航空运总、南航行李规定、南航国内运输总条件、南航限制行李运输规则、南航国内运输散客支线联程运价使用条件、南航国内运输散客票价使用条件规定、南航北京大兴机场、成都天府机场进出港国内客票使用条件规定、南航国内运输散客来回程票价使用条件规定、南航隐私通知、南航国内运输散客中转票价使用条件规定、工商执照信息、旅行社业务经营许可证旅游代订服务合同</text>
</view>
</view>
<!-- Order Info Card -->
<view class="card order-info-card">
<view class="info-row">
<text class="info-label">订单号:</text>
<view class="info-val-box">
<text class="info-val">204014523688</text>
<text class="info-divider">|</text>
<text class="info-copy">复制</text>
</view>
</view>
<view class="info-row">
<text class="info-label">下单时间:</text>
<text class="info-val">2025-02-28 13:52:22</text>
</view>
</view>
<!-- Branding -->
<view class="branding-area">
<view class="brand-main">
<text class="brand-line">—</text>
<text class="brand-text">低价购·安心飞</text>
<text class="brand-line">—</text>
</view>
<view class="brand-sub">
<view class="bs-item">
<uni-icons type="checkbox-filled" size="12" color="#999"></uni-icons>
<text>价格安心</text>
</view>
<view class="bs-item">
<uni-icons type="checkbox-filled" size="12" color="#999"></uni-icons>
<text>出行安心</text>
</view>
<view class="bs-item">
<uni-icons type="checkbox-filled" size="12" color="#999"></uni-icons>
<text>售后安心</text>
</view>
</view>
</view>
<view class="placeholder" style="height: 200rpx;"></view>
</view>
</view>
<!-- Bottom Fixed -->
<view class="bottom-bar">
<button class="invoice-btn">开具发票</button>
<view class="home-indicator"
style="height: 10rpx; width: 30%; background: #000; border-radius: 10rpx; margin: 20rpx auto 0; opacity: 0.2;">
</view>
</view>
</view>
</template>
<script setup>
import navBar from '@/components/nav-bar/nav-bar.vue';
import { ref, onMounted, reactive } from 'vue';
const statusBarHeight = ref(20);
const passengerList = ref([
{ name: '鱼鱼', id: '5102***********553', ticketNo: '778-2255223370' },
{ name: '鱼鱼', id: '5102***********553', ticketNo: '778-2255223370' }
]);
const data = reactive({
navBar: {
bgColor: '#09D2E3',
title: '出票完成',
isBack: true,
textColor: '#fff'
}
})
onMounted(() => {
const sys = uni.getSystemInfoSync();
if (sys.statusBarHeight) {
statusBarHeight.value = sys.statusBarHeight;
}
});
const goBack = () => {
uni.navigateBack();
};
</script>
<style lang="less" scoped>
.page-container {
min-height: 100vh;
background-color: #F0F1F6;
position: relative;
}
.nav-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
background-color: transparent;
.nav-content {
height: 44px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24rpx;
.nav-right {
display: flex;
gap: 32rpx;
.nav-icon-item {
display: flex;
flex-direction: column;
align-items: center;
.nav-text {
font-size: 20rpx;
color: #fff;
margin-top: -4rpx;
}
}
}
}
}
.main-content {
// background: linear-gradient(180deg, #09D2E3 0%, #09D2E3 0%, rgba(77, 212, 223, 0.12) 85.26%, rgba(216, 216, 216, 0) 100%);
}
.header-bg {
background: #09D2E3;
.image-box {
display: flex;
margin: 0 16rpx;
}
}
.gradient-bg {
margin-top: -1px;
height: 88px;
background: linear-gradient(180deg, #09D2E3 0%, #09D2E3 0%, rgba(77, 212, 223, 0.12) 85.26%, rgba(216, 216, 216, 0) 100%);
}
.status-section {
padding: 0 32rpx;
color: #fff;
.status-row {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 8rpx;
.status-title {
font-size: 48rpx;
font-weight: bold;
}
.price-box {
display: flex;
align-items: baseline;
.price-label {
font-size: 24rpx;
opacity: 0.9;
margin-right: 4rpx;
}
.price-symbol {
font-size: 26rpx;
}
.price-val {
font-size: 44rpx;
font-weight: bold;
margin-right: 4rpx;
}
}
}
.order-no-row {
display: flex;
align-items: center;
font-size: 24rpx;
opacity: 0.9;
margin-bottom: 12rpx;
}
.status-desc {
font-size: 26rpx;
opacity: 0.95;
}
}
.content-area {
margin-top: -88px;
position: relative;
z-index: 10;
}
.card {
margin: 0 24rpx 24rpx;
background-color: #fff;
border-radius: 24rpx;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.03);
}
.ticket-wrapper {
margin: 0 16rpx 24rpx;
border-radius: 0 0 20rpx20rpx;
overflow: hidden;
box-shadow: 0 4rpx 16rpx rgba(0, 181, 224, 0.1);
}
.ticket-card {
background-color: #fff;
.flight-section {
padding: 32rpx 24rpx 24rpx;
.section-title {
font-size: 30rpx;
color: #333;
font-weight: bold;
margin-bottom: 20rpx;
display: block;
}
.flight-header {
display: flex;
align-items: center;
margin-bottom: 24rpx;
.tag {
background-color: #00bcd4;
color: #fff;
font-size: 20rpx;
padding: 2rpx 8rpx;
border-radius: 4rpx;
margin-right: 12rpx;
}
.flight-name {
font-size: 24rpx;
color: #666;
}
}
.flight-time-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.time-col {
display: flex;
flex-direction: column;
.time-big {
font-size: 56rpx;
font-weight: bold;
color: #333;
line-height: 1;
margin-bottom: 12rpx;
letter-spacing: -1rpx;
}
.airport-text {
font-size: 24rpx;
color: #666;
display: flex;
align-items: center;
gap: 4rpx;
}
}
.align-right {
align-items: flex-end;
}
.arrow-col {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 20rpx;
.plane-line {
width: 100%;
height: 20rpx;
/* Placeholder for dashed line image if not available, create CSS dashed line */
border-bottom: 2rpx dashed #ddd;
position: relative;
margin-bottom: 8rpx;
&::after {
content: '✈';
position: absolute;
top: -14rpx;
left: 50%;
transform: translateX(-50%) rotate(90deg);
color: #ddd;
font-size: 24rpx;
background-color: #fff;
padding: 0 8rpx;
}
}
.duration-text {
font-size: 22rpx;
color: #999;
}
}
}
.flight-detail-row {
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #999;
margin-bottom: 32rpx;
gap: 8rpx;
.detail-divider {
color: #eee;
margin: 0 8rpx;
}
}
.flight-actions {
display: flex;
gap: 20rpx;
.action-btn {
flex: 1;
border: 1rpx solid #c2f0f8;
border-radius: 16rpx;
padding: 20rpx 0;
display: flex;
align-items: center;
justify-content: center;
gap: 12rpx;
.btn-text {
color: #00bcd4;
font-size: 28rpx;
}
.btn-right {
display: flex;
flex-direction: column;
align-items: flex-start;
.sub-text {
font-size: 20rpx;
color: #333;
}
}
}
}
}
.ticket-divider {
position: relative;
height: 40rpx;
background-color: #fff;
display: flex;
align-items: center;
overflow: hidden;
.half-circle {
width: 30rpx;
height: 30rpx;
background-color: #f3f4f6;
border-radius: 50%;
position: absolute;
top: 50%;
transform: translateY(-50%);
&.left {
left: -15rpx;
}
&.right {
right: -15rpx;
}
}
.dashed-line {
flex: 1;
margin: 0 30rpx;
border-top: 2rpx dashed #eee;
}
}
.passenger-section {
padding: 24rpx 24rpx 32rpx;
.section-title-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.section-title {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.link-right {
font-size: 22rpx;
color: #999;
display: flex;
align-items: center;
}
}
.passenger-row {
display: flex;
margin-bottom: 32rpx;
.row-label {
width: 140rpx;
font-size: 26rpx;
color: #999;
}
.row-label-placeholder {
width: 140rpx;
}
.row-content {
flex: 1;
.p-name {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 8rpx;
text-decoration: underline;
text-decoration-color: #333;
}
.p-sub {
font-size: 24rpx;
color: #999;
margin-bottom: 8rpx;
display: flex;
align-items: center;
}
}
}
.contact-row {
display: flex;
align-items: center;
.row-label {
width: 140rpx;
font-size: 26rpx;
color: #999;
}
.contact-val {
font-size: 30rpx;
color: #333;
}
}
}
}
.combined-alert-box {
margin: 0 24rpx 24rpx;
background-color: #fff4f2;
border-radius: 12rpx;
padding: 24rpx;
.alert-row {
display: flex;
align-items: flex-start;
.alert-tag {
background: linear-gradient(90deg, #ff6b6b, #ff4d4f);
color: #fff;
font-size: 20rpx;
padding: 4rpx 10rpx;
border-radius: 6rpx;
margin-right: 16rpx;
white-space: nowrap;
line-height: normal;
margin-top: 4rpx;
}
.alert-content {
font-size: 24rpx;
color: #d45d52;
line-height: 1.5;
flex: 1;
text-align: justify;
}
}
.alert-divider {
height: 1rpx;
border-top: 1rpx dashed #f5caca;
margin: 20rpx 0;
}
}
.service-card {
padding: 32rpx 24rpx;
.service-header-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 24rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
}
.service-list-header {
display: flex;
align-items: center;
margin-bottom: 24rpx;
.sl-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
}
.product-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 20rpx;
margin-bottom: 20rpx;
.product-item {
width: 48%;
background-color: #fff;
/* Assuming a slight border or shadow if needed, but per screenshot seems flat/clean or needs wrapper */
/* The screenshot shows them as white cards on white? No, actually they seem to have a border or background */
/* Let's try to match the container style or just ensure they look distinct */
/* Actually in the screenshot, the "Travel Package" header is outside? */
/* Wait, looking closely at screenshot: The items look like they are in a white card. */
/* Let's keep them clean. */
background-color: #fafafa;
padding: 20rpx;
border-radius: 12rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 120rpx;
/* First item spans full width in screenshot? */
/* "接送机立减券" is on left, "度假券" on right? */
/* Actually the screenshot shows: */
/* Row 1: Left Item (Airport transfer), Right Item (Vacation) */
/* Row 2: Left Item (Car rental) */
/* Wait, looking at the layout: "接送机" (Airport) seems to be item 1. "度假券" item 2. "租车券" item 3. */
.pi-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 8rpx;
.pi-title {
font-size: 28rpx;
color: #333;
font-weight: bold;
flex: 1;
margin-right: 8rpx;
}
}
.pi-sub {
font-size: 22rpx;
color: #ff9900;
}
&:first-child {
/* If item 1 looks like it takes same width */
}
}
}
.show-more-row {
display: flex;
justify-content: center;
align-items: center;
padding-top: 16rpx;
font-size: 24rpx;
color: #666;
gap: 4rpx;
}
}
.faq-card {
padding: 32rpx 24rpx;
.section-title-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.link-right {
font-size: 24rpx;
color: #999;
display: flex;
align-items: center;
}
}
.faq-tags {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
.faq-tag {
padding: 12rpx 32rpx;
background-color: #fff;
border: 1rpx solid #e5e5e5;
border-radius: 32rpx;
font-size: 26rpx;
color: #666;
}
}
}
.terms-card {
padding: 32rpx 24rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 24rpx;
display: block;
}
.terms-content {
font-size: 24rpx;
line-height: 1.6;
text-align: justify;
.t-gray {
color: #999;
}
.t-blue {
color: #00bcd4;
}
}
}
.order-info-card {
padding: 32rpx 24rpx;
.info-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
.info-label {
font-size: 30rpx;
color: #333;
}
.info-val-box {
display: flex;
align-items: center;
font-size: 28rpx;
color: #999;
.info-val {
margin-right: 16rpx;
}
.info-divider {
color: #eee;
margin-right: 16rpx;
font-size: 24rpx;
}
.info-copy {
color: #666;
}
}
.info-val {
font-size: 28rpx;
color: #999;
}
}
}
.branding-area {
padding-bottom: 200rpx;
display: flex;
flex-direction: column;
align-items: center;
.brand-main {
display: flex;
align-items: center;
gap: 16rpx;
margin-bottom: 12rpx;
.brand-line {
color: #ccc;
}
.brand-text {
font-size: 32rpx;
font-weight: bold;
color: #ccc;
/* Note: Screenshot might show generic gray brand */
}
}
.brand-sub {
display: flex;
gap: 24rpx;
.bs-item {
display: flex;
align-items: center;
gap: 4rpx;
font-size: 20rpx;
color: #999;
}
}
}
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
z-index: 999;
background-color: #fff;
padding: 24rpx 32rpx 40rpx;
box-sizing: border-box;
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.03);
.invoice-btn {
background-color: #53dcf9;
color: #fff;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: bold;
border: none;
&::after {
border: none;
}
}
}
</style>