Commit 7b8259b8 authored by youjie's avatar youjie

no message

parent 5445ecdb
import { HttpResponse } from '../@types'
import request from './request'
class scheduledTripService {
// 行程详情
static async GetB2BTravelInfoV1(param:any):Promise<HttpResponse>{
return request('b2b_get_GetB2BTravelInfoV1',param)
}
// 获取分页数据
static async GetB2BTravelPageList(param:any):Promise<HttpResponse>{
return request('b2b_get_GetB2BTravelPageList',param)
}
// 获取地区数据
static async GetSearchArea(param:any):Promise<HttpResponse>{
return request('ws_get_GetSearchArea',param)
}
// 基础配置
static async GetWebSiteConfig(param:any):Promise<HttpResponse>{
return request('ws_get_GetWebSiteConfig',param)
}
}
export default scheduledTripService
<?xml version="1.0" encoding="UTF-8"?>
<svg t="1675838086946" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2586" width="200" height="200"><path d="M889.9 922.4H199.6c-9.4 0-17-7.6-17-17s7.6-17 17-17h690.3c31.8 0 57.7-24.8 57.7-55.3s-25.9-55.3-57.7-55.3H155.2c-50.5 0-91.7-40-91.7-89.3s41.1-89.3 91.7-89.3h197.3c9.4 0 17 7.6 17 17s-7.6 17-17 17H155.2c-31.8 0-57.7 24.8-57.7 55.3s25.9 55.3 57.7 55.3h734.7c50.5 0 91.7 40 91.7 89.3s-41.2 89.3-91.7 89.3z m-764 0H63.6c-9.4 0-17-7.6-17-17s7.6-17 17-17h62.3c9.4 0 17 7.6 17 17s-7.6 17-17 17z" fill="#8a8a8a" p-id="2587"></path><path d="M533.2 752.4c-34 0-306-184.2-306-348.5s133.2-297.5 297.5-297.5 297.5 133.2 297.5 297.5-255 348.5-289 348.5z m0-470.7c-44 0-79.7 35.7-79.7 79.7s35.7 79.7 79.7 79.7 79.7-35.7 79.7-79.7-35.7-79.7-79.7-79.7z" fill="#8a8a8a" p-id="2588"></path><path d="M266.1 522.9C343 646.1 506.1 752.4 532 752.4c25.8 0 179.1-106.3 251.4-229.5H266.1z" fill="#8a8a8a" opacity=".2" p-id="2589"></path><path d="M554.2 437.9c-6.8 1.9-13.7 3.2-21.1 3.2s-14.3-1.3-21.1-3.2H230.9c32.5 154.7 270.6 314.5 302.2 314.5s255-159.8 285.5-314.5H554.2z" fill="#8a8a8a" opacity=".15" p-id="2590"></path><path d="M612.9 361.4c0 44-35.7 79.7-79.7 79.7s-79.7-35.7-79.7-79.7c0-2.9 0.6-5.7 0.9-8.5H231.9c-2.9 16.6-4.7 33.6-4.7 51 0 164.3 272 348.5 306 348.5s289-184.2 289-348.5c0-17.4-1.8-34.4-4.7-51H612c0.3 2.9 0.9 5.6 0.9 8.5z" fill="#8a8a8a" opacity=".1" p-id="2591"></path></svg>
\ No newline at end of file
<template>
<div
class="u-mask"
:style="[maskStyle]"
:class="[show ? 'u-mask-show' : '']"
@click="click"
@touchmove.stop.prevent
>
<slot />
</div>
</template>
<script>
/**
* mask 遮罩
* @description 创建一个遮罩层,用于强调特定的页面元素,并阻止用户对遮罩下层的内容进行操作,一般用于弹窗场景
* @tutorial https://www.uviewui.com/components/mask.html
* @property {Boolean} show 是否显示遮罩(默认false)
* @property {String Number} z-index z-index 层级(默认1070)
* @property {Object} custom-style 自定义样式对象,见上方说明
* @property {String Number} duration 动画时长,单位毫秒(默认300)
* @property {Boolean} zoom 是否使用scale对这招进行缩放(默认true)
* @property {Boolean} mask-click-able 遮罩是否可点击,为false时点击不会发送click事件(默认true)
* @event {Function} click mask-click-able为true时,点击遮罩发送此事件
* @example <u-mask :show="show" @click="show = false"></u-mask>
*/
export default {
name: "u-mask",
props: {
// 是否显示遮罩
show: {
type: Boolean,
default: false
},
// 层级z-index
zIndex: {
type: [Number, String],
default: 98
},
// 用户自定义样式
customStyle: {
type: Object,
default() {
return {};
}
},
// 遮罩的动画样式, 是否使用使用zoom进行scale进行缩放
zoom: {
type: Boolean,
default: true
},
// 遮罩的过渡时间,单位为ms
duration: {
type: [Number, String],
default: 300
},
// 是否可以通过点击遮罩进行关闭
maskClickAble: {
type: Boolean,
default: true
}
},
computed: {
maskStyle() {
let style = {};
style.backgroundColor = "rgba(0, 0, 0, 0.6)";
style.zIndex = this.zIndex ? this.zIndex : this.$u.zIndex.mask;
style.transition = `all ${this.duration / 1000}s ease-in-out`;
// 缩放
if (this.zoom == true) style.transform = "scale(1.2, 1.2)";
// 判断用户传递的对象是否为空
if (Object.keys(this.customStyle).length)
style = { ...style, ...this.customStyle };
// 合并自定义的样式
//Object.assign(style, customStyle);
return style;
}
},
methods: {
click() {
if (!this.maskClickAble) return;
this.$emit("click");
}
}
};
</script>
<style lang="scss" scoped>
.u-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
visibility: hidden;
}
.u-mask-show {
opacity: 1;
visibility: visible;
transform: scale(1);
}
</style>
This diff is collapsed.
<template>
<!-- 豆腐块 -->
<div class="Search_center">
<ul class="pd-list">
<li class="pd-box" v-for="(item,index) in DataList" :key="index">
<a class="pd-link">
<div class="pd-img"
:style="{backgroundImage:`url('${item.newCoverImg}')`}">
<div class="pd-price">
<div class="price">
{{item.dayNum}}
<small class="unit"></small> {{item.b2BPrice}}
<small class="unit">元起</small>
</div>
</div>
</div>
<div class="pd-content">
<h3 class="pd-title">{{item.title}}</h3>
<div class="pd-departure">
出發日期:{{item.startDate}}
<span class="more" @click="GotoDetails(item)" style="cursor:pointer">...更多</span>
</div>
</div>
</a>
</li>
</ul>
</div>
</template>
<script>
export default {
props: ["DataList", "PageCount"],
data() {
return {
};
},
methods: {
GotoDetails(item) {
this.CommonJump('/details/' + encodeURIComponent(item.id) + "/" + item.tcid, {});
}
}
}
</script>
This diff is collapsed.
<template>
<!-- 列表 -->
<div class="group-result-list">
<div class="group-statis-block">
<div class="group-share" style="display:none;"></div>
<div class="group-statis-detail">
<span class="title" v-if="qMsg.searchKey">{{qMsg.searchKey}} :</span>
找到
<span class="num"> {{qMsg.TotalCount}} </span>個行程
<span class="pc">,目前在第<span style="color: #7f7f7f;"> {{qMsg.pageIndex}} </span></span>
</div>
</div>
<div>
<div class="group-box" v-for="(item,index) in DataList" :key="index">
<a class="group-cover">
<img v-if="item.newCoverImg" :src="item.newCoverImg" />
</a>
<div class="group-main">
<div class="group-info">
<div class="group-name" style="margin-bottom:5px;cursor:pointer" @click="GotoDetails(item)">
{{item.title}}
</div>
<div class="group-detail">
<i class="iconfont iconaddress"></i>
<span>{{item.countryName}}</span>
</div>
<div class="group-detail">
<i class="iconfont icontime"></i>
<span>{{item.dayNum}}</span>
</div>
<ul class="group-list">
<li>
<a>{{item.startDate}}</a>
</li>
</ul>
</div>
<div class="price-info">
<div class="price-wrap">
<div class="price_Search">
<small class="price_unit">TWD$</small> {{item.b2BPrice}}
</div>
<a class="btn_warning" @click="GotoDetails(item)" style="cursor:pointer">更多出發日</a>
</div>
</div>
</div>
</div>
<div style="display:flex;justify-content: center;">
<q-pagination v-if="qMsg.PageCount>1" v-model="qMsg.pageIndex" :max="qMsg.PageCount" @input="gerOrderList()"
:direction-links="true">
</q-pagination>
</div>
</div>
</div>
</template>
<script>
import { inject, provide, reactive, toRefs, defineComponent,onMounted } from 'vue';
import { useRouter } from 'vue-router'
export default {
props: ["DataList", "qMsg"],
setup(props,context) {
const $router = useRouter()
const data= reactive({
DataList: props.DataList,
qMsg: props.qMsg,
})
const methods = {
GotoDetails(item) {
$router.push({ path:`/detail/${encodeURIComponent(item.id)}/${item.tcid}`})
},
//调用
gerOrderList(){
context.emit('getPage')
}
}
return {
...toRefs(data),
...methods
}
}
}
</script>
<template>
<div>
<div class="text-subtitle2 text-weight-bold">選擇日期、選項</div>
<div class="text-grey-6 f12 q-my-md">請選擇出發日期</div>
<div class="rounded-borders" style="border: 1px solid #eee">
<div class="q-px-lg q-py-sm row items-center">
<div class="text-subtitle2 text-weight-bold col">
{{ months[currentMonth].display }}
</div>
<div>
<q-btn
color="primary"
round
icon="iconfont iconpreviewleft"
flat
@click="changeShowMonthHandler(-1)"
class="q-mr-sm"
:disable="currentMonth == 0"
/>
<q-btn
color="primary"
round
icon="iconfont iconpreviewright"
flat
@click="changeShowMonthHandler(1)"
:disable="currentMonth == months.length - 1"
/>
</div>
</div>
<div class="q-pa-sm non-selectable" style="border-top: 1px solid #eee">
<div class="row items-center">
<div
class="col text-weight-bold text-center"
style="padding: 10px 0 20px"
v-for="(x, i) in chineseWeek"
:key="i"
>
{{ x }}
</div>
</div>
<div class="row wrap">
<div
class="rounded-borders text-center text-weight-bold"
:class="{
'cursor-pointer hover-date': x.value != '' && x.price,
'cursor-not-allowed': !x.price && x.value != '',
'bg-primary': x.value != '' && x.value == currentDate,
}"
style="padding: 8px 4px; width: 14.285%"
v-for="(x, i) in col"
:key="i"
@click="chosenDateHandler(x)"
>
<div
class="text-dark"
:class="{ 'text-white': x.value == currentDate }"
v-if="x.price"
>
{{ x.display }}
</div>
<div class="text-grey-6" v-else>{{ x.display }}</div>
<div
class="q-mt-sm f12"
:class="{
'text-grey-1': x.value == currentDate,
' text-grey-6': x.value != currentDate,
}"
>
{{
x.price ? moneyFormat(x.price.originalB2CPrice, 0) : "&nbsp;"
}}
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { date,useQuasar } from "quasar";
import { inject, provide, reactive, toRefs, defineComponent,onMounted,ref,watch, getCurrentInstance } from 'vue';
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { DirtionmaryHelper } from 'src/config/dictionary'
import scheduledTripService from 'src/api/scheduledTrip'
import { ApiResult } from 'src/@types/enumHelper'
import message from 'src/utils/message'
import { moneyFormat } from 'src/utils/tools'
export default defineComponent({
components: { },
props: ['priceList'],
setup(props, context) {
const $router = useRouter()
const { t } = useI18n()
const $q = useQuasar()
const qDateProxy = ref(null) as any
let {ctx:that, proxy} = getCurrentInstance()
watch(props.priceList,(n,o)=>{
data.prices = n;
methods.init();
})
const data= reactive({
chineseWeek: ["日", "一", "二", "三", "四", "五", "六"],
chineseMonth: [
"一月",
"二月",
"三月",
"四月",
"五月",
"6月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
],
data: [],
months: [],
currentMonth: 0,
col: [],
prices: props.priceList,
currentDate: "",
})
data.prices = props.priceList;
const methods = {
init() {
methods.createChosenDateHandler();
let firstMonth = date.formatDate(
new Date(data.prices[0].startDate),
"YYYY/MM"
);
data.currentMonth =
data.months.findIndex((x) => x.monthValue == firstMonth) ?? 0;
methods.changeMonthHandler();
},
createChosenDateHandler() {
let beginDate = new Date();
let endDate = date.addToDate(beginDate, { years: 1 });
while (beginDate <= endDate) {
let i = parseInt(date.formatDate(beginDate, "M")) - 1;
data.months.push({
value: date.formatDate(beginDate, "YYYY/MM/DD"),
monthValue: date.formatDate(beginDate, "YYYY/MM"),
display: `${date.formatDate(beginDate, "YYYY")} ${
data.chineseMonth[i]
}`,
});
beginDate = date.addToDate(beginDate, { months: 1 });
}
},
changeShowMonthHandler(i) {
data.currentMonth += i;
methods.changeMonthHandler();
},
changeMonthHandler() {
data.col = [];
let newDate = new Date(data.months[data.currentMonth].monthValue);
let newBeginDate = date.startOfDate(newDate, "month");
let newEndDate = date.endOfDate(newDate, "month");
for (let i = 0; i < date.formatDate(newBeginDate, "d"); i++) {
data.col.push({
value: "",
});
}
while (newBeginDate <= newEndDate) {
let value = date.formatDate(newBeginDate, "YYYY-MM-DD");
let price = data.prices.find((x) => x.startDate == value && x.remainNum>0);
data.col.push({
value,
display: date.formatDate(newBeginDate, "DD"),
price,
});
newBeginDate = date.addToDate(newBeginDate, { days: 1 });
}
let after = 6 - date.formatDate(newBeginDate, "d");
for (let i = 0; i < after; i++) {
data.col.push({
value: "",
});
}
},
chosenDateHandler(item) {
if (item.price) {
data.currentDate = item.value;
context.emit("change", item);
}
},
reset() {
data.currentDate = "";
},
}
methods.init();
return {
...toRefs(data),
...methods,
moneyFormat
}
}
})
</script>
<style>
.hover-date:hover {
background: #eee;
}
</style>
This diff is collapsed.
<template>
<div class="q-mt-md">
<div class="text-subtitle2 text-weight-bold">產品概要</div>
<div class="row q-pt-md q-col-gutter-md">
<div class="row items-center q-pt-mb col-6" v-if="traffic!=''">
<div class="col-3 q-mr-md">往返交通:</div>
<div class="col text-grey-6">{{ traffic }}</div>
</div>
<div class="row items-center q-pt-mb col-6" v-if="hotel!=''">
<div class="col-3 q-mr-md">酒店住宿:</div>
<div class="col text-grey-6">{{ hotel }}</div>
</div>
<div class="row items-center q-pt-mb col-6">
<div class="col-3 q-mr-md">購物:</div>
<div class="col text-grey-6">{{ trip.shopList.length>0?`${trip.shopList.length}個購物點`:'無購物行程' }}</div>
</div>
<div class="row items-center q-pt-mb col-6" v-if="team!=''">
<div class="col-3 q-mr-md">團隊人數:</div>
<div class="col text-grey-6">{{ team }}</div>
</div>
<div class="row items-center q-pt-mb col-6">
<div class="col-3 q-mr-md">景點:</div>
<div class="col text-grey-6">{{ trip.scenicList.length }}個景點或場館</div>
</div>
<div class="row items-center q-pt-mb col-6">
<div class="col-3 q-mr-md">自費項目:</div>
<div class="col text-grey-6">{{ trip.selfpayingList.length>0?`${trip.selfpayingList.length}個自費項目`:'無自費項目' }}</div>
</div>
<div class="row items-center q-pt-mb col-6" v-if="trip.freedomList.length>0">
<div class="col-3 q-mr-md">自由活動:</div>
<div class="col text-grey-6">{{ trip.freedomList.length}} 次自由活動</div>
</div>
<div class="row items-center q-pt-mb col-6">
<div class="col-3 q-mr-md">餐食:</div>
<div class="col text-grey-6">{{ dinner }}</div>
</div>
<div class="row items-center q-pt-mb col-6">
<div class="col-3 q-mr-md">服務用語</div>
<div class="col text-grey-6">普通話/日本語</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { date,useQuasar } from "quasar";
import { inject, provide, reactive, toRefs, defineComponent,onMounted,ref,watch, getCurrentInstance } from 'vue';
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { DirtionmaryHelper } from 'src/config/dictionary'
import scheduledTripService from 'src/api/scheduledTrip'
import { ApiResult } from 'src/@types/enumHelper'
import message from 'src/utils/message'
import { groupBy } from 'src/utils/tools'
export default defineComponent({
components: { },
props: ["trip"],
setup(props) {
const $router = useRouter()
const { t } = useI18n()
const $q = useQuasar()
const qDateProxy = ref(null) as any
let {ctx:that, proxy} = getCurrentInstance()
const data= reactive({
traffic: "",
stars:['一星酒店','二星酒店','三星酒店','四星酒店','五星酒店','六星酒店','七星酒店','民宿','溫泉酒店'],
hotel:'',
team: '',
dinner: '',
trip: props.trip
})
const methods = {
formatTeam(){
let p = data.trip.priceList[0]
let t = p.priceTeamType??1
t=t==0?1:t
if(t==1){
data.team = `${p.seat}人團隊散拼`
}else{
data.team = '一单一团'
}
},
formatDinner(){
let d = []
data.trip.dinnerList.forEach(x=>{
if(x.dinnerName.indexOf('自理')==-1 && x.dinnerName.indexOf('请选择')==-1){
d.push(x)
}
})
if(d && d.length>0){
let g=groupBy(d,x=>{ return x.useDinnerType})
let t = ['早餐','午餐','晚餐']
g.forEach(x=>{
data.dinner+=`${x.data.length}次 ${t[parseInt(x.key)-1]};`
})
}else{
data.dinner = '無餐食供應'
}
},
formatTraffic() {
let z = data.trip.trafficList[0].subTraffic[0]
if (z&&z.arrivalType == 1) {
data.traffic = '飛機往返';
} else if (z&&z.arrivalType == 2) {
data.traffic = '巴士往返';
} else if (z&&z.arrivalType == 3) {
data.traffic = '郵輪往返';
} else {
data.traffic = '高鐵往返';
}
},
formatHotel(){
let h = []
data.trip.hotelList.forEach(x=>{
if(h.findIndex(y=>y.dayNum==x.dayNum)==-1){
h.push(x)
}
})
if(h && h.length>0){
let g = groupBy(h,(x)=>{return x.star})
g.forEach(x=>{
data.hotel+=`${x.data.length}晚${data.stars[parseInt(x.key)-1]};`
})
}
}
}
methods.formatTraffic()
methods.formatHotel()
methods.formatTeam()
methods.formatDinner()
return {
...toRefs(data),
...methods,
}
}
})
</script>
<style></style>
<style>
.Style_main_Top {
height: 460px;
overflow: hidden;
}
.Style_main_Top .detOne_top {
display: inline-block;
width: calc(100% + 20px);
height: 100%;
margin-left: -10px;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
z-index: 0;
filter: blur(5px);
}
.Style_main_Top .detOneModel {
position: absolute;
left: 0;
top: 0;
display: inline-block;
z-index: 2;
width: 50%;
height: 450px;
float: left;
text-align: center;
}
.detOneModel label {
position: relative;
display: inline-block;
width: 400px;
height: 100%;
background-color: rgba(255, 255, 255, .55);
padding: 60px 40px 40px;
text-align: left;
}
.detOneModel>* {
display: inline-block;
letter-spacing: 2px;
}
.Style_main_Top .main-title {
font-size: 55px;
font-weight: bold;
color: #000;
/* -webkit-writing-mode: vertical-lr;
writing-mode: vertical-lr; */
height: 100%;
width:82px;
display:inline-block;
word-wrap: break-word;
line-height: 55px;
}
.Style_main_Top .sub-title {
font-size: 24px;
font-weight: lighter;
/* padding-top: 74px; */
/* -webkit-writing-mode: vertical-lr;
writing-mode: vertical-lr; */
height: 100%;
display: inline-block;
width:36px;
word-wrap: break-word;
position: absolute;
top:85px;
}
@media only screen and (max-width: 768px) {
.Style_main_Top .detOneModel {
width: 100%;
height: 280px;
top:80px;
}
.Style_main_Top .main-title{
font-size:30px;
width:36px;
line-height: 30px;
position:absolute;
top:40px;
}
.Style_main_Top .sub-title{
font-size:15px;
width:22px;
position: absolute;
top: 65px;
left: 80px;
}
.detOneModel label {
width: 100%;
padding-top: 50px;
}
}
</style>
<template>
<div class="Style_main_Top">
<div class="detOne_top" v-if="imgCover.length>0"
:style="{backgroundImage:'url('+imgCover[0].Url+')'}">
</div>
<div class="detOneModel">
<label>
<span class="main-title">{{dataList.countryName}}</span>
<span class="sub-title">{{dataList.placeName}}</span>
</label>
</div>
</div>
</template>
<script>
import { reactive, toRefs, defineComponent } from 'vue';
import { useI18n } from 'vue-i18n'
export default defineComponent({
components: { },
props: ['dataList'],
setup(props) {
const { t } = useI18n()
const data= reactive({
imgCover:[],
dataList: props.dataList
})
const methods = {
}
data.imgCover = JSON.parse(data.dataList.imgCover);
return {
...toRefs(data),
...methods,
}
}
})
</script>
<style>
.Style2_main {
position: relative;
margin-top: -10px;
padding: 40px 0;
background-color: #fff;
border-bottom: 1px solid #e5e5e5;
z-index: 3;
}
.Style2_main .wl-section-block {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
display: flex;
}
.Style2_main .wl-section-block>* {
flex: 1;
}
.Style2_main .tour-intro {
padding:0 30px;
}
.Style2_main .tour_Nmae {
margin-bottom: 10px;
font-size: 24px;
font-weight: bold;
}
.Style2_main .drop-wrap {
position: relative;
margin-bottom: 10px;
display: inline-block;
vertical-align: middle;
}
.drop-wrap a,
.print_box {
margin-right: 10px;
margin-bottom: 10px;
display: inline-block;
font-size: 14px;
color: #006be2;
padding: 4px 8px;
transition: .15s ease-in;
}
.Style2_main .tour-detail-list {
padding: 0 0 20px;
font-size: 16px;
color: #999;
list-style: none;
}
.Style2_main .tour-detail-list li {
line-height: 2;
}
.Style2_main .tour-cover2 img {
width: 100%;
height: auto;
}
@media only screen and (max-width: 768px) {
.Style2_main .wl-section-block {
padding: 0;
display: block;
}
.Style2_main {
padding: 0;
}
}
</style>
<template>
<div class="Style2_main">
<div class="wl-section-block">
<div class="tour-cover2" v-if="imgCover.length>0">
<div class="q-pa-md">
<q-carousel
animated
v-model="slide"
navigation
height="400px"
infinite
autoplay
transition-prev="slide-right"
transition-next="slide-left"
>
<q-carousel-slide v-for="(x, i) in imgCover" :name="i" :key="i" :img-src="x.Url" />
</q-carousel>
</div>
</div>
<div class="tour-intro">
<div class="tour_Nmae">{{dataList.title}}</div>
<div class="drop-wrap">
<a>分享</a>
<a class="print_box" @click="window.print()">打印</a>
</div>
<ul class="tour-detail-list">
<li>行程編號:
<template v-if="dataList.currentPriceInfo&&dataList.currentPriceInfo.tcnum">
{{dataList.currentPriceInfo.tcnum.toUpperCase()}}
</template></li>
<li>旅遊地點:{{dataList.countryName}}</li>
<li>旅遊天數:{{dataList.dayNum}}天</li>
<li>出團日期:
<template v-if="dataList.currentPriceInfo&&dataList.currentPriceInfo.startDate">
{{dataList.currentPriceInfo.startDate}}
</template>
</li>
<li style="margin-top:30px;">
<q-btn v-if="dataList.currentPriceInfo&&dataList.currentPriceInfo.tcnum" style="width:115px;" type="a" label="立即预定" color="primary" @click="buyNow()" />
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import { reactive, toRefs, defineComponent } from 'vue';
import { useI18n } from 'vue-i18n'
export default defineComponent({
components: { },
props: ['dataList'],
setup(props, context) {
const { t } = useI18n()
const data= reactive({
slide: 1,
imgCover: [],
dataList: props.dataList
})
const methods = {
buyNow(){
context.emit('showDialog')
}
}
data.imgCover = JSON.parse(data.dataList.imgCover);
return {
...toRefs(data),
...methods,
}
}
})
</script>
This diff is collapsed.
<style>
.wl-section-block {
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
.section-tour {
margin-bottom: 30px !important;
padding: 30px 30px 0;
border: 1px solid #e5e5e5;
background-color: #fff;
}
.section-tour .isHiden4 {
height: 450px;
overflow: hidden;
}
.toggle_down:before {
content: "";
width: 100%;
position: absolute;
top: -100px;
left: 0;
z-index: 2;
height: 100px;
background-image: -webkit-linear-gradient(-90deg, rgba(255, 255, 255, 0), #fff);
background-image: -moz-linear-gradient(-90deg, rgba(255, 255, 255, 0), #fff);
background-image: -o-linear-gradient(-90deg, rgba(255, 255, 255, 0), #fff);
background-image: linear-gradient(180deg, rgba(255, 255, 255, 0), #fff);
}
</style>
<template>
<div>
<section class="section-tour wl-section-block">
<div class="todayTitle">行程特色</div>
<div class="featureBox">
<template v-if="showType==3">
<div class="feature-inner" v-html="htmlData" :class="{'isHiden4':isShow}"></div>
</template>
<template v-if="showType>=4">
<div class="feature-inner" v-html="htmlData" :class="{'isHiden4':isShow}"></div>
</template>
<div class="collapse_toggle" v-if="!isShow">
<i class="iconfont iconarrow-top" @click="isShow=true"></i>
</div>
<div class="collapse_toggle toggle_down" v-else>
<i class="iconfont iconarrowdown" @click="isShow=false"></i>
</div>
</div>
</section>
</div>
</template>
<script>
import { reactive, toRefs, defineComponent } from 'vue';
import { useI18n } from 'vue-i18n'
import { GetHtml } from 'src/utils/tools'
export default defineComponent({
components: { },
props: ['dataList'],
setup(props) {
const { t } = useI18n()
const data= reactive({
TripConfig: {},
isShow: false,
showType:-1,
dataList: props.dataList,
htmlData: ''
})
const methods = {
}
if (localStorage.baseifo) {
data.TripConfig = JSON.parse(localStorage.getItem('baseifo'));
}
if (data.TripConfig.TripConfig.TripFeatureIsOpen == 1) {
data.isShow = false
} else {
data.isShow = true;
}
data.showType= data.dataList.feature.featureType;
if(data.dataList.feature.featureContent==3){
data.htmlData = GetHtml(data.dataList.feature.featureContent)
}
if(data.dataList.feature.featureContent>=4){
data.htmlData = GetHtml(data.dataList.feature.featureHtml)
}
return {
...toRefs(data),
...methods,
}
}
})
</script>
<style>
.wl-section-block {
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
.section-tour {
margin-bottom: 30px !important;
padding: 30px 30px 0;
border: 1px solid #e5e5e5;
background-color: #fff;
}
.style5_item_title {
padding: 20px 0;
text-align: center;
width: 100%;
}
.fee_title {
color: #333;
font-size: 18px;
font-family: PingFangR;
}
.fee_line {
text-align: center;
color: #ccc;
font-size: 12px;
width: 100%;
}
.fee_line {
width: 32px;
height: 2px;
background: #ee4454;
display: inline-block;
}
.expense {
/* display: flex; */
margin: 30px auto;
width: 100%;
}
.detail-box .expense .left {
width: 100%;
text-align: center;
font-size: 17px;
margin-bottom:20px;
font-family: PingFangR;
}
.detail-box .expense .right {
/* -webkit-box-flex: 1;
flex: 1; */
overflow: hidden;
font-size: 16px;
line-height: 25px;
color: #666;
text-align: left;
}
.section-tour .isHiden5 {
height: 450px;
overflow: hidden;
}
.toggle_down:before {
content: "";
width: 100%;
position: absolute;
top: -100px;
left: 0;
z-index: 2;
height: 100px;
background-image: -webkit-linear-gradient(-90deg, rgba(255, 255, 255, 0), #fff);
background-image: -moz-linear-gradient(-90deg, rgba(255, 255, 255, 0), #fff);
background-image: -o-linear-gradient(-90deg, rgba(255, 255, 255, 0), #fff);
background-image: linear-gradient(180deg, rgba(255, 255, 255, 0), #fff);
}
</style>
<template>
<div>
<section class="section-tour wl-section-block">
<div class="style5_item_title detail-box">
<div :class="{'isHiden5':isShow}">
<div class="fee_title">费用</div>
<div class="fee_line">
<small class="s"></small>
</div>
<div style="color:#ccc">Expense</div>
<div class="expense">
<div class="left">费用包含</div>
<div class="right">
<div v-html="htmlData1"></div>
</div>
</div>
<div class="expense">
<div class="left">自理费用</div>
<div class="right">
<div v-html="htmlData2"></div>
</div>
</div>
<div class="fee_title">购物说明</div>
<div class="fee_line">
<small class="s"></small>
</div>
<div style="color:#ccc">Expense</div>
<div class="expense">
<div class="left"></div>
<div class="right">
<div v-html="htmlData3"></div>
</div>
</div>
<div class="fee_title">预订须知</div>
<div class="fee_line">
<small class="s"></small>
</div>
<div style="color:#ccc">Tips</div>
<div class="expense">
<div class="left">重要提示</div>
<div class="right">
<div v-html="htmlData4"></div>
</div>
</div>
<div class="expense">
<div class="left">温馨提示</div>
<div class="right">
<div v-html="htmlData5"></div>
</div>
</div>
<div class="fee_title">签证</div>
<div class="fee_line">
<small class="s"></small>
</div>
<div style="color:#ccc">Visa</div>
<div class="expense">
<div class="left">签证须知</div>
<div class="right">
<div v-html="dataList.feature.visaRemark"></div>
</div>
</div>
<div class="fee_title">同行备注</div>
<div class="fee_line">
<small class="s"></small>
</div>
<div style="color:#ccc">Remark</div>
<div class="expense">
<div class="left"></div>
<div class="right">
<div v-html="dataList.feature.b2BRemark"></div>
</div>
</div>
</div>
<div class="collapse_toggle" v-if="!isShow">
<i class="iconfont iconarrow-top" @click="isShow=true"></i>
</div>
<div class="collapse_toggle toggle_down" v-else>
<i class="iconfont iconarrowdown" @click="isShow=false"></i>
</div>
</div>
</section>
</div>
</template>
<script>
import { reactive, toRefs, defineComponent, } from 'vue';
import { useI18n } from 'vue-i18n'
import { GetHtml } from 'src/utils/tools'
export default defineComponent({
components: { },
props: ['dataList'],
setup(props) {
const { t } = useI18n()
const data= reactive({
TripConfig: {},
isShow: false,
dataList: props.dataList,
htmlData1: '',
htmlData2: '',
htmlData3: '',
htmlData4: '',
htmlData5: '',
})
const methods = {
}
if (localStorage.baseifo) {
data.TripConfig = JSON.parse(localStorage.getItem('baseifo'));
}
if (data.TripConfig.TripConfig.NoticeItemIsOpen == 1) {
data.isShow = false;
} else {
data.isShow = true;
}
data.htmlData1 = GetHtml(data.dataList.feature.feeInclude)
data.htmlData2 = GetHtml(data.dataList.feature.feeNonInclude)
data.htmlData3 = GetHtml(data.dataList.feature.shopRemark)
data.htmlData4 = GetHtml(data.dataList.feature.importantTip)
data.htmlData5 = GetHtml(data.dataList.feature.warmTip)
return {
...toRefs(data),
...methods,
}
}
})
</script>
This diff is collapsed.
<template>
<div class="q-mt-lg">
<div class="text-subtitle1 text-weight-bold row items-center">
<span class="col">每日行程</span>
<span class="">
<q-chip class="bg-transparent text-weight-light text-grey-7 f12" icon="iconfont icontime" :label="`行程時間:${trip.dayList.length}天`" />
</span>
</div>
<q-tabs
v-model="displayType"
class="text-dark q-mt-md"
align="left"
:breakpoint="20"
inline-label
active-class="text-primary"
dense
>
<q-tab name="image" @click="changeHandler()" icon="iconfont iconimage" class="no-padding q-mr-lg" label="圖文模式" />
<q-tab name="dates" @click="changeHandler()" icon="iconfont iconrili" class="no-padding q-mr-lg" label="日曆模式" />
</q-tabs>
<list :days="trip.dayList" v-if="displayType=='image'"></list>
<calendar :days="trip.dayList" v-if="displayType=='dates'"></calendar>
</div>
</template>
<script lang="ts">
import { reactive, toRefs, defineComponent,ref,watch } from 'vue';
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import calendar from './tripView/calendar.vue'
import list from './tripView/list.vue'
export default defineComponent({
components: { list, calendar },
props: ['trip'],
setup(props, context) {
const { t } = useI18n()
const data= reactive({
trip: props.trip,
displayType: 'image'
})
watch(() => props.trip,(n,o) => {
data.trip = n;
},{deep: true}
)
const methods = {
changeHandler(){
// data.displayType =
context.emit('change')
}
}
return {
...toRefs(data),
...methods,
}
}
})
</script>
<style>
</style>
<template>
<div class="q-mt-lg q-mb-lg">
<div class="section-block download1">
<!-- <div class="group-title">{{plugData.Title}}</div> -->
<q-table v-if="plugData&&plugData.length>0 && !$q.screen.xs" :pagination.sync="paginationDesktop" :data="plugData"
:columns="columns" row-key="id" :filter="filter" table-header-class="travel-list" card-class="travel-list"
:pagination-label="formatLabel" rows-per-page-label=" " :rows-per-page-options="[]" TCNUM-data-labe="沒有找到適合的團期">
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="startDate" :props="props">
<span class="text-red">{{ props.row.startDate }}</span>
</q-td>
<q-td key="title" :props="props">
<div style="max-width:435px;white-space: pre-wrap;">
<a>{{ props.row.title }}</a>
</div>
</q-td>
<q-td key="dayNum" :props="props">{{ props.row.dayNum }}</q-td>
<q-td key="FlightStatus" :props="props">
<q-icon color="grey" name="iconfont iconhangbanxinxicopy" class="cursor-pointer" size="14">
<q-popup-proxy :offset="[260, 3]">
<q-banner class="bg-black text-white">
<table class="tripDetails_table">
<tr>
<th>出發時間</th>
<th>抵達時間</th>
<th>出發地點</th>
<th>抵達地點</th>
<th>航空公司</th>
</tr>
<tr v-for="(item,index) in props.row.priceFlight" :key="index">
<td>{{item.startDate.substring(5).replace('-','/')}} {{item.departureTime}}</td>
<td>{{item.arriveDate.substring(5).replace('-','/')}} {{item.arrivalTime}}</td>
<td>{{item.departureAirPortName}}</td>
<td>{{item.arrivalAirPortName}}</td>
<td>{{item.alName}}</td>
</tr>
</table>
</q-banner>
</q-popup-proxy>
</q-icon>
</q-td>
<q-td key="b2BPrice" :props="props">
<span caption>$</span>
<span class="text-subtitle2 text-weight-medium">{{ props.row.b2BPrice }}</span>
</q-td>
<q-td key="totalSeat" :props="props">
<span>{{ props.row.totalSeat }}</span>
</q-td>
<q-td key="seat" :props="props">
<span>{{ props.row.seat }}</span>
</q-td>
<q-td key="isSubstitution" :props="props">
<span
:class="{'text-orange':props.row.seat>0,'text-pink':(props.row.seat==0 && props.row.isSubstitution),'text-red':(props.row.seat==0 && !props.row.isSubstitution)}">{{ props.row.seat>0?'有名額':(props.row.seat==0 && props.row.isSubstitution?'可候補':'名額已滿') }}</span>
</q-td>
<q-td key="tcid" :props="props">
<q-btn type="a" :label="props.row.seat>0||props.row.isSubstitution?'報名GO!':'無法預訂'"
:color="props.row.seat>0||props.row.isSubstitution?'indigo':'grey'" rounded unelevated
:disable="props.row.seat==0&&props.row.isSubstitution" @click="goSignUp(props.row.seat)" />
</q-td>
</q-tr>
</template>
</q-table>
<q-table :pagination.sync="pagination" v-if="plugData&&plugData.length>0 && $q.screen.xs" grid :data="plugData"
:columns="columns" row-key="id" :filter="filter" table-header-class="travel-list" card-class="travel-list"
:pagination-label="formatLabel" rows-per-page-label=" " :rows-per-page-options="[]" TCNUM-data-labe="沒有找到適合的團期">
<template v-slot:item="props">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 grid-style-transition">
<q-card class="q-mb-md q-pt-xs q-pb-xs" flat>
<q-list>
<q-item>
<q-item-section>
<q-item-label class="text-grey">出發日期</q-item-label>
<q-item-label class="text-red">{{props.row.startDate}}</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label class="text-grey">團體名稱</q-item-label>
<q-item-label>{{props.row.title}}</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label class="text-grey">天數</q-item-label>
<q-item-label>{{props.row.dayNum}}</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label class="text-grey">交通</q-item-label>
<q-item-label>
<!--v-if="props.row.FlightStatus"-->
<q-icon color="grey" name="iconfont iconhangbanxinxicopy" size="14" />
</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label class="text-grey">售價</q-item-label>
<q-item-label>
<span caption>$</span>
<span class="text-subtitle2 text-weight-medium">{{ props.row.b2BPrice }}</span>
<span></span>
</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label class="text-grey">狀態</q-item-label>
<q-item-label>
<span
:class="{'text-orange':props.row.seat>0,'text-pink':(props.row.seat==0 && props.row.isSubstitution),'text-red':(props.row.seat==0 && !props.row.isSubstitution)}">{{ props.row.seat>0?'有名額':(props.row.seat==0 && props.row.isSubstitution?'可候補':'名額已滿') }}</span>
</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-btn type="a" :label="props.row.seat>0||props.row.isSubstitution?'報名GO!':'無法預訂'"
:color="props.row.seat>0||props.row.isSubstitution?'indigo':'grey'" rounded unelevated
:disable="props.row.seat==0&&props.row.isSubstitution" @click="goSignUp(props.row.seat)" />
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</template>
</q-table>
</div>
</div>
</template>
<script>
export default {
props: ["plugData"],
data() {
return {
pagination: {
sortBy: "id",
descending: false,
page: 1,
rowsPerPage: 1
},
paginationDesktop: {
sortBy: "id",
descending: false,
page: 1,
rowsPerPage: 5
},
filter: "",
columns: [{
name: "startDate",
required: true,
label: "出發日期",
align: "left",
sortable: true
},
{
name: "title",
label: "團體名稱",
align: "left",
field: "title"
},
{
name: "dayNum",
label: "天數",
align: "left",
field: "dayNum"
},
{
name: "FlightStatus",
label: "交通",
align: "left",
field: "FlightStatus"
},
{
name: "b2BPrice",
label: "售價",
align: "left",
field: "b2BPrice"
},
{
name: "totalSeat",
label: "位數",
align: "left",
field: "totalSeat"
},
{
name: "seat",
label: "可報名",
align: "left",
field: "seat"
},
{
name: "isSubstitution",
label: "狀態",
align: "left",
field: "isSubstitution"
},
{
name: "tcid",
label: "報名",
align: "left",
field: "tcid"
}
],
};
},
methods: {
formatLabel(firstRowIndex, endRowIndex, totalRowsNumber) {
return "";
},
//报名
goSignUp(seat){
if(seat>0){
this.$emit('showDialog');
}
}
},
mounted() {
}
};
</script>
<style>
.my-th-head {
font-size: 18px !important;
font-weight: 600 !important;
}
.download1 .group-title {
margin: 0;
padding: 0;
line-height: unset;
margin-bottom: 20px;
font-size: 24px;
text-align: center;
font-weight: 600;
text-align: center;
}
.travel-list th {
font-size: 16px !important;
}
.travel-list td {
font-size: 14px !important;
}
.tripDetails_table td{
text-align:center;
padding:6px;
}
.tripDetails_table th{
width:100px;
}
</style>
<template>
<q-table data="days" :columns="cols" flat class="q-mt-md" hide-pagination>
<template v-slot:body-cell-day="props">
<q-td :props="props">
<div class="text-h6">{{ props.row.dayNum }}</div>
<div class="f12 text-grey-8">{{ props.row.title }}</div>
</q-td>
</template>
<template v-slot:body-cell-dinner="props">
<q-td :props="props">
<div class="f12 text-grey-8">早餐:</div>
<div class="f12 text-grey-8">{{ props.row.breakfast }}</div>
<div class="f12 text-grey-8 q-mt-sm">午餐:</div>
<div class="f12 text-grey-8">{{ props.row.lanuch }}</div>
<div class="f12 text-grey-8 q-mt-sm">晚餐:</div>
<div class="f12 text-grey-8">{{ props.row.dinner }}</div>
</q-td>
</template>
<template v-slot:body-cell-acitvity="props">
<q-td :props="props">
<div v-for="(x,i) in props.row.activity" :key="i" >
<q-chip class="bg-transparent" text-color="blue" dense :label="x.n" v-if="x.t==1" />
<q-chip class="bg-transparent" text-color="dark" dense :label="x.n" v-if="x.t==2"/>
</div>
</q-td>
</template>
<template v-slot:body-cell-hotel="props">
<q-td :props="props">
<div v-for="(x,i) in props.row.hotel" :key="i" class="row items-center" >
<q-chip class="bg-transparent" text-color="blue" dense :label="x.n" />
<span class="q-ml-sm">{{ x.t==0?'保證入住':'或同級別酒店' }}</span>
</div>
<div class="q-mt-sm" v-if="props.row.tips">{{ props.row.tips }}</div>
</q-td>
</template>
</q-table>
</template>
<script lang="ts">
import { date,useQuasar } from "quasar";
import { reactive, toRefs, defineComponent,ref,watch,getCurrentInstance } from 'vue';
import { useI18n } from 'vue-i18n'
export default defineComponent({
components: { },
props: ['days'],
setup(props) {
const { t } = useI18n()
const $q = useQuasar()
const qDateProxy = ref(null) as any
let {ctx:that, proxy} = getCurrentInstance()
const data= reactive({
cols: [
{ name: "day", label: "行程", align: "left",style:'vertical-align:top;' },
{ name: "dinner", label: "用餐", align: "left",style:'vertical-align:top;' },
{ name: "acitvity", label: "景点/场馆&活动", align: "left",style:'vertical-align:top;' },
{ name: "hotel", label: "酒店", align: "left",style:'vertical-align:top;' },
],
days: props.days,
d: props.days
})
watch(() => props.days,(n,o) => {
data.days = props.days
data.d = n;
},{deep: true}
)
const methods = {
formatDay() {
if (data.d.length > 0) {
data.d.forEach((x) => {
x.breakfast='不含餐'
x.lanuch='不含餐'
x.dinner='不含餐'
x.activity=[]
x.hotel=[]
x.tips=''
x.dayArray.forEach((y) => {
if (y.type == 7) {
x.title = y.childItem.title;
} else if (y.type == 1&&y.childItem.subTraffic[0]&&y.childItem.subTraffic[0].startTime) {
y.subtitle =
y.childItem.subTraffic[0].startTime +
" - " +
y.childItem.subTraffic[y.childItem.subTraffic.length - 1]
.endTime;
y.title = methods.formatTraffice(y.childItem.subTraffic);
y.icon = "iconfont iconjiaotong";
} else if (y.type == 4) {
if(y.childItem.dinnerName.indexOf('自理')==-1 && y.childItem.dinnerName.indexOf('请选择')==-1){
if(y.childItem.useDinnerType=='1'){
x.breakfast =x.breakfast=='不含餐'?y.childItem.dinnerName:x.breakfast+','+y.childItem.dinnerName
} else if(y.childItem.useDinnerType=='2'){
x.lanuch =x.lanuch=='不含餐'?y.childItem.dinnerName:x.lanuch+','+y.childItem.dinnerName
} else if(y.childItem.useDinnerType=='3'){
x.dinner =x.dinner=='不含餐'?y.childItem.dinnerName:x.dinner+','+y.childItem.dinnerName
}
}
} else if (y.type == 2) {
x.activity.push({
t:1,
n:y.childItem.couponsName
})
} else if (y.type == 5) {
x.activity.push({
t:2,
n:'自由活動'
})
} else if (y.type == 3) {
x.hotel.push({n:y.childItem.hotelName,t:y.childItem.IsSameLevel})
} else if (y.type == 6) {
x.tips = y.childItem.descriptionText??''
}
});
});
}
},
formatTraffice(tras) {
let txt = "從" + tras[0].startCityName;
tras.forEach((z, i) => {
if (i > 0) {
txt = ";再";
}
if (z.arrivalType == 1) {
txt += "搭乘航班";
} else if (z.arrivalType == 2) {
txt += "乘坐豪華巴士";
} else if (z.arrivalType == 3) {
txt += "乘坐豪華郵輪";
} else {
txt += "乘坐高鐵";
}
txt += " 到達" + z.arrivalCityName;
});
return txt;
},
}
methods.formatDay();
return {
...toRefs(data),
...methods,
}
}
})
</script>
<style></style>
This diff is collapsed.
This diff is collapsed.
...@@ -88,5 +88,10 @@ class DirtionmaryHelper { ...@@ -88,5 +88,10 @@ class DirtionmaryHelper {
* 門票列表參數 * 門票列表參數
*/ */
static readonly TICKET_QUERY_PARAM = "ticketlistquery" static readonly TICKET_QUERY_PARAM = "ticketlistquery"
/**
* 元素滚动參數
*/
static readonly SCROLL_AREA_OBJ = "scrollareaobj"
} }
export { userDictionmary,DirtionmaryHelper } export { userDictionmary,DirtionmaryHelper }
...@@ -345,6 +345,11 @@ export default { ...@@ -345,6 +345,11 @@ export default {
second: '門票檢索', second: '門票檢索',
three: '門票訂單' three: '門票訂單'
}, },
stroke: {
first: '預訂行程',
second: '行程檢索',
three: '行程預訂'
},
finance: { finance: {
first: '帳單', first: '帳單',
second: '月度請求書', second: '月度請求書',
...@@ -1074,7 +1079,39 @@ export default { ...@@ -1074,7 +1079,39 @@ export default {
c14: '輸入手提行李数', c14: '輸入手提行李数',
c15: '輸入托运行李数', c15: '輸入托运行李数',
} }
} },
}, },
//#endregion //#endregion
//#region ending v1.0.3
v103: {
scheduledTrip:{
pageTitle: '行程檢索',
screeningtitle: '篩選目的地',
searchinput: '搜尋目的地',
allcommoditytype: '所有商品類別',
screeningdate: '篩選出發日期',
screeningprice: '價錢篩選',
journeytime: '旅程時間',
experiencetrip: '項體驗行程',
sort: '排序',
quickconfirmation: '急速確認',
residualvacancy: '剩餘空位',
daysoftravel: '行程天數',
day: '天',
above: '天以上',
recommend: '強力推薦',
ascendingorder: '價格:低到高',
descendingorder: '價格:高到低',
sightseeingitinerary: '觀光行程',
daytrip: '半/一日遊',
multiday: '多日遊',
interval: '價格區間的最低價格不能低於最大價格',
},
details:{
since: '起',
selectionscheme: '選擇方案'
}
}
//#endregion
} }
<template> <template>
<q-layout view="lHh lpr lFf" style="background: #f5f8fa"> <q-layout view="lHh lpr lFf" style="background: #f5f8fa">
<q-header reveal class="bg-white text-white q-px-md q-py-sm"> <q-header reveal class="bg-white text-white q-px-md q-py-sm">
<q-toolbar> <q-toolbar>
...@@ -44,8 +45,8 @@ ...@@ -44,8 +45,8 @@
</q-scroll-area> </q-scroll-area>
</q-drawer> </q-drawer>
<q-page-container class="window-height"> <q-page-container class="window-height" id="scrollId">
<q-scroll-area :thumb-style="scrollStyle.thumbStyle" :bar-style="scrollStyle.barStyle" class="full-height"> <q-scroll-area ref="scrollAreaRef" :thumb-style="scrollStyle.thumbStyle" :bar-style="scrollStyle.barStyle" class="full-height">
<router-view /> <router-view />
</q-scroll-area> </q-scroll-area>
</q-page-container> </q-page-container>
...@@ -61,7 +62,7 @@ ...@@ -61,7 +62,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { inject, provide, reactive, ref, toRefs, onMounted, computed } from 'vue' import { inject, provide, reactive, ref, toRefs, onMounted, computed,watch,nextTick } from 'vue'
import { getStoreGetter } from '../store/utils' import { getStoreGetter } from '../store/utils'
import { UserGetter } from '../store/modules/user/getters' import { UserGetter } from '../store/modules/user/getters'
import svgIcon from '../components/global/svg-icon.vue' import svgIcon from '../components/global/svg-icon.vue'
...@@ -72,18 +73,25 @@ import Notifications from "../components/layout/Notifications.vue"; ...@@ -72,18 +73,25 @@ import Notifications from "../components/layout/Notifications.vue";
import { DirtionmaryHelper } from '../config/dictionary' import { DirtionmaryHelper } from '../config/dictionary'
import { env } from 'process' import { env } from 'process'
import { AppConfig } from 'src/config/app' import { AppConfig } from 'src/config/app'
import scheduledTripService from 'src/api/scheduledTrip'
import Store from '../store'
import { ApiResult } from 'src/@types/enumHelper'
import message from 'src/utils/message'
export default { export default {
components: { svgIcon, Navs,userInfo,Notifications }, components: { svgIcon, Navs,userInfo,Notifications },
setup() { setup() {
const leftDrawerOpen = ref(false) const leftDrawerOpen = ref(false)
const data = reactive({ const data = reactive({
userInfo: {} as any, userInfo: {} as any,
leftDrawerOpen: false, leftDrawerOpen: false,
scrollStyle: {} as any, scrollStyle: {} as any,
timer: 0, timer: 0,
isDadge: true, isDadge: true,
version:'' version:'',
}) })
const childPageTitle = ref('') const childPageTitle = ref('')
provide(DirtionmaryHelper.PAGE_TITLE_KEY ,childPageTitle) provide(DirtionmaryHelper.PAGE_TITLE_KEY ,childPageTitle)
const activeMenu=ref(0) const activeMenu=ref(0)
...@@ -93,14 +101,47 @@ export default { ...@@ -93,14 +101,47 @@ export default {
// //console.log(getStoreGetter<UserGetter>('user', 'getUser'),'....') // //console.log(getStoreGetter<UserGetter>('user', 'getUser'),'....')
// return getStoreGetter<UserGetter>('user', 'getUser') // return getStoreGetter<UserGetter>('user', 'getUser')
// }) // })
data.scrollStyle = useScrollModule().scrollStyle data.scrollStyle = useScrollModule().scrollStyle
const scrollAreaRef = ref()
const scrollArea = reactive({
pagesTop: 0
})
// 储存滚动位置
provide(DirtionmaryHelper.SCROLL_AREA_OBJ, scrollArea)
watch(() => scrollArea.pagesTop,(n,o) => {
scrollAreaRef.value.setScrollPosition('vertical', n, 100)
}
)
const methods = { const methods = {
toggleLeftDrawer() { toggleLeftDrawer() {
data.leftDrawerOpen = !data.leftDrawerOpen data.leftDrawerOpen = !data.leftDrawerOpen
}, },
//获取网站配置数据
getConfigData() {
scheduledTripService.GetWebSiteConfig({
RB_Group_Id: Store.state.user?.userDetail?.groupId,
B2BDomain: Store.state.user?.userDetail?.name
}).then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
if (r.data.data) {
var jsonData = JSON.stringify(r.data.data);
localStorage.setItem("baseifo", jsonData);
}
} else {
message.errorMsg(r.data.message)
}
}).catch(e => {
message.errorMsg(e.message)
})
},
} }
onMounted(()=>{ onMounted(()=>{
if(!localStorage.getItem('baseifo')){
methods.getConfigData()
}
setInterval(()=> { setInterval(()=> {
data.isDadge = false data.isDadge = false
setTimeout(()=>{ setTimeout(()=>{
...@@ -112,7 +153,9 @@ export default { ...@@ -112,7 +153,9 @@ export default {
return { return {
...toRefs(data), ...toRefs(data),
...methods, ...methods,
childPageTitle childPageTitle,
scrollAreaRef,
scrollArea
} }
} }
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -6,26 +6,35 @@ const routes: RouteRecordRaw[] = [ ...@@ -6,26 +6,35 @@ const routes: RouteRecordRaw[] = [
component: () => import('layouts/MainLayout.vue'), component: () => import('layouts/MainLayout.vue'),
children: [ children: [
{ path: '', component: () => import('pages/Index.vue') }, { path: '', component: () => import('pages/Index.vue') },
{ path: '/hotel', component: () => import('pages/hotel/HotelList.vue') },
{ path: '/hotel', component: () => import('pages/hotel/HotelList.vue') },//酒店
{ path: '/hotel/order/:orderId?', component: () => import('pages/hotel/HotelOrder.vue') }, { path: '/hotel/order/:orderId?', component: () => import('pages/hotel/HotelOrder.vue') },
{ path: '/hotel/modify/:orderId', component: () => import('pages/hotel/ModifyHotelOrder.vue') }, { path: '/hotel/modify/:orderId', component: () => import('pages/hotel/ModifyHotelOrder.vue') },
{ path: '/hotel/offer/:orderId', component: () => import('pages/hotel/ListOfQuotation.vue') }, { path: '/hotel/offer/:orderId', component: () => import('pages/hotel/ListOfQuotation.vue') },
{ path: '/personal', component: () => import('pages/personal/personal.vue') }, { path: '/personal', component: () => import('pages/personal/personal.vue') },
{ path: '/scattered', component: () => import('pages/scattered/HotelList.vue') },
{ path: '/scattered', component: () => import('pages/scattered/HotelList.vue') },//散客
{ path: '/scattered/HotelDetails/:hotelId/:groupBookingFlg/:lowrateBySetCurrency', component: () => import('pages/scattered/hotelDetails.vue') }, { path: '/scattered/HotelDetails/:hotelId/:groupBookingFlg/:lowrateBySetCurrency', component: () => import('pages/scattered/hotelDetails.vue') },
{ path: '/scattered/HotelSure/:hotelId/:roomOptionCd', component: () => import('pages/scattered/HotelSure.vue') }, { path: '/scattered/HotelSure/:hotelId/:roomOptionCd', component: () => import('pages/scattered/HotelSure.vue') },
{ path: '/scattered/HotelOrder', component: () => import('pages/scattered/HotelOrder.vue') }, { path: '/scattered/HotelOrder', component: () => import('pages/scattered/HotelOrder.vue') },
{ path: '/comingsoon', component: () => import('pages/ComingSoon.vue') }, { path: '/comingsoon', component: () => import('pages/ComingSoon.vue') },
{ path: '/ticket/list', component: () => import('pages/ticket/TicketList.vue') },
{ path: '/ticket/list', component: () => import('pages/ticket/TicketList.vue') },//门票
{ path: '/ticket/preview/:ticketId/:Time', component: () => import('pages/ticket/TicketOrderPreview.vue') }, { path: '/ticket/preview/:ticketId/:Time', component: () => import('pages/ticket/TicketOrderPreview.vue') },
{ path: '/ticket/order', component: () => import('pages/ticket/TicketOrder.vue') }, { path: '/ticket/order', component: () => import('pages/ticket/TicketOrder.vue') },
{ path: '/ticket/preview/:ticketId/:Time', component: () => import('pages/ticket/TicketOrderPreview.vue') },
{ path: '/ticket/order/:orderId?', component: () => import('pages/ticket/TicketOrder.vue') },
{ path: '/vehicle/index', component: () => import('pages/CharteredBus/CharteredBusList.vue') },//车辆 { path: '/vehicle/index', component: () => import('pages/CharteredBus/CharteredBusList.vue') },//车辆
{ path: '/vehicle/Preview/:ProductId/:Time/:orderId?', component: () => import('pages/CharteredBus/CharteredBusPreview.vue') }, { path: '/vehicle/Preview/:ProductId/:Time/:orderId?', component: () => import('pages/CharteredBus/CharteredBusPreview.vue') },
{ path: '/vehicle/order/:pages?', component: () => import('pages/vehicle/vehicleOrder.vue') },
{ path: '/vehicle/addEditVehicle/:Id?', component: () => import('pages/vehicle/addEditVehicle.vue') }, { path: '/vehicle/addEditVehicle/:Id?', component: () => import('pages/vehicle/addEditVehicle.vue') },
{ path: '/ticket/preview/:ticketId/:Time', component: () => import('pages/ticket/TicketOrderPreview.vue') }, { path: '/vehicle/order/:pages?', component: () => import('pages/vehicle/vehicleOrder.vue') },
{ path: '/ticket/order/:orderId?', component: () => import('pages/ticket/TicketOrder.vue') }
{ path: '/scheduledTrip/index', component: () => import('pages/scheduledTrip/scheduledTripList.vue') },//预定行程
{ path: '/scheduledTrip/details/:id/:tcid', component: () => import('pages/scheduledTrip/detailsNew.vue') },
] ]
}, },
{ {
......
...@@ -74,27 +74,42 @@ const useMenus = { ...@@ -74,27 +74,42 @@ const useMenus = {
} }
] ]
}), }),
menus.push({ menus.push({
name: t('menu.ticket.first'), name: t('menu.ticket.first'),
url: '', url: '',
id: 7, id: 7,
parentId: 0, parentId: 0,
icon: 'Shopping/Ticket.svg', icon: 'Shopping/Ticket.svg',
childs: [ childs: [
{ {
name: t('menu.ticket.second'), name: t('menu.ticket.second'),
url: '/ticket/list', url: '/ticket/list',
id: 8, id: 8,
parentId: 7, parentId: 7,
}, },
{ {
name: t('menu.ticket.three'), name: t('menu.ticket.three'),
url: '/ticket/order', url: '/ticket/order',
id: 9, id: 9,
parentId: 7, parentId: 7,
} }
] ]
}) })
menus.push({
name: t('menu.stroke.first'),
url: '',
id: 16,
parentId: 0,
icon: 'ScheduledTrip/stroke.svg',
childs: [
{
name: t('menu.stroke.second'),
url: '/scheduledTrip/index',
id: 17,
parentId: 16,
},
]
})
menus.push({ menus.push({
name: t('menu.finance.first'), name: t('menu.finance.first'),
url: '', url: '',
......
...@@ -17,6 +17,121 @@ export interface DateType{ ...@@ -17,6 +17,121 @@ export interface DateType{
text:string text:string
} }
/**
* @description 转化html
*/
export function GetHtml(str: string) {
if (str && str != "") {
return str.replace(/&lt;/g, '<').replace(/&gt;/g, '>')
.replace(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&apos;/g, "'");
}
return str;
}
/**
* @description 添加月份
*/
export function AddMonth(dateStr: string, month: any) {
var v = new Date(dateStr);
if (v) {
var t = new Date(v.getFullYear(), v.getMonth(), v.getDate(), v.getHours(), v.getMinutes(), v.getSeconds(), v.getMilliseconds());
t.setMonth(v.getMonth() + month);
if (t.getDate() != v.getDate()) {
t.setDate(0);
}
return t;
}
}
/**
* @description 格式化日期
*/
export function formatDate(year: string, month: any, day: any) {
var y = year;
var m = month;
if (m < 10) m = "0" + m;
var d = day;
if (d < 10) d = "0" + d;
return y + "-" + m + "-" + d;
}
/**
* @description 格式化日期二
*/
export function formatDate2(dateStr: string) {
var date = new Date(dateStr);
return {
CYear: date.getFullYear(),
CMonth: (date.getMonth() + 1),
CDay: date.getDate(),
}
}
/**
* @description 计算日期
*/
export function createCalendar(dateStr: any) {
var days = [];
var date:any;
if (dateStr) {
date = new Date(dateStr);
} else {
var now = new Date();
date = new Date(formatDate(String(now.getFullYear()), now.getMonth() + 1, 1));
}
var currentDay = date.getDate();
var currentYear = date.getFullYear();
var currentMonth = date.getMonth() + 1;
var currentWeek = date.getDay(); // 1...6,0
var str = formatDate(
currentYear,
currentMonth,
currentDay
);
days.length = 0;
// 当月第一天是周日,放在第一行第1个位置,前面0个
//初始化第一周
for (var i = currentWeek; i >= 0; i--) {
var d = new Date(str);
d.setDate(d.getDate() - i);
var dayobject = {} as any;
dayobject.day = d;
days.push(dayobject); //将日期放入data 中的days数组 供页面渲染使用
}
//其他周
var temp = 35;
if (
currentWeek +
new Date(currentYear, currentMonth, 0).getDate() > 35
) {
temp = 41;
}
for (var i: any = 1; i < temp - currentWeek; i++) {
var d = new Date(str);
d.setDate(d.getDate() + i);
var dayobject = {} as any;
dayobject.day = d;
days.push(dayobject);
}
return {
DayArray: days,
CurrentDay: currentDay,
CurrentMonth: currentMonth,
CurrentYear: currentYear,
CurrentWeek: currentWeek
};
}
/**
* @description 获取URL中参数
*/
export function getUrlKey(name: string, url: string) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(url) || [, ""])[1].replace(/\+/g, '%20')) || null
}
/** /**
* @description 计算距离天数 * @description 计算距离天数
*/ */
...@@ -186,7 +301,7 @@ export function moneyFormat (num:any, decimal = 2, split = ','):any { ...@@ -186,7 +301,7 @@ export function moneyFormat (num:any, decimal = 2, split = ','):any {
var res = '' var res = ''
var dotIndex = String(num).indexOf('.') var dotIndex = String(num).indexOf('.')
if (dotIndex === -1) { // 整数 if (dotIndex === -1) { // 整数
res = thousandFormat(String(num)) + '.' + '0'.repeat(decimal) res = thousandFormat(String(num)) + '' + '0'.repeat(decimal)
} else { } else {
const numStr = String((Math.round(num * Math.pow(10, decimal)) / Math.pow(10, decimal)).toFixed(decimal)) // 四舍五入,然后固定保留2位小数 const numStr = String((Math.round(num * Math.pow(10, decimal)) / Math.pow(10, decimal)).toFixed(decimal)) // 四舍五入,然后固定保留2位小数
const decimals = numStr.slice(dotIndex, dotIndex + decimal + 1) // 截取小数位 const decimals = numStr.slice(dotIndex, dotIndex + decimal + 1) // 截取小数位
......
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