Commit 446f37cc authored by 罗超's avatar 罗超

修改訂單

parent 3fca6160
......@@ -211,7 +211,7 @@ export type StandardStatus = {
export type RoomType = {
TypeId:number,
TypeName:string,
Filed?:string
Field?:string
}
export type OrderType={
......
......@@ -259,4 +259,7 @@ body
right: 0
z-index: 1
box-shadow: rgba(0, 0, 0, 0.05) -2px 0px 0px
.q-dialog__inner--minimized>div
max-width: unset !important
</style>
<template>
<div class="rounded-borders bg-white row items-center q-pa-md">
<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>
</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" />
<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" />
<svg-icon color="dark" icon="Text/Filter.svg" :tips="$t('morequery')" :size="20"></svg-icon>
<q-tooltip>{{ $t('morequery') }}</q-tooltip>
<q-popup-proxy class="no-shadow" style="box-shadow: 0 0 50px #ddd !important" :offset="[0, 20]" :model-value="canHide">
<q-card class="q-pa-md rounded-borders" style="width: 300px">
<div class="q-mb-md text-subtitle2">{{ $t('morequery') }}</div>
<div v-if="$q.platform.is.mobile">
<n-cascader @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 />
</div>
<div class="q-my-md" v-if="$q.platform.is.mobile">
<q-field stack-label :label="$t('daterange')" outlined style="min-width: 190px" dense>
<div class="self-center full-width no-outline" tabindex="0">{{ search.StartDate }} - {{search.EndDate}}</div>
</q-field>
</div>
<div v-if="$q.platform.is.mobile">
<n-select filterable 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>
<div class="q-my-md">
<q-select v-model="search.Star" dense :options="hotelsRates" emit-value option-label="name" option-value="id" map-options clearable :label="$t('hotel.hotelRate')" standout />
</div>
<div class="row items-center">
<q-input v-model="search.MinPrice" class="col q-mr-md" mask="#.##" reverse-fill-mask dense type="text" standout :label="$t('hotel.minPrice')" />
<q-input v-model="search.MaxPrice" class="col" dense mask="#.##" reverse-fill-mask ftype="text" standout :label="$t('hotel.maxPrice')" />
</div>
</q-card>
</q-popup-proxy>
</q-btn>
</div>
</template>
<script lang="ts">
import svgIcon from '../../global/svg-icon.vue'
import { computed, inject, provide, reactive, ref, toRefs, defineComponent, onMounted, watch } from 'vue'
import HotelService from '../../../api/hotel'
import message from '../../../utils/message'
import { ApiResult } from '../../../@types/enumHelper'
import { CascaderOption } from 'naive-ui'
import { date } from 'quasar'
import { HotelRate, useHotel } from '../../../utils/hotelRate'
import { useQuasar } from 'quasar'
import useScrollModule from '../../../module/scrollbar/scrollModule'
import { DirtionmaryHelper } from '../../../config/dictionary'
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'
},
provinces: [],
cascader: {
addressValue: null
} as any,
hotelName: '',
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
data.hotelsRates = useHotel.getHotelRate()
const methods = {
initAddress() {
HotelService.GetDestination(data.addressParams)
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
r.data.data.forEach((x: any) => {
x.isLeaf = false
x.depth = 1
})
data.provinces = r.data.data
} else {
message.errorMsg(r.data.message)
}
})
.catch(e => {
message.errorMsg(e.message)
})
},
initHotels() {
HotelService.GetHasStockHotelList()
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
data.cacheHotels = r.data.data
} else {
message.errorMsg(r.data.message)
}
})
.catch(e => {
message.errorMsg(e.message)
})
},
loadChilds(option: CascaderOption) {
return new Promise<void>(resolve => {
console.log('innnnnnn', option)
HotelService.GetDestination({ Id: option.ID })
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
r.data.data.forEach((x: any) => {
x.isLeaf = true
x.depth = 2
})
option.children = r.data.data
resolve()
} else {
message.errorMsg(r.data.message)
resolve()
}
})
.catch(e => {
message.errorMsg(e.message)
resolve()
})
})
},
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
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
}
}
const searchCnt = computed(() => {
let setCnt = 0
if ($q.platform.is.mobile) {
if (search.Province > 0) setCnt++
if (search.StartDate.length > 0) setCnt++
if (search.HotelChooseArray.length > 0) setCnt++
}
if (search.Star != 0) setCnt++
if (search.MaxPrice.length > 0) setCnt++
if (search.MinPrice.length > 0) setCnt++
return setCnt
})
methods.initAddress()
methods.initHotels()
return {
...toRefs(data),
...methods,
qDateProxy,
qNameProxy,
searchCnt,
search
}
}
})
</script>
<style>
</style>
<template>
<q-card flat bordered class="q-pa-md bg-white column" style="width:100vw;height: 80vh;">
<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>
</q-card>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs } from "vue";
import ChosenHeader from "./ChosenHeader.vue";
import ChosenTable from "./ChosenTable.vue";
export default defineComponent({
components: { ChosenHeader, ChosenTable },
setup(props) {
const data=reactive({})
const methods = {}
return {
...toRefs(data),
...methods
}
}
})
</script>
<style>
</style>
<template>
<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">
<div class="col"></div>
<div class="flex items-center q-ml-md" v-for="x in dateTypes">
<div class="cos-item-icon rounded-border q-mr-sm" :class="[x.bg]"></div>
<span class="f12">{{ x.text }}</span>
</div>
</div>
</template>
<template v-slot:header>
<q-tr>
<q-th>{{ $t('hotel.col.first') }}</q-th>
<q-th>{{ $t('hotel.col.second') }}</q-th>
<q-th v-for="(x, i) in cols">
{{ x }}
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td>
<div class="ellipsis-3-lines" style="padding: 7px 16px;width: 200px;white-space: break-spaces;">{{ props.row.HotelName }}</div>
</q-td>
<q-td>
<div class="td-item">{{ $t('hotel.table.price') }}</div>
<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)">
<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-tooltip>
<sample-price-list :price="x"></sample-price-list>
</q-tooltip>
</div>
</template>
<div class="td-item bg-dark" v-else></div>
<div class="td-item cursor-pointer">
{{ x.Inventory }}/{{ x.UseInventory }}/{{ x.RemainingInventory }}
</div>
<div class="td-item" :class="{ 'bg-red-9 text-white': x.UseInventory - x.Inventory > 0 }">
<span v-if="x.UseInventory - x.Inventory > 0">
{{ x.UseInventory - x.Inventory }}
</span>
</div>
</q-td>
</q-tr>
</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-table
hide-header
v-else
:rows="hotels"
grid
:columns="mobileCols"
row-key="name"
card-class="no-shadow bg-primary text-white"
:pagination="pages"
:loading="loading"
@row-click="viewHotelPriceListHandler"
>
<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>
</q-dialog>
</div>
</template>
<script lang="ts">
import { ApiResult } from '../../../@types/enumHelper'
import HotelService from '../../../api/hotel'
import { DirtionmaryHelper } from '../../../config/dictionary'
import message from '../../../utils/message'
import { defineComponent, inject, reactive, toRefs, watch } from 'vue'
import { date,useQuasar } from 'quasar'
import { DateType, getDateType, getDayOfWeek } from '../../../utils/tools'
import { useI18n } from 'vue-i18n'
import HotelPriceList from '../list/HotelPriceList.vue'
import SamplePriceList from '../list/SamplePriceList.vue'
export default defineComponent({
components: { HotelPriceList, SamplePriceList },
name: 'list-table',
setup() {
const $q=useQuasar()
const { t } = useI18n()
const search = inject(DirtionmaryHelper.HOTEL_QUERY_PARAM) as any
watch(search, (n, o) => {
if (data.loading) return
data.pages.pageIndex = 1
methods.calcDateRangeCols()
methods.initHotels()
})
const data = reactive({
hotels: [] as Array<any>,
loading: false,
cols: [] as Array<string>,
pages: {
pageIndex: 1,
pageSize: 10,
pageCount: 0,
rowsPerPage: 10
},
pageTitle: '' as (string | undefined),
dateTypes: [] as Array<DateType>,
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')}`}
],
showPriceList:false,
queryHotelObj:{},
orderSubmitObj:{} as any,
orderSubmitItemObj:{} as any,
showOrderPreview: false
})
data.dateTypes = getDateType()
data.pageTitle = inject(DirtionmaryHelper.PAGE_TITLE_KEY)
const methods = {
initHotels() {
data.loading = true
data.hotels = []
let param = Object.assign(data.pages, search)
HotelService.GetHotelList(param)
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
r.data.data.pageData.forEach((x: any) => {
x.subList.forEach((y: any) => {
y.PriceList.forEach((z: any) => {
z.ins = methods.getDateTypeById(z.InventoryType)
})
let cd=new Date(y.DateStr)
y.FormatDate=`${date.formatDate(cd, 'MM/DD')} (${getDayOfWeek(date.getDayOfWeek(cd))})`
})
if($q.platform.is.mobile){
x.LowerPrice=methods.calcLowerPrice(x)
}
})
data.hotels = r.data.data.pageData
} else {
message.errorMsg(r.data.message)
}
data.pages.pageCount = r.data.data.pageCount
data.loading = false
})
.catch(e => {
message.errorMsg(e.message)
data.loading = false
})
},
calcDateRangeCols() {
data.cols = []
let dateBegin = new Date(search.StartDate)
const dateEnd = new Date(search.EndDate)
while (dateBegin <= dateEnd) {
data.cols.push(`${date.formatDate(dateBegin, 'MM/DD')} (${getDayOfWeek(date.getDayOfWeek(dateBegin))})`)
dateBegin = date.addToDate(dateBegin, { days: 1 })
}
console.log(data.cols)
},
changePageHandler(n: any) {
console.log(n)
data.pages.pageIndex = n
methods.initHotels()
},
getDateTypeById(id: number) {
return data.dateTypes.find(x => x.id == id)
},
calcLowerPrice(hotel:any){
let lower=0
hotel.subList.forEach((x:any)=>{
if(x.PriceList &&x.PriceList.length>0){
x.PriceList.forEach((y:any)=>{
if(y.CostPrice>lower) lower= y.CostPrice
})
}
})
return lower
},
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()
methods.initHotels()
return { ...toRefs(data), ...methods }
}
})
</script>
<style>
.cos-item-icon {
width: 14px;
height: 14px;
border-radius: 4px;
}
.td-item {
width: 100%;
height: 35px;
line-height: 35px;
font-size: 13px;
font-family: 'Microsoft YaHei' !important;
color: var(--q-dark);
text-align: center;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}
.td-item:last-child {
border-bottom: none;
}
.hotel-table .q-table td {
padding: 0 !important;
}
/* .td-item.cursor-pointer:hover{
color: var(--q-primary) !important;
} */
</style>
......@@ -94,8 +94,8 @@ export default defineComponent({
data.scrollStyle = useScrollModule().scrollStyle
const search = inject(DirtionmaryHelper.HOTEL_QUERY_PARAM) as any
data.dateRange.to = date.formatDate(date.addToDate(new Date(), { days: 37 }), 'YYYY/MM/DD')
data.dateRange.from = date.formatDate(date.addToDate(new Date(), { days: 7 }), 'YYYY/MM/DD')
data.dateRange.to = date.formatDate(date.addToDate(new Date(), { days: 45 }), 'YYYY/MM/DD')
data.dateRange.from = date.formatDate(date.addToDate(new Date(), { days: 15 }), 'YYYY/MM/DD')
data.dateRangeFormat = `${data.dateRange.from} - ${data.dateRange.to}`
search.StartDate = data.dateRange.from
search.EndDate = data.dateRange.to
......@@ -162,7 +162,7 @@ export default defineComponent({
if (qDateProxy.value) qDateProxy.value.hide()
},
optionsFn(cd: any) {
return cd >= date.formatDate(date.addToDate(new Date(), { days: 7 }), 'YYYY/MM/DD')
return cd >= date.formatDate(date.addToDate(new Date(), { days: 15 }), 'YYYY/MM/DD')
},
changearea(e: number, option: any, pathValues: Array<any>) {
search.Province = 0
......
......@@ -22,7 +22,7 @@
<template v-slot:body="props">
<q-tr :props="props">
<q-td>
<div style="padding: 7px 16px">{{ props.row.HotelName }}</div>
<div class="ellipsis-3-lines" style="padding: 7px 16px;width: 200px;white-space: break-spaces;">{{ props.row.HotelName }}</div>
</q-td>
<q-td>
<div class="td-item">{{ $t('hotel.table.price') }}</div>
......@@ -232,9 +232,7 @@ export default defineComponent({
</script>
<style>
.q-dialog__inner--minimized > div{
max-width: unset !important;
}
.cos-item-icon {
width: 14px;
height: 14px;
......
......@@ -47,7 +47,10 @@ export default {
},
hotelm:{
pageTitle:"酒店訂單變更",
otherRoom:"添加其他房型",
otherRoom:"使用其他房型",
noneOther:"無其他可用房型",
save:'保存訂單',
cancel:'取消訂單'
},
hotelorder: {
dialog:{
......
This diff is collapsed.
......@@ -136,7 +136,7 @@ export function getHotelRoomType(getNormal:boolean = false):Array<RoomType>{
rooms.push({
TypeId:(i+1),
TypeName:x,
Filed:fileds[i]
Field:fileds[i]
})
})
return rooms
......
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