Commit f0f72ffb authored by 罗超's avatar 罗超

机票

parent c4979ed0
......@@ -117,6 +117,9 @@
.items-center{
align-items: center;
}
.items-start{
align-items: start;
}
.justify-center{
justify-content: center;
}
......
@font-face {
font-family: "tffont"; /* Project id 4816119 */
src: url('//at.alicdn.com/t/c/font_4816119_vhne921vx0o.woff2?t=1739518077462') format('woff2'),
url('//at.alicdn.com/t/c/font_4816119_vhne921vx0o.woff?t=1739518077462') format('woff'),
url('//at.alicdn.com/t/c/font_4816119_vhne921vx0o.ttf?t=1739518077462') format('truetype');
src: url('//at.alicdn.com/t/c/font_4816119_61ojoauzfi8.woff2?t=1739876734691') format('woff2'),
url('//at.alicdn.com/t/c/font_4816119_61ojoauzfi8.woff?t=1739876734691') format('woff'),
url('//at.alicdn.com/t/c/font_4816119_61ojoauzfi8.ttf?t=1739876734691') format('truetype');
}
.tffont {
......@@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale;
}
.tffont-qianwangx:before {
content: "\e608";
}
.tffont-qianwang:before {
content: "\e601";
}
.tffont-arrowleft:before {
content: "\e610";
}
......
......@@ -745,6 +745,13 @@
{
"navigationStyle" : "custom"
}
},
{
"path" : "flightDetail",
"style" :
{
"navigationBarTitleText" : "填写机票订单信息"
}
}
]
}
......
......@@ -34,14 +34,14 @@
mode="aspectFill">
</image>
<view class="city-list-item col">
<view style="margin-bottom: 30rpx;" class=" row items-center">
<view @click="goListHandle('')" style="margin-bottom: 30rpx;" class=" row items-center">
<view class="bold col">{{x.DepartureName}} - {{x.ArrivalCityName}}</view>
<view class="row items-center">
<view style="font-size: 22rpx;">更多日期</view>
<u-icon name='arrow_right' custom-prefix="tffont" color="#00000066" size="28"></u-icon>
</view>
</view>
<view class="flights row items-center" v-for="(f,fi) in x.TicketProductList">
<view @click="goListHandle(f.FlightDate)" class="flights row items-center" v-for="(f,fi) in x.TicketProductList">
<image style="width: 30rpx;" :src="`https://static.tripcdn.com/packages/flight/airline-logo/latest/airline/48/${f.AlCode}.png`" mode="widthFix"></image>
<view style="font-size: 22rpx;width:50rpx;margin:0 4px">
{{ f.DayCount }}
......@@ -58,15 +58,7 @@
</view>
<u-icon name='arrow_right' custom-prefix="tffont" color="#00000066" size="28"></u-icon>
</view>
<!-- <view class="row q-mt-md">
<view class="col">
<text style="font-size: 22rpx;color: #A4A4A4;font-weight: 400;">仅需:</text>
<text style="color:#FF3166;font-size: 22rpx;">¥</text>
<text
style="font-size: 32rpx;font-weight: bold;color:#FF3166;">{{x.Flight.B2BPrice}}</text>
</view>
<view class="more-date">更多日期</view>
</view> -->
</view>
</view>
......@@ -152,7 +144,7 @@
if (this.dateRangeValue.type == 1) {
this.parementers.StartDate = this.dateRangeValue.startDate
//this.parementers.EndDate = this.dateRangeValue.startDate
this.parementers.EndDate = this.dateRangeValue.startDate
} else {
const d = this.resolveDateByFuzzyHandle(this.dateRangeValue.fuzzy.fuzzyType)
this.parementers.StartDate = d[0]
......@@ -260,6 +252,15 @@
})
this.getTopLowTicketHandle()
},
goListHandle(val){
let url ='/pages/airTicket/ticketList/ticketList'
if(val!=''){
url += `?dv=${encodeURIComponent(val)}`
}
uni.navigateTo({
url
})
}
}
}
</script>
......
......@@ -180,16 +180,19 @@
},
methods: {
searchFlightHandle(){
if(this.chosenResult[0].ID==0||this.chosenResult[1].ID==0){
uni.setStorageSync('scf',{
cities:this.chosenResult,
dateRange: this.dateRangeValue
})
if(this.chosenResult[0].ID==0||this.chosenResult[1].ID==0){
uni.navigateTo({
url:'/pages/airTicket/airCity'
})
}else{
//查询航班列表
uni.navigateTo({
url:'/pages/airTicket/ticketList/ticketList'
})
}
},
async getContainerWidth() {
......
<template>
<view style="height: 100vh; z-index:2; width:100vw;position: fixed;left: 0;top: 0;background-color: rgba(0, 0, 0, 0.6);">
<view style="z-index: 2; background-color: #FFF;padding-bottom:36rpx;position: absolute;top: 0;left: 0;right: 0;border-radius: 0 0 16rpx 16rpx;">
<view style="padding:24rpx;font-size: 40rpx;font-weight: bold;color: #121212;" class="text-center">
<view style="padding:24rpx;font-size: 40rpx;font-weight: bold;color: #121212;" class="text-center" :style="{'margin-top':paddingTop}">
重新选择
</view>
<view class="air-tools">
......@@ -21,11 +21,12 @@
<view @click="setCitiesHandler" class="text-center cities-name q-mt-md" style="background-color: #B99846;border-radius: 10rpx;height: 90rpx; line-height: 90rpx;color:#EEF1F4">确 认</view>
<u-popup mode="bottom" border-radius="20" :popup="false" v-model="citiesVisible" :maskCloseAble="true" length="auto" :safeAreaInsetBottom="true" @close="popupClose" :z-index="9999">
<city-list :city-type="currentCityObj.type" :city-value="currentCityObj.ID" @change="setCityHandler"></city-list>
<city-list :enable-all="enableAll" :city-type="currentCityObj.type" :city-value="currentCityObj.ID" @change="setCityHandler"></city-list>
</u-popup>
</view>
<view style="height: 100%;width: 100%;" @click="closed"></view>
</view>
<view style="height: 100%;width: 100%;" @click="closed"></view>
</view>
</template>
......@@ -36,6 +37,14 @@
props:{
value:{
type:Array
},
paddingTop:{
type:String,
default:'0px'
},
enableAll:{
type:Boolean,
default:true
}
},
data(){
......
......@@ -9,13 +9,13 @@
<template v-if="showAddress && showAddress.length>0">
<scroll-view scroll-y="true" style="height: 55vh;">
<div class="row q-mt-md">
<view class="col city-item big q-mr-sm" v-if="keywords==''" :class="{'active':currentValue==0}" @click="setCurrentCity(0)">
<view class="col city-item big q-mr-sm" v-if="keywords=='' && enableAll" :class="{'active':currentValue==0}" @click="setCurrentCity(0)">
<u-icon name="ditu-xian" custom-prefix="tffont" size="66" v-if="showAddress.length>2"></u-icon>
<view style="font-size: 28rpx;font-weight: 600;">全部低价城市</view>
</view>
<view class="col row flex-grid flex-wrap">
<template v-for="(x,i) in showAddress">
<view class="city-item " v-if="i<4" :key="i" @click="setCurrentCity(x.ID)" :class="{'active':currentValue==x.ID,'col-t-b':keywords=='','col-f-b':keywords!=''}">{{x.Name}}</view>
<view class="city-item " v-if="i<4" :key="i" @click="setCurrentCity(x.ID)" :class="{'active':currentValue==x.ID,'col-t-b':(keywords=='' && enableAll),'col-f-b':(keywords!='' || !enableAll)}">{{x.Name}}</view>
</template>
</view>
</div>
......@@ -58,6 +58,10 @@
cityValue:{
type:Number,
default:0
},
enableAll:{
type:Boolean,
default:true
}
},
created() {
......
<template>
<view>
<view class="row items-center">
<u-radio-group v-model="ia">
<u-radio shape="circle">月明人倚楼</u-radio>
</u-radio-group>
</view>
</view>
</template>
<script>
export default{
data(){
return {
ia:false
}
}
}
</script>
<style>
</style>
\ No newline at end of file
<template>
<view class="calendar-container">
<view class="week-header">
<view v-for="(day, index) in weekDays" :key="index" class="week-day">{{ day }}</view>
</view>
<scroll-view scroll-y class="col" style="width:100%;height: 1px;">
<view v-for="(month, monthIndex) in calendarData" :key="monthIndex" class="month-container">
<view class="month-title">{{ month.year }}{{ month.month }}</view>
<view class="days-grid">
<view
v-for="(dayOffset, index) in month.firstDayOffset"
:key="`offset-${index}`"
class="day-placeholder"
></view>
<view
v-for="(day, dayIndex) in month.days"
:key="dayIndex"
class="day-item"
:class="[
{ 'selected': isSelected(monthIndex, dayIndex) },
{ 'disabled': isDisabled(monthIndex, dayIndex) },
{ 'range': isInRange(monthIndex, dayIndex) },
{ 'festival': isFestivalDay(month, day) }
]"
@tap="handleDaySelect(monthIndex, dayIndex)"
>
<view class="day-number">{{ day }}</view>
<view v-if="calendarFestivals[`${month.year}${month.month}${day}`]" class="day-status">{{calendarFestivals[`${month.year}${month.month}${day}`]}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import festivals from "./day.js";
export default {
props: {
defaultStartDate: {
type: String,
default: ""
},
defaultEndDate: {
type: String,
default: ""
}
},
data() {
return {
weekDays: ['日', '一', '二', '三', '四', '五', '六'],
calendarData: [],
selectedStartDate: [], // Start date index
selectedEndDate: [], // End date index
screenWidth: 375,
calendarFestivals: {}
};
},
computed: {
currentDate() {
const date = new Date();
return {
year: date.getFullYear(),
month: date.getMonth() + 1,
day: date.getDate()
};
}
},
mounted() {
this.initializeCalendar();
},
methods: {
initializeCalendar() {
this.getScreenWidth();
this.generateCalendarData();
this.setInitialSelection();
this.applyFestivalData();
},
getScreenWidth() {
uni.getSystemInfo({
success: (res) => {
this.screenWidth = res.windowWidth;
}
});
},
generateCalendarData() {
let year = this.currentDate.year;
let month = this.currentDate.month;
this.calendarData = Array.from({ length: 6 }, (_, index) => {
const monthData = this.createMonthData(year, month + index);
return monthData;
});
},
createMonthData(year, month) {
const actualMonth = month > 12 ? month % 12 : month;
return {
year: month > 12 ? year + 1 : year,
month: actualMonth,
days: Array.from({ length: new Date(year, actualMonth, 0).getDate() }, (_, index) => index + 1),
firstDayOffset: new Date(`${year}/${actualMonth}/1`).getDay()
};
},
applyFestivalData() {
this.calendarFestivals = festivals.reduce((acc, { year, month, festival }) => {
const subResult = festival.map(({ name, day }) => {
const key = `${year}${month}${day}`;
return { [key]: name };
});
return { ...acc, ...Object.assign({}, ...subResult) };
}, {});
},
setInitialSelection() {
if (this.defaultStartDate) {
const [year, month, day] = this.defaultStartDate.split('-');
const monthIndex = this.calendarData.findIndex(m => m.year == year && m.month == month);
if (monthIndex !== -1) {
this.selectedStartDate = [monthIndex, parseInt(day) - 1];
}
}
if (this.defaultEndDate) {
const [year, month, day] = this.defaultEndDate.split('-');
const monthIndex = this.calendarData.findIndex(m => m.year == year && m.month == month);
if (monthIndex !== -1) {
this.selectedEndDate = [monthIndex, parseInt(day) - 1];
}
}
},
isSelected(monthIndex, dayIndex) {
return (this.selectedStartDate[0] === monthIndex && this.selectedStartDate[1] === dayIndex) ||
(this.selectedEndDate[0] === monthIndex && this.selectedEndDate[1] === dayIndex);
},
isInRange(monthIndex, dayIndex) {
if (!this.selectedStartDate.length || !this.selectedEndDate.length) return false;
const start = this.selectedStartDate;
const end = this.selectedEndDate;
return (monthIndex > start[0] || (monthIndex === start[0] && dayIndex >= start[1])) &&
(monthIndex < end[0] || (monthIndex === end[0] && dayIndex <= end[1]));
},
isDisabled(monthIndex, dayIndex) {
if (monthIndex === 0) {
return dayIndex + 1 < this.currentDate.day;
}
return false;
},
isFestivalDay(month, day) {
return typeof day === 'string';
},
handleDaySelect(monthIndex, dayIndex) {
if (this.isDisabled(monthIndex, dayIndex)) return;
// Handle the selection of start and end date for range
if (!this.selectedStartDate.length || (this.selectedStartDate.length && this.selectedEndDate.length)) {
this.selectedStartDate = [monthIndex, dayIndex];
this.selectedEndDate = []; // Reset end date
} else {
if (monthIndex > this.selectedStartDate[0] ||
(monthIndex === this.selectedStartDate[0] && dayIndex >= this.selectedStartDate[1])) {
this.selectedEndDate = [monthIndex, dayIndex];
} else {
this.selectedStartDate = [monthIndex, dayIndex];
this.selectedEndDate = []; // Reset if the start date is changed
}
}
this.$emit('selected-range', this.getSelectedRange());
},
getSelectedRange() {
const startMonthData = this.calendarData[this.selectedStartDate[0]];
const endMonthData = this.calendarData[this.selectedEndDate[0]];
const startDayNumber = this.selectedStartDate[1] + 1;
const endDayNumber = this.selectedEndDate[1] + 1;
return [ !startMonthData?'':`${startMonthData.year}-${String(startMonthData.month).padStart(2, '0')}-${String(startDayNumber).padStart(2, '0')}`,!endMonthData?'':`${endMonthData.year}-${String(endMonthData.month).padStart(2, '0')}-${String(endDayNumber).padStart(2, '0')}`];
}
}
};
</script>
<style>
.calendar-container {
height: 100%;
display: flex;
flex-direction: column;
}
.week-header {
display: flex;
justify-content: space-around;
padding: 10px 0;
background: #f8f8f8;
border-radius: 16rpx;
}
.week-day {
width: 14.28%;
text-align: center;
font-size: 14px;
color: #333;
}
.month-container {
padding: 15px 10px;
}
.month-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
padding-left: 10px;
}
.days-grid {
display: flex;
flex-wrap: wrap;
}
.day-item, .day-placeholder {
width: 14.28%;
min-height: 50px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 5px 0;
}
.day-item {
position: relative;
font-size: 14px;
color: #333;
background: #fff;
}
.day-placeholder {
visibility: hidden;
}
.day-item.selected {
background: #000 !important;
color: #fff;
}
.day-item.disabled {
color: #ccc;
}
.day-item.festival {
color: #d32f2f;
font-size: 12px;
}
.day-status {
font-size: 10px;
color: #d32f2f;
position: absolute;
bottom: 2px;
}
.day-item.range {
background-color: #f1f2f4; /* light yellow */
/* color: #000; */
}
</style>
\ No newline at end of file
<template>
<view style="display: inline-block;" @click="()=>showDateVisible=true">
<slot></slot>
<u-popup mode="bottom" border-radius="20" :popup="false" v-model="showDateVisible" :maskCloseAble="true" length="auto" :safeAreaInsetBottom="true" @close="()=>showDateVisible=false" :z-index="9999">
<view class="column" style="height: 70vh;">
<scroll-view scroll-y="true" class="col" style="width: 100%;height: 1px;">
<date-select-range @selected-range="changeHandle" v-if="selectType==1" :default-start-date="rangeValue[0]" :default-end-date="rangeValue[1]"></date-select-range>
<date-select @selected="changeHandle" v-else :default-date="value"></date-select>
</scroll-view>
<view @click="selected" class="text-center q-mt-md q-ml-md q-mr-md" style="background-color: #B99846;border-radius: 10rpx;height: 90rpx; line-height: 90rpx;color:#EEF1F4;font-weight: bold;font-size: 32rpx;">确定</view>
</view>
</u-popup>
</view>
</template>
<script>
import DateSelectRange from '../sign/range.vue';
import DateSelect from '../sign/sign.vue'
export default{
data(){
return {
showDateVisible:false,
value:'',
rangeValue:[],
selectType:0
}
},
props:{
defaultValue:{
type:String|Array,
default:''
}
},
components:{
DateSelectRange,
DateSelect
},
created() {
this.selectType = typeof this.defaultValue == 'string'?0:1
if(this.selectType == 0) this.value = this.defaultValue
else this.rangeValue = this.defaultValue
},
methods: {
changeHandle(val){
if(this.selectType == 0) this.value = val
else this.rangeValue = val
},
selected(){
this.$emit('change',this.selectType==0?this.value:this.rangeValue)
this.showDateVisible = false
}
}
}
</script>
<style>
</style>
\ No newline at end of file
<template>
<view class="f-detail">
<view class="column items-center justify-center q-mt-md" v-if="loading">
<u-loading mode="circle" size="40"></u-loading>
<view class="normal-label text-center q-mt-sm">正在加载信息</view>
</view>
<template v-if="flight && !loading">
<view class="flight-card">
<view class="row items-center">
<view class="flight-status">去程</view>
<view class="city bold">{{goList[0].DepartureName}}</view>
<u-icon name='qianwangx' custom-prefix="tffont" color="#00000033" size="28"></u-icon>
<view class="city bold">{{goList[goList.length-1].ArrivalCityName}}</view>
<view class="col row" style="font-size: 14px;justify-content: flex-end;">
<text>{{goList[0].FlightDate.split('-').splice(1,2).join('-')}} {{getWeeks(goList[0].FlightDate)}} {{goList[0].Departure_time}}</text>
<u-icon class="q-ml-sm" name='arrow_down' custom-prefix="tffont" color="#00000066" size="32"></u-icon>
</view>
</view>
</view>
<view class="flight-card">
<view class="row items-center">
<view class="flight-status">回程</view>
<view class="city bold">{{backList[0].DepartureName}}</view>
<u-icon name='qianwangx' custom-prefix="tffont" color="#00000033" size="28"></u-icon>
<view class="city bold">{{backList[goList.length-1].ArrivalCityName}}</view>
<view class="col row" style="font-size: 14px;justify-content: flex-end;">
<text>{{backList[0].FlightDate.split('-').splice(1,2).join('-')}} {{getWeeks(backList[0].FlightDate)}} {{backList[0].Departure_time}}</text>
<u-icon class="q-ml-sm" name='arrow_down' custom-prefix="tffont" color="#00000066" size="32"></u-icon>
</view>
</view>
</view>
<view class="flight-card q-mt-md">
<view class="title">选择乘机人</view>
<guest></guest>
</view>
</template>
</view>
</template>
<script>
import guest from './components/guest/index.vue'
export default {
data() {
return {
id:0,
loading:false,
flight:null,
goList:[],
backList:[],
dateRangeValue: {
type: 0,
startDate: '',
fuzzy: {
fuzzyType: 0,
fuzzyTypeName: '',
weeks: [],
dayRangStatus: false,
dayRange: [4, 10]
},
formatStartDate: '任意时间出发'
},
chosenResult: [{
type: 0,
ID: 0,
Name: '全部城市'
},
{
type: 1,
ID: 0,
Name: '全部城市'
}
],
parementers: {
StartDate: '',
EndDate: '',
DepartCityId: 0,
ArriveCityId: 0,
AirLineID: 0,
groupId: 2,
TicketType: 2,
StartPlayDay: 0,
EndPlayDay: 0,
WeekDay: ''
},
}
},
components:{guest},
onLoad(options) {
if(options.id && uni.getStorageSync('scf')){
this.id = options.id
uni.setNavigationBarColor({
backgroundColor:'#DEBF7B',
frontColor:'#000000'
})
const s = uni.getStorageSync('scf')
this.dateRangeValue = s.dateRange
this.chosenResult = s.cities
this.getTopLowTicketHandle()
return
}
this.navigatorToHomeHandle()
},
created() {
},
methods: {
navigatorToHomeHandle(){
uni.redirectTo({
url:'/pages/index/index'
})
},
getTopLowTicketHandle() {
this.resolveParameterHanle()
this.lowData = []
this.loading = true
this.apipost('AirTicket_get_GetTopTicketProduct', this.parementers, (r) => {
if (r.resultCode == 1) {
this.resolveTicketHandle(r.data)
}else{
this.navigatorToHomeHandle()
}
this.loading = false
}, (e) => {
this.loading = false
this.navigatorToHomeHandle()
})
},
resolveTicketHandle(data){
const t = data[0].TicketProductList.find(x=>x.TCID==this.id)
if(!t) {
this.navigatorToHomeHandle()
return
}
this.goList = t.FlightList.filter(x=>x.FlightType==1)
this.backList = t.FlightList.filter(x=>x.FlightType==3)
this.flight = t
},
getWeeks(d){
const date = new Date(d)
const weeks = ['日', '一', '二', '三', '四', '五', '六']
return `周${weeks[date.getDay()]}`
},
resolveParameterHanle() {
this.resetParameterHandle()
this.parementers.DepartCityId = this.chosenResult[0].ID
this.parementers.ArriveCityId = this.chosenResult[1].ID
if (this.dateRangeValue.type == 1) {
this.currentDate = this.formatDateHandle(start)
this.filterDate.start = this.dateRangeValue.startDate
this.filterDate.end = this.dateRangeValue.startDate
} else {
const d = this.resolveDateByFuzzyHandle(this.dateRangeValue.fuzzy.fuzzyType)
this.parementers.StartDate = d[0]
this.parementers.EndDate = d[1]
}
},
resetParameterHandle() {
this.currentDate = ''
this.parementers = {
StartDate: '',
EndDate: '',
DepartCityId: 0,
ArriveCityId: 0,
AirLineID: 0,
groupId: 2,
TicketType: 2,
StartPlayDay: 0,
EndPlayDay: 0,
WeekDay: ''
}
},
formatDateHandle(date) {
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`
},
resolveDateByFuzzyHandle(t) {
if (t == 0) return ['', '']
let start = new Date();
let end = new Date()
if (t == -1) {
start.setTime(start.getTime() + 3600 * 1000 * 24 * 1);
end.setMonth(end.getMonth() + 1);
} else if (t == -2) {
start.setTime(start.getTime() + 3600 * 1000 * 24 * 1);
end.setMonth(end.getMonth() + 3)
} else {
const currentDate = new Date()
currentDate.setMonth(currentDate.getMonth() + t);
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
start = new Date(year, month, 1);
end = new Date(year, month + 1, 0);
}
return [this.formatDateHandle(start), this.formatDateHandle(end)]
},
}
}
</script>
<style>
@import url('../../asset/css/flex.css');
.f-detail{
background-color: #F5F5F5;
background-image: linear-gradient(180deg, #DEBF7B, #F5F5F5);
background-size: 100% 900rpx;
background-repeat: no-repeat;
height: 100vh;
width: 100vw;
padding-top: 30rpx;
}
.f-detail .flight-card{
background-color: #fff;
border-radius: 16rpx;
padding: 20rpx;
margin: 30rpx;
}
.f-detail .flight-card .title{
font-size: 32rpx;
font-weight: bold;
color: #080A09;
}
.f-detail .flight-card .flight-status{
background: #E1C278;
border-radius: 8rpx;
font-size: 24rpx;
color: #111111;
font-weight: 400;
padding: 7rpx 14rpx;
}
.f-detail .flight-card .city{
width: 98rpx;
margin: 0 12rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #080A09;
}
.f-detail .flight-card .bold{
font-size: 28rpx;
font-weight: bold;
line-height: 1;
}
</style>
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment