Commit df725c80 authored by 罗超's avatar 罗超

添加

parent 237aec35
......@@ -50,7 +50,7 @@ module.exports = configure(function (ctx) {
// Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build
build: {
vueRouterMode: 'hash', // available values: 'hash', 'history'
vueRouterMode: 'history', // available values: 'hash', 'history'
target: {
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
node: 'node16'
......
......@@ -56,7 +56,7 @@ export default defineComponent({
.msl
font-family: 'msl'
.din
font-family: 'din'
font-family: 'din' !important
.Poppins
font-family: 'Poppins'
......@@ -228,4 +228,13 @@ body
td:first-child, th:first-child
position: sticky
left: 0
.draw-close
position: fixed
right: 500px
top: 200px
border-bottom-left-radius: 5px
border-top-left-radius: 5px
background: var(--q-primary)
color: white
cursor: pointer
</style>
<template>
<div class="full-height column">
<div class="full-height column hotel-list">
<q-table v-if="$q.platform.is.desktop" :loading="loading" :rows="hotels" :loading-label="$t('loading')" class="sticky-column-table col sticky-header-column-table hotel-table" flat :pagination="pages" :no-data-label="$t('noneData')">
<template v-slot:top>
<div class="row full-width">
......@@ -29,23 +29,15 @@
<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">
<q-td v-for="x in props.row.subList" @click="showOrderSubmitHandler(props.row,x)">
<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 }}
<q-popup-proxy v-if="x.RemainingInventory>0" class="no-shadow" transition-show="scale" transition-hide="scale">
<TableOperation :HotelRow="props.row" :hotelInfor="x"></TableOperation>
<q-btn v-close-popup label="关闭" color="primary" flat style="float:right" />
</q-popup-proxy>
</div>
</template>
<div class="td-item bg-dark" v-else></div>
<div class="td-item cursor-pointer">
{{ x.Inventory }}/{{ x.UseInventory }}/{{ x.RemainingInventory }}
<q-popup-proxy v-if="x.RemainingInventory>0" class="no-shadow" transition-show="scale" transition-hide="scale">
<TableOperation :HotelRow="props.row" :hotelInfor="x"></TableOperation>
<q-btn v-close-popup label="关闭" color="primary" flat style="float:right" />
</q-popup-proxy>
</div>
<div class="td-item" :class="{ 'bg-red-9 text-white': x.UseInventory - x.Inventory > 0 }">
<span v-if="x.UseInventory - x.Inventory > 0">
......@@ -80,6 +72,9 @@
<q-dialog v-model="showPriceList">
<hotel-price-list :hotel="queryHotelObj"></hotel-price-list>
</q-dialog>
<q-dialog v-model="showOrderPreview" persistent>
<TableOperation :HotelRow="orderSubmitObj" :hotelInfor="orderSubmitItemObj" @close="showOrderPreview = false"></TableOperation>
</q-dialog>
</div>
</template>
......@@ -127,7 +122,10 @@ export default defineComponent({
{name:'LowerPrice',label:t('hotel.col.four'),field:(row:any)=>${row.LowerPrice.toFixed(2)}${t('hotel.col.low')}`}
],
showPriceList:false,
queryHotelObj:{}
queryHotelObj:{},
orderSubmitObj:{} as any,
orderSubmitItemObj:{} as any,
showOrderPreview: false
})
......@@ -155,7 +153,7 @@ export default defineComponent({
x.LowerPrice=methods.calcLowerPrice(x)
}
})
data.hotels = r.data.data.pageData
} else {
message.errorMsg(r.data.message)
......@@ -200,6 +198,11 @@ export default defineComponent({
viewHotelPriceListHandler(e:any,row:any,index:number){
data.queryHotelObj = row
data.showPriceList = true
},
showOrderSubmitHandler(row:any,col:any){
data.orderSubmitObj = row
data.orderSubmitItemObj = col
data.showOrderPreview = true
}
}
methods.calcDateRangeCols()
......@@ -210,6 +213,9 @@ export default defineComponent({
</script>
<style>
.q-dialog__inner--minimized > div{
max-width: unset !important;
}
.cos-item-icon {
width: 14px;
height: 14px;
......
<template>
<q-card class="bg-white q-pb-md" style="width: 500px;">
<div class="drawerTop row justify-between items-center q-py-md q-px-lg">
<q-btn rounded class="q-mr-md" color="red" icon="shopping_cart">
<q-badge class="text-red" color="white" rounded floating>{{HotelLength}}</q-badge>
</q-btn>
<q-icon class="cursor-pointer" name="close" size="18px" color="grey-5" @click="$emit('close')"></q-icon>
<q-card class="bg-white q-pb-md window-height column" style="width: 500px;">
<div class="q-pt-md q-px-lg row items-center justify-between">
<span class="text-h6">{{$t('hotel.car.subtitle')}}</span>
<span v-html="$t('hotel.car.title',{days:cars.length,hotels:HotelLength})" class="q-pa-sm rounded-border bg-orange-1 text-orange-8 f12"></span>
<div class="draw-close q-pa-sm">
<q-icon name="close" size="26px" v-close-popup></q-icon>
</div>
</div>
<q-separator color="grey-3" class="q-my-sm" />
<div style="height: 660px;">
<q-scroll-area v-if="HotelCarList.length>0" :thumb-style="scrollStyle.thumbStyle" :bar-style="scrollStyle.barStyle" class="full-height">
<q-separator color="grey-3" class="q-mt-md" />
<div class="col">
<div class="q-pa-sm rounded-borders bg-dark text-grey-2 q-mx-md q-mt-md" v-for="x in cars">
<div class="text-subtitle1 din text-weight-bolder" >{{x.Date}}</div>
<div class="q-pa-sm rounded-borders bg-light-blue-1" v-for="y in x.Hotels">
<div class="text-subtitle2 text-weight-bolder text-primary row items-center">
<span class="col">{{y.HotelName}}</span>
<div class="f12">
<span>{{ $t('hotel.shopping.TheSelected') }}</span>
<span class="text-red q-px-sm">{{ y.SumPeople }}</span>
<span>{{ $t('unit.ren') }}</span>
<span class="text-red q-px-sm">{{ y.Total }}</span>
<span>{{ $t('hotel.shopping.between') }}</span>
</div>
</div>
<div class="q-mt-sm q-pb-sm text-dark" style="border-top:1px dashed var(--q-primary);border-bottom:1px dashed var(--q-primary);">
<div class="row no-wrap items-center q-mt-sm" v-for="z in y.DetailList">
<span class="col-3">{{z.RoomName}}</span>
<span class="col-3">{{moneyFormat(z.Unit_Price)}}/{{$t('unit.ren')}}</span>
<span class="col-2">
<span>{{ z.PeopleNumber }}</span>
<span>{{ $t('unit.ren') }}</span>
<span>{{ z.Number }}</span>
<span>{{ $t('hotel.shopping.between') }}</span>
</span>
<span class="col text-right">{{$t('hotelorder.xj')}}{{moneyFormat(z.Unit_Price*z.PeopleNumber)}}</span>
</div>
</div>
<div class="q-mt-sm row items-center text-dark justify-between q-pb-sm" v-if="y.TaxesPrice>0 || y.PriceInTangTax>0" style="border-bottom:1px dashed var(--q-primary);">
<span v-if="y.TaxesPrice>0">{{$t('hotelorder.col.t')}}{{y.TaxesPrice}}*{{y.SumPeople}}{{$t('unit.ren')}}={{moneyFormat(y.TaxesPrice*y.SumPeople)}}</span>
<span v-if="y.PriceInTangTax>0">{{$t('hotelorder.col.t2')}}{{y.PriceInTangTax}}*{{y.SumPeople}}{{$t('unit.ren')}}={{moneyFormat(y.PriceInTangTax*y.SumPeople)}}</span>
</div>
<div class="q-mt-sm text-right text-primary">
{{moneyFormat(y.Money)}}
</div>
</div>
</div>
<!-- <q-scroll-area v-if="cars.length>0" :thumb-style="scrollStyle.thumbStyle" :bar-style="scrollStyle.barStyle" class="full-height">
<q-list>
<q-item class="rounded-borders">
<q-item-section>
......@@ -52,7 +89,7 @@
<q-btn rounded dense color="white" text-color="black" size="xs" icon="remove" @click='addGoods(item,index,x,i,room,s,0)'/>
</div>
<div class="q-px-sm" style="width: 80px;">
<q-input style="width: 100%;" v-model="room.Number" class="col q-mr-md" mask="#.##"
<q-input style="width: 100%;" v-model="room.Number" class="col q-mr-md" mask="#.##"
reverse-fill-mask dense type="text" standout :label="$t('hotel.shopping.labelNum')" />
</div>
<div>
......@@ -64,7 +101,7 @@
<q-btn rounded dense color="white" text-color="black" size="xs" icon="remove" @click='addPeople(item,index,x,i,room,s,0)'/>
</div>
<div class="q-px-sm" style="width: 80px;">
<q-input style="width: 100%;" v-model="room.PeopleNumber" class="col q-mr-md" mask="#.##"
<q-input style="width: 100%;" v-model="room.PeopleNumber" class="col q-mr-md" mask="#.##"
reverse-fill-mask dense type="text" standout :label="$t('hotel.shopping.peopleNum')" />
</div>
<div>
......@@ -72,11 +109,10 @@
</div>
</div>
</div>
</div>
<!-- <q-separator color="grey-3" class="q-my-sm" dark vertical/> -->
</div>
<div class="row justify-end">
<div v-if="item.TaxesPrice>0">
......@@ -101,48 +137,48 @@
</q-item-section>
</q-item>
</q-list>
</q-scroll-area>
<div v-else class="q-pa-lg row items-center justify-center">
</q-scroll-area> -->
<!-- <div v-else class="q-pa-lg row items-center justify-center">
{{$t('noneData')}}
</div>
</div> -->
</div>
<div class="column q-px-md">
<div class="row wrap justify-between col q-py-lg">
<div class="col-6 q-pb-sm">
<n-select filterable @update:value="changeOrderType" style="max-width: 200px;"
v-model:value="parameters.OrderType" :placeholder="$t('hotel.car.OrderType')" :options="cacheHotels"
v-model:value="parameters.OrderType" :placeholder="$t('hotel.car.OrderType')" :options="cacheHotels"
max-tag-count="responsive" size="large" value-field="ID" label-field="Name" />
</div>
<q-input v-if="parameters.OrderType==2" class="col-6" v-model="parameters.TCNum" style="max-width: 200px;" reverse-fill-mask dense
type="text" standout :label="$t('hotel.car.inputText')+$t('hotel.car.TCNum')" ref="TCNumRef"
<q-input v-if="parameters.OrderType==2" class="col-6" v-model="parameters.TCNum" style="max-width: 200px;" reverse-fill-mask dense
type="text" standout :label="$t('hotel.car.inputText')+$t('hotel.car.TCNum')" ref="TCNumRef"
:rules="[val => !!val || $t('hotel.car.inputText')+$t('hotel.car.TCNum')]"/>
<template v-if="parameters.OrderType==1">
<q-input v-model="parameters.ContactName" style="max-width: 200px;" class="col-6" reverse-fill-mask dense
<q-input v-model="parameters.ContactName" style="max-width: 200px;" class="col-6" reverse-fill-mask dense
type="text" standout :label="$t('hotel.car.inputText')+$t('hotel.car.ContactName')" ref="ContactNameRef"
:rules="[val => !!val || $t('hotel.car.inputText')+$t('hotel.car.ContactName')]"/>
<q-input v-model="parameters.ContactNumber" style="max-width: 200px;" class="col-6 q-mr-md" reverse-fill-mask dense
type="text" standout :label="$t('hotel.car.inputText')+$t('hotel.car.ContactNumber')" ref="ContactNumberRef"
<q-input v-model="parameters.ContactNumber" style="max-width: 200px;" class="col-6 q-mr-md" reverse-fill-mask dense
type="text" standout :label="$t('hotel.car.inputText')+$t('hotel.car.ContactNumber')" ref="ContactNumberRef"
:rules="[val => !!val || $t('hotel.car.inputText')+$t('hotel.car.ContactNumber')]"/>
</template>
<q-input class="col-6"
style="max-width: 200px;"
v-model="parameters.Remark"
reverse-fill-mask dense
reverse-fill-mask dense
filled
clearable
type="text"
:label="$t('hotel.car.Remark')"
/>
</div>
<div class="row justify-between">
<div>
<span class="fz14">¥</span>
{{parameters.Money}}
</div>
<q-btn color="red" style="width: 150px" :loading="loading" @click="submit">
<div class="ellipsis">
{{$t('hotel.car.submit')}}
......@@ -150,29 +186,27 @@
</q-btn>
</div>
</div>
</q-card>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, toRefs, provide, onMounted, inject, watch } from 'vue'
import { SitLang } from '../../../@types';
import { useI18n } from 'vue-i18n'
import { dispatchAction } from '../../../store/utils';
import { UserActionsType } from '../../../store/modules/user/actions';
import useScrollModule from '../../../module/scrollbar/scrollModule'
import { DirtionmaryHelper } from '../../../config/dictionary'
import message from '../../../utils/message'
import { ApiResult } from '../../../@types/enumHelper'
import HotelService from '../../../api/hotel'
import { moneyFormat } from '../../../utils/tools'
export default defineComponent({
props: {
},
setup(props, context) {
const HotelCarList = inject(DirtionmaryHelper.HOTEL_CAR_LIST) as any
const {locale,t } = useI18n();
const cars = inject(DirtionmaryHelper.HOTEL_CAR_LIST) as any
const { t } = useI18n();
const TCNumRef = ref(null) as any
const ContactNameRef = ref(null) as any
const ContactNumberRef = ref(null) as any
......@@ -181,7 +215,7 @@
addNum: 1,
parameters: {
Money: 0,
DetailList: [],
DetailList: [] as Array<any>,
Remark: '',
OrderType: 1,//订单类型 1散客 2团队
TCNum: '',//=团队时 传递 组团号
......@@ -202,8 +236,7 @@
})
data.scrollStyle = useScrollModule().scrollStyle
// 今天购买数量
watch(HotelCarList.value, (n, o) => {
methods.calculateNum()
watch(cars.value, (n, o) => {
methods.getMoney()
})
const methods = {
......@@ -214,9 +247,9 @@
},
getMoney(){
data.parameters.Money = 0
HotelCarList.value.forEach(item=>{
item.timeList.forEach(t=>{
t.rooms.forEach(room=>{
cars.value.forEach((item:any)=>{
item.Hotels.forEach((t:any)=>{
t.DetailList.forEach((room:any)=>{
let m = (room.PeopleNumber*room.Unit_Price)+(room.Number*room.TaxesPrice)+(room.Number*room.PriceInTangTax)
data.parameters.Money+=m
})
......@@ -226,7 +259,10 @@
submit() {
// context.emit('success')
// return
// TCNumRef.value.validate()
console.log(ContactNameRef)
ContactNameRef.value.validate()
return;
// ContactNameRef.value.validate()
// ContactNumberRef.value.validate()
if(data.parameters.OrderType==1){
......@@ -244,34 +280,33 @@
}
data.parameters.DetailList = [] as Array<any>
HotelCarList.value.forEach(item=>{
item.timeList.forEach(t=>{
let datas = {
HotelId: item.HotelId,
Date: t.Date,
Destription:'',
RoomList:[],
}
t.rooms.forEach(room=>{
let msg = {
RoomType: room.RoomType,
Unit_Price: room.Unit_Price,
Number: room.Number,
PeopleNumber: room.PeopleNumber,
Destription: room.Destription?room.Destription:''
}
datas.RoomList.push(msg)
})
data.parameters.DetailList.push(datas)
})
})
// console.log(data.parameters,'-----')
// return
// HotelCarList.value.forEach((item:any)=>{
// item.timeList.forEach((t:any)=>{
// let datas = {
// HotelId: item.HotelId,
// Date: t.Date,
// Destription:'',
// RoomList:[] as Array<any>,
// }
// t.rooms.forEach((room:any)=>{
// let msg = {
// RoomType: room.RoomType,
// Unit_Price: room.Unit_Price,
// Number: room.Number,
// PeopleNumber: room.PeopleNumber,
// Destription: room.Destription?room.Destription:''
// }
// datas.RoomList.push(msg)
// })
// data.parameters.DetailList.push(datas)
// })
// })
data.loading = true
HotelService.SetCustomerOrder(data.parameters)
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
if (r.data.resultCode == ApiResult.SUCCESS) {
message.successMsg(`${t('success')}`)
data.parameters = {
Money: 0,
......@@ -296,82 +331,24 @@
},
getLength(){
data.HotelLength = 0
if(HotelCarList.value.length>0){
HotelCarList.value.forEach(item=>{
item.timeList.forEach(t=>{
if(t.rooms.length>0){
data.HotelLength+=t.rooms.length
}
})
})
}
},
// 计算房间数量
calculateNum(){
let list = HotelCarList.value
if(list&&list[data.currentIndex]){
// HotelCarList.value[data.currentIndex].timeList[data.currentI].total = 0
HotelCarList.value&&HotelCarList.value.forEach((item,index)=> {
item.timeList.forEach(t=>{
t.total = 0
t.rooms.forEach(room=>{
t.total+=room.Number
})
})
})
}
},
// 人数
addPeople(item: Object,index: any,x: Object,i: any,room: Object,s: any,type: any){
data.currentIndex = index
data.currentI = i
data.currentS = s
if(type==1&&room.Number<x.RemainingInventory){
room.PeopleNumber++
}else if(type==0&&room.PeopleNumber>1){
room.PeopleNumber--
}
// methods.getMoney()
},
// 房间数
addGoods(item: Object,index: any,x: Object,i: any,room: Object,s: any,type: any){
data.currentIndex = index
data.currentI = i
data.currentS = s
if(type==1&&room.Number<x.RemainingInventory){
if(x.total<x.RemainingInventory){
room.Number++
}
}else if(type==0&&room.Number>0){
if(room.Number==1){
if(HotelCarList.value[index].timeList[i].rooms.length==1&&HotelCarList.value[index].timeList.length>1){
HotelCarList.value[index].timeList.splice(i, 1)
}else if(HotelCarList.value[index].timeList.length==1&&
HotelCarList.value[index].timeList[i].rooms.length==1){
HotelCarList.value.splice(index, 1)
return
}else{
HotelCarList.value[index].timeList[i].rooms.splice(s, 1)
}
methods.getLength()
}
room.Number--
}
cars.value.forEach((item:any)=>{
data.HotelLength+=item.Hotels.length
})
},
}
onMounted(()=>{
methods.getLength()
methods.getMoney()
})
return {...toRefs(data),HotelCarList,TCNumRef,ContactNameRef,ContactNumberRef,...methods}
return {...toRefs(data),cars,TCNumRef,ContactNameRef,ContactNumberRef,...methods,moneyFormat}
}
})
</script>
<style>
.ListCar-title{
white-space: wrap;
}
</style>
\ No newline at end of file
</style>
......@@ -44,18 +44,17 @@
</q-popup-proxy>
</q-btn>
<q-btn color="primary" unelevated :label="$t('query')" />
</div>
<q-dialog v-if="HotelCarList.length>0" v-model="rightCarOpen" maximized full-height position="right">
<ListCar @close="close" @success="setSuccess"></ListCar>
<q-dialog v-if="cars.length>0" v-model="rightCarOpen" maximized full-height position="right">
<list-car @close="close" @success="setSuccess"></list-car>
</q-dialog>
</template>
<script lang="ts">
import svgIcon from '../../global/svg-icon.vue'
import { computed, inject, provide, reactive, ref, toRefs, defineComponent, onMounted, watch } from 'vue'
import { DirtionmaryHelper } from '../../../config/dictionary'
import HotelService from '../../../api/hotel'
import message from '../../../utils/message'
import { ApiResult } from '../../../@types/enumHelper'
......@@ -69,8 +68,7 @@ import { DirtionmaryHelper } from '../../../config/dictionary'
export default defineComponent({
components: { svgIcon, ListCar },
setup() {
inject(DirtionmaryHelper.HOTEL_CAR_LIST)
const HotelCarList = inject(DirtionmaryHelper.HOTEL_CAR_LIST) as any
const cars = inject(DirtionmaryHelper.HOTEL_CAR_LIST) as any
const $q = useQuasar()
const qDateProxy = ref(null) as any
const qNameProxy = ref(null) as any
......@@ -186,18 +184,12 @@ export default defineComponent({
},
setSuccess(){
data.rightCarOpen = false
// HotelCarList.value = [] as Array<any>
// data.HotelLength = 0
},
getLength(){
data.HotelLength = 0
if(HotelCarList.value.length>0){
HotelCarList.value.forEach(item=>{
item.timeList.forEach(t=>{
if(t.rooms.length>0){
data.HotelLength+=t.rooms.length
}
})
if(cars.value.length>0){
cars.value.forEach((item:any)=>{
data.HotelLength+=item.Hotels.length
})
}
},
......@@ -216,7 +208,8 @@ export default defineComponent({
})
methods.initAddress()
methods.initHotels()
watch(HotelCarList.value, (n, o) => {
watch(cars.value, (n, o) => {
localStorage.setItem(DirtionmaryHelper.HOTEL_HOTELCARS_CACHE,JSON.stringify(cars.value))
methods.getLength()
})
onMounted(()=>{
......@@ -229,7 +222,7 @@ export default defineComponent({
qNameProxy,
searchCnt,
search,
HotelCarList
cars
}
}
})
......
<template>
<q-card flat class="q-px-lg q-py-sm bg-grey-1"
style="shadow: 0px 0px 50px 0px rgba(82, 63, 105, 0.15)">
<div class="text-blue column q-pb-xs fz16">
<div class="row items-center justify-center">{{HotelRow.HotelName}}</div>
<div class="row justify-start">
<span class="fz12 text-grey-6">{{hotelInfor.DateStr}}</span>
</div>
<q-card flat class="q-pa-lg" style="shadow: 0px 0px 50px 0px rgba(82, 63, 105, 0.15); width: 50vw">
<div class="q-mb-xs">
<div class="">
<span class="text-primary text-h6">{{ HotelRow.HotelName }}</span>
</div>
<div class="q-my-md rounded-borders q-pa-sm bg-yellow-1 row items-center justify-between">
<q-field stack-label :label="$t('hotel.inHouseDate')" class="text-primary" standout dense>
<template v-slot:control>
<div class="self-center no-outline text-yellow-10" tabindex="0">{{ joinHouse.dateRangeFormat }}</div>
</template>
<!-- <q-popup-proxy :offset="[0, 10]" ref="qDateProxyOpera">
<q-date v-model="joinHouse.dateRange" :options="optionsFn" range mask="YYYY/MM/DD" landscape @range-end="dateRangeHandler"></q-date>
</q-popup-proxy> -->
</q-field>
<span class="text-grey-6 f12" v-html="$t('hotel.inhouseDays', { day: joinHouse.days })"></span>
</div>
</div>
<div class="f12 text-negative q-mb-md">{{ $t('hotel.waringTips') }}</div>
<div class="bg-grey-1 rounded-borders q-px-md q-py-sm" style="max-height: 35vh; overflow-y: auto">
<template v-for="(item, index) in parameters.DetailList">
<div class="row no-wrap items-center q-py-sm" :style="{ 'border-top': index > 0 && !item.Tips ? '1px dashed #ddd' : '' }">
<div class="q-pr-md col-2">
<div class="f12">{{ item.RoomName }}</div>
</div>
<div class="text-negative f12 col-3">
<span class="fz10">¥</span>
<span class="din">{{ item.UPriceFormat }}</span>
<span class="text-dark" style="font-size: 12px">/{{ $t('unit.ren') }}</span>
</div>
<div class="q-pl-md col-4">
<q-input style="width: 100%" @update:model-value="changePeople" v-model="item.PeopleNumber" class="col q-mr-md q-px-sm" mask="#" reverse-fill-mask dense standout :label="$t('hotel.shopping.peopleNum')">
<template v-slot:prepend>
<q-btn color="primary" size="sm" class="q-px-none" flat icon="remove" @click="addPeople(item, 0)" />
</template>
<template v-slot:append>
<q-btn color="primary" size="sm" class="q-px-none" flat icon="add" @click="addPeople(item, 1)" />
</template>
</q-input>
</div>
<div class="text-center col">
<span class="f12 text-grey-6" v-html="$t('hotel.yg', { roomCount: item.Number })"></span>
</div>
</div>
<template v-for="(item,index) in parameters.DetailList">
<div class="row no-wrap justify-between items-center q-py-sm">
<div class="q-pr-md column">
<div class="f12 q-pb-xs">
<template v-if="item.RoomType==1">{{$t('hotel.shopping.StandardRooms')}}</template>
<template v-if="item.RoomType==2">{{$t('hotel.shopping.maxRooms')}}</template>
<template v-if="item.RoomType==3">{{$t('hotel.shopping.naturalRooms')}}</template>
<template v-if="item.RoomType==4">{{$t('hotel.shopping.ThreeRooms')}}</template>
<template v-if="item.RoomType==5">{{$t('hotel.shopping.driverRoom')}}</template>
</div>
<div class="text-red fz10">
<span class="fz10">¥</span>
<span class="fz14 q-pl-xs text-weight-bold">{{item.Unit_Price}}</span>
</div>
</div>
<div class="row items-center no-wrap justify-between">
<div>
<q-btn rounded dense color="white" text-color="black" size="xs" icon="remove" @click='addGoods(item,0)'/>
</div>
<div class="q-px-sm" style="width: 80px;">
<q-input style="width: 100%;" v-model="item.Number" class="col q-mr-md" mask="#.##"
reverse-fill-mask dense type="text" standout :label="$t('hotel.shopping.labelNum')" />
</div>
<div>
<q-btn rounded dense color="primary" size="xs" icon="add" @click='addGoods(item,1)'/>
</div>
</div>
<div class="row items-center no-wrap justify-between q-pl-md">
<div>
<q-btn rounded dense color="white" text-color="black" size="xs" icon="remove" @click='addPeople(item,0)'/>
</div>
<div class="q-px-sm" style="width: 80px;">
<q-input style="width: 100%;" v-model="item.PeopleNumber" class="col q-mr-md" mask="#.##"
reverse-fill-mask dense type="text" standout :label="$t('hotel.shopping.peopleNum')" />
</div>
<div>
<q-btn rounded dense color="primary" size="xs" icon="add" @click='addPeople(item,1)'/>
</div>
</div>
</div>
</template>
<div class="row items-center justify-between q-pt-md">
<div class="text-grey-6 fz12">
{{$t('hotel.shopping.only')}}
<span class="text-orange-14 fz14 q-px-xs">{{onlyNum}}</span>
{{$t('hotel.shopping.between')}}
</div>
<div class="row items-center q-pl-md">
<div v-if="total>0" class="q-pr-md f12">
<span>{{$t('hotel.shopping.TheSelected')}}</span>
<span class="text-red q-px-sm">{{total}}</span>
<span>{{$t('hotel.shopping.between')}}</span>
</div>
<div>
<q-btn round class="border-radius"
:color="total==0?'grey-6':'red'" size="sm" icon="shopping_cart"
:title="$t('hotel.car.addShopping')" @click="total==0?'':join()"/>
</div>
</div>
</template>
</div>
<div class="row items-center justify-between q-pt-md">
<div>
<div class="text-grey-6 fz12 row items-center">
<div class="q-mr-lg">
{{ $t('hotel.shopping.only') }}
<span class="text-orange-14 fz14 q-px-xs">{{ onlyNum }}</span>
{{ $t('hotel.shopping.between') }}
</div>
<div v-if="total > 0" class="q-pr-md f12">
<span>{{ $t('hotel.shopping.TheSelected') }}</span>
<span class="text-red q-px-sm">{{ sumPeople }}</span>
<span>{{ $t('unit.ren') }}</span>
<span class="text-red q-px-sm">{{ total }}</span>
<span>{{ $t('hotel.shopping.between') }}</span>
</div>
</div>
</q-card>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, toRef, toRefs, provide, onMounted, inject, watch } from 'vue'
import { SitLang } from '../../../@types';
import { useI18n } from 'vue-i18n'
import { dispatchAction } from '../../../store/utils';
import { UserActionsType } from '../../../store/modules/user/actions';
import { DirtionmaryHelper } from '../../../config/dictionary'
import message from '../../../utils/message'
import HotelService from '../../../api/hotel'
export default defineComponent({
props: {
HotelRow:{
type: Object,
require: true
},
hotelInfor:{
type: Object,
require: true
}
<div class="q-mt-sm rounded-borders bg-orange-1 text-orange-10 f12 q-pa-sm" v-if="(total-onlyNum)>0">
{{$t('hotel.outbind')}}
</div>
</div>
<div class="row items-center q-pl-md">
<div>
<q-btn flat dense color="dark" :label="$t('close')" class="q-mr-sm" v-close-popup/>
<q-btn unelevated dense color="negative" :disable="total==0" icon="shopping_cart" :label="$t('hotel.car.addShopping')" @click="join" />
</div>
</div>
</div>
</q-card>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, toRef, toRefs, provide, onMounted, inject, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { DirtionmaryHelper } from '../../../config/dictionary'
import { date } from 'quasar'
import message from '../../../utils/message'
import { moneyFormat } from '../../../utils/tools'
export default defineComponent({
props: {
HotelRow: {
type: Object,
require: true
},
setup(props, context) {
const {locale,t } = useI18n();
const HotelCarList = inject(DirtionmaryHelper.HOTEL_CAR_LIST)
const data=reactive({
HotelRow: props.HotelRow,
hotelInfor: props.hotelInfor,
onlyNum: '' as any,
parameters:{
HotelId:'' as String,
HotelName: '' as String,
Date: '' as String,
RemainingInventory: '' as String,
total: 0,
Money: '' as String,
DetailList: [] as Array<any>,
Remark: '' as String,
},
hotelInfor: {
type: Object,
require: true
}
},
emits:['close'],
setup(props, context) {
const { t } = useI18n()
const qDateProxyOpera = ref<any>(null)
const cars = inject(DirtionmaryHelper.HOTEL_CAR_LIST) as any
const data = reactive({
HotelRow: props.HotelRow as any,
hotelInfor: props.hotelInfor as any,
onlyNum: 0,
parameters: {
HotelId: '',
HotelName: '',
Date: '',
RemainingInventory: '',
total: 0,
})
data.onlyNum = JSON.parse(JSON.stringify(data.hotelInfor.RemainingInventory))
Money: 0,
DetailList: [] as Array<any>,
Remark: '',
TaxesPrice:0,
PriceInTangTax:0
},
total: 0,
joinHouse: {
StartDate: '',
EndDate: '',
dateRange: [] as Array<any>,
dateRangeFormat: '',
days: 1
},
sumPrice: 0,
sumPeople: 0
})
watch(
() => props.HotelRow,
(o, n) => {
data.HotelRow = props.HotelRow
data.hotelInfor = props.hotelInfor
methods.setList()
}
)
data.onlyNum = data.hotelInfor.RemainingInventory
// 今天购买数量
watch(data.parameters, (n, o) => {
watch(data.parameters, (n, o) => {
methods.calculateNum()
})
const methods = {
addPeople(item: any, type: any) {
// && item.Number < data.hotelInfor.RemainingInventory
if (type == 1) {
item.PeopleNumber++
} else if (type == 0 && item.PeopleNumber > 1) {
item.PeopleNumber--
}
item.PeopleNumber=item.PeopleNumber!=''?item.PeopleNumber:'0'
methods.calculateNum()
})
const methods = {
addPeople(item: String,type:any){
if(type==1&&item.Number<data.hotelInfor.RemainingInventory){
item.PeopleNumber++
}else if(type==0&&item.PeopleNumber>1){
item.PeopleNumber--
}
},
addGoods(item: String,type:any){
if(type==1&&item.Number<data.hotelInfor.RemainingInventory){
if(data.total<data.hotelInfor.RemainingInventory){
item.Number++
}
}else if(type==0&&item.Number>0){
item.Number--
}
},
// 计算房间数量
calculateNum(){
data.total = 0
data.parameters.DetailList.forEach(item => {
if(data.total<data.hotelInfor.RemainingInventory){
data.total+=item.Number
}
})
},
// 加入购物车
join(){
if(data.total<1||data.total>data.hotelInfor.RemainingInventory){
message.errorMsg(`${t('hotel.shopping.small')}1${t('hotel.shopping.big')}${data.hotelInfor.RemainingInventory}`)
}
const parameters = data.parameters
let msgData = {
HotelId: parameters.HotelId,
HotelName: parameters.HotelName,
timeList: [] as Array<any>
}
let msg = {
Date: parameters.Date,
total: data.total,
RemainingInventory: parameters.RemainingInventory,
rooms: [] as Array<any>
}
data.parameters.DetailList.forEach((x,index)=>{
msgData.TaxesPrice = x.TaxesPrice
msgData.PriceInTangTax = x.PriceInTangTax
if(x.Number>0){
let ArrData = {
HotelId: x.HotelId,
Date: x.Date,
RoomType: x.RoomType,
Unit_Price: x.Unit_Price,
Number: x.Number,
PeopleNumber: x.PeopleNumber,
Destription: x.Destription,
TaxesPrice: x.TaxesPrice,
PriceInTangTax: x.PriceInTangTax,
}
msg.rooms.push(ArrData)
}
})
msgData.timeList.push(msg)
if(data.total>0){
let list = HotelCarList.value
if(list.length>0){
let fault = true
list.forEach((item,index)=>{
if(item.HotelId==parameters.HotelId){
item.timeList.forEach((x,i)=>{
if(fault&&x.Date==parameters.Date){
HotelCarList.value[index].timeList.splice(i,1)
HotelCarList.value[index].timeList.push(msg)
fault = false
}else if(fault&&x.Date!=parameters.Date){
HotelCarList.value[index].timeList.push(msg)
fault = false
}else{
// console.log(fault,x.Date,parameters.Date)
}
})
}
})
if(fault) HotelCarList.value.push(msgData)
}else{
HotelCarList.value.push(msgData)
}
},
changePeople(val:string){
methods.calculateNum()
},
// 计算房间数量
calculateNum() {
data.total = 0
data.sumPeople = 0
data.parameters.DetailList.forEach(item => {
item.Number = Math.ceil(parseFloat(item.PeopleNumber) / parseFloat(item.LimitGuestNum))
data.total += item.Number
data.sumPeople += parseInt(item.PeopleNumber)
})
},
joinOverride(){
const temp= JSON.parse(JSON.stringify(data.parameters))
temp.Money=0
temp.Total=data.total
temp.SumPeople = data.sumPeople
temp.DetailList = temp.DetailList.filter(((x:any)=>x.PeopleNumber>0))
temp.DetailList.forEach((x:any) => {
temp.Money+=(x.PeopleNumber*(x.Unit_Price+x.TaxesPrice+x.PriceInTangTax))
});
let existsIndex = cars.value.findIndex((x:any)=>x.Date == temp.Date)
let exists = existsIndex==-1?null:cars[existsIndex]
if(exists){
let existsHotel = exists.Hotels?.find((h:any)=>h.HotelId==temp.HotelId)
if(existsHotel) exists.Hotels.remove(existsHotel)
}else{
exists = {
Date:temp.Date,
Hotels:[] as Array<any>
}
cars.value.push(exists)
}
exists.Hotels.push(temp)
console.log(cars.value)
message.successMsg(t('success'))
context.emit('close')
},
// 加入购物车
join() {
methods.joinOverride()
return
// if (data.total < 1 || data.total > data.hotelInfor.RemainingInventory) {
// message.errorMsg(`${t('hotel.shopping.small')}1${t('hotel.shopping.big')}${data.hotelInfor.RemainingInventory}`)
// }
// const parameters = data.parameters
// let msgData = {
// HotelId: parameters.HotelId,
// HotelName: parameters.HotelName,
// TaxesPrice: 0.0,
// PriceInTangTax: 0.0,
// timeList: [] as Array<any>
// }
// let msg = {
// Date: parameters.Date,
// total: data.total,
// RemainingInventory: parameters.RemainingInventory,
// rooms: [] as Array<any>
// }
// data.parameters.DetailList.forEach((x, index) => {
// msgData.TaxesPrice = x.TaxesPrice
// msgData.PriceInTangTax = x.PriceInTangTax
// //console.log(moneyFormat(x.Unit_Price),11111111)
// if (x.Number > 0) {
// let ArrData = {
// HotelId: x.HotelId,
// Date: x.Date,
// RoomType: x.RoomType,
// RoomName: x.RoomName,
// Unit_Price: x.Unit_Price,
// Number: x.Number,
// PeopleNumber: x.PeopleNumber,
// Destription: x.Destription,
// TaxesPrice: x.TaxesPrice,
// PriceInTangTax: x.PriceInTangTax
// }
// msg.rooms.push(ArrData)
// }
// })
// msgData.timeList.push(msg)
// if (data.total > 0) {
// let list = HotelCarList.value
// if (list.length > 0) {
// let fault = true
// list.forEach((item: any, index: number) => {
// if (item.HotelId == parameters.HotelId) {
// item.timeList.forEach((x: any, i: number) => {
// if (fault && x.Date == parameters.Date) {
// HotelCarList.value[index].timeList.splice(i, 1)
// HotelCarList.value[index].timeList.push(msg)
// fault = false
// } else if (fault && x.Date != parameters.Date) {
// HotelCarList.value[index].timeList.push(msg)
// fault = false
// }
// })
// }
// })
// if (fault) HotelCarList.value.push(msgData)
// } else {
// HotelCarList.value.push(msgData)
// }
// }
// message.successMsg(`${t('success')}`)
// context.emit('close')
},
// 组装可选房间
setList() {
methods.setDateRange()
data.parameters.DetailList = [] as Array<any>
// 1:標間成本价 2:大床成本价 3:自然間成本价 4:3人間成本价 5:司機房成本价 稅金 TaxesPrice 入湯稅 PriceInTangTax
let roomTyps = ['CostPrice', 'BidroomPrice', 'SingleroomPrice', 'AddBedPrice', 'GuideRoomPrice']
let roomLangs = [t('hotel.rooms.normal'), t('hotel.rooms.big'), t('hotel.rooms.sing'), t('hotel.rooms.three'), t('hotel.rooms.driver')]
let tips = ['', t('hotel.bigTips'), '', '', '']
let limitGuestNum = [2, 1, 1, 3, 1]
let tempPrice = data.hotelInfor.PriceList[0]
let hotel = data.hotelInfor
data.parameters.HotelId = data.HotelRow.HotelId
data.parameters.HotelName = data.HotelRow.HotelName
data.parameters.Date = hotel.DateStr
data.parameters.RemainingInventory = hotel.RemainingInventory
data.parameters.TaxesPrice = tempPrice.TaxesPrice
data.parameters.PriceInTangTax= tempPrice.PriceInTangTax,
roomTyps.forEach((x: any, i: number) => {
if (tempPrice[x] > 0) {
let dataMsg = {
HotelId: data.HotelRow.HotelId,
Date: hotel.DateStr,
RoomType: i + 1,
RoomName: roomLangs[i],
Unit_Price: tempPrice[x],
UPriceFormat: moneyFormat(tempPrice[x]),
LimitGuestNum: limitGuestNum[i],
Tips: tips[i],
Number: 0,
PeopleNumber: 0,
Destription: '',
TaxesPrice: tempPrice.TaxesPrice,
PriceInTangTax: tempPrice.PriceInTangTax,
HotelName: data.HotelRow.HotelName
}
message.successMsg(`${t('success')}`)
},
// 组装可选房间
setList(){
data.parameters.DetailList = [] as Array<any>
// 1:標間成本价 2:大床成本价 3:自然間成本价 4:3人間成本价 5:司機房成本价 稅金 TaxesPrice 入湯稅 PriceInTangTax
let roomTyps=['CostPrice','BidroomPrice','SingleroomPrice','AddBedPrice','GuideRoomPrice']
let tempPrice=data.hotelInfor.PriceList[0]
let hotel=data.hotelInfor
data.parameters.HotelId = data.HotelRow.HotelId,
data.parameters.HotelName = data.HotelRow.HotelName
data.parameters.Date = hotel.DateStr
data.parameters.RemainingInventory = hotel.RemainingInventory,
roomTyps.forEach((x:any,i:number)=>{
if(tempPrice[x]>0){
let dataMsg = {
HotelId: data.HotelRow.HotelId,
Date: hotel.DateStr,
RoomType: i+1,
Unit_Price: tempPrice[x],
Number: 0,
PeopleNumber: 1,
Destription: '',
TaxesPrice: tempPrice.TaxesPrice,
PriceInTangTax: tempPrice.PriceInTangTax,
HotelName: data.HotelRow.HotelName,
}
data.parameters.DetailList.push(dataMsg)
}
})
HotelCarList.value.forEach(item=>{
if(item.HotelId==data.HotelRow.HotelId){
if(item.timeList.length>0){
item.timeList.forEach(x=>{
if(x.Date==hotel.DateStr){
x.rooms.forEach(room=>{
data.parameters.DetailList.forEach(j=>{
if(j.RoomType==room.RoomType){
j.Number = room.Number
j.PeopleNumber = room.PeopleNumber
}
})
})
}
})
}
}
})
},
data.parameters.DetailList.push(dataMsg)
}
})
},
dateRangeHandler(e: any) {
data.joinHouse.StartDate = `${e.from.year}/${e.from.month}/${e.from.day}`
data.joinHouse.EndDate = `${e.to.year}/${e.to.month}/${e.to.day} `
data.joinHouse.dateRangeFormat = `${data.joinHouse.StartDate} - ${data.joinHouse.EndDate} `
data.joinHouse.days = date.getDateDiff(new Date(data.joinHouse.EndDate), new Date(data.joinHouse.StartDate), 'days')
console.log(qDateProxyOpera)
if (qDateProxyOpera.value) qDateProxyOpera.value.hide()
},
setDateRange() {
data.joinHouse.StartDate = date.formatDate(new Date(data.hotelInfor.DateStr), 'YYYY/MM/DD')
data.joinHouse.EndDate = date.formatDate(date.addToDate(new Date(data.joinHouse.StartDate), { days: 1 }), 'YYYY/MM/DD')
data.joinHouse.dateRangeFormat = `${data.joinHouse.StartDate} - ${data.joinHouse.EndDate} `
data.joinHouse.days = date.getDateDiff(new Date(data.joinHouse.EndDate), new Date(data.joinHouse.StartDate), 'days')
},
optionsFn(cd: any) {
return cd >= date.formatDate(date.addToDate(new Date(), { days: 7 }), 'YYYY/MM/DD')
}
onMounted(()=>{
methods.setList()
})
return {...toRefs(data),HotelCarList,...methods}
}
})
</script>
<style>
</style>
\ No newline at end of file
methods.setList()
return { ...toRefs(data), ...methods }
}
})
</script>
<style></style>
......@@ -27,5 +27,10 @@ class DirtionmaryHelper {
* 酒店订单查询条件
*/
static readonly HOTEL_ORDER_SEARCH = 'hotelordersearch'
/**
* 酒店購物車緩存
*/
static readonly HOTEL_HOTELCARS_CACHE = "hotelcarscache"
}
export { userDictionmary,DirtionmaryHelper }
......@@ -13,6 +13,7 @@ export default {
query: '檢索',
noneData: '沒有找到相關的數據',
loading: '正在加載數據',
close:'關閉',
unit: {
jian: '間',
ren: '人',
......@@ -117,9 +118,15 @@ export default {
hotelRate: '酒店星級',
minPrice: '最低價格',
maxPrice: '最高價格',
waringTips:'注意:以下計費與報價均是按照人數進行計費',
inHouseDate:'入住日期',
inhouseDays:'共計 <span class="din text-yellow-10">{day}</span> 晚',
bigTips:'本房型不同的酒店入住人數限制不同,系統默認該房型只能入住一人',
yg:'預計 <span class="din text-yellow-10">{roomCount}</span> 間房',
outbind:'超出現有的庫存預定,我們會即時與酒店協商,請保證收訊通暢',
car: {
shoppingTitle: '購物車',
addShopping: '加入購物車',
addShopping: '暫存購物車',
orderTitle: '訂單',
people: '人',
between: '间',
......@@ -133,7 +140,9 @@ export default {
inputText: '請輸入',
Remark: '備註',
scattered: '散客',
group: '團'
group: '團',
title:'本次行程<span class="din text-orange-10">{days}</span>天,入住<span class="din text-primary">{hotels}</span>個酒店',
subtitle:'酒店採購單'
},
shopping:{
labelNum: '房數',
......@@ -152,7 +161,7 @@ export default {
pricetips: '酒店報價表',
buy: '預定',
table: {
price: '價格',
price: '價格(標準間)',
ins: '總/用/剩',
limit: '超定'
},
......
......@@ -41,7 +41,11 @@ export default defineComponent({
})
provide(DirtionmaryHelper.HOTEL_QUERY_PARAM, search)
const HotelCarList = ref([])
const HotelCarList = ref<Array<any>>([])
const cacheCars = localStorage.getItem(DirtionmaryHelper.HOTEL_HOTELCARS_CACHE)
if(cacheCars){
HotelCarList.value = JSON.parse(cacheCars)
}
provide(DirtionmaryHelper.HOTEL_CAR_LIST, HotelCarList)
const methods = {
......
......@@ -122,7 +122,30 @@ export function getHotelRoomType(getNormal:boolean = false):Array<RoomType>{
})
return rooms
}
export function moneyFormat (num:any, decimal = 2, split = ','):any {
function thousandFormat (num:any):any{
const len = num.length
return len <= 3 ? num : thousandFormat(num.substr(0, len - 3)) + split + num.substr(len - 3, 3)
}
if (isFinite(num)) { // num是数字
if (num === 0) { // 为0
return num.toFixed(decimal)
} else { // 非0
var res = ''
var dotIndex = String(num).indexOf('.')
if (dotIndex === -1) { // 整数
res = thousandFormat(String(num)) + '.' + '0'.repeat(decimal)
} else {
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) // 截取小数位
res = thousandFormat(numStr.slice(0, dotIndex)) + decimals
}
return res
}
} else {
return '--'
}
}
export function getHotelOrderType(getNormal:boolean = false):Array<OrderType>{
let types = [] as Array<OrderType>
if(getNormal){
......
{
"extends": "@quasar/app-vite/tsconfig-preset",
"compilerOptions": {
"target": "es5",
"lib": ["es2017","DOM"],
"baseUrl": "."
}
}
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