Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
bigwood
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
罗超
bigwood
Commits
94f3f544
Commit
94f3f544
authored
Nov 09, 2022
by
罗超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成表格
parent
b9692bff
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
918 additions
and
110 deletions
+918
-110
quasar.conf.js
quasar.conf.js
+1
-1
enumHelper.ts
src/@types/enumHelper.ts
+1
-1
App.vue
src/App.vue
+193
-9
hotel.ts
src/api/hotel.ts
+15
-0
List-Table.vue
src/components/hotel/list/List-Table.vue
+177
-0
ListHeader.vue
src/components/hotel/list/ListHeader.vue
+194
-0
dictionary.ts
src/config/dictionary.ts
+5
-0
table.sass
src/css/table.sass
+109
-0
index.ts
src/i18n/zh-TW/index.ts
+133
-96
MainLayout.vue
src/layouts/MainLayout.vue
+3
-3
hotelRate.ts
src/utils/hotelRate.ts
+29
-0
tools.ts
src/utils/tools.ts
+56
-0
tsconfig.json
tsconfig.json
+2
-0
No files found.
quasar.conf.js
View file @
94f3f544
...
...
@@ -64,7 +64,7 @@ module.exports = configure(function (ctx) {
env
:
ctx
.
dev
?
{
BASE_APP_API
:
'http://192.168.10.
206:8015
/api/common/post'
BASE_APP_API
:
'http://192.168.10.
11:8083
/api/common/post'
}
:
{
BASE_APP_API
:
'https://reborn.oytour.com/api/common/post'
...
...
src/@types/enumHelper.ts
View file @
94f3f544
...
...
@@ -34,4 +34,4 @@ export enum ScaleType {
'21-50人'
=
2
,
'51-100人'
=
3
,
'100人以上'
=
4
}
}
\ No newline at end of file
src/App.vue
View file @
94f3f544
...
...
@@ -10,28 +10,212 @@ export default defineComponent({
});
</
script
>
<
style
lang=
"sass"
>
@import
url('./css/font.sass')
@import
url('//at.alicdn.com/t/c/font_3734871_9agx0gqqibi.css')
.fix-height-subpage
position
:
absolute
left
:
0
right
:
0
top
:
0
bottom
:
0
.light-shadow
box-shadow
:
0px
0px
20px
0px
rgba
(
76
,
87
,
125
,
0
.02
)
@font-face
// 苹方字体
font-family
:
'pf'
src
:
url('../assets/fonts/PingFangMedium.ttf')
format
(
'truetype'
)
font-weight
:
normal
font-style
:
normal
@font-face
// 苹方加粗字体
font-family
:
'pfb'
src
:
url('../assets/fonts/PingFangBold.ttf')
format
(
'truetype'
)
font-weight
:
normal
font-style
:
normal
@font-face
// 微软雅黑极细字体
font-family
:
'msl'
src
:
url('../assets/fonts/MicrosoftYaHeiUISemilight.ttf')
format
(
'truetype'
)
font-weight
:
normal
font-style
:
normal
@font-face
// 加粗数字字体
font-family
:
'din'
src
:
url('../assets/fonts/DIN-Bold.otf')
format
(
'opentype'
)
font-weight
:
normal
font-style
:
normal
@font-face
// 正常英文字体
font-family
:
'Poppins'
src
:
url('../assets/fonts/Poppins-Regular.ttf')
format
(
'truetype'
)
font-weight
:
normal
font-style
:
normal
.pf
font-family
:
'pf'
.pfb
font-family
:
'pfb'
.msl
font-family
:
'msl'
.din
font-family
:
'din'
.Poppins
font-family
:
'Poppins'
.no-underline
text-decoration
:
none
!
important
.change-a-primary
color
:
var
(
--
q-dark
)
.change-a-primary
:hover
color
:
var
(
--
q-primary
)
.f12
font-family
:
'msl'
!
important
font-size
:
13px
.mycard
box-shadow
:
0
0
.5rem
1
.5rem
0
.5rem
rgba
(
0
,
0
,
0
,
0
.075
)
!
important
border-radius
:
0
.475rem
!
important
body
font-family
:
'-apple-system'
,
'BlinkMacSystemFont'
,
'Segoe UI'
,
'Roboto'
,
'Helvetica Neue'
,
'Arial'
,
'Apple Color Emoji'
,
'Segoe UI Emoji'
,
'Segoe UI Symbol'
,
'Noto Color Emoji'
,
'MicrosoftJhengHeiBoldFix'
,
'Microsoft JhengHei'
!
important
font-family
:
'
microsoft yahei'
,
'
-apple-system'
,
'BlinkMacSystemFont'
,
'Segoe UI'
,
'Roboto'
,
'Helvetica Neue'
,
'Arial'
,
'Apple Color Emoji'
,
'Segoe UI Emoji'
,
'Segoe UI Symbol'
,
'Noto Color Emoji'
,
'MicrosoftJhengHeiBoldFix'
,
'Microsoft JhengHei'
!
important
color
:
var
(
--
q-dark
)
.n-base-selection
.n-base-selection-label
background
:
#eee
!
important
.n-base-selection
.n-base-selection-label
,
.n-base-selection
.n-base-selection-tags
background
:
#f1f1f1
!
important
border-radius
:
5px
.n-base-selection
.n-base-selection-label
:active
,
.n-base-selection
.n-base-selection-label
:focus
.n-base-selection
.n-base-selection-label
:focus
,
.n-base-selection
.n-base-selection-tags
:active
,
.n-base-selection
.n-base-selection-tags
:focus
background
:
var
(
--
q-dark
)
!
important
.n-base-selection
.n-base-selection-label
:active
.n-base-selection-input__content
,
.n-base-selection
.n-base-selection-label
:focus
.n-base-selection-input__content
.n-base-selection
.n-base-selection-label
:focus
.n-base-selection-input__content
,
.n-base-selection
.n-base-selection-tags
:active
.n-base-selection-input__content
,
.n-base-selection
.n-base-selection-tags
:focus
.n-base-selection-input__content
color
:
#FFF
!
important
.n-base-selection
.n-base-selection-tags
:active
.n-tag
,
.n-base-selection
.n-base-selection-tags
:focus
.n-tag
background
:
#333
color
:
#FFF
!
important
border
:
none
!
important
.n-base-selection
.n-base-selection-tags
:active
.n-tag
.n-tag__border
,
.n-base-selection
.n-base-selection-tags
:focus
.n-tag
.n-tag__border
border
:
none
!
important
.n-tag
border-radius
:
4px
.n-base-selection
border
:
none
border
:
none
!
important
border-radius
:
5px
!
important
.n-base-selection
.n-base-selection__border
,
.n-base-selection
.n-base-selection__state-border
border
:
0px
solid
#333
!
important
border
:
0px
solid
#333
!
important
box-shadow
:
none
!
important
.v-binder-follower-container
position
:
absolute
z-index
:
99999999999
!
important
.sticky-column-table
max-width
:
100%
thead
background
:
rgb
(
245
,
246
,
247
)
thead
tr
:first-child
height
:
40px
line-height
:
14px
thead
tr
:first-child
th
font-size
:
12px
font-weight
:
400
color
:
rgb
(
168
,
168
,
179
)
thead
tr
:first-child
th
:first-child
background-color
:
rgb
(
245
,
246
,
247
)
td
:first-child
background-color
:
#fff
th
:first-child
,
td
:first-child
position
:
sticky
left
:
0
z-index
:
1
box-shadow
:
rgba
(
0
,
0
,
0
,
0
.05
)
2px
0px
0px
td
.none-shadow
box-shadow
:
none
.sticky-tow-column-table
max-width
:
100%
thead
background
:
rgb
(
245
,
246
,
247
)
thead
tr
:first-child
height
:
40px
line-height
:
14px
thead
tr
:first-child
th
font-size
:
12px
font-weight
:
400
color
:
rgb
(
168
,
168
,
179
)
thead
tr
:first-child
th
:nth-child
(
-n
+
2
)
background-color
:
rgb
(
245
,
246
,
247
)
td
:nth-child
(
-n
+
2
)
background-color
:
#fff
th
:nth-child
(
1
),
td
:nth-child
(
1
)
position
:
sticky
left
:
0
z-index
:
1
th
:nth-child
(
2
),
td
:nth-child
(
2
)
position
:
sticky
z-index
:
1
box-shadow
:
rgba
(
0
,
0
,
0
,
0
.05
)
2px
0px
0px
td
.none-shadow
box-shadow
:
none
.sticky-right-column-table
max-width
:
100%
thead
background
:
rgb
(
245
,
246
,
247
)
thead
tr
:first-child
height
:
40px
line-height
:
14px
thead
tr
:first-child
th
font-size
:
12px
font-weight
:
400
color
:
rgb
(
168
,
168
,
179
)
thead
tr
:first-child
th
:last-child
background-color
:
rgb
(
245
,
246
,
247
)
td
:last-child
background-color
:
#fff
th
:last-child
,
td
:last-child
position
:
sticky
right
:
0
z-index
:
1
box-shadow
:
rgba
(
0
,
0
,
0
,
0
.05
)
-2px
0px
0px
.sticky-header-table
.q-table__top
,
.q-table__bottom
,
thead
tr
:first-child
th
background-color
:
#f5f6f7
thead
tr
th
position
:
sticky
z-index
:
2
!
important
thead
tr
th
:first-child
z-index
:
3
!
important
thead
tr
:first-child
th
top
:
0
&
.q-table--loading
thead
tr
:last-child
th
top
:
48px
.no-bottom-table
.q-table__bottom
display
:
none
!
important
.sticky-header-column-table
td
:first-child
background-color
:
#c1f4cd
!
important
tr
th
position
:
sticky
z-index
:
2
background
:
#fff
thead
tr
:last-child
th
top
:
48px
z-index
:
3
thead
tr
:first-child
th
top
:
0
z-index
:
1
tr
:first-child
th
:first-child
z-index
:
3
td
:first-child
z-index
:
1
td
:first-child
,
th
:first-child
position
:
sticky
left
:
0
</
style
>
src/api/hotel.ts
View file @
94f3f544
...
...
@@ -9,9 +9,24 @@ class HotelService {
* @returns
*/
static
async
GetDestination
(
params
:
any
):
Promise
<
HttpResponse
>
{
return
request
(
'dict_post_Destination_GetChildList'
,
params
)
}
static
async
GetHasStockHotelList
():
Promise
<
HttpResponse
>
{
let
params
=
{
IsMoreThanZero
:
0
,
QCountry
:
"651"
}
return
request
(
'hotel_post_GetHasStockHotelList'
,
params
)
}
static
async
GetHotelList
(
param
:
any
):
Promise
<
HttpResponse
>
{
param
.
MaxPrice
=
param
.
MaxPrice
&&
param
.
MaxPrice
!=
''
?
param
.
MaxPrice
:
0
param
.
MinPrice
=
param
.
MinPrice
&&
param
.
MinPrice
!=
''
?
param
.
MinPrice
:
0
return
request
(
'dict_post_HotelOffer_GetClientHotelStatics'
,
param
)
}
/**
* 查詢酒店信息
* @param name 酒店名稱,支持空格分割
...
...
src/components/hotel/list/List-Table.vue
0 → 100644
View file @
94f3f544
<
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>
</
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"
/>
</
template
>
</q-table>
</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
}
from
'quasar'
import
{
DateType
,
getDateType
,
getDayOfWeek
}
from
'../../../utils/tools'
export
default
defineComponent
({
name
:
'list-table'
,
setup
()
{
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
()
})
const
data
=
reactive
({
hotels
:
[]
as
Array
<
any
>
,
loading
:
false
,
cols
:[]
as
Array
<
string
>
,
pages
:{
pageIndex
:
1
,
pageSize
:
10
,
pageCount
:
0
,
rowsPerPage
:
10
},
dateTypes
:[]
as
Array
<
DateType
>
})
data
.
dateTypes
=
getDateType
()
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
)
});
})
})
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
.
page
methods
.
initHotels
()
},
getDateTypeById
(
id
:
number
){
return
data
.
dateTypes
.
find
(
x
=>
x
.
id
==
id
)
}
}
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
;
}
</
style
>
src/components/hotel/list/ListHeader.vue
0 → 100644
View file @
94f3f544
<
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-popup-proxy
:offset=
"[0, 10]"
ref=
"qDateProxy"
>
<q-date
v-model=
"dateRange"
:options=
"optionsFn"
range
mask=
"YYYY/MM/DD"
landscape
@
range-end=
"dateRangeHandler"
></q-date>
</q-popup-proxy>
</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 q-mr-md"
: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"
>
{{
dateRangeFormat
}}
</div>
<q-popup-proxy
:offset=
"[0, 10]"
ref=
"qDateProxy"
>
<q-date
v-model=
"dateRange"
:options=
"optionsFn"
range
mask=
"YYYY/MM/DD"
landscape
@
range-end=
"dateRangeHandler"
></q-date>
</q-popup-proxy>
</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>
<q-btn
color=
"primary"
unelevated
:label=
"$t('query')"
/>
</div>
</
template
>
<
script
lang=
"ts"
>
import
svgIcon
from
'../../global/svg-icon.vue'
import
{
computed
,
inject
,
provide
,
reactive
,
ref
,
toRefs
,
defineComponent
}
from
'vue'
import
{
DirtionmaryHelper
}
from
'../../../config/dictionary'
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'
export
default
defineComponent
({
components
:
{
svgIcon
},
setup
()
{
const
$q
=
useQuasar
()
const
qDateProxy
=
ref
(
null
)
as
any
const
qNameProxy
=
ref
(
null
)
as
any
const
data
=
reactive
({
addressParams
:
{
Id
:
'651'
},
provinces
:
[],
cascader
:
{
addressValue
:
null
}
as
any
,
dateRange
:
{}
as
any
,
dateRangeFormat
:
''
,
hotelName
:
''
,
loading
:
false
,
cacheHotels
:
[]
as
Array
<
any
>
,
hotelsRates
:
[]
as
Array
<
HotelRate
>
,
canHide
:
false
})
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
.
dateRangeFormat
=
`
${
data
.
dateRange
.
from
}
-
${
data
.
dateRange
.
to
}
`
search
.
StartDate
=
data
.
dateRange
.
from
search
.
EndDate
=
data
.
dateRange
.
to
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
:
7
}),
'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
)
}
}
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
>
src/config/dictionary.ts
View file @
94f3f544
...
...
@@ -12,5 +12,10 @@ class DirtionmaryHelper {
* 子頁面傳遞給主界面的標題KEY
*/
static
readonly
PAGE_TITLE_KEY
=
'page_title_key'
/**
* 酒店查詢參數
*/
static
readonly
HOTEL_QUERY_PARAM
=
'hotelqueryparam'
}
export
{
userDictionmary
,
DirtionmaryHelper
}
src/css/table.sass
0 → 100644
View file @
94f3f544
.sticky-column-table
max-width
:
100%
thead
background
:
rgb
(
245
,
246
,
247
)
thead
tr
:first-child
height
:
40px
line-height
:
14px
thead
tr
:first-child
th
font-size
:
12px
font-weight
:
400
color
:
rgb
(
168
,
168
,
179
)
thead
tr
:first-child
th
:first-child
background-color
:
rgb
(
245
,
246
,
247
)
td
:first-child
background-color
:
#fff
th
:first-child
,
td
:first-child
position
:
sticky
left
:
0
z-index
:
1
box-shadow
:
rgba
(
0
,
0
,
0
,
0
.05
)
2px
0px
0px
td
.none-shadow
box-shadow
:
none
.sticky-tow-column-table
max-width
:
100%
thead
background
:
rgb
(
245
,
246
,
247
)
thead
tr
:first-child
height
:
40px
line-height
:
14px
thead
tr
:first-child
th
font-size
:
12px
font-weight
:
400
color
:
rgb
(
168
,
168
,
179
)
thead
tr
:first-child
th
:nth-child
(
-n
+
2
)
background-color
:
rgb
(
245
,
246
,
247
)
td
:nth-child
(
-n
+
2
)
background-color
:
#fff
th
:nth-child
(
1
),
td
:nth-child
(
1
)
position
:
sticky
left
:
0
z-index
:
1
th
:nth-child
(
2
),
td
:nth-child
(
2
)
position
:
sticky
z-index
:
1
box-shadow
:
rgba
(
0
,
0
,
0
,
0
.05
)
2px
0px
0px
td
.none-shadow
box-shadow
:
none
.sticky-right-column-table
max-width
:
100%
thead
background
:
rgb
(
245
,
246
,
247
)
thead
tr
:first-child
height
:
40px
line-height
:
14px
thead
tr
:first-child
th
font-size
:
12px
font-weight
:
400
color
:
rgb
(
168
,
168
,
179
)
thead
tr
:first-child
th
:last-child
background-color
:
rgb
(
245
,
246
,
247
)
td
:last-child
background-color
:
#fff
th
:last-child
,
td
:last-child
position
:
sticky
right
:
0
z-index
:
1
box-shadow
:
rgba
(
0
,
0
,
0
,
0
.05
)
-2px
0px
0px
.sticky-header-table
.q-table__top
,
.q-table__bottom
,
thead
tr
:first-child
th
background-color
:
#f5f6f7
thead
tr
th
position
:
sticky
z-index
:
2
!
important
thead
tr
th
:first-child
z-index
:
3
!
important
thead
tr
:first-child
th
top
:
0
&
.q-table--loading
thead
tr
:last-child
th
top
:
48px
.no-bottom-table
.q-table__bottom
display
:
none
!
important
.sticky-header-column-table
td
:first-child
background-color
:
#c1f4cd
!
important
tr
th
position
:
sticky
z-index
:
2
background
:
#fff
thead
tr
:last-child
th
top
:
48px
z-index
:
3
thead
tr
:first-child
th
top
:
0
z-index
:
1
tr
:first-child
th
:first-child
z-index
:
3
td
:first-child
z-index
:
1
td
:first-child
,
th
:first-child
position
:
sticky
left
:
0
\ No newline at end of file
src/i18n/zh-TW/index.ts
View file @
94f3f544
...
...
@@ -2,100 +2,137 @@
// so you can safely delete all default props below
export
default
{
failed
:
'執行失敗'
,
success
:
'執行成功'
,
appsuffix
:
"JVS同業預定系統"
,
siteName
:
"同業預定系統"
,
lanuage
:
"系統語言"
,
loginout
:
'登錄信息失效,請重新登錄'
,
timeout
:
'當前網絡環境異常,請求超時'
,
syslog
:
'系統升級告示'
,
sysmsg
:
'系統通知'
,
daterange
:
'請選擇檢索日期'
,
morequery
:
'更多篩選項'
,
query
:
'檢索'
,
Notifications
:{
title
:
'通知'
,
subtitle
:
'條新消息'
,
more
:
'更多'
,
time
:
'h'
},
hotel
:{
pageTitle
:
"酒店檢索"
,
area
:
"檢索區域"
,
searchName
:
'酒店名稱'
},
userMenu
:{
mypro
:
'個人檔案'
,
myfinace
:
'請求書'
,
fapiao
:
'索取發票'
,
lang
:
'系統語言'
,
signOut
:
'登出'
},
menu
:{
hotel
:{
first
:
'酒店預訂'
,
second
:
'酒店檢索'
,
three
:
'酒店訂單'
},
car
:{
first
:
'車輛預定'
,
second
:
'車輛預定'
,
three
:
'用車訂單'
},
ticket
:{
first
:
'門票預訂'
,
second
:
'門票檢索'
,
three
:
'門票訂單'
},
finance
:{
first
:
'帳單'
,
second
:
'月度請求書'
,
three
:
'匯款說明'
}
},
login
:{
notaccess
:
"沒有同業會員帳戶?"
,
registlink
:
"申請註冊"
,
title
:
"登入"
,
subTitle
:
"歡迎您的到來,開啟急速採購"
,
account
:
"帳戶(EMail)"
,
password
:
"密碼"
,
forgot
:
"忘記密碼?"
,
signin
:
"登入"
,
pageTitle
:
"登入"
,
ruleTipsAccount
:
"請填寫正確的郵箱帳號"
,
ruleTipsPwd
:
"請填寫密碼"
,
formTips
:
"請填寫登陸信息"
,
success
:
"登陸成功"
},
forget
:{
pageTitle
:
"忘记密码"
,
title
:
"忘記密碼"
,
subtitle
:
"輸入您的郵箱,以重置密碼"
,
notaccess
:
"已經是會員了?"
,
registlink
:
"登入"
,
account
:
"帳戶(EMail)"
,
submit
:
"提交"
,
cancel
:
"取消"
,
goback
:
"返回"
,
mailResult
:
"郵件已發送到您的郵箱,請根據郵件提示修改密碼"
,
resultBtn
:
"我已知曉"
},
newpwd
:{
pageTitle
:
"設置新密碼"
,
title
:
"設置新密碼"
,
subtitle
:
"為了您的帳戶安全,建議您定期修改密碼"
,
notaccess
:
"你已經重置密碼了嗎?"
,
registlink
:
"登入"
,
pass
:
"新密碼"
,
passTips
:
"使用8個或8個以上的字母、數字和符號的組合"
,
passvalidate
:
"請按照提示要求設置密碼"
,
repeatPassvalidate
:
"兩次輸入密碼不一致"
,
repeatPass
:
"再次輸入密碼"
,
notEmptyPass
:
'新密碼最少為8位'
,
maxLengthPass
:
'密碼長度應為8-16位'
,
updateResult
:
'新密碼已經設置成功,可以立即登入'
,
resultBtn
:
"立即登入"
}
failed
:
'執行失敗'
,
success
:
'執行成功'
,
appsuffix
:
'JVS同業預定系統'
,
siteName
:
'同業預定系統'
,
lanuage
:
'系統語言'
,
loginout
:
'登錄信息失效,請重新登錄'
,
timeout
:
'當前網絡環境異常,請求超時'
,
syslog
:
'系統升級告示'
,
sysmsg
:
'系統通知'
,
daterange
:
'請選擇檢索日期'
,
morequery
:
'更多篩選項'
,
query
:
'檢索'
,
noneData
:
'沒有找到相關的數據'
,
loading
:
'正在加載數據'
,
dayOfWeek
:
{
mon
:
'一'
,
tues
:
'二'
,
wed
:
'三'
,
thur
:
'四'
,
fri
:
'五'
,
sat
:
'六'
,
sun
:
'日'
},
Notifications
:
{
title
:
'通知'
,
subtitle
:
'條新消息'
,
more
:
'更多'
,
time
:
'h'
},
hotel
:
{
pageTitle
:
'酒店檢索'
,
area
:
'檢索區域'
,
searchName
:
'酒店名稱'
,
hotelRate
:
'酒店星級'
,
minPrice
:
'最低價格'
,
maxPrice
:
'最高價格'
,
table
:
{
price
:
'價格'
,
ins
:
'總/用/剩'
,
limit
:
'超定'
},
col
:
{
first
:
'酒店名稱'
,
second
:
'價格&庫存'
},
datetype
:
{
red
:
'紅日'
,
pink
:
'旺季'
,
avg
:
'平日'
,
dan
:
'淡日'
,
spe
:
'特別'
,
xing
:
'行前日'
},
rates
:
{
normal
:
'所有等級'
,
low
:
'三星或商務'
,
middle
:
'四星'
,
hight
:
'五星'
}
},
userMenu
:
{
mypro
:
'個人檔案'
,
myfinace
:
'請求書'
,
fapiao
:
'索取發票'
,
lang
:
'系統語言'
,
signOut
:
'登出'
},
menu
:
{
hotel
:
{
first
:
'酒店預訂'
,
second
:
'酒店檢索'
,
three
:
'酒店訂單'
},
car
:
{
first
:
'車輛預定'
,
second
:
'車輛預定'
,
three
:
'用車訂單'
},
ticket
:
{
first
:
'門票預訂'
,
second
:
'門票檢索'
,
three
:
'門票訂單'
},
finance
:
{
first
:
'帳單'
,
second
:
'月度請求書'
,
three
:
'匯款說明'
}
},
login
:
{
notaccess
:
'沒有同業會員帳戶?'
,
registlink
:
'申請註冊'
,
title
:
'登入'
,
subTitle
:
'歡迎您的到來,開啟急速採購'
,
account
:
'帳戶(EMail)'
,
password
:
'密碼'
,
forgot
:
'忘記密碼?'
,
signin
:
'登入'
,
pageTitle
:
'登入'
,
ruleTipsAccount
:
'請填寫正確的郵箱帳號'
,
ruleTipsPwd
:
'請填寫密碼'
,
formTips
:
'請填寫登陸信息'
,
success
:
'登陸成功'
},
forget
:
{
pageTitle
:
'忘记密码'
,
title
:
'忘記密碼'
,
subtitle
:
'輸入您的郵箱,以重置密碼'
,
notaccess
:
'已經是會員了?'
,
registlink
:
'登入'
,
account
:
'帳戶(EMail)'
,
submit
:
'提交'
,
cancel
:
'取消'
,
goback
:
'返回'
,
mailResult
:
'郵件已發送到您的郵箱,請根據郵件提示修改密碼'
,
resultBtn
:
'我已知曉'
},
newpwd
:
{
pageTitle
:
'設置新密碼'
,
title
:
'設置新密碼'
,
subtitle
:
'為了您的帳戶安全,建議您定期修改密碼'
,
notaccess
:
'你已經重置密碼了嗎?'
,
registlink
:
'登入'
,
pass
:
'新密碼'
,
passTips
:
'使用8個或8個以上的字母、數字和符號的組合'
,
passvalidate
:
'請按照提示要求設置密碼'
,
repeatPassvalidate
:
'兩次輸入密碼不一致'
,
repeatPass
:
'再次輸入密碼'
,
notEmptyPass
:
'新密碼最少為8位'
,
maxLengthPass
:
'密碼長度應為8-16位'
,
updateResult
:
'新密碼已經設置成功,可以立即登入'
,
resultBtn
:
'立即登入'
}
}
src/layouts/MainLayout.vue
View file @
94f3f544
...
...
@@ -43,18 +43,18 @@
</q-drawer>
<q-page-container
class=
"window-height"
>
<q-scroll-area
:thumb-style=
"scrollStyle.thumbStyle"
:bar-style=
"scrollStyle.barStyle"
class=
"full-height
q-pa-md
"
>
<q-scroll-area
:thumb-style=
"scrollStyle.thumbStyle"
:bar-style=
"scrollStyle.barStyle"
class=
"full-height"
>
<router-view
/>
</q-scroll-area>
</q-page-container>
<q-footer
class=
"bg-white text-dark"
>
<
!--
<
q-footer
class=
"bg-white text-dark"
>
<q-toolbar>
<q-toolbar-title>
<div
class=
"text-body2"
>
2022© JVS
</div>
</q-toolbar-title>
</q-toolbar>
</q-footer>
</q-footer>
-->
</q-layout>
</
template
>
...
...
src/utils/hotelRate.ts
0 → 100644
View file @
94f3f544
import
{
i18n
}
from
'../boot/i18n'
interface
HotelRate
{
id
:
number
,
name
:
string
}
const
{
t
}
=
i18n
.
global
const
useHotel
=
{
getHotelRate
():
HotelRate
[]{
let
rates
=
[]
as
HotelRate
[]
rates
.
push
({
id
:
0
,
name
:
t
(
'hotel.rates.normal'
)
})
rates
.
push
({
id
:
3
,
name
:
t
(
'hotel.rates.low'
)
})
rates
.
push
({
id
:
4
,
name
:
t
(
'hotel.rates.middle'
)
})
rates
.
push
({
id
:
5
,
name
:
t
(
'hotel.rates.hight'
)
})
return
rates
}
}
export
{
useHotel
,
type
HotelRate
}
\ No newline at end of file
src/utils/tools.ts
View file @
94f3f544
import
{
SitLang
}
from
'./../@types/index'
;
import
{
i18n
}
from
'../boot/i18n'
const
{
t
}
=
i18n
.
global
/**
* @description 按照需要写入 必要可以注入全局
*/
...
...
@@ -8,6 +10,13 @@ interface enumObj {
value
:
number
}
export
interface
DateType
{
id
:
number
,
bg
:
string
,
color
:
string
,
text
:
string
}
/**
* @description 将枚举转为数组
* @param objEnum 枚举对象
...
...
@@ -31,6 +40,53 @@ export function isNaNModified(inputStr: string) {
return
isNaN
(
numericRepr
)
||
numericRepr
.
toString
().
length
!=
inputStr
.
length
}
export
function
getDayOfWeek
(
day
:
number
){
let
weekLang
=
[
t
(
'dayOfWeek.mon'
),
t
(
'dayOfWeek.tues'
),
t
(
'dayOfWeek.wed'
),
t
(
'dayOfWeek.thur'
),
t
(
'dayOfWeek.fri'
),
t
(
'dayOfWeek.sat'
),
t
(
'dayOfWeek.sun'
)]
return
weekLang
[
day
-
1
]
}
export
function
getDateType
(){
let
types
=
[]
as
Array
<
DateType
>
types
.
push
({
id
:
1
,
text
:
t
(
'hotel.datetype.red'
),
color
:
'text-white'
,
bg
:
'bg-red-9'
})
types
.
push
({
id
:
2
,
text
:
t
(
'hotel.datetype.pink'
),
color
:
'text-white'
,
bg
:
'bg-pink-4'
})
types
.
push
({
id
:
3
,
text
:
t
(
'hotel.datetype.avg'
),
color
:
'text-white'
,
bg
:
'bg-indigo-6'
})
types
.
push
({
id
:
4
,
text
:
t
(
'hotel.datetype.dan'
),
color
:
'text-dark'
,
bg
:
'bg-grey-5'
})
types
.
push
({
id
:
5
,
text
:
t
(
'hotel.datetype.spe'
),
color
:
'text-white'
,
bg
:
'bg-green'
})
types
.
push
({
id
:
6
,
text
:
t
(
'hotel.datetype.xing'
),
color
:
'text-white'
,
bg
:
'bg-brown'
})
return
types
}
export
function
getLangs
()
{
const
zhTw
:
SitLang
=
{
langLocale
:
"zh-TW"
,
...
...
tsconfig.json
View file @
94f3f544
{
"extends"
:
"@quasar/app-vite/tsconfig-preset"
,
"compilerOptions"
:
{
"target"
:
"es2015"
,
"lib"
:
[
"es2017"
,
"DOM"
],
"baseUrl"
:
"."
,
"paths"
:
{
"@/*"
:
[
"src/*"
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment