7a7eddcf by zhangmeng

旅游

1 parent b693f3f5
...@@ -697,4 +697,16 @@ export function getVehicleMa1p(params) { // activityId ...@@ -697,4 +697,16 @@ export function getVehicleMa1p(params) { // activityId
697 }) 697 })
698 } 698 }
699 699
700 // 旅游
701
702 export function getGateListByLasId(params) { // scenicDate,lasId
703 return request({
704 url: `/ota/scenicConfig/getGateListByLasId`,
705 method: 'get',
706 params
707 })
708 }
709
710 // 旅游
711
700 712
......
1 <template> 1 <template>
2 <div> 2 <div>
3 <div class="box"> 3 <!-- top -->
4 <el-card v-loading="loading" class="mt30"> 4 <div class="container top">
5 <el-row v-if="form" class="hotel" align="middle" :gutter="20"> 5 <img :src="fillImgUrl(travel.cover)" alt="" class="cover_img">
6 <!-- <el-col :span="6">-->
7 <!-- <img class="w100" :src="fillImgUrl(form.photos?.split(',')[0])"/>-->
8 <!-- </el-col>-->
9 <el-col :span="language == 0?16:24">
10 <h3 class="esp flex">{{ form?.name }}
11
12 <div class="starBox ml20">
13 <img v-for="i in Number(form?.rank||0)" src="@/assets/booking/star.png">
14 </div>
15 </h3>
16
17 <!-- <div class="tagbox">-->
18 <!-- <span v-for="(t,index) in form?.label?.split(',')" v-show="index<4">{{ t }}</span>-->
19 <!-- <a v-show="form?.label?.split(',').length>4">{{ language == 0 ? '更多' : 'MORE' }} ></a>-->
20 <!-- </div>-->
21 <div class="info"> 6 <div class="info">
22 <el-icon> 7 <div class="title">{{ travel.name }}</div>
23 <Clock /> 8 <div class="select_item_box">
24 </el-icon> 9 <div class="label">
25 <span class="mr10">{{ language == 0 ? '开园时间' : 'Opening Time' }}{{ form?.startTime }}{{ form?.workTime }}</span> 10 {{ triggerLanguage(language, "时间", "Event Date & Time") }} :
26 </div> 11 </div>
27 <div class="info">
28 <el-icon>
29 <Phone />
30 </el-icon>
31 <span class="mr10">{{ language == 0 ? '联系方式' : 'Contact' }}{{ form?.contact }}</span>
32 </div> 12 </div>
33 <div class="info esp"> 13 <div class="select_item_box">
34 <el-icon> 14 <div class="select_item">
35 <MapLocation /> 15 <div
36 </el-icon> 16 v-for="(v, index) in travel.dateList"
37 <span>{{ form?.address }}</span> 17 :key="index"
18 :class="[
19 v== selectForm.scenicDate ? 'tagActive' : 'tag',
20 ]"
21 @click="select(v)"
22 >
23 {{ v }}
38 </div> 24 </div>
39 <div v-if="form?.introduction" class="info pointer">
40 <div :class="showAll?'':'esp_2'" @click="showAll=!showAll" v-html="form.introduction.toString()" />
41 </div> 25 </div>
42 </el-col> 26 </div>
43 </el-row> 27
44 <el-empty v-else :image="`/img/order_no.png`" :image-size="228" description="" /> 28 <div>
45 </el-card> 29 <!-- 成人票 -->
46 30 <br>
47 <div class="mt30"> 31 <div v-for="v in ticketList" v-show="v.leftNum!=0" :key="v.id">
48 <el-row :gutter="20"> 32 <div class="select_item_box">
49 <el-col :span="10"> 33 <div class="label ticket">
50 <div class="imgbox hotelImg"> 34 {{ v.name }} :
51 <el-image 35 </div>
52 :src="fillImgUrl(form?.photos?.split(',')[0])" fit="cover" 36 <div class="rowBox">
53 :preview-src-list="form?.photos?.split(',')" 37 <span class="titleTick">
38 {{
39 triggerLanguage(language, v.price, v.priceEn)
40 }}
41 {{
42 triggerLanguage(language, '¥/人', '€/person')
43 }}
44 </span>
45 <el-input-number
46 v-model="v.count" :max="v.leftNum" :min="0" :precision="0" class="inputNumber"
47 @change="countTotal"
54 /> 48 />
49 <i class="residue">{{ language == 0 ? '剩余票数' : 'Remaining votes' }}{{ v.leftNum }}</i>
55 </div> 50 </div>
56 </el-col>
57 <el-col :span="14">
58 <el-row class="h100" :gutter="20">
59 <el-col v-for="(p,index) in form?.photos?.split(',').slice(1,7)" :key="index" :span="8" class="oddmb">
60 <div class="imgbox hotelImg">
61 <el-image :src="fillImgUrl(p)" fit="cover" />
62 </div> 51 </div>
63 </el-col>
64 </el-row>
65 </el-col>
66 </el-row>
67 </div> 52 </div>
68 53
69 <el-card class="mt30 mb60"> 54 <!-- 价格 -->
70 <div class="lineHead"> 55 <div class="select_item_box">
71 <ul> 56 <div class="label">
72 <li> 57 {{ triggerLanguage(language, '价格', "Price") }} :
73 {{ language == 0 ? '选择日期' : 'tickets type' }}
74 </li>
75 </ul>
76 </div> 58 </div>
77 <div>
78 <!-- 日期-->
79 <el-calendar v-model="currentDate" class="mt20" :range="calendarRange">
80 <template #header="{date}">
81 <el-row style="width: 100%">
82 <el-col :lg="7" class="forPc" />
83 <el-col :lg="10" class="forPc">
84 <el-row justify="center" align="middle">
85 <!-- <div class="canBtn"><el-icon><ArrowLeftBold /></el-icon></div>-->
86 <div class="cTitle">
87 <!-- <el-date-picker-->
88 <!-- v-model="value2"-->
89 <!-- type="daterange"-->
90 <!-- range-separator="-"-->
91 <!-- start-placeholder="Start date"-->
92 <!-- end-placeholder="End date"-->
93 <!-- format="YYYY-MM-DD"-->
94 <!-- value-format="YYYY-MM-DD"-->
95 <!-- size="small"-->
96 <!-- @change="changee"-->
97 <!-- />-->
98 <!-- <el-input readonly :value="date" type="text" size="small" style="width: 280px"></el-input>-->
99 {{ date }}
100 </div> 59 </div>
101 <!-- <div class="canBtn"><el-icon><ArrowRightBold /></el-icon></div>--> 60 <div class="select_item_box">
102 </el-row> 61 <div class="select_item">
103 </el-col> 62 <div class="tagActive" style="min-width: 80px">
104 <el-col :lg="7" :xs="24"> 63 {{ language == 0 ? '¥' : '€' }} {{ language == 0 ? selectForm.price : selectForm.priceEn }}
105 <div style="text-align: right;padding-right: 10px"> 64 </div>
106 <el-date-picker 65 </div>
107 v-model="currentDate1" 66 </div>
108 type="date" 67 <!-- 购票备注-->
109 placeholder="YYYY-MM-DD" 68 <div v-if="matchForm.ticketRemark" class="select_item_box">
110 format="YYYY-MM-DD" 69 <div class="label">
111 :disabled-date="disabledDateRZ" 70 {{
112 :clearable="false" 71 triggerLanguage(language, '购票备注', "Ticket Purchase Note")
113 @change="dateChange" 72 }} :
114 />
115 </div> 73 </div>
116 </el-col>
117 </el-row>
118 </template>
119 <template #date-cell="data">
120 <div :class="data.data.day==query.currentDate?'primaryDate date':'date'" @click="selectDate(data.data.day)">
121 {{ data.data.day.slice(8, 10) }}
122 </div> 74 </div>
123 </template> 75 <div v-if="matchForm.ticketRemark" class="select_item_box">
124 </el-calendar> 76 <div class="select_item">
77 {{ matchForm.ticketRemark }}
78 </div>
125 </div> 79 </div>
126 80
127 <div class="text-center mt30"> 81 <div
128 <el-button 82 v-if="endTime<=0" class="btn" style="margin-left: 40px;opacity: 0.5;cursor: not-allowed;margin-top: 10px"
129 style="color: #fff" size="large" 83 @click="toSelectClosed"
130 class="w200px btn-lineG" :class="{'forbid':!(!hotTime[0])}" round @click="goOrder"
131 > 84 >
132 <span v-if="btnDisable">{{ language==0?'不在预定时间内':'OUT OF ORDER TIME' }}</span> 85 {{
133 <span v-else>{{ language==0?'立即预订':'BOOK NOW' }}</span> 86 triggerLanguage(language, "售票结束", "Sale closed")
134 </el-button> 87 }}
88 </div>
89 <div v-else class="btn" style="margin-left: 40px;margin-top: 10px" @click="toSelectSeat()">
90 {{
91 triggerLanguage(language, "立即购票", "Buy tickets now")
92 }}
93 </div>
94
95 </div>
96
97 </div>
98 </div>
99
100 <div class="container bottom">
101 <div style="display: flex">
102 <div :class="{'bg':active==1}" class="buBg" @click="active=1">{{ language == 0 ? '购票说明' : 'Notice' }}</div>
103 <div :class="{'bg' :active==2}" class="buBg" @click="active=2">{{
104 language == 0 ? '购票须知' : 'Instructions'
105 }}
106 </div>
107 </div>
108 <div v-show="active==1" class="rich_content" v-html="travel.descriptions" />
109 <div v-show="active==2" class="rich_content" v-html="travel.notice" />
110
111 <el-dialog v-model="show" title="" width="1000px">
112 <div>
113 <img :src="fillImgUrl(showUrl)" alt="" style="width: 100%">
135 </div> 114 </div>
136 </el-card> 115 </el-dialog>
137 </div> 116 </div>
138 </div> 117 </div>
139 </template> 118 </template>
140 119
120
141 <script setup> 121 <script setup>
142 import { useRouter } from 'vue-router' 122 import { ref, computed, onMounted } from 'vue'
143 import { ref, onMounted, computed } from 'vue' 123 import * as booking from '@/apiPc/booking'
144 import { useRoute } from 'vue-router'
145 import { dayjs } from 'element-plus'
146 import { getScenicById, checkOrderPay } from '@/apiPc/booking'
147 import { getBaseInfoByActiveId } from '@/apiPc/booking'
148 124
149 import { useStorage } from '@vueuse/core/index'
150 import { ElMessageBox } from 'element-plus' 125 import { ElMessageBox } from 'element-plus'
151 const currentDate = ref(new Date()) 126 import { fillImgUrl } from '/@/utils/ruoyi'
152 const currentDate1 = ref(new Date()) 127 import useUserStore from '/@/store/modules/user'
153 const calendarRange = ref([dayjs(currentDate.value).toDate(), (dayjs(currentDate.value).toDate())]) 128 import { triggerLanguage } from '@/utils/ruoyi'
129 import { useStorage } from '@vueuse/core/index'
130 import { useRoute, useRouter } from 'vue-router'
131 import { getCurrentInstance } from '@vue/runtime-core'
154 132
155 const language = useStorage('language', 0) 133 const language = useStorage('language', 0)
156 const router = useRouter() 134 const useStore = useUserStore()
135 const user = computed(() => useUserStore().user)
157 const route = useRoute() 136 const route = useRoute()
158 const form = ref({}) 137 const router = useRouter()
159 const query = ref({ 138 const show = ref(false)
160 lasId: route.query.lasId 139 const showUrl = ref('')
140 const activeId = ref(route.params.activeId)
141 const active = ref(1)
142
143 const timeData = ref()
144 const endTime = ref()
145 const matchForm = ref({})
146 const selectForm = ref({
147 latsId: null,
148 scenicDate: '',
149 price: '--',
150 priceEn: '--'
161 }) 151 })
162 const hotTime = ref([]) 152
163 const showAll = ref(false) 153 const { proxy } = getCurrentInstance()
164 const loading = ref(false) 154 const travel = ref({})
165 const formTime = ref({}) 155 const ticketList = ref([])
166 156
167 onMounted(() => { 157 onMounted(() => {
168 getBaseInfoByActiveId(route.params.cptId).then(res => { 158 getLogexScenicVoById()
169 formTime.value = res.data || null
170 }).catch(err => {
171 console.log(err)
172 formTime.value = null
173 }).finally(() => {
174 console.log(formTime.value)
175 getData()
176 })
177 }) 159 })
178 160
179 function getData() { 161 async function getLogexScenicVoById() {
180 loading.value = true 162 const res = await booking.getLogexScenicVoById({ id: activeId.value })
181 getScenicById(route.params.scenicId).then(res => { 163 travel.value = res.data
182 loading.value = false 164 selectForm.value.latsId = travel.value.id
183 form.value = res.data 165 if (travel.value.dateList && travel.value.dateList.length > 0) {
184 // initMap() 166 selectForm.value.scenicDate = travel.value.dateList[0]
185 }).catch(err => { 167 await getGateListByLasId()
186 console.log(err) 168 }
169 }
170
171 async function getGateListByLasId() {
172 const res = await booking.getGateListByLasId({
173 latsId: selectForm.value.latsId,
174 scenicDate: selectForm.value.scenicDate
187 }) 175 })
176 ticketList.value = res.data
177 for (const v of ticketList.value) {
178 v.leftNum = v.num - v.orderCount
179 v.count = 0
180 }
188 } 181 }
189 function dateChange() { 182
190 currentDate.value = currentDate1.value 183 function select(v) {
191 calendarRange.value = [dayjs(currentDate.value).toDate(), (dayjs(currentDate.value).toDate())] 184 selectForm.value.scenicDate = v
185 selectForm.value.price = '--'
186 selectForm.value.priceEn = '--'
187 getGateListByLasId()
192 } 188 }
193 189
194 function selectDate(date) { 190 function countTotal() {
195 query.value.currentDate = date 191 let price = 0
196 currentDate1.value = currentDate.value = dayjs(date).toDate() 192 let priceEn = 0
197 console.log(date) 193 for (const val of ticketList.value) {
194 if (val.count > 0) {
195 price += val.price * val.count
196 priceEn += val.priceEn * val.count
197 val.personArr = [...new Array(val.count).fill({
198 customerId: '',
199 name: '',
200 idcType: '',
201 idCard: ''
202 })]
203 }
204 }
205 selectForm.value.price = price
206 selectForm.value.priceEn = priceEn
198 } 207 }
199 208
200 const btnDisable = computed(() => { 209 async function toSelectSeat() {
201 if (formTime.value.scenicStart) { 210 if (!user.value) {
202 const curr = currentDate.value.valueOf() 211 useStore.setVisitor()
203 const today = dayjs(dayjs().format('YYYY-MM-DD')).valueOf() 212 return
204 const start = dayjs(formTime.value.scenicStart).valueOf()
205 const end = dayjs(formTime.value.scenicEnd).valueOf()
206 if (curr >= start && curr <= end && curr >= today) {
207 return false
208 }
209 } 213 }
210 return true
211 })
212 214
213 215 if (!selectForm.value.scenicDate) {
214 function goOrder() { 216 await proxy.$modal.confirm(language.value == 0 ? '请选择日期' : 'Please select a date')
215 if(btnDisable.value){
216 return 217 return
217 } 218 }
218 ElMessageBox.confirm(language.value == 0 ? `你当前选择的出行日期为${dayjs(currentDate.value).format('YYYY-MM-DD')}是否确定?` : `Your current check-in time is ${dayjs(currentDate.value).format('YYYY-MM-DD')} Are you sure?`, { type: 'warning' }).then({}).then(() => { 219 if (!selectForm.value.price == '--' || selectForm.value.price == '--') {
219 checkOrderPay(6).then(res => { 220 await proxy.$modal.confirm(language.value == 0 ? '请选择购票数量' : 'Please select the number of tickets to purchase')
220 if (res.data == -100) { 221 return
221 ElMessageBox.confirm(
222 language.value == 0 ? '你有未支付的旅游预订,是否前往个人中心查看' : 'You already have an unpaid travel order, do you want to go to the personal center to check it?',
223 language.value == 0 ? '提示' : 'Warning',
224 {
225 confirmButtonText: language.value == 1 ? 'Go My Reservation ' : '前往我的预订',
226 // cancelButtonText: language.value==1?'Continue to book':'继续预订',
227 type: 'warning'
228 } 222 }
229 ).then((res) => { 223 await checkOrderPay()
230 console.log(res) 224 }
231 router.push({ 225
226 async function checkOrderPay() {
227 const res = await booking.checkOrderPay(8)
228 if (res.data == -100) {
229 await proxy.$modal.confirm(language.value == 0 ? '你有未支付的旅游预订,是否前往个人中心查看?' : 'You already have an unpaid travel order, do you want to go to the personal center to check it?')
230 await router.push({
232 name: 'myReservation' 231 name: 'myReservation'
233 }) 232 })
234 }) 233 } else {
235 return
236 }
237 goNext() 234 goNext()
238 }) 235 }
239 })
240 } 236 }
241 237
242 function goNext() { 238 function goNext() {
243 router.push({ 239 router.push({
244 name: 'travelOrder', 240 name: 'travelOrder',
245 params: { 241 params: {
246 start: dayjs(currentDate.value).format('YYYY-MM-DD') 242 start: selectForm.value.scenicDate
247 }, 243 },
248 query: { 244 query: {
249 lasId: query.value.lasId 245 lasId: selectForm.value.latsId,
246 item: encodeURIComponent(JSON.stringify(ticketList.value))
250 } 247 }
251 }) 248 })
252 } 249 }
253 250
254 function disabledDateRZ(date) { 251 function toSelectClosed() {
255 // 判读今天大与form.value.hqStart 252 ElMessageBox.confirm(language.value == 0 ? '售票结束' : 'Sale closed', language.value == 0 ? '提示' : 'Tips', {
256 if (formTime.value.scenicStart) { 253 confirmButtonText: language.value == 0 ? '确定' : 'OK',
257 const today = dayjs().format('YYYY-MM-DD') 254 cancelButtonText: language.value == 0 ? '取消' : 'Cancel',
258 if (formTime.value.scenicStart < today) { 255 type: 'warning'
259 return !((date.getTime() >= dayjs(today).valueOf()) && (date.getTime() <= dayjs(formTime.value.scenicEnd).valueOf())) 256 })
260 } else {
261 return !((date.getTime() >= dayjs(formTime.value.scenicStart).valueOf()) && (date.getTime() <= dayjs(formTime.value.scenicEnd).valueOf()))
262 }
263 }
264 } 257 }
265 258
259
266 </script> 260 </script>
267 261
268 <style scoped lang="scss"> 262 <style lang="scss" scoped>
269 .room { 263 .forWei {
270 background: #FAFBFD; 264 display: none
271 margin: 20px 0 0; 265 }
272 padding: 20px;
273 border: 1px solid #E5E5E5;
274 266
275 .name { 267 .buBg {
276 font-size: 20px; 268 cursor: pointer;
277 margin: 0 0 10px; 269 font-size: 18px;
278 } 270 padding: 8px 13px;
271 border-radius: 5px;
272 margin-right: 10px;
273 }
279 274
280 .roomImg { 275 .bg {
281 aspect-ratio: 16/9; 276 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
282 border-radius: 10px; 277 color: #fff;
283 overflow: hidden; 278 }
284 279
285 img { 280 .container {
281 width: 1200px;
282 margin: 0 auto;
283 background-color: #fff;
284 box-shadow: 0 0 46px 0 rgba(1, 16, 64, 0.08);
285 border-radius: 8px;
286 box-sizing: border-box;
287 font-family: SourceHanSansCN, SourceHanSansCN;
288 padding-bottom: 20px;
289 }
290
291 .top {
292 display: flex;
293 padding: 19px;
294 margin-top: 26px;
295
296 .cover_img {
297 width: 500px;
298 object-fit: fill;
299 margin-right: 36px;
300 }
301
302 .info {
303 padding-top: 12px;
286 width: 100%; 304 width: 100%;
287 object-fit: cover; 305
288 object-position: center; 306 .title {
289 height: 100%; 307 font-weight: bold;
308 font-size: 28px;
309 color: #000000;
310 line-height: 1.6;
311 margin-bottom: 15px;
290 } 312 }
313
314 .time {
315 font-weight: 600;
316 font-size: 16px;
317 color: #000;
318 line-height: 24px;
319 margin-bottom: 16px;
291 } 320 }
292 321
293 .price { 322 .address {
294 color: #FF8124; 323 font-weight: 600;
295 font-size: 24px; 324 font-size: 16px;
325 color: #000;
326 line-height: 24px;
327 margin-bottom: 15px;
328 }
296 329
297 span { 330 .select_item_box {
298 font-size: 36px; 331 display: flex;
299 font-family: "DIN Alternate" 332 margin-bottom: 10px;
333
334 &:last-child {
335 margin-bottom: 0;
300 } 336 }
337
338 .label {
339 font-weight: 600;
340 font-size: 16px;
341 color: #000;
342 line-height: 24px;
343 margin-right: 12px;
344 flex-shrink: 0;
301 } 345 }
302 346
303 .bg-lineg { 347 .ticket {
304 margin: auto; 348 height: 40px;
305 border-radius: 10px; 349 line-height: 40px;
306 text-align: center; 350 width: 100px;
307 padding: 7px 2px 2px; 351 }
308 font-size: 24px; 352
309 width: 66px; 353 .rowBox {
354 display: flex;
355
356 .titleTick {
357 color: #493ceb;
310 cursor: pointer; 358 cursor: pointer;
359 font-weight: 600;
360 font-size: 18px;
361 margin-right: 30px;
362 height: 40px;
363 line-height: 40px;
364 width: 180px;
365 //text-align: center;
366 }
311 367
312 div { 368 .inputNumber {
313 background: #fff; 369 height: 35px;
314 font-size: 13px; 370 margin: 2.5px;
315 border-radius: 20px;
316 padding: 0 10px;
317 color: #453DEA;
318 font-weight: 500;
319 } 371 }
372
373 .residue {
374 height: 40px;
375 line-height: 40px;
376 font-size: 14px;
377 color: orange;
378 margin-left: 10px;
320 } 379 }
321 }
322 380
323 .hotel {
324 h3 {
325 margin: 0 0 20px;
326 } 381 }
327 382
328 img.w100 { 383 .forbid {
329 object-fit: cover; 384 opacity: 0.5 !important;
330 aspect-ratio: 16/9 385 cursor: not-allowed !important;
331 } 386 }
332 387
333 .addr { 388 .select_item {
334 font-size: 16px; 389 display: flex;
335 color: #929AA0; 390 flex-wrap: wrap;
391 gap: 10px;
392 user-select: none;
393
394 .tag_t {
395 padding: 1px 15px;
336 font-weight: 400; 396 font-weight: 400;
397 font-size: 14px;
398 color: #493ceb;
399 border-radius: 6px;
400 border: 1px solid #453dea;
401 margin-left: 5px;
402 }
403
404 .tag {
405 display: flex;
406 padding: 12px 18px;
407 background: #eeeeee;
408 border-radius: 4px;
409 border: 1px solid #29343c;
410 font-size: 14px;
411 color: #4a4a4a;
412 cursor: pointer;
337 } 413 }
338 414
339 .price { 415 .tagActive {
340 margin: 0 0 25px; 416 display: flex;
341 color: #FF8124; 417 padding: 12px 18px;
342 font-size: 18px; 418 background: #fff;
419 border-radius: 4px;
420 border: 1px solid #493ceb;
421 font-size: 14px;
422 color: #493ceb;
423 cursor: pointer;
424 }
343 425
344 span { 426 .tao {
345 font-size: 24px; 427 border: 1px solid #493ceb;
346 margin: 0 8px; 428 font-size: 14px;
347 font-family: 'DINAlternate-Bold'; 429 color: #493ceb;
348 font-weight: 600; 430 margin-left: 10px;
349 } 431 }
350 432
351 i { 433 .tagDisabled {
352 font-style: normal; 434 padding: 12px 18px;
353 color: #929AA0; 435 background: #878787;
436 border-radius: 4px;
437 border: 1px solid #29343c;
438 font-size: 14px;
439 color: #4a4a4a;
440 cursor: no-drop;
441 }
354 } 442 }
355 } 443 }
356 }
357 444
358 :deep(.button) { 445 .btn {
359 display: block; 446 width: 175px;
360 height: 55px; 447 height: 40px;
361 width: auto; 448 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
362 color: #fff; 449 border-radius: 20px;
450 line-height: 40px;
451 text-align: center;
452 font-weight: 500;
453 font-size: 16px;
454 color: #ffffff;
455 cursor: pointer;
456 }
457 }
458 }
363 459
364 span { 460 .bottom {
365 display: block !important; 461 padding: 50px;
462 margin-top: 30px;
463 margin-bottom: 30px;
366 464
367 div { 465 .title {
368 margin-top: 3px; 466 padding: 20px 30px;
467 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
468 font-weight: bold;
469 font-size: 20px;
470 color: #ffffff;
471 line-height: 30px;
472 margin-bottom: 30px;
369 } 473 }
474
475 .rich_content {
476 margin-top: 30px;
477
478 :deep(img) {
479 width: 100% !important;
480 height: auto !important;
370 } 481 }
371 482
483 }
372 } 484 }
373 485
374 .starBox { 486 @media screen and (max-width: 768px) {
375 img { 487 .container {
376 display: inline-block; 488 width: 100%;
377 margin-right: 4px 489 }
490 .forWei {
491 display: block
492 }
493 .top {
494 //transform: scale(0.5);transform-origin: left top;
495 .cover_img {
496 width: 120px;
497 height: 160px;
498 margin-right: 15px;
378 } 499 }
379 }
380 500
381 .tagbox { 501 .info {
382 margin: 15px 0; 502 padding: 0;
383 503
384 a { 504 .title {
385 color: #AFB5B9; 505 font-size: 14px;
386 font-size: 12px; 506 margin: 0;
387 } 507 }
388 508
389 span { 509 .time, .address, .label, .tip {
390 border-radius: 13px;
391 font-size: 12px; 510 font-size: 12px;
392 padding: 4px 10px;
393 margin-right: 10px;
394 font-weight: 400;
395 } 511 }
396 512
397 span:nth-child(4n) { 513 .title, .time, .address, .tip, .select_item_box {
398 background: rgba(50, 177, 108, 0.2); 514 margin-bottom: 3px;
399 color: rgba(50, 177, 108, 1);
400 } 515 }
401 516
402 span:nth-child(4n+1) { 517 .select_item_box {
403 background: rgba(243, 152, 0, 0.2); 518 .label {
404 color: rgba(243, 152, 0, 1); 519 font-size: 12px;
405 } 520 }
406 521
407 span:nth-child(4n+2) { 522 .select_item .tag {
408 background: rgba(0, 160, 233, 0.2); 523 padding: 2px 10px;
409 color: rgba(0, 160, 233, 1); 524 font-size: 12px;
410 } 525 }
411 526
412 span:nth-child(4n+3) { 527 .select_item .tagActive {
413 background: rgba(247, 64, 166, 0.2); 528 padding: 2px 10px;
414 color: rgba(247, 64, 166, 1); 529 font-size: 12px;
415 } 530 }
416 }
417 531
418 .mapBox { 532 .select_item .tagDisabled {
419 position: relative; 533 padding: 2px 10px;
420 overflow: hidden; 534 font-size: 12px;
421 height: 200px; 535 }
422
423 #map {
424 position: relative;
425 left: -70px;
426 width: calc(100% + 160px);
427 } 536 }
428 }
429
430 .hotelImg {
431 border-radius: 10px;
432 overflow: hidden;
433 aspect-ratio: 16/9;
434 537
435 img { 538 .btn {
436 object-fit: cover; 539 display: inline-block;
437 object-position: center; 540 margin: 10px 0 0;
438 width: 100%; 541 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
439 height: 100%; 542 border-radius: 20px;
543 line-height: 40px;
544 text-align: center;
545 font-weight: 500;
546 font-size: 16px;
547 color: #ffffff;
548 cursor: pointer;
549 }
550 }
551 }
552 .bottom {
553 padding: 0
440 } 554 }
441 }
442 555
443 .info {
444 font-weight: 400;
445 font-size: 14px;
446 color: #929AA0;
447 556
448 .el-icon {
449 margin-right: 5px;
450 }
451 } 557 }
452 558
453 .oddmb:nth-child(2) { 559 .countDownTitle {
454 margin-bottom: 20px; 560 text-align: center;
561 color: #000;
562 position: relative;
563 width: 100%;
564 left: 0;
565 font-size: 28px;
455 } 566 }
456 567
457 .forbid { 568 .countDownTitle span {
458 cursor: not-allowed !important; 569 background: #fff;
459 filter:grayscale(0.4);opacity: 0.7; 570 padding: 0 10px;
571 position: relative;
572 z-index: 1;
460 } 573 }
461 574
462 .forbid:hover { 575 .countDownTitle::after {
463 box-shadow: none; 576 position: absolute;
577 background: #ccc;
578 height: 1px;
579 content: '';
580 top: 0;
581 bottom: 0;
582 margin: auto;
583 width: 100%;
584 left: 0;
464 } 585 }
465 586
466 .lineHead{display: flex;justify-content: space-between;} 587 .van-count-down {
467 .el-calendar {
468 --el-calendar-border: none;
469 --el-calendar-cell-width: 40px;
470 text-align: center; 588 text-align: center;
471 --el-text-color-regular: #8E8D94; 589 margin: 20px 0;
472 590 display: flex;
473 :deep(.el-calendar__header) {
474 justify-content: center; 591 justify-content: center;
475 padding: 0 0 10px 592 }
476 }
477
478 :deep(.el-calendar__body) {
479 border: 1px solid #F0F0F0;
480 padding: 0
481 }
482
483 :deep(.el-calendar-table .el-calendar-day) {
484 padding: 1px;
485 }
486
487 :deep(.el-calendar-table td.is-selected) {
488 background: transparent;
489 }
490
491 :deep(.el-calendar__button-group) {
492 display: none;
493 }
494 593
495 :deep(.el-calendar-table thead th) { 594 .colon {
496 padding: 5px 0 0 595 display: inline-block;
497 } 596 font-size: 20px;
597 height: 110px;
598 line-height: 110px;
599 margin: 0 8px;
600 color: #7B7F83;
601 }
498 602
499 .primaryDate { 603 .block {
604 display: inline-block;
605 opacity: 0.7;
606 width: 100px;
607 height: 110px;
608 line-height: 110px;
500 color: #fff; 609 color: #fff;
501 background: linear-gradient(90deg, #8623FC, #453DEA); 610 font-size: 35px;
502 }
503
504 .date {
505 margin: auto;
506 border-radius: 50%;
507 width: 30px;
508 height: 30px;
509 line-height: 30px;
510 font-weight: bold; 611 font-weight: bold;
511 } 612 border-radius: 10px;
613 background: url(@/assets/img/djs_bg.png) left;
614 background-size: 100% 100%;
615 text-align: center;
512 } 616 }
513 617
618
514 </style> 619 </style>
......
1 <template>
2 <div>
3 <div class="box">
4 <el-card v-loading="loading" class="mt30">
5 <el-row v-if="form" :gutter="20" align="middle" class="hotel">
6 <!-- <el-col :span="6">-->
7 <!-- <img class="w100" :src="fillImgUrl(form.photos?.split(',')[0])"/>-->
8 <!-- </el-col>-->
9 <el-col :span="language == 0?16:24">
10 <h3 class="esp flex">{{ form?.name }}
11
12 <div class="starBox ml20">
13 <img v-for="i in Number(form?.rank||0)" src="@/assets/booking/star.png">
14 </div>
15 </h3>
16
17 <!-- <div class="tagbox">-->
18 <!-- <span v-for="(t,index) in form?.label?.split(',')" v-show="index<4">{{ t }}</span>-->
19 <!-- <a v-show="form?.label?.split(',').length>4">{{ language == 0 ? '更多' : 'MORE' }} ></a>-->
20 <!-- </div>-->
21 <div class="info">
22 <el-icon>
23 <Clock />
24 </el-icon>
25 <span class="mr10">{{ language == 0 ? '开园时间' : 'Opening Time' }}{{
26 form?.startTime
27 }}{{ form?.workTime }}</span>
28 </div>
29 <div class="info">
30 <el-icon>
31 <Phone />
32 </el-icon>
33 <span class="mr10">{{ language == 0 ? '联系方式' : 'Contact' }}{{ form?.contact }}</span>
34 </div>
35 <div class="info esp">
36 <el-icon>
37 <MapLocation />
38 </el-icon>
39 <span>{{ form?.address }}</span>
40 </div>
41 <div v-if="form?.introduction" class="info pointer">
42 <div :class="showAll?'':'esp_2'" @click="showAll=!showAll" v-html="form.introduction.toString()" />
43 </div>
44 </el-col>
45 </el-row>
46 <el-empty v-else :image="`/img/order_no.png`" :image-size="228" description="" />
47 </el-card>
48
49 <div class="mt30">
50 <el-row :gutter="20">
51 <el-col :span="10">
52 <div class="imgbox hotelImg">
53 <el-image
54 :preview-src-list="form?.photos?.split(',')" :src="fillImgUrl(form?.photos?.split(',')[0])"
55 fit="cover"
56 />
57 </div>
58 </el-col>
59 <el-col :span="14">
60 <el-row :gutter="20" class="h100">
61 <el-col v-for="(p,index) in form?.photos?.split(',').slice(1,7)" :key="index" :span="8" class="oddmb">
62 <div class="imgbox hotelImg">
63 <el-image :src="fillImgUrl(p)" fit="cover" />
64 </div>
65 </el-col>
66 </el-row>
67 </el-col>
68 </el-row>
69 </div>
70
71 <el-card class="mt30 mb60">
72 <div class="lineHead">
73 <ul>
74 <li>
75 {{ language == 0 ? '选择日期' : 'tickets type' }}
76 </li>
77 </ul>
78 </div>
79 <div>
80 <!-- 日期-->
81 <el-calendar v-model="currentDate" :range="calendarRange" class="mt20">
82 <template #header="{date}">
83 <el-row style="width: 100%">
84 <el-col :lg="7" class="forPc" />
85 <el-col :lg="10" class="forPc">
86 <el-row align="middle" justify="center">
87 <!-- <div class="canBtn"><el-icon><ArrowLeftBold /></el-icon></div>-->
88 <div class="cTitle">
89 <!-- <el-date-picker-->
90 <!-- v-model="value2"-->
91 <!-- type="daterange"-->
92 <!-- range-separator="-"-->
93 <!-- start-placeholder="Start date"-->
94 <!-- end-placeholder="End date"-->
95 <!-- format="YYYY-MM-DD"-->
96 <!-- value-format="YYYY-MM-DD"-->
97 <!-- size="small"-->
98 <!-- @change="changee"-->
99 <!-- />-->
100 <!-- <el-input readonly :value="date" type="text" size="small" style="width: 280px"></el-input>-->
101 {{ date }}
102 </div>
103 <!-- <div class="canBtn"><el-icon><ArrowRightBold /></el-icon></div>-->
104 </el-row>
105 </el-col>
106 <el-col :lg="7" :xs="24">
107 <div style="text-align: right;padding-right: 10px">
108 <el-date-picker
109 v-model="currentDate1"
110 :clearable="false"
111 :disabled-date="disabledDateRZ"
112 format="YYYY-MM-DD"
113 placeholder="YYYY-MM-DD"
114 type="date"
115 @change="dateChange"
116 />
117 </div>
118 </el-col>
119 </el-row>
120 </template>
121 <template #date-cell="data">
122 <div
123 :class="data.data.day==query.currentDate?'primaryDate date':'date'"
124 @click="selectDate(data.data.day)"
125 >
126 {{ data.data.day.slice(8, 10) }}
127 </div>
128 </template>
129 </el-calendar>
130 </div>
131
132 <div class="text-center mt30">
133 <el-button
134 :class="{'forbid':!(!hotTime[0])}" class="w200px btn-lineG"
135 round size="large" style="color: #fff" @click="goOrder"
136 >
137 <span v-if="btnDisable">{{ language == 0 ? '不在预定时间内' : 'OUT OF ORDER TIME' }}</span>
138 <span v-else>{{ language == 0 ? '立即预订' : 'BOOK NOW' }}</span>
139 </el-button>
140 </div>
141 </el-card>
142 </div>
143 </div>
144 </template>
145
146 <script setup>
147 import { useRouter } from 'vue-router'
148 import { ref, onMounted, computed } from 'vue'
149 import { useRoute } from 'vue-router'
150 import { dayjs } from 'element-plus'
151 import { getScenicById, checkOrderPay } from '@/apiPc/booking'
152 import { getBaseInfoByActiveId } from '@/apiPc/booking'
153
154 import { useStorage } from '@vueuse/core/index'
155 import { ElMessageBox } from 'element-plus'
156
157 const currentDate = ref(new Date())
158 const currentDate1 = ref(new Date())
159 const calendarRange = ref([dayjs(currentDate.value).toDate(), (dayjs(currentDate.value).toDate())])
160
161 const language = useStorage('language', 0)
162 const router = useRouter()
163 const route = useRoute()
164 const form = ref({})
165 const query = ref({
166 lasId: route.query.lasId
167 })
168 const hotTime = ref([])
169 const showAll = ref(false)
170 const loading = ref(false)
171 const formTime = ref({})
172
173 onMounted(() => {
174 getBaseInfoByActiveId(route.params.cptId).then(res => {
175 formTime.value = res.data || null
176 }).catch(err => {
177 console.log(err)
178 formTime.value = null
179 }).finally(() => {
180 console.log(formTime.value)
181 getData()
182 })
183 })
184
185 function getData() {
186 loading.value = true
187 getScenicById(route.params.scenicId).then(res => {
188 loading.value = false
189 form.value = res.data
190 // initMap()
191 }).catch(err => {
192 console.log(err)
193 })
194 }
195
196 function dateChange() {
197 currentDate.value = currentDate1.value
198 calendarRange.value = [dayjs(currentDate.value).toDate(), (dayjs(currentDate.value).toDate())]
199 }
200
201 function selectDate(date) {
202 query.value.currentDate = date
203 currentDate1.value = currentDate.value = dayjs(date).toDate()
204 console.log(date)
205 }
206
207 const btnDisable = computed(() => {
208 if (formTime.value.scenicStart) {
209 const curr = currentDate.value.valueOf()
210 const today = dayjs(dayjs().format('YYYY-MM-DD')).valueOf()
211 const start = dayjs(formTime.value.scenicStart).valueOf()
212 const end = dayjs(formTime.value.scenicEnd).valueOf()
213 if (curr >= start && curr <= end && curr >= today) {
214 return false
215 }
216 }
217 return true
218 })
219
220
221 function goOrder() {
222 if (btnDisable.value) {
223 return
224 }
225 ElMessageBox.confirm(language.value == 0 ? `你当前选择的出行日期为${dayjs(currentDate.value).format('YYYY-MM-DD')}是否确定?` : `Your current check-in time is ${dayjs(currentDate.value).format('YYYY-MM-DD')} Are you sure?`, { type: 'warning' }).then({}).then(() => {
226 checkOrderPay(6).then(res => {
227 if (res.data == -100) {
228 ElMessageBox.confirm(
229 language.value == 0 ? '你有未支付的旅游预订,是否前往个人中心查看' : 'You already have an unpaid travel order, do you want to go to the personal center to check it?',
230 language.value == 0 ? '提示' : 'Warning',
231 {
232 confirmButtonText: language.value == 1 ? 'Go My Reservation ' : '前往我的预订',
233 // cancelButtonText: language.value==1?'Continue to book':'继续预订',
234 type: 'warning'
235 }
236 ).then((res) => {
237 console.log(res)
238 router.push({
239 name: 'myReservation'
240 })
241 })
242 return
243 }
244 goNext()
245 })
246 })
247 }
248
249 function goNext() {
250 router.push({
251 name: 'travelOrder',
252 params: {
253 start: dayjs(currentDate.value).format('YYYY-MM-DD')
254 },
255 query: {
256 lasId: query.value.lasId
257 }
258 })
259 }
260
261 function disabledDateRZ(date) {
262 // 判读今天大与form.value.hqStart
263 if (formTime.value.scenicStart) {
264 const today = dayjs().format('YYYY-MM-DD')
265 if (formTime.value.scenicStart < today) {
266 return !((date.getTime() >= dayjs(today).valueOf()) && (date.getTime() <= dayjs(formTime.value.scenicEnd).valueOf()))
267 } else {
268 return !((date.getTime() >= dayjs(formTime.value.scenicStart).valueOf()) && (date.getTime() <= dayjs(formTime.value.scenicEnd).valueOf()))
269 }
270 }
271 }
272
273 </script>
274
275 <style lang="scss" scoped>
276 .room {
277 background: #FAFBFD;
278 margin: 20px 0 0;
279 padding: 20px;
280 border: 1px solid #E5E5E5;
281
282 .name {
283 font-size: 20px;
284 margin: 0 0 10px;
285 }
286
287 .roomImg {
288 aspect-ratio: 16/9;
289 border-radius: 10px;
290 overflow: hidden;
291
292 img {
293 width: 100%;
294 object-fit: cover;
295 object-position: center;
296 height: 100%;
297 }
298 }
299
300 .price {
301 color: #FF8124;
302 font-size: 24px;
303
304 span {
305 font-size: 36px;
306 font-family: "DIN Alternate"
307 }
308 }
309
310 .bg-lineg {
311 margin: auto;
312 border-radius: 10px;
313 text-align: center;
314 padding: 7px 2px 2px;
315 font-size: 24px;
316 width: 66px;
317 cursor: pointer;
318
319 div {
320 background: #fff;
321 font-size: 13px;
322 border-radius: 20px;
323 padding: 0 10px;
324 color: #453DEA;
325 font-weight: 500;
326 }
327 }
328 }
329
330 .hotel {
331 h3 {
332 margin: 0 0 20px;
333 }
334
335 img.w100 {
336 object-fit: cover;
337 aspect-ratio: 16/9
338 }
339
340 .addr {
341 font-size: 16px;
342 color: #929AA0;
343 font-weight: 400;
344 }
345
346 .price {
347 margin: 0 0 25px;
348 color: #FF8124;
349 font-size: 18px;
350
351 span {
352 font-size: 24px;
353 margin: 0 8px;
354 font-family: 'DINAlternate-Bold';
355 font-weight: 600;
356 }
357
358 i {
359 font-style: normal;
360 color: #929AA0;
361 }
362 }
363 }
364
365 :deep(.button) {
366 display: block;
367 height: 55px;
368 width: auto;
369 color: #fff;
370
371 span {
372 display: block !important;
373
374 div {
375 margin-top: 3px;
376 }
377 }
378
379 }
380
381 .starBox {
382 img {
383 display: inline-block;
384 margin-right: 4px
385 }
386 }
387
388 .tagbox {
389 margin: 15px 0;
390
391 a {
392 color: #AFB5B9;
393 font-size: 12px;
394 }
395
396 span {
397 border-radius: 13px;
398 font-size: 12px;
399 padding: 4px 10px;
400 margin-right: 10px;
401 font-weight: 400;
402 }
403
404 span:nth-child(4n) {
405 background: rgba(50, 177, 108, 0.2);
406 color: rgba(50, 177, 108, 1);
407 }
408
409 span:nth-child(4n+1) {
410 background: rgba(243, 152, 0, 0.2);
411 color: rgba(243, 152, 0, 1);
412 }
413
414 span:nth-child(4n+2) {
415 background: rgba(0, 160, 233, 0.2);
416 color: rgba(0, 160, 233, 1);
417 }
418
419 span:nth-child(4n+3) {
420 background: rgba(247, 64, 166, 0.2);
421 color: rgba(247, 64, 166, 1);
422 }
423 }
424
425 .mapBox {
426 position: relative;
427 overflow: hidden;
428 height: 200px;
429
430 #map {
431 position: relative;
432 left: -70px;
433 width: calc(100% + 160px);
434 }
435 }
436
437 .hotelImg {
438 border-radius: 10px;
439 overflow: hidden;
440 aspect-ratio: 16/9;
441
442 img {
443 object-fit: cover;
444 object-position: center;
445 width: 100%;
446 height: 100%;
447 }
448 }
449
450 .info {
451 font-weight: 400;
452 font-size: 14px;
453 color: #929AA0;
454
455 .el-icon {
456 margin-right: 5px;
457 }
458 }
459
460 .oddmb:nth-child(2) {
461 margin-bottom: 20px;
462 }
463
464 .forbid {
465 cursor: not-allowed !important;
466 filter: grayscale(0.4);
467 opacity: 0.7;
468 }
469
470 .forbid:hover {
471 box-shadow: none;
472 }
473
474 .lineHead {
475 display: flex;
476 justify-content: space-between;
477 }
478
479 .el-calendar {
480 --el-calendar-border: none;
481 --el-calendar-cell-width: 40px;
482 text-align: center;
483 --el-text-color-regular: #8E8D94;
484
485 :deep(.el-calendar__header) {
486 justify-content: center;
487 padding: 0 0 10px
488 }
489
490 :deep(.el-calendar__body) {
491 border: 1px solid #F0F0F0;
492 padding: 0
493 }
494
495 :deep(.el-calendar-table .el-calendar-day) {
496 padding: 1px;
497 }
498
499 :deep(.el-calendar-table td.is-selected) {
500 background: transparent;
501 }
502
503 :deep(.el-calendar__button-group) {
504 display: none;
505 }
506
507 :deep(.el-calendar-table thead th) {
508 padding: 5px 0 0
509 }
510
511 .primaryDate {
512 color: #fff;
513 background: linear-gradient(90deg, #8623FC, #453DEA);
514 }
515
516 .date {
517 margin: auto;
518 border-radius: 50%;
519 width: 30px;
520 height: 30px;
521 line-height: 30px;
522 font-weight: bold;
523 }
524 }
525
526 </style>
...@@ -3,26 +3,27 @@ ...@@ -3,26 +3,27 @@
3 <div class="box"> 3 <div class="box">
4 <el-card :body-style="{ padding: '0px' }" class="mt20"> 4 <el-card :body-style="{ padding: '0px' }" class="mt20">
5 <div slot="header"> 5 <div slot="header">
6 <div class="bg-lineg">{{ language == 0 ? '旅游服务下单' : 'Hotel booking order' }}</div> 6 <div class="bg-lineg father">{{ language == 0 ? '旅游服务下单' : 'Hotel booking order' }}
7 <sapn class="son" @click="handleGo">{{ language == 0 ? '上一步' : 'Back go' }}</sapn>
8 </div>
7 </div> 9 </div>
8 <!-- {{room}}--> 10 <!-- {{room}}-->
9 <el-row class="pd20" :gutter="20"> 11 <el-row :gutter="20" class="pd20">
10 <el-col :span="14"> 12 <el-col :span="14">
11 <div class="border-info"> 13 <div class="border-info">
12 <el-row class="hotel" align="middle" :gutter="20"> 14 <el-row :gutter="20" align="middle" class="hote ">
13 <!-- <el-col :span="6">-->
14 <!-- <img class="w100" :src="fillImgUrl(form.photos?.split(',')[0])"/>-->
15 <!-- </el-col>-->
16 <el-col :span="language == 0?16:24"> 15 <el-col :span="language == 0?16:24">
17 <h3 class="esp flex">{{ scenicItem?.name }} 16 <h3 class="esp flex">{{ scenicItem?.name }}
18 17
19 <el-tag effect="dark" class="ml20">{{ scenicItem?.rank||0 }}A</el-tag> 18 <el-tag class="ml20" effect="dark">{{ scenicItem?.rank || 0 }}A</el-tag>
20 </h3> 19 </h3>
21 <div class="info"> 20 <div class="info">
22 <el-icon> 21 <el-icon>
23 <Clock /> 22 <Clock />
24 </el-icon> 23 </el-icon>
25 <span class="mr10">{{ language == 0 ? '开园时间' : 'Opening Time' }}{{ scenicItem?.startTime }}{{ scenicItem?.workTime }}</span> 24 <span class="mr10">{{ language == 0 ? '开园时间' : 'Opening Time' }}{{ scenicItem?.startTime }}{{
25 scenicItem?.workTime
26 }}</span>
26 </div> 27 </div>
27 <div class="info"> 28 <div class="info">
28 <el-icon> 29 <el-icon>
...@@ -42,71 +43,83 @@ ...@@ -42,71 +43,83 @@
42 43
43 <div class="leftboderTT">{{ language == 0 ? '预约信息' : 'Reservation information' }}</div> 44 <div class="leftboderTT">{{ language == 0 ? '预约信息' : 'Reservation information' }}</div>
44 <div class="border-rr mt20 pd20"> 45 <div class="border-rr mt20 pd20">
45 <el-form ref="formRef" v-loading="loading" :model="form" :label-width="language == 0 ?'120':'160'" :rules="rules"> 46 <el-form
47 ref="formRef" v-loading="loading" :label-width="language == 0 ?'120':'160'" :model="form"
48 :rules="rules"
49 >
50 <!-- &lt;!&ndash; :disabled-date="disabledDateRZ"&ndash;&gt;-->
51 <!-- <el-form-item :label="language==0?'选择日期':'Date'" required>-->
52 <!-- <el-date-picker-->
53 <!-- v-model="rzRange"-->
54 <!-- :clearable="false"-->
46 <!-- :disabled-date="disabledDateRZ"--> 55 <!-- :disabled-date="disabledDateRZ"-->
47 <el-form-item :label="language==0?'选择日期':'Date'" required> 56 <!-- format="YYYY-MM-DD"-->
48 <el-date-picker 57 <!-- value-format="YYYY-MM-DD"-->
49 v-model="rzRange" 58 <!-- @change="dateChange"-->
50 format="YYYY-MM-DD" 59 <!-- />-->
51 value-format="YYYY-MM-DD" 60 <!-- -->
52 :disabled-date="disabledDateRZ" 61 <!-- <div v-if="lform.scenicStart" class="tip">{{-->
53 :clearable="false" 62 <!-- language == 0 ? '可订日期' : 'Available date'-->
54 @change="dateChange" 63 <!-- }}{{ lform.scenicStart.slice(0, 10) }} ~ {{ lform.scenicEnd.slice(0, 10) }}-->
55 /> 64 <!-- </div>-->
56 65 <!-- -->
57 <div v-if="lform.scenicStart" class="tip">{{ language==0?'可订日期':'Available date' }}{{ lform.scenicStart.slice(0, 10) }} ~ {{ lform.scenicEnd.slice(0, 10) }}</div> 66 <!-- &lt;!&ndash; :picker-options="pickerOptions"&ndash;&gt;-->
58 67 <!-- </el-form-item>-->
59 <!-- :picker-options="pickerOptions"--> 68 <!-- <el-form-item v-for="(n,i) in gateList" :key="i" :label="language==0? n.name:n.name" prop="count">-->
60 </el-form-item> 69 <!-- <el-input-number v-model="n.count" :max="n.leftNum" :min="0" @change="changeNum(n)" />-->
61 <el-form-item v-for="(n,i) in gateList" :key="i" :label="language==0? n.name:n.name" prop="count"> 70 <!-- <el-popover placement="top-start">-->
62 <el-input-number v-model="n.count" :min="0" :max="n.leftNum" @change="changeNum(n)" /> 71 <!-- <template #reference>-->
63 <el-popover placement="top-start"> 72 <!-- <el-icon class="ml20">-->
64 <template #reference> 73 <!-- <Warning />-->
65 <el-icon class="ml20"><Warning /></el-icon> 74 <!-- </el-icon>-->
66 </template> 75 <!-- </template>-->
67 <div v-html="n.details"></div> 76 <!-- <div v-html="n.details" />-->
68 </el-popover> 77 <!-- </el-popover>-->
69 <div class="red ml20"> 78 <!-- <div class="red ml20">-->
70 <span v-if="language == 0">单价: ¥{{ n.price }}</span> 79 <!-- <span v-if="language == 0">单价: ¥{{ n.price }}</span>-->
71 <span v-else>€ {{ n.priceEn }} / Ticket</span> 80 <!-- <span v-else>€ {{ n.priceEn }} / Ticket</span>-->
72 </div> 81 <!-- </div>-->
73 <div class="red ml20"> 82 <!-- <div class="red ml20">-->
74 <span v-if="language == 0">剩余票数:{{ n.leftNum }}</span> 83 <!-- <span v-if="language == 0">剩余票数:{{ n.leftNum }}</span>-->
75 <span v-else>{{ n.leftNum }} sheet remaining </span> 84 <!-- <span v-else>{{ n.leftNum }} sheet remaining </span>-->
76 </div> 85 <!-- </div>-->
77 86 <!-- -->
78 </el-form-item> 87 <!-- </el-form-item>-->
79 88 <!-- -->
80 <div v-if="needPersonNum>0" class="fakeFormItem"> 89 <div v-if="needPersonNum>0" class="fakeFormItem">
81 <label v-if="language == 0">需填写{{ needPersonNum }}位游客</label> 90 <label v-if="language == 0">需填写{{ needPersonNum }}位游客</label>
82 <label v-else>Need {{ needPersonNum }} visitors</label> 91 <label v-else>Need {{ needPersonNum }} visitors</label>
83 <div> 92 <div>
84 <label class="text-warning" v-show="needPersonNum > hasPersonNum && language==0"> 93 <label v-show="needPersonNum > hasPersonNum && language==0" class="text-warning">
85 还需填写{{ needPersonNum-hasPersonNum }}位游客 94 还需填写{{ needPersonNum - hasPersonNum }}位游客
86 </label> 95 </label>
87 </div> 96 </div>
88 </div> 97 </div>
89 <div v-for="(n,i) in gateList" :key="i"> 98 <div v-for="(n,i) in gateList" :key="i">
90 <div v-for="(p,j) in n.personArr" :key="j" class="fakeFormItem personIt"> 99 <div v-for="(p,j) in n.personArr" :key="j" class="fakeFormItem personIt">
91 <label> 100 <label>
92 <el-icon @click="delPerson(n,j)"><Remove /></el-icon> 101 <!-- <el-icon @click="delPerson(n,j)">-->
93 {{ n.name }}{{ j+1 }} 102 <!-- <Remove />-->
103 <!-- </el-icon>-->
104 {{ n.name }}{{ j + 1 }}
94 </label> 105 </label>
95 <div v-if="p.name" class="mation"> 106 <div v-if="p.name" class="mation">
96 <div>{{ p.name }}</div> 107 <div>{{ p.name }}</div>
97 <span v-if="p.idcType==0">{{language==0?'身份证':'ID number'}}</span> 108 <span v-if="p.idcType==0">{{ language == 0 ? '身份证' : 'ID number' }}</span>
98 <span v-if="p.idcType==1">{{language==0?'护照':'Passport'}}</span> 109 <span v-if="p.idcType==1">{{ language == 0 ? '护照' : 'Passport' }}</span>
99 <span v-if="p.idcType==2">{{language==0?'其他':'Other'}}</span> 110 <span v-if="p.idcType==2">{{ language == 0 ? '其他' : 'Other' }}</span>
100 :{{ p.idCard }} 111 :{{ p.idCard }}
101 </div> 112 </div>
102 <el-icon @click="showAddPerson(n, j,p)" color="#453DEA"><Edit /></el-icon> 113 <el-icon color="#453DEA" @click="showAddPerson(n, j,p)">
114 <Edit />
115 </el-icon>
103 </div> 116 </div>
104 </div> 117 </div>
105 118
106 <el-form-item :label="language==0?'联系人':'Contact'" required prop="contacts"> 119 <el-form-item :label="language==0?'联系人':'Contact'" prop="contacts">
107 <el-input v-model="form.contacts" /> 120 <el-input v-model="form.contacts" />
108 </el-form-item> 121 </el-form-item>
109 <el-form-item :label="language==0?'联系手机':'Contact phone'" required prop="phone"> 122 <el-form-item :label="language==0?'联系手机':'Contact phone'" prop="phone" required>
110 <el-input v-model="form.phone" /> 123 <el-input v-model="form.phone" />
111 </el-form-item> 124 </el-form-item>
112 125
...@@ -118,15 +131,19 @@ ...@@ -118,15 +131,19 @@
118 <div class="border-rr mt20 pd20 ccitemBox"> 131 <div class="border-rr mt20 pd20 ccitemBox">
119 132
120 <div v-for="(c, index) in gateList" v-show="c.count>0" :key="index" class="ccitem"> 133 <div v-for="(c, index) in gateList" v-show="c.count>0" :key="index" class="ccitem">
121
122 {{ c.name }} 134 {{ c.name }}
123 <span v-if="language==0">{{ c.count }} * {{ '¥' }}{{ c.price }}</span> 135 <span v-if="language==0">
124 <span v-else>{{ c.count }} * {{ '€' }} {{ c.priceEn }}</span> 136 {{ c.count }} * {{ '¥' }}{{ c.price }}
137 </span>
138 <span v-else>{{ c.count }} * {{ '€' }} {{ c.priceEn }}
139 </span>
125 </div> 140 </div>
126 141
127 <label>{{ language == 0 ? '共计' : 'Total' }}<span 142 <label>{{ language == 0 ? '共计' : 'Total' }}
128 class="fr bigMoney" 143 <span class="fr bigMoney">
129 >{{ language == 0 ? '¥' : '€' }} {{ money }}</span></label> 144 {{ language == 0 ? '¥' : '€' }} {{ money }}
145 </span>
146 </label>
130 147
131 </div> 148 </div>
132 </el-col> 149 </el-col>
...@@ -134,14 +151,18 @@ ...@@ -134,14 +151,18 @@
134 </el-card> 151 </el-card>
135 152
136 <el-card class="mt30"> 153 <el-card class="mt30">
137 <el-row justify="space-between" align="middle"> 154 <el-row align="middle" justify="space-between">
138 <el-col :span="12"> 155 <el-col :span="12">
139 <label>{{ language == 0 ? '共计金额' : 'Total' }}: 156 <label>{{ language == 0 ? '共计金额' : 'Total' }}:
140 <span class=" text-warning"> {{ language == 0 ? '¥' : '€' }}<span class="bigMoney">{{ money }}</span></span> 157 <span class=" text-warning"> {{ language == 0 ? '¥' : '€' }}<span class="bigMoney">{{
158 money
159 }}</span></span>
141 </label> 160 </label>
142 </el-col> 161 </el-col>
143 <el-col :span="12" class="text-right"> 162 <el-col :span="12" class="text-right">
144 <el-button type="primary" class="btn-lineG w200px" size="large" round @click="submit">{{ language == 0 ?'确认付款':'Book Now' }}</el-button> 163 <el-button class="btn-lineG w200px" round size="large" type="primary" @click="submit">
164 {{ language == 0 ? '确认付款' : 'Book Now' }}
165 </el-button>
145 </el-col> 166 </el-col>
146 </el-row> 167 </el-row>
147 </el-card> 168 </el-card>
...@@ -187,29 +208,53 @@ const rzRange = ref('') ...@@ -187,29 +208,53 @@ const rzRange = ref('')
187 const gateList = ref([]) 208 const gateList = ref([])
188 const money = ref(0) 209 const money = ref(0)
189 const choosePersonRef = ref([]) 210 const choosePersonRef = ref([])
211 const ticketList = ref([])
212
190 const rules = ref({ 213 const rules = ref({
191 phone: { required: true, message: language.value == 0 ? '请输入联系电话' : 'Please enter a contact number', trigger: 'blur' } 214 phone: {
215 required: true,
216 message: language.value == 0 ? '请输入联系电话' : 'Please enter a contact number',
217 trigger: 'blur'
218 },
219 contacts: {
220 required: true,
221 message: language.value == 0 ? '请输入联人' : 'Please enter a contact',
222 trigger: 'blur'
223 }
192 }) 224 })
193 225
226
194 onMounted(() => { 227 onMounted(() => {
195 money.value = 0 228 money.value = 0
196 rzRange.value = route.params.start 229 rzRange.value = route.params.start
197 230 gateList.value = ticketList.value = JSON.parse(decodeURIComponent(route.query.item))
231 console.log(gateList.value)
198 getScenic() 232 getScenic()
199 initDays() 233 countMoney()
200 getGate() 234 checkPersonNum()
235 // changeNum()
236 // initDays()
237 // getGate()
201 }) 238 })
239
202 function initDays() { 240 function initDays() {
203 // 可定日期范围 241 // 可定日期范围
204 getBaseInfoByActiveId(route.params.cptId).then(res => { 242 getBaseInfoByActiveId(route.params.cptId).then(res => {
205 lform.value = res.data 243 lform.value = res.data
206 }) 244 })
207 } 245 }
246
247 function getTotal() {
248 // get
249 }
250
251
208 function getScenic() { 252 function getScenic() {
209 getScenicById(route.params.scenicId).then(res => { 253 getScenicById(route.params.scenicId).then(res => {
210 scenicItem.value = res.data 254 scenicItem.value = res.data
211 }) 255 })
212 } 256 }
257
213 function getGate() { 258 function getGate() {
214 gateList.value = [] 259 gateList.value = []
215 loading.value = true 260 loading.value = true
...@@ -259,6 +304,11 @@ const checkPersonNum = () => { ...@@ -259,6 +304,11 @@ const checkPersonNum = () => {
259 }) 304 })
260 } 305 }
261 306
307 function getCountInfo() {
308 // get
309 }
310
311
262 function changeNum(e) { 312 function changeNum(e) {
263 checkPersonNum() 313 checkPersonNum()
264 314
...@@ -329,6 +379,10 @@ function submit() { ...@@ -329,6 +379,10 @@ function submit() {
329 useUserStore().setReLogin() 379 useUserStore().setReLogin()
330 return 380 return
331 } 381 }
382 if (!form.value.contacts) {
383 ElMessage.warning(language.value == 0 ? '请填写联系人' : 'Please fill in the contact person.')
384 return
385 }
332 if (!form.value.phone) { 386 if (!form.value.phone) {
333 ElMessage.warning(language.value == 0 ? '请填写手机号' : 'Please fill in the phone number') 387 ElMessage.warning(language.value == 0 ? '请填写手机号' : 'Please fill in the phone number')
334 return 388 return
...@@ -394,9 +448,13 @@ function submit() { ...@@ -394,9 +448,13 @@ function submit() {
394 }) 448 })
395 } 449 }
396 450
451 function handleGo() {
452 router.go(-1)
453 }
454
397 </script> 455 </script>
398 456
399 <style scoped lang="scss"> 457 <style lang="scss" scoped>
400 .bigMoney { 458 .bigMoney {
401 font-size: 36px !important; 459 font-size: 36px !important;
402 font-family: 'DIN Alternate'; 460 font-family: 'DIN Alternate';
...@@ -463,20 +521,56 @@ function submit() { ...@@ -463,20 +521,56 @@ function submit() {
463 .red { 521 .red {
464 color: #FF8124; 522 color: #FF8124;
465 } 523 }
524
466 .fakeFormItem { 525 .fakeFormItem {
467 display: flex; 526 display: flex;
468 padding: 10px 0; 527 padding: 10px 0;
469 label{ height: 32px; font-size: var(--el-form-label-font-size); width: 120px; 528
470 color: var(--el-text-color-regular); padding: 0 12px 0 0; 529 label {
471 line-height: 32px;flex: 0 0 auto; 530 height: 32px;
531 font-size: var(--el-form-label-font-size);
532 width: 120px;
533 color: var(--el-text-color-regular);
534 padding: 0 12px 0 0;
535 line-height: 32px;
536 flex: 0 0 auto;
472 display: inline-flex; 537 display: inline-flex;
473 justify-content: flex-end; 538 justify-content: flex-end;
474 align-items: center;gap: 10px;white-space: nowrap;} 539 align-items: center;
540 gap: 10px;
541 white-space: nowrap;
542 }
543 }
544
545 .tip {
546 font-size: 14px;
547 color: #666;
548 padding: 0 10px;
475 } 549 }
476 .tip{font-size: 14px;color: #666;padding: 0 10px;} 550
477 .personIt{display: flex;align-items: center; 551 .personIt {
478 .mation{width: 200px;font-size: 12px; 552 display: flex;
479 div{font-size: 14px;} 553 align-items: center;
554
555 .mation {
556 width: 200px;
557 font-size: 12px;
558
559 div {
560 font-size: 14px;
561 }
480 } 562 }
481 } 563 }
564
565 .father {
566 position: relative;
567
568 }
569
570 .son {
571 position: absolute;
572 left: 10px;
573 cursor: pointer;
574 }
575
482 </style> 576 </style>
......
...@@ -172,7 +172,7 @@ function goBooking(n) { ...@@ -172,7 +172,7 @@ function goBooking(n) {
172 router.push({ path: `/booking/photography/${props.matchId}` }) 172 router.push({ path: `/booking/photography/${props.matchId}` })
173 break 173 break
174 case 8: 174 case 8:
175 // 酒店 175 // 旅游
176 router.push({ path: `/booking/travel/${props.matchId}` }) 176 router.push({ path: `/booking/travel/${props.matchId}` })
177 break 177 break
178 } 178 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!