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
446a3afd
Commit
446a3afd
authored
Jan 06, 2023
by
罗超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新增票券
parent
96bc7069
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1597 additions
and
21 deletions
+1597
-21
quasar.conf.js
quasar.conf.js
+1
-1
index.ts
src/@types/index.ts
+5
-0
ImagePreview.vue
src/components/common/ImagePreview.vue
+1
-1
ListTable.vue
src/components/scattered/list/ListTable.vue
+9
-7
TicketCard.vue
src/components/ticket/TicketCard.vue
+217
-0
ListHeader.vue
src/components/ticket/list/ListHeader.vue
+108
-0
ListTable.vue
src/components/ticket/list/ListTable.vue
+126
-0
ModifyOrderAddress.vue
src/components/ticket/order/ModifyOrderAddress.vue
+66
-0
TicketOrderHeader.vue
src/components/ticket/order/TicketOrderHeader.vue
+141
-0
TicketOrderList.vue
src/components/ticket/order/TicketOrderList.vue
+418
-0
dictionary.ts
src/config/dictionary.ts
+10
-0
index.ts
src/i18n/zh-TW/index.ts
+86
-3
TicketList.vue
src/pages/ticket/TicketList.vue
+52
-0
TicketOrder.vue
src/pages/ticket/TicketOrder.vue
+50
-0
TicketOrderPreview.vue
src/pages/ticket/TicketOrderPreview.vue
+263
-0
routes.ts
src/router/routes.ts
+9
-6
menus.ts
src/utils/menus.ts
+2
-2
tools.ts
src/utils/tools.ts
+33
-1
No files found.
quasar.conf.js
View file @
446a3afd
...
...
@@ -64,7 +64,7 @@ module.exports = configure(function (ctx) {
publicPath
:
ctx
.
dev
?
'/'
:
'./'
,
env
:
ctx
.
dev
?
{
BASE_APP_API
:
'http
s://reborn.oytour.com/api/common/post'
,
//http://192.168.10.11:8083/api/common/post
BASE_APP_API
:
'http
://192.168.10.11:8083/api/common/post'
,
JAVA_URL_API
:
'http://efficient.oytour.com'
,
VERSION
:
require
(
'./package.json'
).
version
,
...
...
src/@types/index.ts
View file @
446a3afd
...
...
@@ -228,3 +228,8 @@ export type HotelType = {
Id
:
number
,
Name
:
string
}
export
type
SendType
=
{
Id
:
number
,
Name
:
string
,
Color
:
string
}
src/components/common/ImagePreview.vue
View file @
446a3afd
<
template
>
<div
style=
"width: 100vw !important; height: 100vh !important; overflow: hidden"
class=
"column items-center justify-center"
>
<q-img
width=
"100%"
height=
"100%"
:src=
"images[currentIndex]"
:img-style=
"
{'transform':scaleString+' '+rotateString}" spinner-color="primary" spinner-size="30px" fit="
cover
" />
<q-img
width=
"100%"
height=
"100%"
:src=
"images[currentIndex]"
:img-style=
"
{'transform':scaleString+' '+rotateString}" spinner-color="primary" spinner-size="30px" fit="
none
" />
<!--
<img
:src=
"images[currentIndex]"
class=
"drop-target"
:style=
"
{'transform':scaleString+' '+rotateString}"/> -->
</div>
<div
class=
"img-preview-tools-box"
style=
"box-shadow: none !important"
>
...
...
src/components/scattered/list/ListTable.vue
View file @
446a3afd
...
...
@@ -139,7 +139,8 @@ export default defineComponent({
const
$router
=
useRouter
()
watch
(
search
,
(
n
,
o
)
=>
{
if
(
data
.
loading
)
return
search
.
displayFrom
=
1
console
.
log
(
'search change'
)
data
.
pages
.
displayFrom
=
1
methods
.
initHotels
()
})
...
...
@@ -169,7 +170,7 @@ export default defineComponent({
mobileCols
:[
{
name
:
'hotelName'
,
label
:
t
(
'hotel.col.first'
),
field
:(
row
:
any
)
=>
row
.
hotelName
},
{
name
:
'TotalInventory'
,
label
:
t
(
'hotel.col.three'
),
field
:(
row
:
any
)
=>
row
.
TotalInventory
},
{
name
:
'LowerPrice'
,
label
:
t
(
'hotel.col.four'
),
field
:(
row
:
any
)
=>
`¥
${
row
.
LowerPrice
.
toFixed
(
2
)}${
$t
(
'unit.jp'
)}
$
{
t
(
'hotel.col.low'
)}
`
}
{
name
:
'LowerPrice'
,
label
:
t
(
'hotel.col.four'
),
field
:(
row
:
any
)
=>
`¥
${
row
.
LowerPrice
.
toFixed
(
2
)}${
t
(
'unit.jp'
)}
{t('hotel.col.low')}`
}
],
showPriceList
:
false
,
queryHotelObj
:{},
...
...
@@ -177,7 +178,7 @@ export default defineComponent({
orderSubmitItemObj
:{}
as
any
,
showOrderPreview
:
false
,
showHotelDetailId
:
0
,
})
data
.
themeList
=
useHotel
.
getHotelTheme
()
data
.
pageTitle
=
inject
(
DirtionmaryHelper
.
PAGE_TITLE_KEY
)
...
...
@@ -187,7 +188,7 @@ export default defineComponent({
initHotels
()
{
data
.
loading
=
true
data
.
hotels
=
[]
let
dataList
=
[];
let
dataList
=
[]
as
any
[]
;
data
.
travelLngLat
=
[];
let
param
=
Object
.
assign
(
data
.
pages
,
search
)
HotelService
.
GetJAPANHotelList
(
param
)
...
...
@@ -224,11 +225,11 @@ export default defineComponent({
})
//按价格升序
if
(
data
.
pages
.
sort
==
2
){
data
.
hotels
.
sort
(
methods
.
getSortFun
(
'asc'
,
'lowrateBySetCurrency'
));
data
.
hotels
.
sort
(
methods
.
getSortFun
(
'asc'
,
'lowrateBySetCurrency'
));
}
//按照星级降序
if
(
data
.
pages
.
sort
==
1
){
data
.
hotels
.
sort
(
methods
.
getSortFun
(
'desc'
,
'reviewRating'
));
data
.
hotels
.
sort
(
methods
.
getSortFun
(
'desc'
,
'reviewRating'
));
}
let
jalanTotalCount
=
0
if
(
r
.
data
.
data
.
parmResult
&&
r
.
data
.
data
.
parmResult
.
numberOfResultMatched
)
{
...
...
@@ -240,7 +241,7 @@ export default defineComponent({
ourHotelTotalCount
=
ourHotelList
[
0
].
totalHotelCount
;
}
let
totalCount
=
Number
(
jalanTotalCount
)
+
Number
(
ourHotelTotalCount
);
data
.
pageCount
=
r
.
data
.
data
.
parmResult
.
numberOfResultMatched
data
.
pageCount
=
Math
.
ceil
(
parseFloat
(
r
.
data
.
data
.
parmResult
.
numberOfResultMatched
)
/
data
.
pages
.
numberOfResults
)
data
.
groupBookingFlg
=
r
.
data
.
data
.
parmResult
.
groupBookingFlg
;
data
.
JapanIncrease
=
r
.
data
.
data
.
parmResult
.
JapanIncrease
;
data
.
loading
=
false
...
...
@@ -261,6 +262,7 @@ export default defineComponent({
},
changePageHandler
(
n
:
any
)
{
data
.
pages
.
displayFrom
=
n
console
.
log
(
n
)
methods
.
initHotels
()
},
showHotelDetailHandler
(
hotelId
:
number
){
...
...
src/components/ticket/TicketCard.vue
0 → 100644
View file @
446a3afd
This diff is collapsed.
Click to expand it.
src/components/ticket/list/ListHeader.vue
0 → 100644
View file @
446a3afd
<
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-input
v-model=
"searchClone.TicketName"
standout
:class=
"
{'q-ml-lg':$q.platform.is.desktop,'col':$q.platform.is.mobile}" style="min-width:190px;" dense :label="$t('v102.ticket.name')" />
<div
class=
"col"
v-if=
"$q.platform.is.desktop"
></div>
<q-btn
v-if=
"searchClone.ViewType==1"
:round=
"$q.platform.is.mobile"
:dense=
"$q.platform.is.mobile"
flat
:icon=
"$q.platform.is.desktop?'view_list':'view_stream'"
class=
"bg-grey-3 hover q-mr-md"
color=
"dark"
@
click=
"changeViewHandler(2)"
>
<q-tooltip
class=
"bg-dark"
>
{{
$t
(
'v102.ticket.toggleListType1'
)
}}
</q-tooltip>
</q-btn>
<q-btn
v-if=
"searchClone.ViewType==2"
:round=
"$q.platform.is.mobile"
:dense=
"$q.platform.is.mobile"
flat
icon=
"grid_view"
class=
"bg-grey-3 hover q-mr-md"
color=
"dark"
@
click=
"changeViewHandler(1)"
>
<q-tooltip
class=
"bg-dark"
>
{{
$t
(
'v102.ticket.toggleListType2'
)
}}
</q-tooltip>
</q-btn>
<q-btn
color=
"primary"
:round=
"$q.platform.is.mobile"
:dense=
"$q.platform.is.mobile"
:icon=
"$q.platform.is.mobile?'search':''"
unelevated
:label=
"$q.platform.is.mobile?'':$t('query')"
@
click=
"setSearchHandler"
/>
<!-- view_list grid_view -->
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
inject
,
reactive
,
toRefs
}
from
'vue'
import
{
DirtionmaryHelper
}
from
'src/config/dictionary'
import
HotelService
from
'src/api/hotel'
import
{
CascaderOption
,
NCascader
}
from
'naive-ui'
import
{
ApiResult
}
from
'src/@types/enumHelper'
import
message
from
'src/utils/message'
export
default
{
components
:
{
NCascader
},
setup
(
props
)
{
const
data
=
reactive
({
addressParams
:
{
Id
:
'651'
},
provinces
:
[],
cascader
:
{
addressValue
:
null
}
as
any
,
searchClone
:{}
as
any
})
const
search
=
inject
(
DirtionmaryHelper
.
TICKET_QUERY_PARAM
)
as
any
data
.
searchClone
=
JSON
.
parse
(
JSON
.
stringify
(
search
.
msg
))
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
)
})
},
loadChilds
(
option
:
CascaderOption
)
{
return
new
Promise
<
void
>
(
resolve
=>
{
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
()
})
})
},
changearea
(
e
:
number
,
option
:
any
,
pathValues
:
Array
<
any
>
)
{
data
.
searchClone
.
Province
=
0
data
.
searchClone
.
City
=
0
if
(
pathValues
)
{
if
(
pathValues
.
length
>
0
)
{
data
.
searchClone
.
Province
=
pathValues
[
0
].
ID
}
if
(
pathValues
.
length
>
1
)
{
data
.
searchClone
.
City
=
pathValues
[
1
].
ID
}
}
},
setSearchHandler
(){
search
.
msg
=
JSON
.
parse
(
JSON
.
stringify
(
data
.
searchClone
))
},
changeViewHandler
(
t
:
number
){
data
.
searchClone
.
ViewType
=
t
methods
.
setSearchHandler
()
}
}
methods
.
initAddress
()
return
{
...
toRefs
(
data
),
...
methods
}
}
}
</
script
>
<
style
></
style
>
src/components/ticket/list/ListTable.vue
0 → 100644
View file @
446a3afd
<
template
>
<div
v-if=
"search.msg.ViewType == 1 || $q.platform.is.mobile"
class=
"q-pt-lg row"
:class=
"
{ 'q-col-gutter-sm': $q.platform.is.mobile, 'q-col-gutter-lg': $q.platform.is.desktop }">
<q-card
v-for=
"x in tickets"
:class=
"
{ 'col-4': $q.screen.lt.lg
&&
$q.platform.is.desktop, 'col-3': $q.screen.gt.md
&&
$q.platform.is.desktop, 'col-6': $q.platform.is.mobile
&&
search.msg.ViewType == 1, 'col-12 q-mb-sm': $q.platform.is.mobile
&&
search.msg.ViewType == 2 }" class="transparent" flat>
<img
src=
"https://cdn.quasar.dev/img/mountains.jpg"
/>
<q-card-section
class=
"bg-white"
>
<div
class=
"text-subtitle1 text-weight-bolder ellipsis-2-lines cursor-pointer"
:class=
"
{ 'text-subtitle2': $q.platform.is.mobile }" @click="showCardHandler">四川阿壩州四姑娘山雙橋溝
</div>
<div
class=
"f12 text-grey-700 ellipsis"
>
中國 四川省阿坝藏族羌族自治州 小金縣 四姑娘山風景區
</div>
<div
class=
"q-mt-lg row items-center"
>
<div
class=
"text-grey-900 col"
:class=
"
{ f12: $q.platform.is.mobile, 'text-subtitle2 text-weight-bold': $q.platform.is.desktop }">
{{
$t
(
'v102.ticket.showtt.t1'
)
}}
<span
class=
"text-weight-bolder"
>
3
</span>
{{
$t
(
'v102.ticket.showtt.t2'
)
}}
</div>
<q-btn
color=
"primary"
icon=
"local_grocery_store"
unelevated
dense
size=
"sm"
:label=
"$q.platform.is.desktop || search.msg.ViewType == 2 ? $t('v102.ticket.buy') : $t('v102.ticket.shortBuy')"
@
click=
"toPreviewOrderHandler(1003)"
/>
</div>
</q-card-section>
</q-card>
</div>
<div
v-if=
"search.msg.ViewType == 2 && $q.platform.is.desktop"
class=
"q-pt-lg"
>
<q-card
v-for=
"i in tickets"
flat
class=
"full-width q-pa-sm row q-mb-md"
>
<div>
<q-img
src=
"http://imgfile.oytour.com/Upload/DMC/20200313032017962.jpg"
:ratio=
"16 / 9"
spinner-color=
"grey"
spinner-size=
"50px"
width=
"130px"
fit=
"cover"
class=
"rounded-borders"
/>
</div>
<div
class=
"q-ml-md col"
>
<div
class=
"text-subtitle1 text-weight-bolder cursor-pointer"
@
click=
"showCardHandler"
>
飞弹日枝山王神社
</div>
<div
class=
"f14 text-grey-600"
>
{{
$t
(
'v102.ticket.addr'
)
}}
:
<span>
〒930-0064 富山県富山市山王町4-12
</span>
<q-btn
color=
"primary"
icon=
"map"
:label=
"$t('v102.ticket.map')"
size=
"sm"
dense
flat
class=
"q-ml-md"
/>
</div>
<div>
<q-badge
outline
color=
"positive"
label=
"历史建筑"
class=
"q-mr-md"
/>
<q-badge
outline
color=
"positive"
label=
"人文景观"
/>
</div>
</div>
<div>
<div
class=
"text-h6 din text-negative"
>
<span>
900.00
</span>
<span
class=
"f12 text-grey-600 q-ml-sm"
>
{{
$t
(
'unit.jp'
)
}}{{
$t
(
'hotel.col.low'
)
}}
</span>
</div>
<div
class=
"text-right"
>
<q-btn
color=
"primary"
icon=
"shopping_cart"
:label=
"$t('v102.ticket.buy')"
dense
outline
size=
"sm"
@
click=
"toPreviewOrderHandler(1003)"
/>
</div>
</div>
</q-card>
</div>
<div
class=
"bg-white q-my-md q-pa-sm rounded-borders"
>
<q-pagination
class=
"full-width justify-end"
v-model=
"pages.PageIndex"
color=
"primary"
:max=
"pages.PageCount"
:input=
"true"
@
update:model-value=
"changePageHandler"
/>
</div>
<q-dialog
v-model=
"showDetails"
>
<ticket-card></ticket-card>
</q-dialog>
</
template
>
<
script
lang=
"ts"
>
import
{
useQuasar
}
from
'quasar'
import
{
DirtionmaryHelper
}
from
'src/config/dictionary'
import
{
defineComponent
,
inject
,
reactive
,
toRefs
,
watch
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
TicketCard
from
'../TicketCard.vue'
export
default
defineComponent
({
components
:
{
TicketCard
},
setup
(
props
)
{
const
$q
=
useQuasar
()
const
$router
=
useRouter
()
const
data
=
reactive
({
loading
:
false
,
pages
:
{
PageIndex
:
1
,
PageSize
:
10
,
PageCount
:
30
},
tickets
:
[]
as
any
[],
showDetails
:
false
})
if
(
$q
.
platform
.
is
.
desktop
)
{
if
(
$q
.
screen
.
gt
.
md
)
{
data
.
pages
.
PageSize
=
12
}
else
{
data
.
pages
.
PageSize
=
9
}
}
else
{
data
.
pages
.
PageSize
=
10
}
const
search
=
inject
(
DirtionmaryHelper
.
TICKET_QUERY_PARAM
)
as
any
watch
(
search
,
(
n
,
o
)
=>
{
if
(
data
.
loading
)
return
console
.
log
(
'search change'
)
data
.
pages
.
PageIndex
=
1
methods
.
getTickets
()
})
const
methods
=
{
getTickets
()
{
data
.
tickets
=
[]
for
(
let
i
=
0
;
i
<
data
.
pages
.
PageSize
;
i
++
)
{
data
.
tickets
.
push
({})
}
},
toPreviewOrderHandler
(
id
:
number
){
$router
.
push
({
path
:
`/ticket/preview/
${
id
}
`
})
},
changePageHandler
(
n
:
number
)
{
data
.
pages
.
PageIndex
=
n
methods
.
getTickets
()
},
showCardHandler
(){
data
.
showDetails
=
true
}
}
methods
.
getTickets
()
return
{
...
toRefs
(
data
),
...
methods
,
search
}
}
})
</
script
>
<
style
></
style
>
src/components/ticket/order/ModifyOrderAddress.vue
0 → 100644
View file @
446a3afd
<
template
>
<q-card
class=
"bg-white q-pa-md"
style=
"max-width: 500px; min-width: 375px; "
>
<div
class=
"text-h6 q-mb-lg"
>
{{
$t
(
'v102.to.m.t'
)
}}
</div>
<div
class=
"row items-center"
>
<span
class=
"f12 text-grey-900 text-subtitle2 text-weight-bold"
:class=
"
{ 'col-2': $q.platform.is.desktop, 'col-3': $q.platform.is.mobile }">
{{
$t
(
'v102.ticket.gi'
)
}}
:
</span>
<span
class=
"col f12"
>
<q-radio
v-model=
"m.OrderType"
checked-icon=
"task_alt"
unchecked-icon=
"panorama_fish_eye"
:val=
"0"
:label=
"$t('v102.ticket.zq')"
/>
<q-radio
v-model=
"m.OrderType"
checked-icon=
"task_alt"
unchecked-icon=
"panorama_fish_eye"
:val=
"1"
:label=
"$t('v102.ticket.yj')"
/>
</span>
</div>
<div
v-if=
"m.OrderType == 0"
class=
"bg-light-blue-1 q-pa-md fz14 rounded-borders q-mt-md"
>
<div
class=
"text-weight-bold"
>
{{
$t
(
'v102.ticket.zqs'
)
}}
</div>
<div
class=
"text-grey-900 q-mt-sm f12"
>
{{
$t
(
'v102.ticket.zqd'
)
}}
</div>
</div>
<div
v-else
>
<div
class=
"q-mt-md"
>
<span
class=
"f12 text-grey-900 text-subtitle2 text-weight-bold"
>
{{
$t
(
'v102.ticket.sj'
)
}}
</span>
</div>
<div
class=
"row items-center q-mt-md text-grey-600 q-mb-md"
v-if=
"$q.platform.is.desktop"
>
<div
class=
"col q-mr-md"
>
{{
$t
(
'v102.ticket.sjc.c1'
)
}}
</div>
<div
class=
"col q-mr-md"
>
{{
$t
(
'v102.ticket.sjc.c2'
)
}}
</div>
<!--
<div
class=
"col-2 q-mr-md"
>
{{
$t
(
'v102.ticket.sjc.c3'
)
}}
</div>
-->
<div
class=
"col q-mr-md"
>
{{
$t
(
'v102.ticket.sjc.c4'
)
}}
</div>
<div
class=
"col-4"
>
{{
$t
(
'v102.ticket.sjc.c5'
)
}}
</div>
</div>
<div
style=
"border-top: 1px dashed #eee"
:class=
"
{ 'row items-center': $q.platform.is.desktop, column: $q.platform.is.mobile }">
<q-input
dense
standout
v-model=
"m.ContactName"
class=
"col q-mt-md"
:class=
"
{ 'q-mr-md': $q.platform.is.desktop }" :placeholder="$t('v102.ticket.sjcp.c1')" />
<q-input
dense
standout
v-model=
"m.ContactEnName"
class=
"col q-mt-md"
:class=
"
{ 'q-mr-md': $q.platform.is.desktop }" :placeholder="$t('v102.ticket.sjcp.c2')" />
<q-input
dense
standout
v-model=
"m.ContactPhone"
class=
"col q-mt-md"
:class=
"
{ 'q-mr-md': $q.platform.is.desktop }" :placeholder="$t('v102.ticket.sjcp.c4')" />
<q-input
dense
standout
v-model=
"m.Address"
class=
"col-4 q-mt-md"
:placeholder=
"$t('v102.ticket.sjcp.c5')"
/>
</div>
</div>
<div
class=
"q-mt-md"
>
<q-input
v-model=
"m.Remark"
standout
autogrow
:label=
"$t('v102.ticket.or')"
/>
</div>
<div
class=
"q-mt-lg text-right"
>
<q-btn
color=
"negative"
class=
"q-px-lg"
:label=
"$t('v102.to.m.c')"
v-close-popup
flat
dense
/>
<q-btn
color=
"primary"
class=
"q-ml-md q-px-lg"
:label=
"$t('v102.to.m.c')"
v-close-popup
unelevated
dense
/>
</div>
</q-card>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
,
reactive
,
toRefs
,
watch
}
from
'vue'
export
default
defineComponent
({
props
:
[
'order'
],
setup
(
props
)
{
watch
(
()
=>
props
.
order
,
(
n
,
o
)
=>
{
data
.
m
=
JSON
.
parse
(
JSON
.
stringify
(
n
))
}
)
const
data
=
reactive
({
m
:
{}
as
any
})
const
methods
=
{}
data
.
m
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
order
))
return
{
...
toRefs
(
data
),
...
methods
}
}
})
</
script
>
<
style
></
style
>
src/components/ticket/order/TicketOrderHeader.vue
0 → 100644
View file @
446a3afd
<
template
>
<div
class=
"rounded-borders bg-white row items-center q-pa-md"
>
<q-select
v-if=
"$q.platform.is.desktop"
class=
"q-mr-md"
v-model=
"search.OrderStatus"
@
update:model-value=
"setOrderStatus"
dense
:options=
"status"
emit-value
option-label=
"StatusName"
option-value=
"StatusId"
map-options
:label=
"$t('hotelorder.search.status')"
standout
/>
<q-input
v-if=
"$q.platform.is.desktop"
class=
"q-mr-md"
v-model=
"search.OrderNo"
dense
standout
:label=
"$t('hotelorder.search.orderNum')"
/>
<q-field
v-if=
"$q.platform.is.desktop"
clearable
v-model=
"dateRangeFormat"
:label=
"$t('hotelorder.search.daterange')"
standout
class=
"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>
<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
class=
"q-mt-md row"
>
<q-input
v-model=
"search.OrderNo"
dense
standout
:label=
"$t('hotelorder.search.orderNum')"
class=
"mobile-only col q-mr-md"
/>
<q-input
v-model=
"search.OrderId"
dense
standout
:label=
"$t('hotelorder.search.orderId')"
class=
"col"
/>
</div>
<div
class=
"mobile-only q-mt-md"
>
<q-field
clearable
v-model=
"dateRangeFormat"
:label=
"$t('hotelorder.search.daterange')"
standout
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"
@
range-end=
"dateRangeHandler"
></q-date>
</q-popup-proxy>
</q-field>
</div>
<div
class=
"q-mt-md"
>
<q-input
v-model=
"search.TicketName"
dense
standout
:label=
"$t('v102.to.ticketName')"
/>
</div>
<q-select
class=
"q-mt-md"
v-model=
"search.OrderType"
dense
:options=
"orderTypes"
emit-value
option-label=
"TypeName"
option-value=
"TypeId"
map-options
:label=
"$t('v102.to.qj')"
standout
/>
<q-input
v-model=
"search.ContactName"
dense
standout
:label=
"$t('v102.to.qjc')"
class=
"q-mt-md"
v-if=
"search.OrderType == 1"
/>
<q-input
v-model=
"search.ContactNumber"
dense
standout
:label=
"$t('v102.to.qjp')"
class=
"q-mt-md"
v-if=
"search.OrderType == 1"
/>
</q-card>
</q-popup-proxy>
</q-btn>
<q-btn
unelevated
class=
"bg-blue-1 text-primary hover q-mr-md"
:label=
"$t('hotelorder.recovery')"
/>
<q-btn
color=
"primary"
unelevated
:label=
"$t('query')"
@
click=
"setQueryHandler"
/>
</div>
<div
class=
"rounded-borders bg-white q-pa-sm q-mt-md mobile-only"
>
<q-tabs
v-model=
"search.OrderStatus"
class=
"text-cyan"
dense
>
<q-tab
:name=
"x.StatusId"
:label=
"x.StatusName"
v-for=
"x in status"
@
click=
"setOrderStatus(x.StatusId)"
/>
</q-tabs>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
DirtionmaryHelper
}
from
'../../../config/dictionary'
import
{
computed
,
defineComponent
,
inject
,
reactive
,
ref
,
toRefs
}
from
'vue'
import
{
OrderType
,
RoomType
,
StandardStatus
}
from
'../../../@types'
import
{
getHotelOrderStatus
,
getHotelOrderType
,
getHotelRoomType
,
getTicketOrderType
}
from
'../../../utils/tools'
import
{
date
,
useQuasar
}
from
'quasar'
import
svgIcon
from
'../../global/svg-icon.vue'
export
default
defineComponent
({
components
:
{
svgIcon
},
setup
(
props
)
{
const
qDateProxy
=
ref
(
null
)
as
any
const
$q
=
useQuasar
()
const
data
=
reactive
({
status
:
[]
as
Array
<
StandardStatus
>
,
cancelStatus
:
{}
as
StandardStatus
|
undefined
,
dateRangeFormat
:
''
,
dateRange
:
{}
as
any
,
orderTypes
:
[]
as
Array
<
OrderType
>
,
canHide
:
false
})
const
realSearch
=
inject
(
DirtionmaryHelper
.
TICKET_ORDER_SEARCH
)
as
any
const
search
=
reactive
(
JSON
.
parse
(
JSON
.
stringify
(
realSearch
)))
as
any
const
methods
=
{
initStatus
()
{
//通用的訂單類型
let
allStatus
=
getHotelOrderStatus
()
data
.
status
=
allStatus
.
filter
((
x
:
StandardStatus
)
=>
{
return
x
.
StatusId
!=
3
})
data
.
cancelStatus
=
allStatus
.
find
((
x
:
StandardStatus
)
=>
{
return
x
.
StatusId
==
3
})
data
.
orderTypes
=
getTicketOrderType
(
true
)
},
optionsFn
(
cd
:
any
)
{
return
cd
<
date
.
formatDate
(
date
.
addToDate
(
new
Date
(),
{
days
:
1
}),
'YYYY/MM/DD'
)
},
dateRangeHandler
(
e
:
any
)
{
search
.
StartTime
=
`
${
e
.
from
.
year
}
/
${
e
.
from
.
month
}
/
${
e
.
from
.
day
}
`
search
.
EndTime
=
`
${
e
.
to
.
year
}
/
${
e
.
to
.
month
}
/
${
e
.
to
.
day
}
`
data
.
dateRangeFormat
=
`
${
search
.
StartTime
}
-
${
search
.
EndTime
}
`
if
(
qDateProxy
.
value
)
qDateProxy
.
value
.
hide
()
},
setQueryHandler
()
{
realSearch
.
OrderId
=
search
.
OrderId
realSearch
.
RoomType
=
search
.
RoomType
realSearch
.
StartTime
=
search
.
StartTime
realSearch
.
EndTime
=
search
.
EndTime
realSearch
.
OrderStatus
=
search
.
OrderStatus
realSearch
.
OrderNo
=
search
.
OrderNo
realSearch
.
OrderType
=
search
.
OrderType
realSearch
.
TCNum
=
search
.
TCNum
realSearch
.
ContactName
=
search
.
ContactName
realSearch
.
ContactNumber
=
search
.
ContactNumber
console
.
log
(
realSearch
)
},
setOrderStatus
(
statusId
:
number
)
{
realSearch
.
OrderStatus
=
statusId
}
}
const
searchCnt
=
computed
(()
=>
{
let
setCnt
=
0
if
(
$q
.
platform
.
is
.
mobile
)
{
if
(
search
.
OrderStatus
>
0
)
setCnt
++
if
(
search
.
StartTime
.
length
>
0
)
setCnt
++
if
(
search
.
OrderNo
>
0
)
setCnt
++
}
if
(
search
.
OrderId
.
length
>
0
)
setCnt
++
if
(
search
.
RoomType
>
0
)
setCnt
++
if
(
search
.
OrderType
>
0
)
setCnt
++
if
(
search
.
OrderType
==
1
&&
search
.
ContactName
.
length
>
0
)
setCnt
++
if
(
search
.
OrderType
==
2
&&
search
.
ContactNumber
.
length
>
0
)
setCnt
++
return
setCnt
})
methods
.
initStatus
()
return
{
...
toRefs
(
data
),
...
methods
,
search
,
searchCnt
}
}
})
</
script
>
<
style
></
style
>
src/components/ticket/order/TicketOrderList.vue
0 → 100644
View file @
446a3afd
This diff is collapsed.
Click to expand it.
src/config/dictionary.ts
View file @
446a3afd
...
...
@@ -35,6 +35,11 @@ class DirtionmaryHelper {
*/
static
readonly
HOTEL_ORDER_SEARCH
=
'hotelordersearch'
/**
* 景點订单查询条件
*/
static
readonly
TICKET_ORDER_SEARCH
=
'ticketordersearch'
/**
* 酒店購物車緩存
*/
...
...
@@ -78,5 +83,10 @@ class DirtionmaryHelper {
* 用户是否在中国
*/
static
readonly
USER_IN_COUNTRY
=
'userincountry'
/**
* 門票列表參數
*/
static
readonly
TICKET_QUERY_PARAM
=
"ticketlistquery"
}
export
{
userDictionmary
,
DirtionmaryHelper
}
src/i18n/zh-TW/index.ts
View file @
446a3afd
...
...
@@ -179,7 +179,7 @@ export default {
orderId
:
'訂單流水號'
,
orderType
:
'訂單類型'
,
tcNum
:
'組團號'
,
contactInfo
:
'聯繫
人
信息'
,
contactInfo
:
'聯繫信息'
,
contactInfoHolder
:
'請輸入聯繫人/聯繫電話'
},
orderType
:
{
...
...
@@ -782,7 +782,90 @@ export default {
quxiaodindan
:
'取消訂單'
}
}
},
//#endregion
//#region v1.0.2
v102
:{
ticket
:{
pageTitle
:
"票券檢索"
,
name
:
'請輸入票券名稱'
,
toggleListType1
:
"列表模式"
,
toggleListType2
:
"卡片模式"
,
showtt
:{
t1
:
'共'
,
t2
:
'種票型'
},
buy
:
'立即订票'
,
shortBuy
:
'預訂'
,
addr
:
'地址'
,
map
:
'地圖'
,
jing
:
'景點'
,
detail
:
'景區詳情'
,
d1
:
'開放時間'
,
d2
:
'景區特色'
,
d3
:
'交通說明'
,
d4
:
'溫馨提醒'
,
d5
:
'預訂須知'
,
preview
:{
pageTitle
:
'订单预览'
},
ordertip
:
'請在遊玩前一天的23:00前完成預訂'
,
pt
:
'遊玩日期'
,
tt
:
'選擇票型'
,
ti
:
'票券信息'
,
bc
:
'購買張數'
,
gi
:
'取票方式'
,
zq
:
'自行取票'
,
yj
:
'郵寄票券'
,
zqs
:
'自行取票說明'
,
zqd
:
'自行前往指定位置取票,當您完成付款後我們將通過郵件通知您取票的門票訊息'
,
sj
:
'收件人訊息'
,
unit
:
'張'
,
sex
:{
man
:
'男'
,
women
:
'女'
},
sjc
:{
c1
:
'中文姓名'
,
c2
:
'英文姓名'
,
c3
:
'性別'
,
c4
:
'聯絡電話'
,
c5
:
'收件地址'
},
sjcp
:{
c1
:
'請輸入中文姓名'
,
c2
:
'請輸入英文姓名'
,
c4
:
'請輸入聯絡電話'
,
c5
:
'請輸入收件地址'
},
st
:
'結算帳單'
,
rtt
:
'退票限制'
,
rtc
:
'未消費隨時可退,多張票訂單不支持部分退款'
,
ms
:
'訂票明細'
,
nt
:
'沒有選擇票券'
,
ds
:
'訂單總額'
,
sb
:
'提交訂單'
,
or
:
'訂單備註'
,
zqa
:
'自取地址'
,
nzqa
:
'等待客服確認後,才能看到自取地址,我們將會第一時間通過郵件告知您'
},
to
:{
pageTitle
:
'票券訂單列表'
,
ticketName
:
'票券名稱'
,
qj
:
'取券方式'
,
qjc
:
'取件人姓名(中/英)'
,
qjp
:
'取件人電話'
,
ps
:{
p1
:
'等待配送'
,
p2
:
'已配送'
},
m
:{
t
:
'修改取件方式'
,
c
:
'取消修改'
,
s
:
'保存修改'
}
}
},
//#endregion
}
src/pages/ticket/TicketList.vue
0 → 100644
View file @
446a3afd
<
template
>
<div
class=
"fix-height-subpage column no-wrap q-pa-md"
>
<list-header></list-header>
<list-table></list-table>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
inject
,
provide
,
reactive
,
toRefs
,
defineComponent
}
from
'vue'
;
import
useMetaModule
from
'../../module/meta/metaModule'
import
{
useI18n
}
from
'vue-i18n'
import
{
DirtionmaryHelper
}
from
'../../config/dictionary'
;
import
ListHeader
from
'src/components/ticket/list/ListHeader.vue'
;
import
ListTable
from
'src/components/ticket/list/ListTable.vue'
;
export
default
defineComponent
({
components
:
{
ListHeader
,
ListTable
},
setup
(
props
)
{
let
{
setTitle
}
=
useMetaModule
()
const
{
t
}
=
useI18n
()
const
pageTitle
=
inject
(
DirtionmaryHelper
.
PAGE_TITLE_KEY
)
as
any
pageTitle
.
value
=
t
(
'v102.ticket.pageTitle'
)
setTitle
(
pageTitle
.
value
)
const
data
=
reactive
({
})
const
search
=
reactive
({
msg
:{
StartDate
:
''
,
Country
:
'651'
,
Province
:
0
,
City
:
0
,
TicketName
:
''
,
ViewType
:
1
}
})
provide
(
DirtionmaryHelper
.
TICKET_QUERY_PARAM
,
search
)
const
menu
=
inject
(
DirtionmaryHelper
.
MENU_KEYS
)
as
any
menu
.
value
=
8
const
methods
=
{
}
return
{
...
toRefs
(
data
),
...
methods
}
}
})
</
script
>
<
style
>
</
style
>
src/pages/ticket/TicketOrder.vue
0 → 100644
View file @
446a3afd
<
template
>
<div
class=
"fix-height-subpage column no-wrap q-pa-md"
>
<ticket-order-header></ticket-order-header>
<ticket-order-list></ticket-order-list>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
,
inject
,
provide
,
reactive
,
toRefs
,
onMounted
}
from
'vue'
import
{
currentRouter
}
from
'src/router'
import
useMetaModule
from
'../../module/meta/metaModule'
import
{
useI18n
}
from
'vue-i18n'
import
TicketOrderHeader
from
'src/components/ticket/order/TicketOrderHeader.vue'
import
{
DirtionmaryHelper
}
from
'src/config/dictionary'
import
TicketOrderList
from
'src/components/ticket/order/TicketOrderList.vue'
export
default
defineComponent
({
components
:
{
TicketOrderHeader
,
TicketOrderList
},
setup
(
props
)
{
let
{
setTitle
}
=
useMetaModule
()
const
{
t
}
=
useI18n
()
const
pageTitle
=
inject
(
DirtionmaryHelper
.
PAGE_TITLE_KEY
)
as
any
pageTitle
.
value
=
t
(
'v102.to.pageTitle'
)
setTitle
(
pageTitle
.
value
)
const
search
=
reactive
({
OrderId
:
''
,
OrderNo
:
''
,
OrderStatus
:
0
,
StartTime
:
''
,
EndTime
:
''
,
TicketName
:
''
,
ContactName
:
''
,
ContactNumber
:
''
})
//search.OrderId = currentRouter.currentRoute.value.params.orderId
provide
(
DirtionmaryHelper
.
TICKET_ORDER_SEARCH
,
search
)
const
menu
=
inject
(
DirtionmaryHelper
.
MENU_KEYS
)
as
any
menu
.
value
=
9
const
data
=
reactive
({})
const
methods
=
{}
onMounted
(()
=>
{})
return
{
...
toRefs
(
data
),
...
methods
,
search
}
}
})
</
script
>
<
style
></
style
>
src/pages/ticket/TicketOrderPreview.vue
0 → 100644
View file @
446a3afd
This diff is collapsed.
Click to expand it.
src/router/routes.ts
View file @
446a3afd
...
...
@@ -10,12 +10,15 @@ const routes: RouteRecordRaw[] = [
{
path
:
'/hotel/order/:orderId?'
,
component
:
()
=>
import
(
'pages/hotel/HotelOrder.vue'
)
},
{
path
:
'/hotel/modify/:orderId'
,
component
:
()
=>
import
(
'pages/hotel/ModifyHotelOrder.vue'
)
},
{
path
:
'/hotel/offer/:orderId'
,
component
:
()
=>
import
(
'pages/hotel/ListOfQuotation.vue'
)
},
{
path
:
'/personal'
,
component
:
()
=>
import
(
'pages/personal/personal.vue'
)},
{
path
:
'/scattered'
,
component
:
()
=>
import
(
'pages/scattered/HotelList.vue'
)},
{
path
:
'/scattered/HotelDetails/:hotelId/:groupBookingFlg/:lowrateBySetCurrency'
,
component
:
()
=>
import
(
'pages/scattered/hotelDetails.vue'
)},
{
path
:
'/scattered/HotelSure/:hotelId/:roomOptionCd'
,
component
:
()
=>
import
(
'pages/scattered/HotelSure.vue'
)},
{
path
:
'/scattered/HotelOrder'
,
component
:
()
=>
import
(
'pages/scattered/HotelOrder.vue'
)},
{
path
:
'/comingsoon'
,
component
:
()
=>
import
(
'pages/ComingSoon.vue'
)}
{
path
:
'/personal'
,
component
:
()
=>
import
(
'pages/personal/personal.vue'
)
},
{
path
:
'/scattered'
,
component
:
()
=>
import
(
'pages/scattered/HotelList.vue'
)
},
{
path
:
'/scattered/HotelDetails/:hotelId/:groupBookingFlg/:lowrateBySetCurrency'
,
component
:
()
=>
import
(
'pages/scattered/hotelDetails.vue'
)
},
{
path
:
'/scattered/HotelSure/:hotelId/:roomOptionCd'
,
component
:
()
=>
import
(
'pages/scattered/HotelSure.vue'
)
},
{
path
:
'/scattered/HotelOrder'
,
component
:
()
=>
import
(
'pages/scattered/HotelOrder.vue'
)
},
{
path
:
'/comingsoon'
,
component
:
()
=>
import
(
'pages/ComingSoon.vue'
)
},
{
path
:
'/ticket/list'
,
component
:
()
=>
import
(
'pages/ticket/TicketList.vue'
)
},
{
path
:
'/ticket/preview/:ticketId'
,
component
:
()
=>
import
(
'pages/ticket/TicketOrderPreview.vue'
)},
{
path
:
'/ticket/order'
,
component
:
()
=>
import
(
'pages/ticket/TicketOrder.vue'
)}
]
},
{
...
...
src/utils/menus.ts
View file @
446a3afd
...
...
@@ -83,13 +83,13 @@ const useMenus={
childs
:[
{
name
:
t
(
'menu.ticket.second'
),
url
:
'/
comingsoon
'
,
url
:
'/
ticket/list
'
,
id
:
8
,
parentId
:
7
,
},
{
name
:
t
(
'menu.ticket.three'
),
url
:
'/
comingsoon
'
,
url
:
'/
ticket/order
'
,
id
:
9
,
parentId
:
7
,
}
...
...
src/utils/tools.ts
View file @
446a3afd
import
{
SitLang
,
StandardStatus
,
RoomType
,
OrderType
,
DinnerType
,
HotelType
}
from
'./../@types/index'
;
import
{
SitLang
,
StandardStatus
,
RoomType
,
OrderType
,
DinnerType
,
HotelType
,
SendType
}
from
'./../@types/index'
;
import
{
i18n
}
from
'../boot/i18n'
const
{
t
}
=
i18n
.
global
/**
...
...
@@ -216,6 +216,24 @@ export function getHotelOrderType(getNormal:boolean = false):Array<OrderType>{
return
types
}
export
function
getTicketOrderType
(
getNormal
:
boolean
=
false
):
Array
<
OrderType
>
{
let
types
=
[]
as
Array
<
OrderType
>
if
(
getNormal
){
types
.
push
({
TypeId
:
-
1
,
TypeName
:
t
(
'hotelorder.orderType.default'
)
})
}
let
typeLangs
=
[
t
(
'v102.ticket.zq'
),
t
(
'v102.ticket.yj'
)]
typeLangs
.
forEach
((
x
:
string
,
i
:
number
)
=>
{
types
.
push
({
TypeId
:
i
,
TypeName
:
x
})
})
return
types
}
export
function
getDinners
():
DinnerType
[]{
let
dinners
=
[]
as
Array
<
DinnerType
>
let
dinStr
=
[
t
(
'dinner.a'
),
t
(
'dinner.b'
),
t
(
'dinner.c'
)]
...
...
@@ -228,6 +246,20 @@ export function getDinners():DinnerType[]{
return
dinners
}
export
function
getSendType
():
SendType
[]{
let
sendType
=
[]
as
Array
<
SendType
>
let
sendStr
=
[
t
(
'v102.to.ps.p1'
),
t
(
'v102.to.ps.p2'
)]
let
colors
=
[
'text-negative'
,
'text-positive'
]
sendStr
.
forEach
((
x
:
string
,
i
:
number
)
=>
{
sendType
.
push
({
Id
:
i
+
2
,
Name
:
x
,
Color
:
colors
[
i
]
})
})
return
sendType
}
export
function
getHotelType
():
HotelType
[]{
let
hotelTypes
=
[]
as
Array
<
HotelType
>
...
...
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