Commit cc704727 authored by 罗超's avatar 罗超

完成訂單修改,並且修復BUG

parent 23ead798
......@@ -264,4 +264,13 @@ body
.q-dialog__inner--minimized>div
max-width: unset !important
.full-window
.q-dialog__inner--minimized
padding: unset !important
.q-dialog__inner--minimized>div
max-width: unset !important
max-height: unset !important
width: 100vw !important
height: 100vh !important
</style>
<template>
<div class="rounded-borders bg-white row items-center q-pa-md">
<q-icon name="navigate_before" size="36px" style="margin-left:-15px" v-close-popup />
<n-cascader v-if="$q.platform.is.desktop" class="col-2 no-border" @update:value="changearea" v-model:value="cascader.addressValue" size="large" :placeholder="$t('hotel.area')" clearable check-strategy="all" :options="provinces" value-field="ID" label-field="Name" remote :on-load="loadChilds" cascade />
<q-field v-if="$q.platform.is.desktop" stack-label :label="$t('daterange')" standout class="q-ml-lg col-2" style="min-width: 190px" dense>
<div class="self-center full-width no-outline" tabindex="0">{{ dateRangeFormat }}</div>
<div class="self-center full-width no-outline" tabindex="0">{{ search.StartDate }} - {{search.EndDate}}</div>
</q-field>
<n-select v-if="$q.platform.is.desktop" filterable @update:value="changeHotel" class="q-ml-lg col-2" style="min-width: 190px" clearable v-model:value="search.HotelChooseArray" :placeholder="$t('hotel.searchName')" multiple :options="cacheHotels" max-tag-count="responsive" size="large" value-field="ID" label-field="Name" />
<n-select v-if="$q.platform.is.desktop" filterable class="q-ml-lg col-2" style="min-width: 190px" clearable v-model:value="search.HotelChooseArray" :placeholder="$t('hotel.searchName')" multiple :options="cacheHotels" max-tag-count="responsive" size="large" value-field="ID" label-field="Name" />
<div class="col"></div>
<q-btn unelevated class="bg-grey-3 hover" :title="$t('morequery')">
<q-badge rounded class="din bg-red-2 text-red-14 text-weight-bold" floating :label="searchCnt" v-if="searchCnt > 0" />
......@@ -40,7 +41,7 @@
<script lang="ts">
import svgIcon from '../../global/svg-icon.vue'
import { computed, inject, provide, reactive, ref, toRefs, defineComponent, onMounted, watch } from 'vue'
import { computed, inject, reactive, toRefs, defineComponent } from 'vue'
import HotelService from '../../../api/hotel'
import message from '../../../utils/message'
import { ApiResult } from '../../../@types/enumHelper'
......@@ -54,10 +55,7 @@ export default defineComponent({
components: { svgIcon },
setup() {
const $q = useQuasar()
const qDateProxy = ref(null) as any
const qNameProxy = ref(null) as any
const data = reactive({
rightCarOpen: false,
scrollStyle: {} as any,
addressParams: {
Id: '651'
......@@ -70,8 +68,6 @@ export default defineComponent({
loading: false,
cacheHotels: [] as Array<any>,
hotelsRates: [] as Array<HotelRate>,
canHide: false,
HotelLength: 0
})
data.scrollStyle = useScrollModule().scrollStyle
const search = inject(DirtionmaryHelper.HOTEL_QUERY_PARAM) as any
......@@ -131,35 +127,20 @@ export default defineComponent({
})
})
},
dateRangeHandler(e: any) {
search.StartDate = `${e.from.year}/${e.from.month}/${e.from.day}`
search.EndDate = `${e.to.year}/${e.to.month}/${e.to.day} `
data.dateRangeFormat = `${search.StartDate} - ${search.EndDate} `
if (qDateProxy.value) qDateProxy.value.hide()
},
optionsFn(cd: any) {
return cd >= date.formatDate(date.addToDate(new Date(), { days: 15 }), 'YYYY/MM/DD')
},
changearea(e: number, option: any, pathValues: Array<any>) {
search.Province = 0
search.City = 0
try {
if (pathValues.length > 0) {
search.Province = pathValues[0].ID
}
if (pathValues.length > 1) {
search.City = pathValues[1].ID
}
},
changeHotel() {
setTimeout(() => {
console.log(search.HotelChooseArray)
}, 1000)
},
close(){
data.rightCarOpen = false
},
setSuccess(){
data.rightCarOpen = false
} catch (error) {}
}
}
const searchCnt = computed(() => {
......@@ -179,8 +160,6 @@ export default defineComponent({
return {
...toRefs(data),
...methods,
qDateProxy,
qNameProxy,
searchCnt,
search
}
......
<template>
<q-card flat bordered class="q-pa-md bg-white column" style="width:100vw;height: 80vh;">
<q-card flat bordered class="bg-white column" style="width:50vw;height: 70vh;">
<div style="height:72px;overflow:hidden;">
<chosen-header></chosen-header>
<div class="col q-mt-md" :class="{'light-shadow q-pa-md bg-white rounded-border':$q.platform.is.desktop}">
<chosen-table></chosen-table>
</div>
<div class="col" :class="{'light-shadow bg-white rounded-border':$q.platform.is.desktop}">
<chosen-table @finish="finishHandler"></chosen-table>
</div>
</q-card>
</template>
......@@ -13,12 +15,16 @@ import ChosenHeader from "./ChosenHeader.vue";
import ChosenTable from "./ChosenTable.vue";
export default defineComponent({
components: { ChosenHeader, ChosenTable },
setup(props) {
emits:["finish"],
setup(props,context) {
const data=reactive({})
const methods = {}
const methods = {
finishHandler(hotel:any){
context.emit('finish',hotel)
}
}
return {
...toRefs(data),
......
......@@ -17,11 +17,12 @@
<q-th v-for="(x, i) in cols">
{{ x }}
</q-th>
<q-th>{{$t('hotel.addRoomBtn')}}</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td>
<q-td style="width:200px">
<div class="ellipsis-3-lines" style="padding: 7px 16px;width: 200px;white-space: break-spaces;">{{ props.row.HotelName }}</div>
</q-td>
<q-td>
......@@ -29,7 +30,7 @@
<div class="td-item">{{ $t('hotel.table.ins') }}</div>
<div class="td-item">{{ $t('hotel.table.limit') }}</div>
</q-td>
<q-td v-for="x in props.row.subList" @click="showOrderSubmitHandler(props.row,x)">
<q-td v-for="x in props.row.subList">
<template v-if="x.PriceList && x.PriceList.length > 0">
<div class="td-item cursor-pointer" :class="[x.PriceList[0].ins.bg, x.PriceList[0].ins.color]">
{{ x.PriceList[0].CostPrice }}
......@@ -48,6 +49,9 @@
</span>
</div>
</q-td>
<q-td class="text-center" style="border-left:1px solid #eee;">
<q-btn color="primary" :label="$t('hotel.addRoom')" size="sm" outline @click="finishHanler(props.row)"/>
</q-td>
</q-tr>
</template>
<template v-slot:bottom>
......@@ -62,20 +66,35 @@
grid
:columns="mobileCols"
row-key="name"
card-class="no-shadow bg-primary text-white"
card-class="no-shadow bg-primary text-white col"
:pagination="pages"
:loading="loading"
@row-click="viewHotelPriceListHandler"
>
<template v-slot:item="props">
<div @click="viewHotelPriceListHandler(props.row)" class="rounded-borders bg-primary text-white col-12 q-mb-sm" style="padding: 12px;margin-left: 12px;margin-right: 12px; width: calc(100% - 24px);">
<div>
<div style="opacity: 0.54;font-weight: 500;font-size: 12px;margin-bottom: 4px;">{{$t('hotel.col.first')}}</div>
<div style="font-size: 13px;">{{props.row.HotelName}}</div>
</div>
<div class="q-my-md">
<div style="opacity: 0.54;font-weight: 500;font-size: 12px;margin-bottom: 4px;">{{$t('hotel.col.three')}}</div>
<div style="font-size: 13px;">{{props.row.TotalInventory}}</div>
</div>
<div>
<div style="opacity: 0.54;font-weight: 500;font-size: 12px;margin-bottom: 4px;">{{$t('hotel.col.four')}}</div>
<div class="row items-center justify-between">
<span>¥{{props.row.LowerPrice.toFixed(2)}}{{$t('hotel.col.low')}}</span>
<q-btn color="grey-3" :label="$t('hotel.addRoom')" size="sm" outline @click="finishHanler(props.row)"/>
</div>
</div>
</div>
</template>
<template v-slot:bottom>
<q-pagination class="full-width justify-end" v-model="pages.pageIndex" color="primary" :max="pages.pageCount" :input="true" @update:model-value="changePageHandler" />
</template>
</q-table>
<q-dialog v-model="showPriceList">
<hotel-price-list :hotel="queryHotelObj" @update:model-value="showOrderSubmitHandler"></hotel-price-list>
</q-dialog>
<q-dialog v-model="showOrderPreview" persistent>
<TableOperation :HotelRow="orderSubmitObj" :hotelInfor="orderSubmitItemObj" @close="showOrderPreview = false"></TableOperation>
<hotel-price-list :hotel="queryHotelObj"></hotel-price-list>
</q-dialog>
</div>
</template>
......@@ -94,7 +113,8 @@ import SamplePriceList from '../list/SamplePriceList.vue'
export default defineComponent({
components: { HotelPriceList, SamplePriceList },
name: 'list-table',
setup() {
emits:['finish'],
setup(props,context) {
const $q=useQuasar()
const { t } = useI18n()
const search = inject(DirtionmaryHelper.HOTEL_QUERY_PARAM) as any
......@@ -120,13 +140,10 @@ export default defineComponent({
mobileCols:[
{name:'HotelName',label:t('hotel.col.first'),field:(row:any)=>row.HotelName},
{name:'TotalInventory',label:t('hotel.col.three'),field:(row:any)=>row.TotalInventory},
{name:'LowerPrice',label:t('hotel.col.four'),field:(row:any)=>${row.LowerPrice.toFixed(2)}${t('hotel.col.low')}`}
{name:'LowerPrice',label:t('hotel.col.four'),field:(row:any)=>row.LowerPrice}
],
showPriceList:false,
queryHotelObj:{},
orderSubmitObj:{} as any,
orderSubmitItemObj:{} as any,
showOrderPreview: false
queryHotelObj:{}
})
......@@ -196,19 +213,17 @@ export default defineComponent({
})
return lower
},
viewHotelPriceListHandler(e:any,row:any,index:number){
viewHotelPriceListHandler(row:any){
data.queryHotelObj = row
data.showPriceList = true
},
showOrderSubmitHandler(row:any,col:any){
data.orderSubmitObj = row
data.orderSubmitItemObj = col
data.showOrderPreview = true
finishHanler(hotel:any){
context.emit('finish',hotel)
}
}
methods.calcDateRangeCols()
methods.initHotels()
return { ...toRefs(data), ...methods }
return { ...toRefs(data), ...methods,search }
}
})
</script>
......
......@@ -36,7 +36,7 @@
<!-- <div class="q-ml-md" style="font-size: 12px; opacity: 0.5">{{ $t('hotel.col.more') }}</div> -->
</div>
</div>
<q-btn color="color" :label="$t('hotel.buy')" class="q-pa-none q-px-md" dense outline style="opacity: 0.5" @click="showOrderSubmitHandler(h,x)"/>
<q-btn color="color" v-if="!search.SearchByUpdate" :label="$t('hotel.buy')" class="q-pa-none q-px-md" dense outline style="opacity: 0.5" @click="showOrderSubmitHandler(h,x)"/>
</div>
<div class="row justify-between q-mt-md q-pa-sm rounded-borders" style="background:rgba(255,255,255,.3)" v-if="x.PriceList[0].room.length>0">
<div class="price-item q-ma-none" v-for="y in x.PriceList[0].room">
......@@ -78,6 +78,7 @@ export default defineComponent({
)
data.scrollStyle = useScrollModule().scrollStyle
const search = inject(DirtionmaryHelper.HOTEL_QUERY_PARAM) as any
const methods = {
showOrderSubmitHandler(row:any,col:any){
......@@ -121,7 +122,6 @@ export default defineComponent({
}
methods.setCurrentHotel(props.hotel)
const search = inject(DirtionmaryHelper.HOTEL_QUERY_PARAM) as any
return { ...toRefs(data), ...methods, search }
}
......
......@@ -21,7 +21,7 @@
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td>
<q-td style="width:200px">
<div class="ellipsis-3-lines" style="padding: 7px 16px;width: 200px;white-space: break-spaces;">{{ props.row.HotelName }}</div>
</q-td>
<q-td>
......
......@@ -199,7 +199,7 @@ export default defineComponent({
}
exists.Hotels.push(temp)
cars.value.sort((x:any,y:any)=>{
return new Date(x.Date).getDate()-new Date(y.Date).getDate()
return new Date(x.Date).getTime()-new Date(y.Date).getTime()
})
message.successMsg(t('success'))
editor.value={}
......
......@@ -3,15 +3,18 @@
<q-card class="light-shadow q-pa-md bg-white rounded-borders q-mb-md" flat v-for="x in orders">
<div class="row items-center desktop-only">
<div class="q-mr-md">
<q-btn :color="x.OrderType == 1 ? 'cyan' : 'negative'" unelevated disable size="sm" :label="`${x.OrderType == 1 ? $t('hotelorder.orderType.guest') : $t('hotelorder.orderType.tour')}`"></q-btn>
<q-btn :color="x.OrderType == 1 ? 'cyan' : 'negative'" unelevated disable size="sm"
:label="`${x.OrderType == 1 ? $t('hotelorder.orderType.guest') : $t('hotelorder.orderType.tour')}`"></q-btn>
</div>
<div class="f12 text-grey-6">{{ $t('hotelorder.search.orderNum') }}{{ x.OrderNo }}</div>
<div class="q-ml-md">
<q-btn color="dark" flat size="sm" :label="$t('hotelorder.copy')" v-if="copyId != x.OrderId" @click="setCopyHandler(x)" />
<q-btn color="dark" flat size="sm" :label="$t('hotelorder.copy')" v-if="copyId != x.OrderId"
@click="setCopyHandler(x)" />
<q-btn color="cyan" icon="check" outline size="sm" :label="$t('hotelorder.copyed')" v-else></q-btn>
</div>
<div class="col text-center f12 text-grey-6">
<span v-if="x.OrderType == 1">{{ $t('hotelorder.search.contactInfo') }}{{ x.ContactName }}/{{ x.ContactNumber }}</span>
<span v-if="x.OrderType == 1">{{ $t('hotelorder.search.contactInfo') }}{{ x.ContactName }}/{{ x.ContactNumber
}}</span>
<span v-else>{{ $t('hotelorder.search.tcNum') }}{{ x.TCNum }}</span>
</div>
<div class="f12 text-grey-6">{{ $t('hotelorder.createTime') }}{{ x.CreateTime }}</div>
......@@ -23,7 +26,9 @@
<div class="mobile-only">
<div class="row justify-between">
<div class="q-mr-md">
<q-btn :color="x.OrderType == 1 ? 'cyan' : 'negative'" unelevated disable size="sm" :label="`${x.OrderType == 1 ? $t('hotelorder.orderType.guest') : $t('hotelorder.orderType.tour')}`"></q-btn>
<q-btn :color="x.OrderType == 1 ? 'cyan' : 'negative'" unelevated disable size="sm"
:label="`${x.OrderType == 1 ? $t('hotelorder.orderType.guest') : $t('hotelorder.orderType.tour')}`">
</q-btn>
</div>
<div class="q-ml-md f12" :class="[x.typeInfo.Color]">
<q-icon :name="x.typeInfo.Icon" />
......@@ -34,12 +39,15 @@
<div class="row items-center justify-between">
<div class="f12 text-grey-6">{{ $t('hotelorder.search.orderNum') }}{{ x.OrderNo }}</div>
<div class="q-ml-md">
<q-btn color="dark" flat size="sm" :label="$t('hotelorder.copy')" v-if="copyId != x.OrderId" @click="setCopyHandler(x)" />
<q-btn color="dark" flat size="sm" :label="$t('hotelorder.copy')" v-if="copyId != x.OrderId"
@click="setCopyHandler(x)" />
<q-btn color="cyan" outline size="sm" :label="$t('hotelorder.copyed')" v-else></q-btn>
</div>
</div>
<div class="f12 text-grey-6">
<span v-if="x.OrderType == 1">{{ $t('hotelorder.search.contactInfo') }}{{ x.ContactName }}/{{ x.ContactNumber }}</span>
<span v-if="x.OrderType == 1">{{ $t('hotelorder.search.contactInfo') }}{{ x.ContactName }}/{{
x.ContactNumber
}}</span>
<span v-else>{{ $t('hotelorder.search.tcNum') }}{{ x.TCNum }}</span>
</div>
<div class="f12 text-grey-6">{{ $t('hotelorder.createTime') }}{{ x.CreateTime }}</div>
......@@ -47,7 +55,8 @@
</div>
<div class="q-mt-md row">
<q-table separator="cell" :hide-bottom="true" dense :rows="x.DetailList" bordered :columns="cols" class="sticky-rightrowspan-column-table light-border col no-shadow">
<q-table separator="cell" :pagination="{ rowsPerPage: 100 }" :hide-bottom="true" dense :rows="x.DetailList"
bordered :columns="cols" class="sticky-rightrowspan-column-table light-border col no-shadow">
<template v-slot:header-cell-Room="props">
<q-th :props="props">
<div class="row items-center">
......@@ -61,7 +70,8 @@
<q-td :props="props">
<div class="room-item f12 text-grey-6" v-for="x in props.row.RoomList">
<span class="q-mr-md"> {{ x.RoomInfo.TypeName }}: {{ x.Number }} {{ $t('unit.jian') }} </span>
<span class="q-mr-md"> {{ $t('hotelorder.people') }}: {{ x.PeopleNumber ?? 1 }} {{ $t('unit.ren') }} </span>
<span class="q-mr-md"> {{ $t('hotelorder.people') }}: {{ x.PeopleNumber ?? 1 }} {{ $t('unit.ren') }}
</span>
<span class="q-mr-md"> {{ $t('hotelorder.unitPrice') }}: {{ x.Unit_Price ?? 1 }} </span>
<span class="q-mr-md"> {{ $t('hotelorder.xj') }}: {{ x.Money ?? 1 }} </span>
</div>
......@@ -90,34 +100,44 @@
</template>
</q-table>
</div>
<div class="q-mt-md" v-if="x.OrderStatus != 3" :class="{ row: $q.platform.is.desktop, 'column reverse': $q.platform.is.mobile }">
<div class="pay row text-grey rounded-borders q-pa-md" v-if="$q.platform.is.desktop || ($q.platform.is.mobile && expendsOrderId == x.OrderId)" :class="{ 'bg-grey-2': $q.platform.is.mobile }">
<svg-icon color=" svg-red" icon="Code/Warning-1-circle.svg" :size="16" v-if="$q.platform.is.desktop"></svg-icon>
<div class="q-mt-md" v-if="x.OrderStatus != 3"
:class="{ row: $q.platform.is.desktop, 'column reverse': $q.platform.is.mobile }">
<div class="pay row text-grey rounded-borders q-pa-md"
v-if="$q.platform.is.desktop || ($q.platform.is.mobile && expendsOrderId == x.OrderId)"
:class="{ 'bg-grey-2': $q.platform.is.mobile }">
<svg-icon color=" svg-red" icon="Code/Warning-1-circle.svg" :size="16" v-if="$q.platform.is.desktop">
</svg-icon>
<div class="q-ml-sm">
<div class="q-mb-sm" v-if="x.CustomerPayType == 2 || x.CustomerPayType == 3">
<div class="f12">
{{$t('hotelorder.pay.t1')}}
<span class="text-orange">{{x.PaymentDate}}</span>
{{$t('hotelorder.pay.t11')}}
<span class="text-orange">{{x.FinalPaymentDate}}</span>
{{$t('hotelorder.pay.t12')}}
</div>
<q-btn dense outline color="accent" size="sm" class="q-mt-sm" :label="$t('hotelorder.payinfo')" @click="ViewPayment"></q-btn>
{{ $t('hotelorder.pay.t1') }}
<span class="text-orange">{{ x.PaymentDate }}</span>
{{ $t('hotelorder.pay.t11') }}
<span class="text-orange">{{ x.FinalPaymentDate }}</span>
{{ $t('hotelorder.pay.t12') }}
</div>
<q-btn dense outline color="accent" size="sm" class="q-mt-sm" :label="$t('hotelorder.payinfo')"
@click="ViewPayment"></q-btn>
<!-- <q-btn dense unelevated color="accent" size="sm" class="q-mt-sm q-ml-sm" :label="$t('hotelorder.sendpay')"></q-btn> -->
</div>
<div v-if="x.CustomerPayType == 1 || x.CustomerPayType == 3">
<div class="f12">
{{$t('hotelorder.pay.t2')}}
<span class="text-negative">{{x.UploadGuestDate }}</span>
{{$t('hotelorder.pay.t21')}}
{{ $t('hotelorder.pay.t2') }}
<span class="text-negative">{{ x.UploadGuestDate }}</span>
{{ $t('hotelorder.pay.t21') }}
</div>
<div class="row items-center f12 q-mt-sm">
<div class="text-accent q-mr-md" v-if="x.GuestFileList.length>0">{{x.GuestFileList[0].split('/').at(-1)}}</div>
<q-btn dense unelevated color="primary" size="sm" class="q-mr-sm" v-if="x.GuestFileList.length>0">
<a class="text-white" style="text-decoration:none" :href="x.GuestFileList[0]">{{$t('upload.down')}}</a>
<div class="text-accent q-mr-md" v-if="x.GuestFileList.length > 0">{{
x.GuestFileList[0].split('/').at(-1)
}}</div>
<q-btn dense unelevated color="primary" size="sm" class="q-mr-sm" v-if="x.GuestFileList.length > 0">
<a class="text-white" style="text-decoration: none" :href="x.GuestFileList[0]">{{ $t('upload.down')
}}</a>
</q-btn>
<n-upload class="col" :action="importFileUrl" @finish="handleFinish" @change="uploadHandleChange(x.OrderId)" file-list-style="display:none">
<q-btn dense outline color="primary" size="sm" :label="x.GuestFileList.length==0?$t('hotelorder.uploadGuest'):$t('upload.reload')"></q-btn>
<n-upload class="col" :action="importFileUrl" @finish="handleFinish"
@change="uploadHandleChange(x.OrderId)" file-list-style="display:none">
<q-btn dense outline color="primary" size="sm"
:label="x.GuestFileList.length == 0 ? $t('hotelorder.uploadGuest') : $t('upload.reload')"></q-btn>
</n-upload>
</div>
</div>
......@@ -128,10 +148,12 @@
<svg-icon color=" svg-red" icon="Code/Warning-1-circle.svg" :size="16"></svg-icon>
<span class="q-ml-sm">{{ $t('hotelorder.warn') }}</span>
</div>
<q-btn color="grey" @click="setShowWarnHander(x.OrderId)" dense size="sm" flat :label="expendsOrderId == x.OrderId ? $t('expends.off') : $t('expends.on')" />
<q-btn color="grey" @click="setShowWarnHander(x.OrderId)" dense size="sm" flat
:label="expendsOrderId == x.OrderId ? $t('expends.off') : $t('expends.on')" />
</div>
<div class="col desktop-only"></div>
<div class="rounded-borders bg-grey-2 q-pa-md" :class="{ 'q-mx-md': $q.platform.is.desktop, 'q-mt-md': $q.platform.is.mobile }">
<div class="rounded-borders bg-grey-2 q-pa-md"
:class="{ 'q-mx-md': $q.platform.is.desktop, 'q-mt-md': $q.platform.is.mobile }">
<div class="row items-center justify-between q-mb-sm q-pb-sm" style="border-bottom: 1px dashed #ddd">
<div class="f12 text-grey">{{ $t('hotelorder.orderMoney') }}</div>
<div class="dark q-ml-xl">
......@@ -140,7 +162,8 @@
<span class="f12">{{ $t('unit.jp') }}</span>
</div>
</div>
<div class="row items-center justify-between q-mb-sm q-pb-sm" style="border-bottom: 1px dashed #ddd" v-if="x.CustomerPayType == 1 || x.CustomerPayType == 3">
<div class="row items-center justify-between q-mb-sm q-pb-sm" style="border-bottom: 1px dashed #ddd"
v-if="x.CustomerPayType == 1 || x.CustomerPayType == 3">
<div class="f12 text-grey">{{ $t('hotelorder.payType.t1') }}</div>
<div class="dark">
<span class="f12">{{ moneyFormat(x.SelfPayMoney) }}</span>
......@@ -155,8 +178,10 @@
</div>
</div>
</div>
<div class="rounded-borders q-pa-sm justify-between" :class="{ column: $q.platform.is.desktop, 'row items-center': $q.platform.is.mobile, 'bg-green-1': x.OrderStatus != 1, 'bg-grey-2': x.OrderStatus == 1 }">
<q-list dense v-if="x.OrderStatus == 1" :class="{ 'row items-center justify-between full-width': $q.platform.is.mobile }">
<div class="rounded-borders q-pa-sm justify-between"
:class="{ column: $q.platform.is.desktop, 'row items-center': $q.platform.is.mobile, 'bg-green-1': x.OrderStatus != 1, 'bg-grey-2': x.OrderStatus == 1 }">
<q-list dense v-if="x.OrderStatus == 1"
:class="{ 'row items-center justify-between full-width': $q.platform.is.mobile }">
<q-item class="text-negative" clickable v-close-popup @click="cancelConfirmHandler(x.OrderId)">
<q-item-section>
<q-item-label>{{ $t('hotelorder.opera.cancel') }}</q-item-label>
......@@ -184,7 +209,8 @@
</div>
</q-card>
<q-card class="light-shadow q-pa-md bg-white rounded-borders q-mb-md" v-if="pages.pageCount > 0" flat>
<q-pagination class="full-width justify-end" v-model="pages.pageIndex" color="primary" :max="pages.pageCount" :input="true" @update:model-value="changePageHandler" />
<q-pagination class="full-width justify-end" v-model="pages.pageIndex" color="primary" :max="pages.pageCount"
:input="true" @update:model-value="changePageHandler" />
</q-card>
<q-inner-loading :showing="loading" :label="$t('loading')" label-class="text-grey-6 f12" />
</div>
......@@ -193,30 +219,29 @@
<div class="q-mt-md f12 text-grey-6">{{ $t('noneData') }}</div>
</div>
<q-dialog v-model="PaymentDialog">
<div class="rounded-borders bg-white q-px-lg q-pb-lg q-pt-lg" :style="{'width': $q.platform.is.desktop?'450px':'450px'}">
<div class="orderListDialog-title row justify-center q-pb-xs ">
<span class="text-weight-bold">{{$t('hotelorder.dialog.title')}}</span>
<q-icon class="orderListDialog-close text-grey" name="close" @click="PaymentDialog=false"></q-icon>
<div class="rounded-borders bg-white q-pb-lg q-pt-lg" style="width: 450px">
<div class="orderListDialog-title row justify-center q-pb-xs">
<span class="text-weight-bold">{{ $t('hotelorder.dialog.title') }}</span>
<q-icon class="orderListDialog-close text-grey" name="close" @click="PaymentDialog = false"></q-icon>
</div>
<div class="orderListDialog-bg column rounded-borders q-ma-lg q-py-lg q-px-lg">
<div class="orderListDialog-img">
<div class="row items-end q-pb-md">
<span class="text-grey-3">{{$t('hotelorder.dialog.AccountName')}}:</span>
<span class="text-weight-bold text-white" style="font-size: 18px;">張三</span>
</div>
<div class="row items-center justify-between q-pb-sm">
<div>
<span class="text-grey-3">{{$t('hotelorder.dialog.account')}}:</span>
<span class="text-cyan-12 text-weight-bold" style="font-size: 18px;">7489327279423</span>
<span class="text-grey-3">{{ $t('hotelorder.dialog.AccountName') }}:</span>
<span class="text-weight-bold text-white" style="font-size: 18px">張三</span>
</div>
<q-btn size="xs" color="cyan-12 q-ml-sm">
<span class="text-dark">{{$t('hotelorder.dialog.copy')}}</span></q-btn>
<div class="q-pb-sm" :class="{'row items-center justify-between':$q.platform.is.desktop}">
<div :class="{'q-mb-sm':$q.platform.is.mobile,'col':$q.platform.is.desktop}" >
<span class="text-grey-3">{{ $t('hotelorder.dialog.account') }}:</span>
<span class="text-cyan-12 text-weight-bold din" style="font-size: 18px">7489 3272 7942 311</span>
</div >
<q-btn :class="{'q-ml-xl':$q.platform.is.mobile}" unelevated size="xs" class="bg-blue-11 text-white" v-if="copyId != -1" :label="$t('hotelorder.dialog.copy')" @click="setCopyHandler(null,'開戶名:張三,帳戶:7489 3272 7942 311')"></q-btn>
<q-btn :class="{'q-ml-xl':$q.platform.is.mobile}" icon="check" unelevated size="xs" class="bg-blue-11 text-white" :label="$t('hotelorder.copyed')" v-else></q-btn>
</div>
</div>
</div>
<div class="row justify-center q-pb-lg q-px-lg q-mx-lg">
<span class="text-center text-grey-8 q-px-lg">{{$t('hotelorder.dialog.prompt')}}</span>
<div class="row justify-center q-pb-lg">
<span class="text-center f12 text-grey-6 q-px-lg">{{ $t('hotelorder.dialog.prompt') }}</span>
</div>
</div>
</q-dialog>
......@@ -232,7 +257,7 @@ import { RoomType, StandardStatus } from '../../../../@types'
import { getHotelOrderStatus, getHotelRoomType, moneyFormat } from '../../../../utils/tools'
import { useI18n } from 'vue-i18n'
import svgIcon from '../../../global/svg-icon.vue'
import { useQuasar } from 'quasar'
import { copyToClipboard, useQuasar } from 'quasar'
import { currentRouter } from '../../../../router'
import { UploadFileInfo } from 'naive-ui'
import { slice } from 'lodash'
......@@ -281,7 +306,7 @@ export default defineComponent({
})
const methods = {
ViewPayment(){
ViewPayment() {
data.PaymentDialog = true
},
initOrders() {
......@@ -341,8 +366,15 @@ export default defineComponent({
data.loading = false
})
},
setCopyHandler(order: any) {
setCopyHandler(order: any,ctx?:string) {
if(ctx){
data.copyId = -1
copyToClipboard(ctx)
}else{
data.copyId = order.OrderId
copyToClipboard(order.OrderNo)
}
setTimeout(() => {
data.copyId = 0
}, 2000)
......@@ -354,7 +386,7 @@ export default defineComponent({
data.pages.pageIndex = n
methods.initOrders()
},
uploadHandleChange(orderId:number) {
uploadHandleChange(orderId: number) {
data.uploadOrderId = orderId
data.loading = true
},
......@@ -370,32 +402,33 @@ export default defineComponent({
handleFinish(options: { file: UploadFileInfo; event?: ProgressEvent }) {
data.loading = false
let r = (options.event?.target as XMLHttpRequest).response
if(r){
let res=JSON.parse(r)
if(res.resultCode == ApiResult.SUCCESS && res.data){
if (r) {
let res = JSON.parse(r)
if (res.resultCode == ApiResult.SUCCESS && res.data) {
methods.setGuestListHandler(res.data)
}else{
} else {
message.errorMsg(t('upload.failed'))
data.loading=false
data.loading = false
}
}else{
} else {
message.errorMsg(t('upload.failed'))
data.loading=false
data.loading = false
}
},
setGuestListHandler(url:string){
HotelService.SetGuestFile(data.uploadOrderId,url).then(r=>{
if(r.data.resultCode == ApiResult.SUCCESS){
setGuestListHandler(url: string) {
HotelService.SetGuestFile(data.uploadOrderId, url)
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
message.successMsg(t('upload.success'))
let order = data.orders.find(x=>x.OrderId==data.uploadOrderId)
order.GuestFileList=[url]
}else{
let order = data.orders.find(x => x.OrderId == data.uploadOrderId)
order.GuestFileList = [url]
} else {
message.errorMsg(t('upload.failed'))
}
data.loading=false
}).catch(r=>{
data.loading=false
data.loading = false
})
.catch(r => {
data.loading = false
message.errorMsg(r.message)
})
}
......@@ -419,37 +452,45 @@ export default defineComponent({
.light-border table th {
border-color: #eee !important;
}
.light-border .room-item {
height: 28px;
line-height: 28px;
border-bottom: 1px solid #eee;
}
.light-border .room-item:last-child {
border-bottom: none;
}
.light-border .max-hotelname {
width: 140px;
height: 28px;
line-height: 28px;
}
.orderListDialog-title{
.orderListDialog-title {
position: relative;
}
.orderListDialog-title span{
.orderListDialog-title span {
font-size: 20px;
}
.orderListDialog-close{
.orderListDialog-close {
position: absolute;
right: 0;
top: -10px;
font-size: 26px;
}
.orderListDialog-bg{
background: #5098FF;
.orderListDialog-bg {
background: #5098ff;
border-radius: 10px;
}
.orderListDialog-img{
background: url('../../../../assets/images/wallet.png')no-repeat right #5098FF;
.orderListDialog-img {
background: url('../../../../assets/images/wallet.png') no-repeat right #5098ff;
background-size: 97px 100%;
}
</style>
......@@ -164,6 +164,11 @@ export default {
time: "h"
},
hotel: {
newDateOrder:'新日期預定',
newDateTips:'請先選擇需要預訂的日期',
newHotelBtn:'選擇酒店',
addRoomBtn:'操作',
addRoom:'選擇',
groupPrice:"合計",
pageTitle: "酒店檢索",
area: "檢索區域",
......
<template>
<div class="fix-height-subpage no-wrap q-pa-md" v-if="order">
<div class="q-py-sm q-px-md rounded-borders bg-white row items-center justify-between f12">
<div class="q-py-sm q-px-md rounded-borders bg-white f12" :class="{'row items-center justify-between':$q.platform.is.desktop,'colunm':$q.platform.is.mobile}">
<div class="f12 text-grey-6">{{ $t('hotelorder.search.orderNum') }}{{ order.OrderNo }}</div>
<div class="q-pa-sm rounded-border text-orange-10 f12">
<div class="rounded-border text-orange-10 f12" :class="{'q-pa-sm':$q.platform.is.desktop,'q-my-sm':$q.platform.is.mobile}">
{{ $t('hotel.car.title') }}
<span class="din text-orange-10">{{ order.DetailList.length }}</span>
{{ $t('hotel.car.title1') }}
<span class="din text-primary">{{ order.HotelCount }}</span>
{{ $t('hotel.car.title2') }}
</div>
<div class="q-ml-md f12" :class="[order.typeInfo.Color]">
<q-icon :name="order.typeInfo.Icon" />
<span class="q-ml-sm">{{ order.typeInfo.StatusName }}</span>
<div class="text-negative text-weight-bolder din">
<span class="text-weight-thin">{{$t('hotel.car.sumPrice')}}</span>
<span class="fz14">¥</span>
<span class="text-h6">{{ moneyFormat(order.Money) }}</span>
</div>
<div>
<div :class="{'text-right q-mt-sm':$q.platform.is.mobile}">
<q-btn color="negative" class="q-mr-sm" flat :label="$t('hotelm.cancel')" @click="cancelOrder" />
<q-btn color="primary" unelevated :label="$t('hotelm.save')" />
<q-btn color="primary" unelevated :label="$t('hotelm.save')" @click="saveOrderHandler" />
</div>
</div>
<div class="q-py-sm q-px-md rounded-borders bg-white row f12 q-mt-md">
<div class="f12 q-mb-sm text-grey-5" :class="{'col-12':$q.platform.is.desktop}">訂單信息</div>
<div :class="{'col-12':$q.platform.is.mobile}">
<n-select filterable v-model:value="order.OrderType" :placeholder="$t('hotel.car.OrderType')" :options="cacheHotels" max-tag-count="responsive" size="large" value-field="ID" label-field="Name" />
</div>
<div :class="{'col-12 q-my-md':$q.platform.is.mobile,'q-mx-md':$q.platform.is.desktop}" v-if="order.OrderType == 2">
<q-input v-model="order.TCNum" reverse-fill-mask dense standout :label="$t('hotel.car.inputText') + $t('hotel.car.TCNum')" ref="TCNumRef" :rules="$q.platform.is.desktop ? [val => !!val || $t('hotel.car.inputText') + $t('hotel.car.TCNum')] : [val => !!val || '']" />
</div>
<div :class="{'col-12 q-my-md':$q.platform.is.mobile,'q-mx-md':$q.platform.is.desktop}" v-if="order.OrderType == 1">
<q-input v-model="order.ContactName" reverse-fill-mask dense standout :label="$t('hotel.car.inputText') + $t('hotel.car.ContactName')" ref="ContactNameRef" :rules="$q.platform.is.desktop?[val => !!val || $t('hotel.car.inputText') + $t('hotel.car.ContactName')]:[val => !!val || '']" />
</div>
<div :class="{'col-12 q-mb-md':$q.platform.is.mobile,'q-mr-md':$q.platform.is.desktop}" v-if="order.OrderType == 1">
<q-input v-model="order.ContactNumber" reverse-fill-mask dense type="text" standout :label="$t('hotel.car.inputText') + $t('hotel.car.ContactNumber')" ref="ContactNumberRef" :rules="$q.platform.is.desktop?[val => !!val || $t('hotel.car.inputText') + $t('hotel.car.ContactNumber')]:[val => !!val || '']" />
</div>
<q-input :class="{'col-12':$q.platform.is.mobile,'col':$q.platform.is.desktop}" v-model="order.Remark" reverse-fill-mask dense filled type="text" :label="$t('hotel.car.Remark')" />
</div>
<div class="flex justify-start items-start content-start">
<div class="q-pa-sm rounded-borders bg-white q-mt-md q-mr-md" style="width: 320px" v-for="(x, xi) in order.DetailList">
<div class="q-pa-sm rounded-borders bg-white q-mt-md" :class="{'q-mr-md':$q.platform.is.desktop}" :style="{'width':$q.platform.is.mobile?'100%':'320px'}" v-for="(x, xi) in order.DetailList">
<div class="text-h6 row items-center">
<div class="col">{{ x.key }}</div>
<q-btn color="primary" icon="add" class="q-mr-md" rounded dense size="sm" flat />
<q-btn color="primary" icon="add" class="q-mr-md" rounded dense size="sm" flat @click="chosenNewHotel(x)" />
<q-btn color="negative" icon="delete" rounded dense size="sm" flat @click="removeHotelHandler(xi, -1)" />
</div>
<div class="q-pa-sm rounded-borders bg-blue-grey-1 q-mt-sm" v-for="(y, yi) in x.data">
......@@ -100,10 +118,29 @@
</div>
</div>
</div>
<div class="q-pa-sm rounded-borders bg-white q-mt-md" :class="{'q-mr-md':$q.platform.is.desktop,'q-mb-md':$q.platform.is.mobile}" :style="{'width':$q.platform.is.mobile?'100%':'320px'}">
<div class="text-h6 row items-center">
<div class="col">{{ $t('hotel.newDateOrder') }}</div>
<q-field :label="$t('daterange')" style="min-width: 120px" standout :model-value="tempHotels.key" class="col-2 text-dark" dense>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{ tempHotels.key }}</div>
</template>
<q-popup-proxy :offset="[0, 10]" ref="qDateProxy">
<q-date v-model="tempHotels.key" :options="optionsFn" mask="YYYY/MM/DD" landscape></q-date>
</q-popup-proxy>
</q-field>
</div>
<div class="q-pa-sm rounded-borders bg-blue-grey-1 q-mt-sm q-">
<div style="padding: 100px 0" class="text-center">
<q-btn color="primary" :label="$t('hotel.newHotelBtn')" :disable="tempHotels.key == ''" outline @click="chosenNewHotel(tempHotels)" />
<div class="text-blue-grey-4 q-mt-md" v-if="tempHotels.key == ''">* {{ $t('hotel.newDateTips') }}</div>
</div>
</div>
</div>
<q-dialog v-model="showChosenHotel">
<chosen-hotel></chosen-hotel>
</div>
</div>
<q-dialog v-model="showChosenHotel" :class="{ 'full-window': $q.platform.is.mobile }">
<chosen-hotel @finish="finishHandler"></chosen-hotel>
</q-dialog>
<q-inner-loading :showing="loading" :label="$t('loading')" label-class="text-grey-6 f12" />
......@@ -120,14 +157,14 @@ import HotelService from 'src/api/hotel'
import { DirtionmaryHelper } from 'src/config/dictionary'
import { currentRouter } from 'src/router'
import message from 'src/utils/message'
import { defineComponent, inject, provide, reactive, toRefs } from 'vue'
import { defineComponent, inject, provide, reactive, ref, toRefs } from 'vue'
import { useI18n } from 'vue-i18n'
import { RoomType, StandardStatus } from 'src/@types'
import { getHotelOrderStatus, getHotelRoomType, groupBy, moneyFormat } from 'src/utils/tools'
import { useQuasar } from 'quasar'
import { date, useQuasar } from 'quasar'
import ChosenHotel from '../../components/hotel/chosen/ChosenHotel.vue'
export default defineComponent({
components:{ChosenHotel},
components: { ChosenHotel },
setup(props) {
const $q = useQuasar()
let { setTitle } = useMetaModule()
......@@ -138,6 +175,10 @@ export default defineComponent({
const menu = inject(DirtionmaryHelper.MENU_KEYS) as any
menu.value = 3
const TCNumRef = ref(null) as any
const ContactNameRef = ref(null) as any
const ContactNumberRef = ref(null) as any
const search = reactive({
HotelChooseArray: [],
StartDate: '2022/11/25',
......@@ -150,8 +191,8 @@ export default defineComponent({
PriceLevel: 0,
Supplier: 0,
MaxPrice: '',
MinPrice: ''
MinPrice: '',
SearchByUpdate: true
})
provide(DirtionmaryHelper.HOTEL_QUERY_PARAM, search)
const data = reactive({
......@@ -161,7 +202,15 @@ export default defineComponent({
status: [] as Array<StandardStatus>,
rooms: [] as Array<RoomType>,
limitGuestNum: [2, 1, 1, 3, 1],
showChosenHotel:true
showChosenHotel: false,
tempHotels: {
key: '',
data: [] as Array<any>
},
cacheHotels: [
{ Name: t('hotel.car.scattered'), ID: 1 },
{ Name: t('hotel.car.group'), ID: 2 }
]
})
data.orderId = currentRouter.currentRoute.value.params.orderId
if (data.orderId == 0) {
......@@ -192,6 +241,7 @@ export default defineComponent({
data.order.DetailList = groupBy(data.order.DetailList, (x: any) => {
return x.Date
})
console.log(data.order)
} else {
message.errorMsg(r.data.message)
}
......@@ -220,6 +270,7 @@ export default defineComponent({
money += peoples * (hotel.TaxesPrice + hotel.PriceInTangTax)
hotel.PeopleNum = peoples
hotel.HotelMoeny = money
methods.cancelHotelCount()
//return money
},
loadOtherRoom(hotel: any) {
......@@ -314,6 +365,124 @@ export default defineComponent({
} else {
data.order.DetailList.splice(x, 1)
}
methods.cancelHotelCount()
})
},
chosenNewHotel(x: any) {
search.StartDate = x.key
search.EndDate = x.key
data.showChosenHotel = true
},
finishHandler(h: any) {
data.showChosenHotel = false
let hp = h.subList[0].PriceList[0]
console.log(h)
//#region 組裝對象
let hotel = {
ContractUrl: null,
CurrencyId: hp.CurrencyId,
CurrencyName: '日元',
CustomerPayType: 0,
Date: h.subList[0].DateStr.replace(/-/g, '/'),
Destription: null,
HaveOtherRoom: false,
HotelId: h.HotelId,
HotelMoeny: 0.0,
HotelName: h.HotelName,
HotelStatus: 1,
HotelStatusName: '暫定',
Id: 0,
ImageList: h.ImageList,
PeopleNum: 0,
PriceInTangTax: hp.PriceInTangTax,
ReserveRoomNo: null,
RoomList: [] as Array<any>,
TaxesPrice: hp.TaxesPrice
}
data.rooms.forEach((x: RoomType) => {
if (hp[x.Field ?? ''] > 0) {
hotel.RoomList.push({
Destription: '',
IsSelf: true,
Money: 0,
PeopleNumber: 0,
RoomInfo: x,
RoomType: x.TypeId,
RoomName: x.TypeName,
Unit_Price: hp[x.Field ?? '']
})
}
})
//#endregion
let i = data.order.DetailList.findIndex((x: any) => x.key == hotel.Date)
if (i == -1) {
data.order.DetailList.push({
key: hotel.Date,
data: [hotel]
})
data.order.DetailList.sort((x: any, y: any) => {
return new Date(x.key).getTime() - new Date(y.key).getTime()
})
} else {
let y = data.order.DetailList[i].data.findIndex((x: any) => x.HotelId == hotel.HotelId)
if (y == -1) data.order.DetailList[i].data.push(hotel)
}
if (hotel.Date == data.tempHotels.key) {
data.tempHotels.key = ''
data.tempHotels.data = []
}
methods.cancelHotelCount()
},
optionsFn(cd: any) {
return cd >= date.formatDate(date.addToDate(new Date(), { days: 15 }), 'YYYY/MM/DD') && data.order.DetailList.findIndex((x: any) => x.key == cd) == -1
},
cancelHotelCount() {
data.order.HotelCount = 0
data.order.Money = 0
data.order.DetailList.forEach((x: any) => {
data.order.HotelCount += x.data.length
x.data.forEach((y:any)=>{
data.order.Money+=y.HotelMoeny
})
})
},
saveOrderHandler(){
if(data.loading) return
let flag = false
if (data.order.OrderType == 1) {
ContactNameRef.value.validate()
ContactNumberRef.value.validate()
flag = !ContactNameRef.value.hasError && !ContactNumberRef.value.hasError
}else{
TCNumRef.value.validate()
flag = !TCNumRef.value.hasError
}
if(!flag) return
data.loading = true
let detailList=[] as Array<any>
data.order.DetailList.forEach((x:any)=>{
detailList.push(...x.data)
})
detailList.forEach((x:any)=>{
x.RoomList = x.RoomList.filter((y:any)=>y.Number>0)
})
detailList = detailList.filter((x:any)=>x.RoomList.length>0)
let parameter = JSON.parse(JSON.stringify(data.order))
parameter.DetailList = detailList
HotelService.SetCustomerOrder(parameter)
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
message.successMsg(`${t('success')}`)
currentRouter.push('/hotel/order')
} else {
message.errorMsg(r.data.message)
}
data.loading = false
})
.catch(e => {
message.errorMsg(e.message)
data.loading = false
})
}
}
......@@ -323,7 +492,10 @@ export default defineComponent({
return {
...toRefs(data),
...methods,
moneyFormat
moneyFormat,
TCNumRef,
ContactNameRef,
ContactNumberRef
}
}
})
......
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