Commit e334c745 authored by 罗超's avatar 罗超

完成手機版本

parent 6cecc1ed
......@@ -40,7 +40,7 @@ export default defineComponent({
@font-face
// 加粗数字字体
font-family: 'din'
src: url('../assets/fonts/DIN-Bold.otf') format('opentype')
src: url('./assets/fonts/DIN-Bold.otf') format('opentype')
font-weight: normal
font-style: normal
@font-face
......
<template>
<q-card flat class="light-shadow rounded-border window-width q-pa-none">
<q-card-section class="q-pa-sm">
<div class="text-h6">{{ h.HotelName }}</div>
<div class="f12 text-grey-5">{{ `${search.StartDate} 至 ${search.EndDate}` }} {{ $t('hotel.pricetips') }}</div>
</q-card-section>
<div style="max-height: 60vh; overflow-y: auto" class="q-pa-sm">
<template v-for="x in h.subList">
<div class="rounded-borders q-pa-sm q-mt-md" v-if="x.PriceList && x.PriceList.length > 0" :class="[x.PriceList[0].ins.bg, x.PriceList[0].ins.color]">
<div class="row items-center">
<div class="text-subtitle2 col">
{{ x.FormatDate }}
</div>
<div class="f12" style="opacity: 0.5" :class="[x.PriceList[0].ins.color]">{{ x.PriceList[0].ins.text }}</div>
</div>
<!-- <q-separator color="white" style="opacity: .3;"/> -->
<div class="row justify-between q-pb-sm" style="border-bottom: 1px dashed rgba(255, 255, 255, 0.2)">
<div class="price-item">
<div class="label">{{ $t('hotel.col.ins') }}</div>
<div class="din">{{ x.Inventory }}</div>
</div>
<div class="price-item">
<div class="label">{{ $t('hotel.col.sins') }}</div>
<div class="din">{{ x.RemainingInventory }}</div>
</div>
<div class="price-item">
<div class="label">{{ $t('hotel.col.uins') }}</div>
<div class="din">{{ x.UseInventory }}</div>
</div>
</div>
<div class="row justify-between items-center">
<div class="price-item">
<div class="label">{{ $t('hotel.col.five') }}</div>
<div class="row items-center">
<div class="din">{{ x.PriceList[0].CostPrice.toFixed(2) }}</div>
<!-- <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" />
</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">
<div class="label">{{ y.name }}</div>
<div class="f12">{{ y.price.toFixed(2) }}</div>
</div>
</div>
</div>
</template>
</div>
</q-card>
</template>
<script lang="ts">
import { DirtionmaryHelper } from '../../../config/dictionary'
import { defineComponent, toRefs, watch, reactive, inject } from 'vue'
import useScrollModule from '../../../module/scrollbar/scrollModule'
import { useI18n } from 'vue-i18n'
export default defineComponent({
props: {
hotel: {
type: Object,
default: {},
require: true
}
},
setup(props) {
const { t } = useI18n()
const data = reactive({
h: {} as any,
scrollStyle: {} as any
})
watch(
() => props.hotel,
(o, n) => {
methods.setCurrentHotel(n)
}
)
data.scrollStyle = useScrollModule().scrollStyle
const methods = {
setCurrentHotel(hotel:any) {
hotel.subList.forEach((x: any) => {
x.ShowMorePrice = false
if (x.PriceList && x.PriceList.length > 0) {
x.PriceList.forEach((y: any) => {
y.room = []
if (y.BidroomPrice > 0) {
y.room.push({
name: t('hotel.rooms.big'),
price: y.BidroomPrice
})
}
if (y.SingleroomPrice > 0) {
y.room.push({
name: t('hotel.rooms.sing'),
price: y.SingleroomPrice
})
}
if (y.AddBedPrice > 0) {
y.room.push({
name: t('hotel.rooms.three'),
price: y.GuideRoomPrice
})
}
if (y.GuideRoomPrice > 0) {
y.room.push({
name: t('hotel.rooms.driver'),
price: y.GuideRoomPrice
})
}
})
}
})
data.h = hotel
}
}
methods.setCurrentHotel(props.hotel)
const search = inject(DirtionmaryHelper.HOTEL_QUERY_PARAM) as any
return { ...toRefs(data), ...methods, search }
}
})
</script>
<style scoped>
.price-item {
margin-top: 8px;
}
.price-item .label {
opacity: 0.5;
font-size: 12px;
font-weight: 400;
}
</style>
<template>
<div class="full-height column">
<q-table
:grid="$q.platform.is.mobile"
: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 class="full-height column">
<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>
</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 style="padding:7px 16px;">{{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">
<template v-if="x.PriceList && x.PriceList.length>0">
<div class="td-item" :class="[x.PriceList[0].ins.bg,x.PriceList[0].ins.color]">
{{x.PriceList[0].CostPrice}}
</div>
</template>
<div class="td-item bg-dark" v-else></div>
<div class="td-item">
{{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" />
</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 style="padding: 7px 16px">{{ 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">
<template v-if="x.PriceList && x.PriceList.length > 0">
<div class="td-item" :class="[x.PriceList[0].ins.bg, x.PriceList[0].ins.color]">
{{ x.PriceList[0].CostPrice }}
</div>
</template>
</q-table>
</div>
<div class="td-item bg-dark" v-else></div>
<div class="td-item">{{ 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
:title="pageTitle"
: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"></hotel-price-list>
</q-dialog>
</div>
</template>
<script lang="ts">
......@@ -71,53 +79,77 @@ 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 } from 'quasar'
import { date,useQuasar } from 'quasar'
import { DateType, getDateType, getDayOfWeek } from '../../../utils/tools'
import { useI18n } from 'vue-i18n'
import HotelPriceList from './HotelPriceList.vue'
export default defineComponent({
components: { HotelPriceList },
name: 'list-table',
setup() {
const $q=useQuasar()
const { t } = useI18n()
inject(DirtionmaryHelper.HOTEL_QUERY_PARAM)
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()
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
cols: [] as Array<string>,
pages: {
pageIndex: 1,
pageSize: 10,
pageCount: 0,
rowsPerPage: 10
},
dateTypes:[] as Array<DateType>
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:{}
})
data.dateTypes=getDateType()
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)
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)
});
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.pages.pageCount = r.data.data.pageCount
data.loading = false
})
.catch(e => {
......@@ -125,23 +157,38 @@ export default defineComponent({
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})
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){
changePageHandler(n: any) {
console.log(n)
data.pages.pageIndex=n.page
data.pages.pageIndex = n
methods.initHotels()
},
getDateTypeById(id:number){
return data.dateTypes.find(x=>x.id==id)
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
}
}
methods.calcDateRangeCols()
......@@ -152,26 +199,25 @@ export default defineComponent({
</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;
}
.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;
}
</style>
......@@ -38,6 +38,7 @@ export default {
hotelRate: '酒店星級',
minPrice: '最低價格',
maxPrice: '最高價格',
car:{
shoppingTitle: '購物車',
addShopping: '加入購物車',
......@@ -50,21 +51,37 @@ export default {
small: '數量不能小於',
big: '大於剩餘數嘚',
},
pricetips: '酒店報價表',
buy:'預定',
table: {
price: '價格',
ins: '總/用/剩',
limit: '超定'
},
rooms:{
big:'大床房',
sing:'自然單間',
three:'三人間',
driver:'司導間'
},
col: {
first: '酒店名稱',
second: '價格&庫存'
second: '價格&庫存',
three: '總庫存',
four:'價格',
five:'標準間價格',
low:'起',
ins:'庫存',
sins:'剩餘庫存',
uins:'已預訂',
more:'更多房型報價'
},
datetype: {
red: '紅日',
pink: '旺季',
avg: '平日',
dan: '淡日',
spe: '特別',
spe: '特別',
xing: '行前日'
},
rates: {
......
<template>
<div class="fix-height-subpage column no-wrap q-pa-md">
<list-header></list-header>
<div class="light-shadow col q-mt-md q-pa-md bg-white rounded-border">
<div class="col q-mt-md" :class="{'light-shadow q-pa-md bg-white rounded-border':$q.platform.is.desktop}">
<list-table></list-table>
</div>
</div>
......@@ -9,7 +9,7 @@
<script lang="ts">
import useMetaModule from '../../module/meta/metaModule'
import { DateTimeFormatResult, useI18n } from 'vue-i18n'
import { useI18n } from 'vue-i18n'
import svgIcon from '../../components/global/svg-icon.vue'
import { inject, provide, reactive, ref, toRefs } from 'vue'
import { DirtionmaryHelper } from '../../config/dictionary'
......@@ -19,7 +19,7 @@ export default {
components: { svgIcon, ListHeader, ListTable },
setup() {
const data = reactive({})
console.log(' in ')
let { setTitle } = useMetaModule()
const { locale, t } = useI18n()
const pageTitle = inject(DirtionmaryHelper.PAGE_TITLE_KEY) as any
......
......@@ -4,7 +4,9 @@ const routes: RouteRecordRaw[] = [
{
path: '/index',
component: () => import('../layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('../pages/Index.vue') },{ path: '/hotel', component: () => import('../pages/hotel/HotelList.vue') }]
children: [
{ path: '', component: () => import('../pages/Index.vue') },
{ path: '/hotel', component: () => import('../pages/hotel/HotelList.vue') }]
},
{
path:'/auth/login',
......
......@@ -69,7 +69,7 @@ export function getDateType(){
id:4,
text:t('hotel.datetype.dan'),
color:'text-dark',
bg:'bg-grey-5'
bg:'bg-grey-3'
})
types.push({
id:5,
......
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