47440f2a by zhangmeng

票务

1 parent cf591983
...@@ -410,3 +410,56 @@ export function ppOtaReceipt(query) { ...@@ -410,3 +410,56 @@ export function ppOtaReceipt(query) {
410 params:query 410 params:query
411 }) 411 })
412 } 412 }
413 // 获取票务信息
414 export function getTicketInfoByActivityId(params) {
415 return request({
416 url: `/ota/activityTicket/getTicketInfoByActivityId`,
417 method: 'get',
418 params
419 })
420 }
421
422 // 根据赛事ID获取票档
423 export function getTicketListApi(params) {
424 return request({
425 url: `/ota/activityTicket/getTicketList`,
426 method: 'get',
427 params
428 })
429 }
430
431 // 根据赛事ID获取票档
432 export function listApi(params) {
433 return request({
434 url: `/ota/activityType/list`,
435 method: 'get',
436 params
437 })
438 }
439
440 // 获取当前用户的观影人列表
441 export function customerListApi(params) {
442 return request({
443 url: `/ota/customer/list`,
444 method: 'get',
445 params
446 })
447 }
448
449
450 // 新增观影人
451 export function aadCustomer(data) {
452 return request({
453 url: `/ota/customer`,
454 method: 'post',
455 data
456 })
457 }
458
459 // 删除观影人
460 export function delCustomer(id) {
461 return request({
462 url: `/ota/customer/${id}`,
463 method: 'delete',
464 })
465 }
......
...@@ -344,12 +344,24 @@ export const constantRoutes = [ ...@@ -344,12 +344,24 @@ export const constantRoutes = [
344 redirect: '/booking', 344 redirect: '/booking',
345 children: [ 345 children: [
346 { 346 {
347 path: 'ticket/:cptId', 347 path: 'ticket/:activeId',
348 component: () => import('@/viewsPc/booking/ticket'), 348 component: () => import('@/viewsPc/booking/ticket/index.vue'),
349 name: 'ticket', 349 name: 'ticket',
350 meta: { title: 'Ticket Booking' } 350 meta: { title: 'Ticket Booking' }
351 }, 351 },
352 { 352 {
353 path: 'ticket/:activeId/:latId',
354 component: () => import('@/viewsPc/booking/ticket/confirmOrder.vue'),
355 name: 'confirmOrder',
356 meta: { title: 'confirmOrder' }
357 },
358 {
359 path: 'ticket/peopleManage',
360 component: () => import('@/viewsPc/booking/ticket/peopleManage.vue'),
361 name: 'peopleManage',
362 meta: { title: 'peopleManage' }
363 },
364 {
353 path: 'hotel/:cptId', 365 path: 'hotel/:cptId',
354 component: () => import('@/viewsPc/booking/hotel'), 366 component: () => import('@/viewsPc/booking/hotel'),
355 name: 'hotel', 367 name: 'hotel',
......
1 <template>
2 <div>
3 <div class="box">
4 <el-card class="mt30">
5 票务预订
6 </el-card>
7 </div>
8
9 </div>
10 </template>
11
12 <script setup>
13
14 </script>
15
16 <style scoped>
17
18 </style>
1 <template>
2 <el-card class="container" >
3 <div v-loading="loading" >
4 <div class="title">
5 {{ languageFormat(language, "订单确认", "Order confirmation") }}
6 </div>
7 <div class="content pd20">
8 <el-row gutter="20">
9 <el-col :lg="16" class="left">
10 <div class="info">
11 <div class="name">{{ order.activityName }}</div>
12 <div class="address">{{ order.placeName }}</div>
13 </div>
14
15 <div class="ticket_info mb20">
16 <div class="tit_box">
17 <div class="line"></div>
18 <div class="txt">
19 {{ languageFormat(language, "订票信息", "Ticket Info") }}
20 </div>
21 </div>
22
23 <div class="form">
24 <el-form label-width="100px">
25 <el-form-item
26 :label="language == 0 ? '联系人电话' : 'contact phone'"
27 >
28 <el-input
29 v-model="form.phone"
30 :placeholder=" language == 0 ? '请输入联系电话' : 'Please enter the contact phone number'" style="width: 320px"
31 />
32 </el-form-item>
33 <el-form-item :label="language == 0 ? '观看人' : 'Viewer'">
34 <div class="p_box">
35 <div class="people">
36 <el-checkbox-group
37 v-model="form.viewers"
38 :max="order.length"
39 >
40 <div
41 v-for="(it, index) in cousList"
42 :key="index"
43 class="prople_item"
44 >
45 <div>
46 <div class="name">{{ it.name }}</div>
47 <div class="idcard">{{ it.idCard }}</div>
48 </div>
49 <el-checkbox :value="it.id" />
50 </div>
51 </el-checkbox-group>
52 </div>
53 <!-- button -->
54 <div
55 class="btn"
56 @click="$router.push({ path: '/booking/ticket/peopleManage' })"
57 >
58 {{ languageFormat(language, "新增", "Add") }}
59 </div>
60 </div>
61 </el-form-item>
62 </el-form>
63 </div>
64 </div>
65 </el-col>
66
67 <el-col :lg="8" class="right">
68 <div class="tit_box">
69 <div class="line"></div>
70 <div class="txt">
71 {{ languageFormat(language, "订单明细", "Order summary") }}
72 </div>
73 </div>
74
75 <div class="detail">
76 <div class="detail_top">
77 <div class="time">
78 {{ order.data?.dateStr }}
79 <span v-if="order.data?.ticketType == 1" class="tag_t">
80 {{ languageFormat(language, "套票", "Package ticket") }}
81 </span>
82 </div>
83 <div class="ticket">
84 {{ order?.singlePrice }}<span v-if="language == 0"></span
85 >{{ languageFormat(language, "票档", "Ticket file") }} x{{
86 order?.seatInfo?.length
87 }}{{ languageFormat(language, "张", "tickets") }}
88 </div>
89 </div>
90 <div class="detail_center">
91 <div
92 v-for="(it, index) in order.seatInfo"
93 :key="index"
94 class="ticket"
95 >
96 <span v-if="it.venueId == 1"
97 >{{ it.area }}{{ languageFormat(language, "区", "Zones") }}
98 </span>
99 {{ it.pai }}{{ languageFormat(language, "排", "Row") }} {{
100 it.no
101 }}{{ languageFormat(language, "座", "Seat") }} ({{
102 it.venueId == 1 ? "B6" : "B4"
103 }}{{ languageFormat(language, "馆", "Venue") }})
104 </div>
105 </div>
106 <div class="detail_b">
107 <div class="sum_txt">
108 {{ languageFormat(language, "共计", "Total") }}
109 </div>
110 <div class="price_num">
111 <span>{{ language == 0 ? "¥" : "€" }}</span>
112 {{ order?.paymentAmount }}
113 </div>
114 </div>
115 </div>
116 </el-col>
117 </el-row>
118 </div>
119 <div class="footer">
120 <div>
121 <span class="label">
122 {{ languageFormat(language, "共计金额", "Subtotal") }}
123 </span>
124 <span class="value">
125 <span>{{ language == 0 ? "¥" : "€" }}</span>
126 {{ order.data?.paymentAmount }}
127 </span>
128 </div>
129 <div class="pay" @click="payment.paymentHandle()">
130 {{ languageFormat(language, "立即支付", "Pay Now") }}
131 </div>
132 </div>
133
134 <el-dialog
135 v-model="payment.showCodeDialog"
136 title="支付"
137 width="300"
138 @closed="payment.handleCloce()"
139 >
140 <div>
141 <img alt :src="payment.qrCodeData" class="qrcode"/>
142 </div>
143 </el-dialog>
144 </div>
145 </el-card>
146
147 </template>
148
149 <script setup>
150 import {ref} from 'vue'
151 import {customerListApi} from'@/apiPc/booking'
152 import {confirmOrder} from "@/viewsPc/seat/api/index.js";
153 import {ElMessage} from "element-plus";
154 import {payOrder, viewPeopleList, checkPaySuccess} from "@/viewsPc/seat/api/index.js";
155 // import qrCodeDialog from "./components/qrCodeDialog.vue";
156 import qrcode from "qrcode";
157 import {languageFormat} from "@/viewsPc/seat/utils/language.js";
158 import {useStorage} from "@vueuse/core/index";
159
160 const language = useStorage("language", 0);
161 const loading = ref(false);
162 const route = useRoute();
163 const router = useRouter();
164 const order = ref({
165 data:{}
166 })
167 const audience = ref({})
168 const payment = ref({})
169 const props = defineProps({
170 activityId: [String, Number],
171 });
172 const form = ref({})
173 const cousList = ref([])
174
175 let timer = null;
176
177 const startCheckSuccessListener = (orderSn, actId) => {
178 timer = setInterval(() => {
179 checkPaySuccess({orderSn}).then((res) => {
180 if (res.data) {
181 clearInterval(timer);
182 timer = null;
183 // 支付成功
184 payment.showCodeDialog = false;
185 ElMessage({
186 type: "success",
187 message: languageFormat(
188 language.value,
189 "支付成功",
190 "Payment succeeded"
191 ),
192 });
193 router.replace({
194 path: "/seat/order",
195 });
196 } else {
197 return false;
198 }
199 });
200 }, 3000);
201 };
202
203 // const payment = reactive({
204 // showCodeDialog: false,
205 // btn_loading: false,
206 // form: {
207 // viewers: [],
208 // phone: "",
209 // },
210 // qrInfo: {},
211 // qrCodeData: "",
212 // paymentHandle() {
213 // if (payment.form.viewers.length != order.data?.seatInfo?.length)
214 // return ElMessage({
215 // type: "warning",
216 // message: languageFormat(
217 // language.value,
218 // "观看人与购买票数不符",
219 // "The number of viewers does not match the number of tickets purchased."
220 // ),
221 // });
222 // if (!payment.form.phone)
223 // return ElMessage({
224 // type: "warning",
225 // message: languageFormat(
226 // language.value,
227 // "请输入联系电话",
228 // "Please enter the contact phone number."
229 // ),
230 // });
231 // // if (!/^[1][3,4,5,7,8][0-9]{9}$/.test(payment.form.phone)) {
232 // // return ElMessage({
233 // // type: "warning",
234 // // message: languageFormat(
235 // // language.value,
236 // // "联系电话格式不正确",
237 // // "The format of the contact phone is incorrect."
238 // // ),
239 // // });
240 // // }
241 // loading.value = true
242 // payOrder({
243 // contactPhone: payment.form.phone,
244 // customerIds: payment.form.viewers,
245 // orderToken: order.data?.orderToken,
246 // payType: language.value == 0 ? 1 : 2,
247 // paymentAmount: order.data?.paymentAmount,
248 // }).then((res) => {
249 // if (res.data.language == "zh-cn") {
250 // payment.qrInfo = res.data;
251 // qrcode.toDataURL(res.data.scanCodeUrl, (err, url) => {
252 // if (url) {
253 // payment.qrCodeData = url;
254 // }
255 // });
256 // payment.showCodeDialog = true;
257 // startCheckSuccessListener(res.data.orderSn, props.activityId);
258 // } else {
259 // // TODO:这里是英文环境支付
260 // location.href = res.data.scanCodeUrl
261 // }
262 // }).finally(() => {
263 // loading.value = false
264 // });
265 // },
266 // handleCloce() {
267 // payment.showCodeDialog = false;
268 // payment.qrCodeData = "";
269 // clearInterval(timer);
270 // timer = null;
271 // router.replace({
272 // path: "/seat/order",
273 // });
274 // },
275 // });
276
277 // const order = reactive({
278 // data: null,
279 // fetchData() {
280 // confirmOrder({
281 // actId: props.activityId,
282 // openType: route.query.openType,
283 // sessionId: route.query.sessionId,
284 // sitePlace: route.query.sitePlace,
285 // ticketType: route.query.ticketType,
286 // seatIds: route.query.seatIds.split(","),
287 // }).then((res) => {
288 // this.data = res.data;
289 // });
290 // },
291 // });
292
293 // const audience = reactive({
294 // data: [],
295 // fetchData() {
296 // viewPeopleList().then((res) => {
297 // audience.data = res.data;
298 // });
299 // },
300 // });
301
302
303 // audience.fetchData();
304 // order.fetchData();
305
306
307 customerList()
308 async function customerList(){
309 const res =await customerListApi()
310 cousList.value=res.rows
311 }
312 </script>
313
314
315 <style lang="scss" scoped>
316 div {
317 box-sizing: border-box;
318 }
319
320 .qrcode {
321 width: 200px;
322 height: 200px;
323 margin: 0 auto;
324 }
325
326 .container {
327 //padding: 20px 0;
328 width: 1200px;
329 margin: 20px auto;
330
331 .tag_t {
332 padding: 1px 10px;
333 font-weight: 400;
334 font-size: 12px;
335 color: #493ceb;
336 border-radius: 6px;
337 border: 1px solid #453dea;
338 margin-left: 5px;
339 }
340
341 .title {
342 padding: 11px;
343 text-align: center;
344 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
345 font-size: 18px;
346 color: #ffffff;
347 }
348
349 .content {
350 background-color: #fff;
351 }
352
353 .line {
354 width: 4px;
355 height: 18px;
356 background: linear-gradient(180deg, #493ceb 0%, #8623fc 100%);
357 border-radius: 4px;
358 }
359
360 .left {
361 .info {
362 background: rgba(69, 61, 234, 0.04);
363 border-radius: 8px;
364 border: 1px solid #d3d1f6;
365 padding: 20px 0 28px 33px;
366 margin-bottom: 20px;
367
368 .name {
369 font-weight: 500;
370 font-size: 18px;
371 color: #000000;
372 margin-bottom: 20px;
373 }
374
375 .address {
376 font-weight: 400;
377 font-size: 14px;
378 color: #929aa0;
379 }
380 }
381
382 .ticket_info {
383 .tit_box {
384 display: flex;
385 align-items: center;
386 gap: 10px;
387 margin-bottom: 14px;
388
389 .txt {
390 font-weight: bold;
391 font-size: 16px;
392 color: #493ceb;
393 }
394 }
395
396 .form {
397 min-height: 464px;
398 padding: 20px 60px;
399 border-radius: 5px;
400 border: 1px solid #dcdfe6;
401
402 .p_box {
403 display: flex;
404 width: 100%;
405 gap: 10px;
406 max-width: 400px;
407
408 .people {
409 width: 100%;
410 background: #fbfcfd;
411 border-radius: 2px;
412 border: 1px solid #dcdfe6;
413 padding: 0 14px;
414
415 .prople_item {
416 display: flex;
417 justify-content: space-between;
418 align-items: center;
419 padding: 14px 0;
420 border-bottom: 1px solid #dcdfe6;
421
422 &:last-child {
423 border: none;
424 }
425
426 .name {
427 font-size: 16px;
428 color: #929aa0;
429 margin-bottom: 20px;
430 }
431
432 .idcard {
433 font-size: 10px;
434 color: #929aa0;
435 }
436 }
437 }
438
439 .btn {
440 width: 90px;
441 height: 40px;
442 background: #fbfcfd;
443 border-radius: 20px;
444 border: 1px solid #493ceb;
445 margin-top: 10px;
446 font-size: 14px;
447 color: #493ceb;
448 line-height: 40px;
449 text-align: center;
450 cursor: pointer;
451 user-select: none;
452 }
453 }
454 }
455 }
456 }
457
458 .right {
459 .tit_box {
460 display: flex;
461 align-items: center;
462 gap: 10px;
463 margin-bottom: 20px;
464
465 .txt {
466 font-weight: bold;
467 font-size: 16px;
468 color: #493ceb;
469 }
470 }
471
472 .detail {
473 padding: 15px 26px;
474 border-radius: 5px;
475 border: 1px solid #dcdfe6;
476
477 .detail_top {
478 padding-bottom: 13px;
479 border-bottom: 1px solid #dcdfe6;
480
481 .time {
482 font-weight: 500;
483 font-size: 18px;
484 color: #2d373f;
485 line-height: 25px;
486 margin-bottom: 8px;
487 }
488
489 .ticket {
490 font-size: 16px;
491 color: #2d373f;
492 }
493 }
494
495 .detail_center {
496 margin-top: 14px;
497 display: flex;
498 flex-direction: column;
499 padding-bottom: 13px;
500 border-bottom: 1px solid #dcdfe6;
501 gap: 8px;
502
503 .ticket {
504 font-size: 16px;
505 color: #2d373f;
506 }
507 }
508
509 .detail_b {
510 display: flex;
511 justify-content: space-between;
512 align-items: center;
513 margin-top: 16px;
514
515 .sum_txt {
516 font-weight: 600;
517 font-size: 18px;
518 color: #2d373f;
519 line-height: 25px;
520 }
521
522 .price_num {
523 font-weight: 600;
524 font-size: 36px;
525 color: #ff8124;
526 line-height: 50px;
527 }
528 }
529 }
530 }
531
532 .footer {
533 display: flex;
534 justify-content: space-between;
535 height: 70px;
536 align-items: center;
537 background: #ffffff;
538 box-shadow: 0px 0px 46px 0px rgba(1, 16, 64, 0.08);
539 margin-top: 9px;
540 padding: 0 30px;
541
542 .label {
543 font-size: 16px;
544 color: #7b7f83;
545 line-height: 22px;
546 }
547
548 .value {
549 font-size: 22px;
550 color: #ff8124;
551 line-height: 30px;
552 font-weight: 600;
553 }
554
555 .pay {
556 width: 200px;
557 height: 40px;
558 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
559 border-radius: 20px;
560 font-weight: 500;
561 font-size: 16px;
562 color: #ffffff;
563 line-height: 40px;
564 text-align: center;
565 cursor: pointer;
566 user-select: none;
567 }
568 }
569 }
570
571 @media screen and (max-width: 768px) {
572 .container {
573 width: 100%;
574 }
575 }
576 </style>
1 <template>
2 <div>
3 <!-- top -->
4 <div class="container top">
5 <img :src="fillImgUrl(matchForm.ticketImg)" class="cover_img"/>
6 <div class="info">
7 <div class="title">{{ matchForm.name }}</div>
8 <div class="time">
9 {{ languageFormat(language, "时间", "Event Date & Time") }}{{
10 matchForm.ticketStart
11 ? dayjs(matchForm.ticketStart).format("YYYY.MM.DD")
12 : ""
13 }}
14 {{
15 matchForm.ticketStart
16 ? getDayName(
17 new Date(matchForm.ticketStart),
18 language == 1 ? "en-US" : "zh-CN"
19 )
20 : ""
21 }}
22
23 {{
24 matchForm.ticketEnd
25 ? dayjs(matchForm.ticketEnd).format("YYYY.MM.DD")
26 : ""
27 }}
28 {{
29 matchForm.ticketEnd
30 ? getDayName(
31 new Date(matchForm.ticketEnd),
32 language == 1 ? "en-US" : "zh-CN"
33 )
34 : ""
35 }}
36 </div>
37 <div class="address">
38 {{ languageFormat(language, "地址", "Location") }}{{
39 matchForm.address
40 }}
41 </div>
42 <!-- 时间 -->
43 <div class="select_item_box">
44 <div class="label">
45 {{ languageFormat(language, "票档", "Tickets") }}
46 </div>
47 <div class="select_item">
48 <div
49 v-for="(it, index) in tickClass"
50 :key="index"
51 :class="[
52 it.id == selectForm.latId ? 'tagActive' : 'tag',
53 ]"
54 @click="select(it)"
55 >
56 {{ it.name }}
57 </div>
58 </div>
59 </div>
60 <!-- 时间 -->
61 <div class="select_item_box">
62 <div class="label">
63 {{ languageFormat(language, "时间", "Event Date & Time") }}
64 </div>
65 <div class="select_item">
66 <div
67 v-for="(it, index) in tickList"
68 :key="index"
69 :class="[
70 it.id == selectForm.id ? 'tagActive' : 'tag',
71 ]"
72 @click="selectTick(it)"
73 >
74 {{ it.name }}
75 </div>
76 </div>
77 </div>
78
79 <!-- button -->
80 <div class="btn forPc" @click="toSelectSeat()">
81 {{ languageFormat(language, "添加观影人", "Add Moviegoers") }}
82 </div>
83 </div>
84 </div>
85
86 <div class="container bottom">
87 <div class="rich_content" v-html="matchForm.ticketDes"></div>
88 </div>
89 </div>
90 </template>
91
92
93 <script setup>
94 import {ref, reactive, onMounted, watch} from "vue";
95 import {listApi, getTicketInfoByActivityId, getTicketListApi} from '@/apiPc/booking'
96
97 import {dayjs} from "element-plus";
98 import useUserStore from "@/store/modules/user";
99 import {ElMessageBox, ElMessage} from "element-plus";
100 import {languageFormat, getDayName} from "@/viewsPc/seat/utils/language";
101 import {fillImgUrl} from "/@/utils/ruoyi";
102
103 const route = useRoute();
104 const router = useRouter();
105 const userStore = useUserStore();
106 const activeId = ref(route.params.activeId)
107 const props = defineProps({
108 activityId: [String, Number],
109 });
110
111 const matchForm = ref({})
112 const tickClass = ref([])
113 const selectForm = ref({
114 latId: null,
115 id: null
116 })
117 const tickList = ref([])
118
119 // 获取票务信息
120 getDetail()
121
122 async function getDetail() {
123 const res = await getTicketInfoByActivityId({activityId: activeId.value})
124 matchForm.value = res.data
125 }
126
127 // 根据赛事ID获取票档
128 getTicketList()
129
130 async function getTicketList() {
131 const res = await getTicketListApi({activityId: activeId.value})
132 tickClass.value = res.rows
133 selectForm.value.latId = tickClass.value?.[0]?.id
134 await getTicketListType()
135 }
136
137 // 根据票档获取场次
138 async function getTicketListType() {
139 const res = await listApi({latId: selectForm.value.latId})
140 tickList.value = res.rows
141 }
142
143 function select(v) {
144 selectForm.value.latId = v.id
145 getTicketListType()
146 }
147
148 function selectTick(v) {
149 selectForm.value.id = v.id
150 }
151
152 function toSelectSeat() {
153 if (!selectForm.value.latId) return ElMessage.error("请选择票档")
154 if (!selectForm.value.id) return ElMessage.error("请选择时间")
155 router.push({
156 name:'confirmOrder',
157 params: {
158 activeId: activeId.value,
159 latId: selectForm.value.latId,
160 id: selectForm.value.id
161 }
162 })
163 }
164
165 </script>
166
167
168 <style lang="scss" scoped>
169 .forWei {
170 display: none
171 }
172
173 .container {
174 width: 1200px;
175 margin: 0 auto;
176 background-color: #fff;
177 box-shadow: 0px 0px 46px 0px rgba(1, 16, 64, 0.08);
178 border-radius: 8px;
179 box-sizing: border-box;
180 font-family: SourceHanSansCN, SourceHanSansCN;
181 padding-bottom: 20px;
182 }
183
184 .top {
185 display: flex;
186 padding: 19px;
187 margin-top: 26px;
188
189 .cover_img {
190 width: 390px;
191 height: 517px;
192 object-fit: fill;
193 margin-right: 36px;
194 }
195
196 .info {
197 padding-top: 12px;
198
199 .title {
200 font-weight: bold;
201 font-size: 28px;
202 color: #000000;
203 line-height: 42px;
204 margin-bottom: 34px;
205 }
206
207 .time {
208 font-weight: 500;
209 font-size: 16px;
210 color: #4a4a4a;
211 line-height: 24px;
212 margin-bottom: 16px;
213 }
214
215 .address {
216 font-weight: 500;
217 font-size: 16px;
218 color: #4a4a4a;
219 line-height: 24px;
220 margin-bottom: 33px;
221 }
222
223 .select_item_box {
224 display: flex;
225 margin-bottom: 30px;
226
227 &:last-child {
228 margin-bottom: 0;
229 }
230
231 .label {
232 font-weight: 600;
233 font-size: 16px;
234 color: #000;
235 line-height: 24px;
236 margin-right: 12px;
237 flex-shrink: 0;
238 }
239
240 .select_item {
241 display: flex;
242 flex-wrap: wrap;
243 gap: 10px;
244 user-select: none;
245
246 .tag_t {
247 padding: 1px 15px;
248 font-weight: 400;
249 font-size: 14px;
250 color: #493ceb;
251 border-radius: 6px;
252 border: 1px solid #453dea;
253 margin-left: 5px;
254 }
255
256 .tag {
257 display: flex;
258 padding: 12px 18px;
259 background: #eeeeee;
260 border-radius: 4px;
261 border: 1px solid #29343c;
262 font-size: 14px;
263 color: #4a4a4a;
264 cursor: pointer;
265 }
266
267 .tagActive {
268 display: flex;
269 padding: 12px 18px;
270 background: #fff;
271 border-radius: 4px;
272 border: 1px solid #493ceb;
273 font-size: 14px;
274 color: #493ceb;
275 cursor: pointer;
276 }
277
278 .tagDisabled {
279 padding: 12px 18px;
280 background: #878787;
281 border-radius: 4px;
282 border: 1px solid #29343c;
283 font-size: 14px;
284 color: #4a4a4a;
285 cursor: no-drop;
286 }
287 }
288 }
289
290 .btn {
291 width: 175px;
292 height: 40px;
293 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
294 border-radius: 20px;
295 line-height: 40px;
296 text-align: center;
297 font-weight: 500;
298 font-size: 16px;
299 color: #ffffff;
300 cursor: pointer;
301 }
302 }
303 }
304
305 .bottom {
306 padding: 50px;
307 margin-top: 30px;
308 margin-bottom: 30px;
309
310 .title {
311 padding: 20px 30px;
312 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
313 font-weight: bold;
314 font-size: 20px;
315 color: #ffffff;
316 line-height: 30px;
317 margin-bottom: 30px;
318 }
319
320 .rich_content {
321 margin-top: 30px;
322 }
323 }
324
325 @media screen and (max-width: 768px) {
326 .container {
327 width: 100%;
328 }
329 .forWei {
330 display: block
331 }
332 .top {
333 //transform: scale(0.5);transform-origin: left top;
334 .cover_img {
335 width: 120px;
336 height: 160px;
337 margin-right: 15px;
338 }
339
340 .info {
341 .title {
342 font-size: 14px;
343 }
344
345 .time, .address, .label, .tip {
346 font-size: 12px;
347 }
348
349 .title, .time, .address, .tip, .select_item_box {
350 margin-bottom: 3px;
351 }
352
353 .select_item_box {
354 .label {
355 font-size: 12px;
356 }
357
358 .select_item .tag {
359 padding: 2px 10px;
360 font-size: 12px;
361 }
362
363 .select_item .tagActive {
364 padding: 2px 10px;
365 font-size: 12px;
366 }
367
368 .select_item .tagDisabled {
369 padding: 2px 10px;
370 font-size: 12px;
371 }
372 }
373 }
374 }
375 .bottom {
376 padding: 0
377 }
378 }
379 </style>
1 <template>
2 <el-card class="container">
3 <div class="title">
4 <div
5 class="add_btn"
6 @click="addPeople"
7 >
8 {{ languageFormat(language, "新增", "Add") }}
9 </div>
10 {{ languageFormat(language, "观影人管理", "Viewers") }}
11 </div>
12 <div class="content">
13 <div class="people_box">
14 <div
15 v-for="(it, index) in cousList"
16 :key="index"
17 class="people_item"
18 >
19 <div class="name">{{ it.name }}</div>
20 <div class="idcard">
21 {{ languageFormat(language, "证件号", "Identity Card") }}{{
22 it.idCard
23 }}
24 </div>
25 <div class="btn" @click="deletePeople(it.id)">
26 {{ languageFormat(language, "删除", "delete") }}
27 </div>
28 </div>
29 </div>
30 </div>
31
32 <el-dialog
33 v-model="show"
34 center
35 title="新增观影人"
36 width="700"
37 >
38 <el-form ref="formRef" :model="form" :rules="rules" label-width="80px" size="large" style="margin: 80px">
39 <el-form-item label="姓名" required prop="name">
40 <el-input v-model="form.name" size=""></el-input>
41 </el-form-item>
42 <el-form-item label="证件号" required prop="idCard">
43 <el-input v-model="form.idCard"></el-input>
44 </el-form-item>
45 </el-form>
46
47 <br>
48 <br>
49 <span slot="footer" class="dialog-footer">
50 <div style="text-align: center">
51 <el-button class="can_pay" @click="show = false">取 消</el-button>
52 <el-button class="pay" type="primary" @click="submit">确 定</el-button>
53 </div>
54 </span>
55 <br>
56 <br>
57 <br>
58 </el-dialog>
59 </el-card>
60
61 </template>
62
63
64 <script setup>
65 import {reactive, ref} from "vue";
66 import {customerListApi,aadCustomer,delCustomer} from '@/apiPc/booking'
67
68 import {deleteViewPeople, viewPeopleList} from "@/viewsPc/seat/api/index.js";
69 import {ElMessageBox, ElMessage} from "element-plus";
70 import {languageFormat} from "@/viewsPc/seat/utils/language.js";
71 import {useStorage} from "@vueuse/core/index";
72
73 const language = useStorage("language", 0);
74
75 const audience = reactive({
76 data: [],
77 fetchData() {
78 viewPeopleList().then((res) => {
79 audience.data = res.data;
80 });
81 },
82
83 deletePeople(id) {
84 ElMessageBox.confirm(
85 languageFormat(
86 language.value,
87 "确认删除该观看人吗?",
88 "Are you sure to delete this viewer?"
89 ),
90 languageFormat(language.value, "提示", "Reminder"),
91 {
92 confirmButtonText: languageFormat(language.value, "确认", "confirm"),
93 cancelButtonText: languageFormat(language.value, "取消", "cancel"),
94 type: "warning",
95 draggable: true,
96 }
97 )
98 .then(() => {
99 deleteViewPeople({id}).then(() => {
100 audience.fetchData();
101 ElMessage({
102 type: "success",
103 message: languageFormat(
104 language.value,
105 "操作成功",
106 "Operate successfully"
107 ),
108 });
109 });
110 })
111 .catch(() => {
112 });
113 },
114 });
115
116 const cousList = ref([])
117 const show = ref(false)
118 const form = ref({})
119 const formRef = ref(null)
120 const rules = ref({
121 name: [
122 {required: true, message: "请输入姓名", trigger: "blur"},
123 ],
124 idCard: [
125 {required: true, message: "请输入证件号", trigger: "blur"},
126 ],
127 })
128
129 customerList()
130 async function customerList() {
131 const res = await customerListApi()
132 // cousList.value = res.rows
133 cousList.value = [{},{}]
134 }
135
136 function addPeople() {
137 show.value = true
138 formRef.value?.resetFields()
139 }
140
141 function submit() {
142 formRef.value.validate((valid) => {
143 if (valid) {
144 console.log(form.value);
145 aadCustomer(form.value).then(res=>{
146 show.value = false
147 customerList()
148 ElMessage.success('添加成功')
149 })
150 } else {
151 return ElMessage.waiting('请完善信息')
152 }
153 })
154 }
155
156 async function deletePeople(v){
157 const res =await delCustomer(v.id)
158 if(res.code===200){
159 ElMessage.success('删除成功')
160 await customerList()
161 }
162 }
163 </script>
164
165
166 <style lang="scss" scoped>
167 div {
168 box-sizing: border-box;
169 }
170
171 :deep(.el-dialog) {
172 padding: 0;
173
174 .el-dialog__header {
175 height: 50px;
176 line-height: 50px;
177 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
178
179 .el-dialog__title {
180 color: #fff;
181 }
182 }
183 }
184
185 .pay {
186 width: 200px;
187 height: 40px;
188 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
189 border-radius: 20px;
190 font-weight: 500;
191 font-size: 16px;
192 color: #ffffff;
193 line-height: 40px;
194 text-align: center;
195 cursor: pointer;
196 }
197
198 .can_pay {
199 width: 200px;
200 height: 40px;
201 background: #f6f6f6;
202 border-radius: 20px;
203 font-weight: 500;
204 font-size: 16px;
205 color: #999;
206 line-height: 40px;
207 text-align: center;
208 box-sizing: border-box;
209 cursor: pointer;
210 }
211
212 .container {
213 //padding: 20px 0;
214 //:deep(.el-card__body){
215 // padding: 0;
216 //}
217 width: 1200px;
218 margin: 20px auto;
219
220 .title {
221 position: relative;
222 padding: 11px;
223 text-align: center;
224 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
225 font-size: 18px;
226 color: #ffffff;
227
228 .add_btn {
229 position: absolute;
230 left: 20px;
231 top: 50%;
232 transform: translateY(-50%);
233 width: 68px;
234 height: 24px;
235 border-radius: 12px;
236 border: 1px solid #ffffff;
237 font-weight: 400;
238 font-size: 12px;
239 color: #ffffff;
240 text-align: center;
241 line-height: 24px;
242 box-sizing: border-box;
243 user-select: none;
244 cursor: pointer;
245 }
246 }
247
248 .content {
249 min-height: 590px;
250 background-color: #fff;
251 box-shadow: 0px 0px 46px 0px rgba(1, 16, 64, 0.08);
252 padding: 20px;
253
254 .people_box {
255 display: flex;
256 flex-wrap: wrap;
257 gap: 20px;
258
259 .people_item {
260 width: 275px;
261 height: 137px;
262 background: #ffffff;
263 border: 1px solid #dcdfe6;
264 padding: 16px;
265
266 .name {
267 font-weight: 600;
268 font-size: 16px;
269 color: #2d373f;
270 line-height: 22px;
271 }
272
273 .idcard {
274 font-size: 16px;
275 color: #95a1a6;
276 line-height: 22px;
277 margin-top: 12px;
278 margin-bottom: 17px;
279 }
280
281 .btn {
282 width: 69px;
283 height: 32px;
284 background: #e7e6ff;
285 font-weight: 400;
286 font-size: 16px;
287 color: #493ceb;
288 line-height: 32px;
289 text-align: center;
290 cursor: pointer;
291 user-select: none;
292 }
293 }
294 }
295 }
296 }
297
298 @media screen and (max-width: 768px) {
299 .container {
300 width: 100%;
301 }
302 }
303 </style>
...@@ -119,7 +119,7 @@ function popRemark(type) { ...@@ -119,7 +119,7 @@ function popRemark(type) {
119 || (form.value.isFoodView == 0 && type == '3') 119 || (form.value.isFoodView == 0 && type == '3')
120 || (form.value.isMealView == 0 && type == '4') 120 || (form.value.isMealView == 0 && type == '4')
121 || (form.value.isPhotoView == 0 && type == '5') 121 || (form.value.isPhotoView == 0 && type == '5')
122 // || (type == '0') 122 || (form.value.isTicket==0&&type == '0')
123 ) { 123 ) {
124 building() 124 building()
125 return 125 return
...@@ -138,9 +138,9 @@ function goBooking(n) { ...@@ -138,9 +138,9 @@ function goBooking(n) {
138 case 0: 138 case 0:
139 // 票务 139 // 票务
140 router.push({ 140 router.push({
141 path: `/seat/detail`, 141 path: `/booking/ticket/${props.matchId}`,
142 params: {id: 1}, 142 // params: {id:props.matchId},
143 query: {id: 1} 143 // query: {id: props.matchId}
144 }) 144 })
145 break; 145 break;
146 case 1: 146 case 1:
......
...@@ -135,8 +135,8 @@ function popRemark(type) { ...@@ -135,8 +135,8 @@ function popRemark(type) {
135 || (form.value.isCarView == 0 && type == '2') 135 || (form.value.isCarView == 0 && type == '2')
136 || (form.value.isFoodView == 0 && type == '3') 136 || (form.value.isFoodView == 0 && type == '3')
137 || (form.value.isMealView == 0 && type == '4') 137 || (form.value.isMealView == 0 && type == '4')
138 || (type == '5' && form.value.isPhotoView == 0) 138 || (form.value.isPhotoView == 0&&type == '5')
139 || (type == '0') 139 || (form.value.isTicket==0 &type == '0')
140 ) 140 )
141 { 141 {
142 building() 142 building()
...@@ -157,11 +157,8 @@ function goBooking(n) { ...@@ -157,11 +157,8 @@ function goBooking(n) {
157 switch (n) { 157 switch (n) {
158 case 0: 158 case 0:
159 // 票务 159 // 票务
160 // 票务
161 router.push({ 160 router.push({
162 path: `/seat/detail`, 161 path: `/booking/ticket/${props.matchId}`,
163 params: {id: 1},
164 query: {id: 1}
165 }) 162 })
166 break; 163 break;
167 case 1: 164 case 1:
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!