6fe7ecb0 by yyx

1

1 parent 89a307bd
...@@ -514,6 +514,12 @@ export const constantRoutes = [ ...@@ -514,6 +514,12 @@ export const constantRoutes = [
514 meta: { title: '购票详情' } 514 meta: { title: '购票详情' }
515 }, 515 },
516 { 516 {
517 path: 'seat_picker',
518 name: 'seat_picker',
519 component: () => import('@/viewsPc/seat/seat-picker'),
520 meta: { title: '选座' }
521 },
522 {
517 path: 'order', 523 path: 'order',
518 name: 'seat_order', 524 name: 'seat_order',
519 component: () => import('@/viewsPc/seat/order-list'), 525 component: () => import('@/viewsPc/seat/order-list'),
......
1 <script setup></script> 1 <script setup>
2 import { ElMessage } from "element-plus";
3 import { addViewPeople } from "./api/index.js";
4
5 const router = useRouter();
6
7 const people = reactive({
8 form: {
9 name: "",
10 idCard: "",
11 },
12 type: "身份证",
13 onConfirm() {
14 if (!people.form.name)
15 return ElMessage({ type: "warning", message: "请输入姓名" });
16 if (!people.form.idCard)
17 return ElMessage({ type: "warning", message: "请输入证件号" });
18
19 // 使用正则验证身份证号码格式
20 const idCardRegex =
21 /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[\dXx]$/;
22 if (!idCardRegex.test(people.form.idCard))
23 return ElMessage({ type: "warning", message: "身份证号格式不正确" });
24
25 addViewPeople(people.form).then((res) => {
26 ElMessage({ type: "success", message: "操作成功" });
27 router.go(-2);
28 });
29 },
30 });
31 </script>
2 32
3 <template> 33 <template>
4 <div class="container"> 34 <div class="container">
...@@ -8,15 +38,15 @@ ...@@ -8,15 +38,15 @@
8 <div> 38 <div>
9 <div class="label">姓名</div> 39 <div class="label">姓名</div>
10 <el-input 40 <el-input
11 v-model="input" 41 v-model="people.form.name"
12 style="width: 570px" 42 style="width: 570px"
13 placeholder="Please input" 43 placeholder="请输入姓名"
14 /> 44 />
15 </div> 45 </div>
16 <div> 46 <div>
17 <div class="label">证件类型</div> 47 <div class="label">证件类型</div>
18 <el-input 48 <el-input
19 v-model="input" 49 v-model="people.type"
20 style="width: 570px" 50 style="width: 570px"
21 placeholder="Please input" 51 placeholder="Please input"
22 readonly 52 readonly
...@@ -27,9 +57,9 @@ ...@@ -27,9 +57,9 @@
27 <div> 57 <div>
28 <div class="label">身份证号</div> 58 <div class="label">身份证号</div>
29 <el-input 59 <el-input
30 v-model="input" 60 v-model="people.form.idCard"
31 style="width: 570px" 61 style="width: 570px"
32 placeholder="Please input" 62 placeholder="请输入身份证号"
33 /> 63 />
34 </div> 64 </div>
35 </div> 65 </div>
...@@ -37,7 +67,7 @@ ...@@ -37,7 +67,7 @@
37 67
38 <div class="footer"> 68 <div class="footer">
39 <div class="can_pay">取消</div> 69 <div class="can_pay">取消</div>
40 <div class="pay">确认</div> 70 <div class="pay" @click="people.onConfirm()">确认</div>
41 </div> 71 </div>
42 </div> 72 </div>
43 </template> 73 </template>
......
1 import request from "../utils/request";
2
3 export const loginFree = (data) => request("POST", "/login/loginFree", data);
4 /** 活动详情 */
5 export const activityDetail = (data) =>
6 request("GET", `/api/activity/detail/${data.actId}`, data);
7 /** 场次详情 */
8 export const sessionDetail = (data) =>
9 request("GET", `/api/activity/sessionDetail/${data.actId}`, data);
10 /** 获取场馆信息 */
11 export const getSitePlaceInfo = (data) =>
12 request("GET", `/api/activity/getSitePlaceInfo`, data);
13 /** 获取票档信息 */
14 export const getPriceLevelInfo = (data) =>
15 request("GET", `/api/activity/getPriceLevelInfo`, data);
16 /** 获取座位信息 */
17 export const getSiteConfig = (data) =>
18 request("GET", `/api/activity/getSiteConfig`, data);
19 /** 确认订单 */
20 export const confirmOrder = (data) =>
21 request("POST", `/api/order/confirmOrder`, data);
22 /** 订单支付 */
23 export const payOrder = (data) =>
24 request("POST", `/api/order/payment`, data);
25 /** 观众列表 */
26 export const viewPeopleList = (data) =>
27 request("GET", `/api/customer/list`, data);
28 /** 删除观众 */
29 export const deleteViewPeople = (data) =>
30 request("POST", `/api/customer/delete/${data.id}`, data);
31 /** 新增观众 */
32 export const addViewPeople = (data) =>
33 request("POST", `/api/customer/add`, data);
34 /** 订单列表 */
35 export const getOrderList = (data) =>
36 request("GET", `/api/order/list`, data);
37 /** 立即支付 */
38 export const immediatePay = (data) =>
39 request("POST", `/api/order/immediatePay`, data);
40 /** 取消支付 */
41 export const cancelPay = (data) =>
42 request("POST", `/api/order/cancelPay/${data.orderSn}`, data);
43 /** 退单 */
44 export const cancelOrder = (data) =>
45 request("POST", `/api/order/cancelOrder/${data.orderSn}`, data);
46 /** 订单详情 */
47 export const getOrderDetail = (data) =>
48 request("GET", `/api/order/detail/${data.orderSn}`, data);
1 <script setup>
2 const props = defineProps({
3 showCodeDialog: {
4 type: Boolean,
5 default: false,
6 },
7 qrCode: {
8 type: String,
9 default: ''
10 }
11 });
12 </script>
13
14 <template>
15 <div>
16 <el-dialog v-model="props.showCodeDialog" title="支付" width="300">
17 <div>
18 <img class="qrcode" :src="props.qrCode" />
19 </div>
20 </el-dialog>
21 </div>
22 </template>
23
24 <style scoped lang="scss">
25 .qrcode {
26 width: 150px;
27 height: 150px;
28 background-color: #8623fc;
29 margin: 0 auto;
30 }
31 </style>
1 <script setup></script> 1 <script setup>
2 import { confirmOrder } from "./api/index.js";
3 import { ElMessage } from "element-plus";
4 import { payOrder, viewPeopleList } from "./api/index.js";
5 import { reactive } from "vue";
6 import qrCodeDialog from "./components/qrCodeDialog.vue";
7
8 const route = useRoute();
9 const router = useRouter();
10
11 const payment = reactive({
12 showCodeDialog: false,
13 btn_loading: false,
14 form: {
15 viewers: [],
16 phone: "",
17 },
18 qrInfo: {},
19 paymentHandle() {
20 if (payment.form.viewers.length != order.data?.seatInfo?.length)
21 return ElMessage({ type: "warning", message: "观看人与购买票数不符" });
22 if (!payment.form.phone)
23 return ElMessage({ type: "warning", message: "请输入联系人电话" });
24 payOrder({
25 contactPhone: payment.form.phone,
26 customerIds: payment.form.viewers,
27 orderToken: order.data?.orderToken,
28 payType: 1,
29 paymentAmount: order.data?.paymentAmount,
30 }).then((res) => {
31 // TODO: 这里有一个二维码
32 payment.qrInfo = res.data;
33 payment.showCodeDialog = true;
34 router.push({
35 path: "/seat/order",
36 });
37 });
38 },
39 });
40
41 const order = reactive({
42 data: null,
43 fetchData() {
44 confirmOrder({
45 actId: route.query.actId ?? 1,
46 openType: route.query.openType,
47 sessionId: route.query.sessionId,
48 sitePlace: route.query.sitePlace,
49 ticketType: route.query.ticketType,
50 seatIds: route.query.seatIds.split(","),
51 }).then((res) => {
52 this.data = res.data;
53 });
54 },
55 });
56
57 const audience = reactive({
58 data: [],
59 fetchData() {
60 viewPeopleList().then((res) => {
61 audience.data = res.data;
62 });
63 },
64 });
65
66 audience.fetchData();
67 order.fetchData();
68 </script>
2 69
3 <template> 70 <template>
4 <div class="container"> 71 <div class="container">
...@@ -6,8 +73,8 @@ ...@@ -6,8 +73,8 @@
6 <div class="content"> 73 <div class="content">
7 <div class="left"> 74 <div class="left">
8 <div class="info"> 75 <div class="info">
9 <div class="name">2024亚洲舞蹈比赛无锡站</div> 76 <div class="name">{{ order.data?.activityName }}</div>
10 <div class="address">无锡会展中心</div> 77 <div class="address">{{ order.data?.placeName }}</div>
11 </div> 78 </div>
12 79
13 <div class="ticket_info"> 80 <div class="ticket_info">
...@@ -19,27 +86,39 @@ ...@@ -19,27 +86,39 @@
19 <div class="form"> 86 <div class="form">
20 <el-form> 87 <el-form>
21 <el-form-item label="联系人"> 88 <el-form-item label="联系人">
22 <el-input placeholder="请输入手机号" style="width: 260px" /> 89 <el-input
90 v-model="payment.form.phone"
91 placeholder="请输入联系人电话"
92 style="width: 260px"
93 />
23 </el-form-item> 94 </el-form-item>
24 <el-form-item label="观看人"> 95 <el-form-item label="观看人">
25 <div class="p_box"> 96 <div class="p_box">
26 <div class="people"> 97 <div class="people">
27 <el-checkbox-group @change=""> 98 <el-checkbox-group
99 v-model="payment.form.viewers"
100 :max="order.data?.seatInfo?.length"
101 >
28 <div 102 <div
29 v-for="(it, index) in 5" 103 v-for="(it, index) in audience.data"
30 :key="index" 104 :key="index"
31 class="prople_item" 105 class="prople_item"
32 > 106 >
33 <div> 107 <div>
34 <div class="name">张三</div> 108 <div class="name">{{ it.name }}</div>
35 <div class="idcard">412************073</div> 109 <div class="idcard">{{ it.idCard }}</div>
36 </div> 110 </div>
37 <el-checkbox> </el-checkbox> 111 <el-checkbox :value="it.id"> </el-checkbox>
38 </div> 112 </div>
39 </el-checkbox-group> 113 </el-checkbox-group>
40 </div> 114 </div>
41 <!-- button --> 115 <!-- button -->
42 <div class="btn">新增</div> 116 <div
117 class="btn"
118 @click="$router.push({ path: '/seat/people_manage' })"
119 >
120 新增
121 </div>
43 </div> 122 </div>
44 </el-form-item> 123 </el-form-item>
45 </el-form> 124 </el-form>
...@@ -55,17 +134,28 @@ ...@@ -55,17 +134,28 @@
55 134
56 <div class="detail"> 135 <div class="detail">
57 <div class="detail_top"> 136 <div class="detail_top">
58 <div class="time">2024.03.03 周六</div> 137 <div class="time">{{ order.data?.dateStr }}</div>
59 <div class="ticket">80.00元票档 X2张</div> 138 <div class="ticket">
139 {{ order.data?.singlePrice }}元票档 x{{
140 order.data?.seatInfo?.length
141 }}
142 </div>
60 </div> 143 </div>
61 <div class="detail_center"> 144 <div class="detail_center">
62 <div v-for="(it, index) in 4" :key="index" class="ticket"> 145 <div
63 A区 6排14座 (B6馆) 146 v-for="(it, index) in order.data?.seatInfo"
147 :key="index"
148 class="ticket"
149 >
150 <span v-if="it.venueId == 1">{{ it.area }}</span>
151 {{ it.pai }}{{ it.no }}座 ({{
152 it.venueId == 1 ? "B6" : "B4"
153 }}馆)
64 </div> 154 </div>
65 </div> 155 </div>
66 <div class="detail_b"> 156 <div class="detail_b">
67 <div class="sum_txt">共计</div> 157 <div class="sum_txt">共计</div>
68 <div class="price_num">¥160.00</div> 158 <div class="price_num">¥{{ order.data?.paymentAmount }}</div>
69 </div> 159 </div>
70 </div> 160 </div>
71 </div> 161 </div>
...@@ -74,8 +164,13 @@ ...@@ -74,8 +164,13 @@
74 <div> 164 <div>
75 <span class="label">共计金额:</span><span class="value">¥900.00</span> 165 <span class="label">共计金额:</span><span class="value">¥900.00</span>
76 </div> 166 </div>
77 <div class="pay">立即支付</div> 167 <div class="pay" @click="payment.paymentHandle()">立即支付</div>
78 </div> 168 </div>
169
170 <qrCodeDialog
171 :showCodeDialog="payment.showCodeDialog"
172 :qrCode="payment.qrInfo?.scanCodeUrl"
173 />
79 </div> 174 </div>
80 </template> 175 </template>
81 176
...@@ -83,6 +178,12 @@ ...@@ -83,6 +178,12 @@
83 div { 178 div {
84 box-sizing: border-box; 179 box-sizing: border-box;
85 } 180 }
181 .qrcode {
182 width: 150px;
183 height: 150px;
184 background-color: #8623fc;
185 margin: 0 auto;
186 }
86 .container { 187 .container {
87 padding: 20px 0; 188 padding: 20px 0;
88 width: 1200px; 189 width: 1200px;
......
1 <script setup></script> 1 <script setup>
2 import { reactive } from "vue";
3 import { cancelOrder, getOrderDetail } from "./api/index.js";
4 import qrCodeDialog from "./components/qrCodeDialog.vue";
5 import { ElMessageBox, ElMessage } from "element-plus";
6
7 const route = useRoute();
8 const router = useRouter();
9
10 const status = reactive({
11 0: {
12 txt: "待支付",
13 color: "#F740A6",
14 bgColor: "#FFE2F2",
15 },
16 1: {
17 txt: "已支付",
18 color: "#757575",
19 bgColor: "#DDDDDD",
20 },
21 2: {
22 txt: "未支付",
23 color: "#34C759",
24 bgColor: "#D2FFDD",
25 },
26 3: {
27 txt: "已退款",
28 color: "#FFCC00",
29 bgColor: "#FFF7D9",
30 },
31 });
32
33 const detail = reactive({
34 data: null,
35 fetchData() {
36 getOrderDetail({ orderSn: route.query.orderSn }).then((res) => {
37 detail.data = res.data;
38 });
39 },
40 });
41
42 detail.fetchData();
43 </script>
2 44
3 <template> 45 <template>
4 <div class="container"> 46 <div class="container">
...@@ -14,11 +56,17 @@ ...@@ -14,11 +56,17 @@
14 </div> 56 </div>
15 <div class="line"></div> 57 <div class="line"></div>
16 <div class="tr"> 58 <div class="tr">
17 <div style="width: 30%" class="td">2024年亚洲舞蹈大赛无锡站</div> 59 <div style="width: 30%" class="td">{{ detail.data?.name }}</div>
18 <div style="width: 25%" class="td">无锡太湖国际博览中心</div> 60 <div style="width: 25%" class="td">{{ detail.data?.placeName }}</div>
19 <div style="width: 20%" class="td">¥80.00</div> 61 <div style="width: 20%" class="td">
20 <div style="width: 12%" class="td">x3</div> 62 ¥{{ detail.data?.singlePrice }}
21 <div style="width: 13%; text-align: right" class="td">¥240.00</div> 63 </div>
64 <div style="width: 12%" class="td">
65 x{{ detail.data?.seatList?.length }}
66 </div>
67 <div style="width: 13%; text-align: right" class="td">
68 ¥{{ detail.data?.payAmount }}
69 </div>
22 </div> 70 </div>
23 </div> 71 </div>
24 <!-- 座位 --> 72 <!-- 座位 -->
...@@ -30,17 +78,20 @@ ...@@ -30,17 +78,20 @@
30 </div> 78 </div>
31 <div class="tr"> 79 <div class="tr">
32 <div style="width: 30.33%" class="td flex-col"> 80 <div style="width: 30.33%" class="td flex-col">
33 <div>2024.05.03 周六</div> 81 <div>{{ detail.data?.dateStr }}</div>
34 <div>A区 6排16座 (B6馆)</div> 82 <div v-for="(it, index) in detail.data?.seatList" :key="index">
35 <div>A区 6排16座 (B6馆)</div> 83 <span v-if="it.venueId == 1">{{ it.area }}</span
36 <div>A区 6排16座 (B6馆)</div> 84 >{{ it.pai }}{{ it.no }}座 ({{
85 it.venueId == 1 ? "B6" : "B4"
86 }}馆)
87 </div>
37 </div> 88 </div>
38 <div style="width: 30.33%" class="td flex-col"> 89 <div style="width: 30.33%" class="td flex-col">
39 <div>订单编号:12783893435</div> 90 <div>订单编号:{{ detail.data?.orderSn }}</div>
40 <div>创建时间:2024.05.07 16:3</div> 91 <div>创建时间:{{ detail.data?.orderTime }}</div>
41 </div> 92 </div>
42 <div style="width: 30.33%" class="td"> 93 <div style="width: 30.33%" class="td">
43 <div>联系电话:12783893435</div> 94 <div>联系电话:{{ detail.data?.contactPhone }}</div>
44 </div> 95 </div>
45 </div> 96 </div>
46 </div> 97 </div>
...@@ -48,9 +99,13 @@ ...@@ -48,9 +99,13 @@
48 <div class="pay_ticket"> 99 <div class="pay_ticket">
49 <div class="title">购票人</div> 100 <div class="title">购票人</div>
50 <div class="people"> 101 <div class="people">
51 <div v-for="(it, index) in 4" :key="index" class="p_info"> 102 <div
52 <div>张三</div> 103 v-for="(it, index) in detail.data?.customerList"
53 <div class="idcard">身份证:244************0</div> 104 :key="index"
105 class="p_info"
106 >
107 <div>{{ it.name }}</div>
108 <div class="idcard">身份证:{{ it.idCard }}</div>
54 </div> 109 </div>
55 </div> 110 </div>
56 </div> 111 </div>
...@@ -61,19 +116,31 @@ ...@@ -61,19 +116,31 @@
61 <div class="title">结算信息</div> 116 <div class="title">结算信息</div>
62 <div class="cell"> 117 <div class="cell">
63 <div class="label">订单状态</div> 118 <div class="label">订单状态</div>
64 <div class="value">待支付</div> 119 <div class="value">{{ status[detail.data?.state]?.txt }}</div>
65 </div> 120 </div>
66 <div class="cell"> 121 <div class="cell">
67 <div class="label">订单金额</div> 122 <div class="label">订单金额</div>
68 <div class="value">待支付</div> 123 <div class="value">¥{{ detail.data?.payAmount }}</div>
69 </div> 124 </div>
70 <!-- button --> 125 <!-- button -->
71 <div class="btn_box"> 126 <div v-if="detail.data?.state == 0" class="btn_box">
72 <div class="can_pay">取消支付</div> 127 <div class="can_pay">取消支付</div>
73 <div class="pay">立即支付</div> 128 <div class="pay">立即支付</div>
74 </div> 129 </div>
130 <div v-else>
131 <div v-if="detail.data?.state == 1 && detail.data?.isRefund" class="btn_box">
132 <div class="can_pay">取消购票</div>
133 <div class="pay">再来一单</div>
134 </div>
135
136 <div v-else class="btn_box">
137 <div class="pay_dis">请联系工作人员</div>
138 </div>
139 </div>
140 </div>
141 <div v-if="detail.data?.state == 0" class="tip">
142 请尽快完成支付,还剩15分00秒
75 </div> 143 </div>
76 <div class="tip">请尽快完成支付,还剩15分00秒</div>
77 </div> 144 </div>
78 </div> 145 </div>
79 </template> 146 </template>
...@@ -216,6 +283,18 @@ ...@@ -216,6 +283,18 @@
216 padding-top: 20px; 283 padding-top: 20px;
217 display: flex; 284 display: flex;
218 gap: 20px; 285 gap: 20px;
286 .pay_dis {
287 width: 360px;
288 height: 40px;
289 background: #A09DFF;
290 border-radius: 20px;
291 font-weight: 500;
292 font-size: 16px;
293 color: #ffffff;
294 line-height: 40px;
295 text-align: center;
296 cursor: pointer;
297 }
219 .pay { 298 .pay {
220 width: 170px; 299 width: 170px;
221 height: 40px; 300 height: 40px;
......
1 <script setup> 1 <script setup>
2 import { getOrderList, immediatePay, cancelPay } from "./api/index.js";
3 import qrCodeDialog from "./components/qrCodeDialog.vue";
4 import { ElMessageBox, ElMessage } from "element-plus";
5
2 const status = reactive({ 6 const status = reactive({
3 0: { 7 0: {
4 txt: "待支付", 8 txt: "待支付",
...@@ -21,47 +25,121 @@ const status = reactive({ ...@@ -21,47 +25,121 @@ const status = reactive({
21 bgColor: "#FFF7D9", 25 bgColor: "#FFF7D9",
22 }, 26 },
23 }); 27 });
28
29 const order = reactive({
30 showCodeDialog: false,
31 qrInfo: {},
32 pay_loading: false,
33 pageNo: 1,
34 pageSize: 10,
35 total: 0,
36 data: [],
37 fetchData() {
38 getOrderList({ pageNo: order.pageNo, pageSize: order.pageSize }).then(
39 (res) => {
40 order.data = res.data.lists;
41 order.total = res.data.count;
42 }
43 );
44 },
45 payment(it) {
46 if (order.pay_loading) return;
47 order.pay_loading = true;
48 immediatePay({ orderSn: it.orderSn, payType: 1 })
49 .then((res) => {
50 order.qrInfo = res.data;
51 order.showCodeDialog = true;
52 })
53 .finally(() => (order.pay_loading = false));
54 },
55 cancelPayment(it) {
56 ElMessageBox.confirm("确定取消支付吗?", "Warning", {
57 confirmButtonText: "确认",
58 cancelButtonText: "取消",
59 type: "warning",
60 draggable: true,
61 })
62 .then(() => {
63 cancelPay({ orderSn: it.orderSn }).then(() => {
64 order.fetchData();
65 ElMessage({
66 type: "success",
67 message: "操作成功",
68 });
69 });
70 })
71 .catch(() => {});
72 },
73 });
74
75 order.fetchData();
24 </script> 76 </script>
25 77
26 <template> 78 <template>
27 <div class="container"> 79 <div class="container">
28 <div 80 <div
29 v-for="(it, index) in 10" 81 v-for="(it, index) in order.data"
30 :key="index" 82 :key="index"
31 @click="$router.push({ path: '/seat/order_detail' })" 83 @click="
84 $router.push({
85 path: '/seat/order_detail',
86 query: { orderSn: it.orderSn },
87 })
88 "
32 class="order-item" 89 class="order-item"
33 > 90 >
34 <div class="info_box"> 91 <div class="info_box">
35 <img class="cover_img" /> 92 <img class="cover_img" :src="it.coverImg" />
36 <div class="info"> 93 <div class="info">
37 <div class="title">2024年亚洲舞蹈大赛无锡站</div> 94 <div class="title">{{ it.name }}</div>
38 <div class="common">时间:2024.05.06 周六</div> 95 <div class="common">时间:{{ it.dateStr }}</div>
39 <div class="common">地址:无锡太湖博览中心</div> 96 <div class="common">地址:{{ it.placeName }}</div>
40 <div class="common">订单编号:739274039504</div> 97 <div class="common">订单编号:{{ it.orderSn }}</div>
41 <div class="common">张数:2</div> 98 <div class="common">张数:{{ it.ticketNum }}</div>
42 <div class="common">金额:¥728.00</div> 99 <div class="common">金额:¥{{ it.payAmount }}</div>
43 <div class="status"> 100 <div class="status">
44 <div class="label">订单状态:</div> 101 <div class="label">订单状态:</div>
45 <div class="value"> 102 <div class="value">
46 <div 103 <div
47 :style="{ 104 :style="{
48 borderColor: status[0].color, 105 borderColor: status[it.state].color,
49 background: status[0].bgColor, 106 background: status[it.state].bgColor,
50 color: status[0].color, 107 color: status[it.state].color,
51 }" 108 }"
52 class="tag" 109 class="tag"
53 > 110 >
54 {{ status[0].txt }} 111 {{ status[it.state].txt }}
55 </div> 112 </div>
56 <div v-if="true" class="tip">请尽快完成支付,还剩15分00秒</div> 113 <div v-if="it.state == 0" class="tip">
114 请尽快完成支付,还剩15分00秒
57 </div> 115 </div>
58 </div> 116 </div>
59 </div> 117 </div>
60 </div> 118 </div>
61 <div class="btn_box">
62 <div class="pay">立即支付</div>
63 <div class="can_pay">取消支付</div>
64 </div> 119 </div>
120 <div v-if="it.state == 0" class="btn_box">
121 <div class="pay" @click.stop="order.payment(it)">立即支付</div>
122 <div class="can_pay" @click.stop="order.cancelPayment(it)">
123 取消支付
124 </div>
125 </div>
126 </div>
127
128 <qrCodeDialog
129 :showCodeDialog="order.showCodeDialog"
130 :qrCode="order.qrInfo?.scanCodeUrl"
131 />
132
133 <div class="pagination">
134 <el-pagination
135 v-show="order.total > 0"
136 v-model:current-page="order.pageNo"
137 v-model:page-size="order.pageSize"
138 background
139 layout="prev, pager, next"
140 :total="order.total"
141 @current-change="order.fetchData()"
142 />
65 </div> 143 </div>
66 </div> 144 </div>
67 </template> 145 </template>
...@@ -87,6 +165,7 @@ const status = reactive({ ...@@ -87,6 +165,7 @@ const status = reactive({
87 .cover_img { 165 .cover_img {
88 width: 155px; 166 width: 155px;
89 height: 200px; 167 height: 200px;
168 object-fit: fill;
90 } 169 }
91 .info { 170 .info {
92 .title { 171 .title {
...@@ -163,4 +242,9 @@ const status = reactive({ ...@@ -163,4 +242,9 @@ const status = reactive({
163 } 242 }
164 } 243 }
165 } 244 }
245
246 .pagination {
247 display: flex;
248 justify-content: center;
249 }
166 </style> 250 </style>
......
1 <script setup></script> 1 <script setup>
2 import { deleteViewPeople, viewPeopleList } from "./api/index.js";
3 import { ElMessageBox, ElMessage } from "element-plus";
4
5
6 const audience = reactive({
7 data: [],
8 fetchData() {
9 viewPeopleList().then((res) => {
10 audience.data = res.data;
11 });
12 },
13
14 deletePeople(id) {
15 ElMessageBox.confirm("确定删除该观看人吗?", "Warning", {
16 confirmButtonText: "确认",
17 cancelButtonText: "取消",
18 type: "warning",
19 draggable: true,
20 })
21 .then(() => {
22 deleteViewPeople({ id }).then(() => {
23 audience.fetchData();
24 ElMessage({
25 type: "success",
26 message: "操作成功",
27 });
28 });
29 })
30 .catch(() => {});
31 },
32 });
33
34 audience.fetchData();
35 </script>
2 36
3 <template> 37 <template>
4 <div class="container"> 38 <div class="container">
5 <div class="title">观影人管理</div> 39 <div class="title">
40 <div
41 class="add_btn"
42 @click="$router.push({ path: '/seat/add_watch_people' })"
43 >
44 新增
45 </div>
46 观影人管理
47 </div>
6 <div class="content"> 48 <div class="content">
7 <div class="people_box"> 49 <div class="people_box">
8 <div v-for="(it, index) in 10" :key="index" class="people_item"> 50 <div
9 <div class="name">朱育杰</div> 51 v-for="(it, index) in audience.data"
10 <div class="idcard">身份证:244************074</div> 52 :key="index"
11 <div class="btn">删除</div> 53 class="people_item"
54 >
55 <div class="name">{{ it.name }}</div>
56 <div class="idcard">身份证:{{ it.idCard }}</div>
57 <div class="btn" @click="audience.deletePeople(it.id)">删除</div>
12 </div> 58 </div>
13 </div> 59 </div>
14 </div> 60 </div>
...@@ -25,11 +71,30 @@ div { ...@@ -25,11 +71,30 @@ div {
25 margin: 0 auto; 71 margin: 0 auto;
26 72
27 .title { 73 .title {
74 position: relative;
28 padding: 11px; 75 padding: 11px;
29 text-align: center; 76 text-align: center;
30 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%); 77 background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%);
31 font-size: 18px; 78 font-size: 18px;
32 color: #ffffff; 79 color: #ffffff;
80 .add_btn {
81 position: absolute;
82 left: 20px;
83 top: 50%;
84 transform: translateY(-50%);
85 width: 68px;
86 height: 24px;
87 border-radius: 12px;
88 border: 1px solid #ffffff;
89 font-weight: 400;
90 font-size: 12px;
91 color: #ffffff;
92 text-align: center;
93 line-height: 24px;
94 box-sizing: border-box;
95 user-select: none;
96 cursor: pointer;
97 }
33 } 98 }
34 99
35 .content { 100 .content {
......
1 <script setup>
2 import { ElMessage } from "element-plus";
3 import { getPriceLevelInfo, getSiteConfig } from "./api/index.js";
4 const route = useRoute();
5 const router = useRouter()
6
7 const iframeRef = ref();
8
9 // 获取票档
10 const price = reactive({
11 curPriceId: route.query.ticket_block,
12 data: [],
13
14 fetchData() {
15 getPriceLevelInfo({
16 actId: route.query?.actId ?? 1,
17 sessionId: route.query.sessionId,
18 openType: route.query.openType,
19 sitePlace: route.query.sitePlace,
20 ticketType: route.query.ticketType,
21 }).then((res) => {
22 this.data = res.data;
23 // price.curPriceId = route.query.ticket_block
24 });
25 },
26 onClickPrice(e) {
27 // if (selectedSeats.value?.length) {
28 // return ElMessage({ type: "warning", message: "请先取消已选座位" });
29 // }
30 price.curPriceId = e.priceId;
31 },
32 });
33
34 // 座位禁用时图标地址
35 const disabledIconUrl =
36 "http://book.xiaojinyu.games/api/uploads/image/20240511/unselect_default.png";
37
38 const siteConfig = reactive({
39 loading: false,
40 data: [],
41 fetchData() {
42 return getSiteConfig({
43 actId: route.query.actId ?? 1,
44 openType: route.query.openType,
45 sessionId: route.query.sessionId,
46 sitePlace: route.query.sitePlace,
47 ticketType: route.query.ticketType,
48 }).then((res) => {
49 const gridSize = 40;
50 const seat_arr = res.data.map((it, index) => {
51 return {
52 ...it,
53 // 这几个是iframe引擎渲染座位必须的属性,规定好的
54 x: gridSize * it.x,
55 y: gridSize * it.y,
56 w: gridSize,
57 h: gridSize,
58 icon: it.state == 1 ? it.selectIcon : disabledIconUrl, // 图片的url
59 active: 0, // 是否选中
60 priceId: route.query.openType == 0 ? it.dayPriceId : it.nightPriceId,
61 };
62 });
63 siteConfig.data = seat_arr;
64 return seat_arr;
65 });
66 },
67 });
68
69 watch(
70 () => price.curPriceId,
71 (priceId) => {
72 siteConfig.data.forEach((it) => {
73 sendMsg("update-seat", {
74 id: it.id,
75 data: {
76 icon:
77 it.state == 1 && priceId == it.priceId
78 ? it.active
79 ? it.unSelectIcon
80 : it.selectIcon
81 : disabledIconUrl,
82 },
83 });
84 });
85 console.log("update完成");
86 },
87 { immediate: true }
88 );
89
90 const sendMsg = (type, data) =>
91 iframeRef.value?.contentWindow.postMessage({ type: type, data: data }, "*");
92
93 /**
94 * 1. 加載iframe 3. 请求API的数据
95 * 2. 等待iframe里面资源加载完毕并触发picker-ready事件
96 * 4. 传递数据给iframe,等待渲染
97 */
98
99 window.addEventListener("message", (e) => {
100 const data = e.data;
101 console.log("[parent]", data);
102
103 if (data.type == "picker-ready") {
104 // apiPromise.then(() => {})
105
106 siteConfig.fetchData().then((res) => {
107 const seat_arr = res.map((it) => {
108 return {
109 ...it,
110 active: 0,
111 icon:
112 it.state == 1 && price.curPriceId == it.priceId
113 ? it.selectIcon
114 : disabledIconUrl,
115 };
116 });
117 // 子页面加载完毕,这里iframeRef一定ok
118 iframeRef.value.contentWindow.postMessage(
119 {
120 type: "load-seats",
121 data: seat_arr,
122 },
123 "*"
124 );
125 });
126 } else if (data.type == "seat-click") {
127 // 子页面点击了座位
128 const seatData = data.data;
129 console.log("座位点击", seatData);
130
131 // 如果座位处于不可点击状态,就return
132 if (seatData.state != 1) return;
133
134 // 如果当前筛选了某种座位,点击的不是这种座位,也返回
135 if (price.curPriceId && seatData.priceId != price.curPriceId) return;
136
137 const newActive = seatData.active == 0 ? 1 : 0;
138 const siteConfigItem = siteConfig.data.find((it) => it.id == seatData.id);
139 if (siteConfigItem) {
140 siteConfigItem.active = newActive;
141 }
142 sendMsg("update-seat", {
143 id: seatData.id,
144 data: {
145 active: newActive,
146 icon: newActive ? seatData.unSelectIcon : seatData.selectIcon,
147 },
148 });
149 }
150 });
151 const deleteSiteConfigItem = (seatData) => {
152 const newActive = seatData.active == 0 ? 1 : 0;
153 const siteConfigItem = siteConfig.data.find((it) => it.id == seatData.id);
154 if (siteConfigItem) {
155 siteConfigItem.active = newActive;
156 }
157 sendMsg("update-seat", {
158 id: seatData.id,
159 data: { icon: newActive ? seatData.unSelectIcon : seatData.selectIcon },
160 });
161 };
162
163 /** 所选座位 */
164 const selectedSeats =
165 computed(() => siteConfig.data.filter((it) => it.active == 1)) ?? [];
166
167 /** 所选座位价格 */
168 const sumPrice = computed(() => {
169 return selectedSeats.value.reduce((total, item) => {
170 const price =
171 route.query.openType == 0
172 ? Number(item.dayPrice)
173 : Number(item.nightPrice);
174 return total + price;
175 }, 0);
176 });
177
178 const toConfirmOrder = () => {
179 const seatIds = selectedSeats.value.map((it) => it.id);
180 if (!seatIds.length)
181 return ElMessage({ type: "warning", message: "请先选择座位" });
182
183 router.push({
184 path: "/seat/confirm_order",
185 query: {
186 openType: route.query.openType,
187 sessionId: route.query.sessionId,
188 sitePlace: route.query.sitePlace,
189 ticketType: route.query.ticketType,
190 seatIds: seatIds.join(","),
191 },
192 });
193 };
194
195 price.fetchData();
196 </script>
197
198 <template>
199 <div class="container">
200 <div class="top">
201 <div class="time">
202 <span>{{ route.query?.time_txt }}</span>
203 <span class="place">{{ route.query.sitePlace }}</span>
204 </div>
205 <div class="price_tab">
206 <div
207 v-for="(it, index) in price.data"
208 class="tab_item"
209 :class="{ tabActive: it.priceId == price.curPriceId }"
210 @click="price.onClickPrice(it)"
211 >
212 <img class="seat" :src="it.selectIcon" />
213 <span class="price">{{ it.price }}¥</span>
214 </div>
215 </div>
216 </div>
217
218 <div v-if="selectedSeats?.length" class="bottom">
219 <div class="seat_box">
220 <!-- v-for="(it, index) in selectedSeats" -->
221 <div v-for="(it, index) in selectedSeats" class="seat_item">
222 <img class="seat_icon" :src="it.selectIcon" />
223 <span class="num">{{ it.area }}{{ it.pai }}{{ it.no }}</span>
224 <el-icon
225 style="cursor: pointer"
226 color="#ccc"
227 @click="deleteSiteConfigItem(it)"
228 ><CircleCloseFilled
229 /></el-icon>
230 </div>
231 </div>
232 <div class="pay">
233 <div class="sum">¥{{ sumPrice?.toFixed(2) }}</div>
234 <div class="pay_btn" @click="toConfirmOrder()">立即购买</div>
235 </div>
236 </div>
237
238 <div class="iframeBox">
239 <iframe
240 ref="iframeRef"
241 class="iframe"
242 id="iframe"
243 src="http://seat-choose.parent4relax.com/#/seat-picker"
244 ></iframe>
245 </div>
246 </div>
247 </template>
248
249 <style scoped lang="scss">
250 .container {
251 width: 1200px;
252 margin: 0 auto;
253 padding: 20px;
254
255 .top {
256 width: 100%;
257 background-color: #fff;
258 padding: 20px;
259 margin-bottom: 10px;
260 border-radius: 6px;
261 .time {
262 font-size: 18px;
263 font-weight: 600;
264 margin-bottom: 10px;
265 .place {
266 color: #7e8489;
267 margin-left: 15px;
268 }
269 }
270
271 .price_tab {
272 display: flex;
273 align-items: center;
274 flex-wrap: wrap;
275 gap: 10px;
276 .tabActive {
277 background: #eeeeee !important;
278 border: 2px solid #7e8489 !important;
279 }
280 .tab_item {
281 display: flex;
282 align-items: center;
283 padding: 10px 14px;
284 background: #f5f7f8;
285 border-radius: 30px;
286 border: 2px solid #dcdedf;
287 font-size: 16px;
288 color: #646666;
289 cursor: pointer;
290 user-select: none;
291
292 .seat {
293 width: 14px;
294 height: 14px;
295 margin-right: 5px;
296 }
297 }
298 }
299 }
300
301 .iframeBox {
302 border-radius: 6px;
303 background-color: #fff;
304 padding: 20px;
305 margin-bottom: 20px;
306 }
307
308 .iframe {
309 width: 100%;
310 height: 500px;
311 border: none;
312 background-color: #f7f8fa;
313 }
314
315 .bottom {
316 border-radius: 6px;
317 background-color: #fff;
318 padding: 20px;
319 margin-bottom: 20px;
320 .seat_box {
321 display: flex;
322 flex-wrap: wrap;
323 gap: 10px;
324 width: 100%;
325 .seat_item {
326 display: flex;
327 align-items: center;
328 padding: 10px 14px;
329 font-size: 16px;
330 color: #29343c;
331 background: #eeeeee;
332 border-radius: 30px;
333 border: 2px solid #7e8489;
334 user-select: none;
335 .seat_icon {
336 width: 14px;
337 height: 14px;
338 margin-right: 5px;
339 }
340 .num {
341 margin-right: 5px;
342 }
343 }
344 }
345
346 .pay {
347 display: flex;
348 justify-content: space-between;
349 align-items: center;
350 margin-top: 10px;
351 .sum {
352 font-weight: 600;
353 font-size: 22px;
354 color: #493ceb;
355 }
356 .pay_btn {
357 width: 200px;
358 height: 40px;
359 background: #493ceb;
360 border-radius: 20px;
361 margin-top: 10px;
362 font-size: 14px;
363 color: #fff;
364 line-height: 40px;
365 text-align: center;
366 cursor: pointer;
367 font-weight: 600;
368 user-select: none;
369 }
370 }
371 }
372 }
373 </style>
1 <script setup></script> 1 <script setup>
2 import dayjs from "dayjs";
3 import useUserStore from "@/store/modules/user";
4 import { setToken, getToken } from "./utils/local-store.js";
5 import {
6 loginFree,
7 activityDetail,
8 sessionDetail,
9 getSitePlaceInfo,
10 getPriceLevelInfo,
11 } from "./api/index.js";
12 import { ElMessage } from "element-plus";
13 import { reactive } from "vue";
14
15 const route = useRoute();
16 const router = useRouter();
17 const userStore = useUserStore();
18 const actId = 1;
19
20 // 用户免登录
21 const login = () => {
22 return new Promise((resolve, reject) => {
23 return loginFree({
24 userId: 1,
25 sign: "e00363b5016dbb6ee6cf78626a149f9c",
26 }).then((res) => {
27 setToken(res.data.token);
28 resolve(res.data);
29 });
30 });
31 };
32
33 const select_form = reactive({
34 venueItem: {
35 id: 0,
36 dateStr: "",
37 dayOpen: 1,
38 nightOpen: 1,
39 type: 0,
40 }, // 所选场次
41 session: -1, // 日/夜场 0:日场 1:夜场
42 place: "", // 场馆
43 ticket_block: 0, // 票档
44 onClickVenue(e, index) {
45 if (e.state == 1) return; // 表示
46 select_form.venueItem = e;
47 if (
48 (e.dayOpen == 0 && select_form.session == 0) ||
49 (e.nightOpen == 0 && select_form.session == 1)
50 ) {
51 select_form.session = -1;
52 select_form.place = "";
53 select_form.ticket_block = 0;
54 }
55 },
56 // 选择日/夜场
57 onClickSession(e) {
58 if (
59 (e == 0 && select_form.venueItem?.dayOpen == 1) ||
60 (e == 1 && select_form.venueItem?.nightOpen == 1)
61 ) {
62 select_form.session = e;
63 // select_form.place = "";
64 select_form.ticket_block = 0;
65 }
66 },
67 // 选择场馆
68 onClickPlace(e) {
69 if (e.state == 1) return;
70 select_form.place = e.placeName;
71 select_form.ticket_block = 0;
72 },
73 // 选择票档
74 onClickPrice(e) {
75 if (e.state == 1) return;
76 select_form.ticket_block = e.priceId;
77 },
78 // 去选座
79 toSelectSeat() {
80 if (!select_form.venueItem?.id)
81 return ElMessage({ type: "warning", message: "请选择时间" });
82 if (select_form.session == -1)
83 return ElMessage({ type: "warning", message: "请选择场次" });
84 if (!select_form.place)
85 return ElMessage({ type: "warning", message: "请选择场馆" });
86 if (!select_form.ticket_block)
87 return ElMessage({ type: "warning", message: "请选择票档" });
88
89 router.push({
90 path: "/seat/seat_picker",
91 query: {
92 openType: select_form.session,
93 sessionId: select_form.venueItem?.id,
94 sitePlace: select_form.place,
95 ticketType: select_form.venueItem?.type,
96 ticket_block: select_form.ticket_block,
97 time_txt: select_form.venueItem?.dateStr,
98 },
99 });
100 },
101 });
102
103 // 活动详情
104 const detail = reactive({
105 loading: false,
106 data: null,
107 fetchData() {
108 this.loading = true;
109 activityDetail({ actId: route.query?.actId ?? actId })
110 .then((res) => {
111 this.data = res.data;
112 })
113 .finally(() => (this.loding = false));
114 },
115 });
116
117 // 获取场次信息
118 const timeVenue = reactive({
119 loading: false,
120 data: [],
121 fetchData() {
122 this.loading = true;
123 sessionDetail({ actId: route.query?.actId ?? actId })
124 .then((res) => {
125 this.data = res.data;
126 })
127 .finally(() => (this.loading = false));
128 },
129 });
130
131 // 获取场馆
132 const sitePlaceInfo = reactive({
133 data: [
134 { placeName: "B4", state: "0" },
135 { placeName: "B6", state: "0" },
136 ],
137 fetchData() {
138 console.log(select_form.venueItem?.id, select_form.session);
139 getSitePlaceInfo({
140 sessionId: select_form.venueItem?.id,
141 openType: select_form.session,
142 }).then((res) => {
143 this.data = res.data;
144 });
145 },
146 });
147
148 // 获取票档
149 const price = reactive({
150 data: [],
151 fetchData() {
152 getPriceLevelInfo({
153 actId: route.query?.actId ?? actId,
154 sessionId: select_form.venueItem?.id,
155 openType: select_form.session,
156 sitePlace: select_form.place,
157 ticketType: select_form.venueItem?.type,
158 }).then((res) => {
159 this.data = res.data;
160 });
161 },
162 });
163
164 watchEffect(() => {
165 if (select_form.session != -1 && select_form.venueItem?.id) {
166 if (select_form.session == 1 && select_form.place == "B4") {
167 select_form.place = "";
168 }
169 sitePlaceInfo.fetchData();
170 }
171 });
172
173 watchEffect(() => {
174 if (
175 select_form.venueItem?.id &&
176 select_form.session != -1 &&
177 select_form.place
178 ) {
179 price.fetchData();
180 }
181 });
182
183 login().then((res) => {
184 detail.fetchData();
185 timeVenue.fetchData();
186 });
187 </script>
2 188
3 <template> 189 <template>
4 <div> 190 <div>
5 <!-- top --> 191 <!-- top -->
6 <div class="container top"> 192 <div class="container top">
7 <img class="cover_img" /> 193 <img class="cover_img" :src="detail.data?.coverImg" />
8 <div class="info"> 194 <div class="info">
9 <div class="title">2024年亚洲舞蹈大赛无锡站</div> 195 <div class="title">{{ detail.data?.name }}</div>
10 <div class="time">时间:2024.05.02 周六 — 2024.05.08 周一</div> 196 <div class="time">
11 <div class="address">地址:无锡太湖博览中心</div> 197 时间:{{
198 detail.data?.startTime
199 ? dayjs(detail.data?.startTime).format("YYYY.MM.DD")
200 : ""
201 }}
202 {{ detail.data?.startTime ? dayjs().format("ddd") : "" }}
203 {{
204 detail.data?.endTime
205 ? dayjs(detail.data?.endTime).format("YYYY.MM.DD")
206 : ""
207 }}
208 {{
209 detail.data?.endTime
210 ? dayjs(detail.data?.endTime).format("ddd")
211 : ""
212 }}
213 </div>
214 <div class="address">地址:{{ detail.data?.address }}</div>
12 <!-- 时间 --> 215 <!-- 时间 -->
13 <div class="select_item_box"> 216 <div class="select_item_box">
14 <div class="label">时间</div> 217 <div class="label">时间</div>
15 <div class="select_item"> 218 <div class="select_item">
16 <div 219 <div
17 v-for="(it, index) in 4" 220 v-for="(it, index) in timeVenue.data"
18 :key="index" 221 :key="index"
19 :class="[false ? 'tagActive' : 'tag']" 222 :class="[
223 it.id == select_form.venueItem?.id ? 'tagActive' : 'tag',
224 ]"
225 @click="select_form.onClickVenue(it)"
20 > 226 >
21 2024.05.02 周六 227 {{ it.dateStr }}
228 <div v-if="it.type == 1" class="tag_t">套票</div>
22 </div> 229 </div>
23 </div> 230 </div>
24 </div> 231 </div>
...@@ -26,11 +233,29 @@ ...@@ -26,11 +233,29 @@
26 <div class="select_item_box"> 233 <div class="select_item_box">
27 <div class="label">场次</div> 234 <div class="label">场次</div>
28 <div class="select_item"> 235 <div class="select_item">
29 <div :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']"> 236 <div
237 :class="[
238 select_form.venueItem?.dayOpen == 1
239 ? select_form.session == 0
240 ? 'tagActive'
241 : 'tag'
242 : 'tagDisabled',
243 ]"
244 @click="select_form.onClickSession(0)"
245 >
30 日场 246 日场
31 </div> 247 </div>
32 <div :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']"> 248 <div
33 日场 249 :class="[
250 select_form.venueItem?.nightOpen == 1
251 ? select_form.session == 1
252 ? 'tagActive'
253 : 'tag'
254 : 'tagDisabled',
255 ]"
256 @click="select_form.onClickSession(1)"
257 >
258 夜场
34 </div> 259 </div>
35 </div> 260 </div>
36 </div> 261 </div>
...@@ -39,39 +264,56 @@ ...@@ -39,39 +264,56 @@
39 <div class="label">场馆</div> 264 <div class="label">场馆</div>
40 <div class="select_item"> 265 <div class="select_item">
41 <div 266 <div
42 v-for="(it, index) in 2" 267 v-for="(it, index) in sitePlaceInfo.data"
43 :key="index" 268 :key="index"
44 :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']" 269 :class="[
270 it.state == 0
271 ? it.placeName == select_form.place
272 ? 'tagActive'
273 : 'tag'
274 : 'tagDisabled',
275 ]"
276 @click="select_form.onClickPlace(it)"
45 > 277 >
46 B6 278 {{ it.placeName }}
47 </div> 279 </div>
48 </div> 280 </div>
49 </div> 281 </div>
50 <!-- 票档 --> 282 <!-- 票档 -->
51 <div class="select_item_box"> 283 <div
284 v-if="price.data?.length && select_form.place"
285 class="select_item_box"
286 >
52 <div class="label">票档</div> 287 <div class="label">票档</div>
53 <div class="select_item"> 288 <div class="select_item">
54 <div 289 <div
55 v-for="(it, index) in 3" 290 v-for="(it, index) in price.data"
56 :key="index" 291 :key="index"
57 :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']" 292 :class="[
293 it.state == 0
294 ? it.priceId == select_form.ticket_block
295 ? 'tagActive'
296 : 'tag'
297 : 'tagDisabled',
298 ]"
299 @click="select_form.onClickPrice(it)"
58 > 300 >
59 200.00 301 {{ it.price }}
60 </div> 302 </div>
61 </div> 303 </div>
62 </div> 304 </div>
63 <!-- button --> 305 <!-- button -->
64 <div class="btn">选座购票</div> 306 <div class="btn" @click="select_form.toSelectSeat()">选座购票</div>
65 </div> 307 </div>
66 </div> 308 </div>
67 309
68 <!-- bottom --> 310 <!-- bottom -->
69 <div class="container bottom"> 311 <div class="container bottom">
70 <div class="title">活动介绍</div> 312 <div class="title">活动介绍</div>
71 <div class="rich_content" v-html="'123123123123123123'"></div> 313 <div class="rich_content" v-html="detail.data?.introduceInfo"></div>
72 314
73 <div class="title" style="margin-top: 30px">购票须知</div> 315 <div class="title" style="margin-top: 30px">购票须知</div>
74 <div class="rich_content" v-html="'123123123123123123'"></div> 316 <div class="rich_content" v-html="detail.data?.buyNotice"></div>
75 </div> 317 </div>
76 </div> 318 </div>
77 </template> 319 </template>
...@@ -142,7 +384,18 @@ ...@@ -142,7 +384,18 @@
142 display: flex; 384 display: flex;
143 flex-wrap: wrap; 385 flex-wrap: wrap;
144 gap: 10px; 386 gap: 10px;
387 user-select: none;
388 .tag_t {
389 padding: 1px 15px;
390 font-weight: 400;
391 font-size: 14px;
392 color: #493ceb;
393 border-radius: 6px;
394 border: 1px solid #453dea;
395 margin-left: 5px;
396 }
145 .tag { 397 .tag {
398 display: flex;
146 padding: 12px 18px; 399 padding: 12px 18px;
147 background: #eeeeee; 400 background: #eeeeee;
148 border-radius: 4px; 401 border-radius: 4px;
...@@ -151,7 +404,9 @@ ...@@ -151,7 +404,9 @@
151 color: #4a4a4a; 404 color: #4a4a4a;
152 cursor: pointer; 405 cursor: pointer;
153 } 406 }
407
154 .tagActive { 408 .tagActive {
409 display: flex;
155 padding: 12px 18px; 410 padding: 12px 18px;
156 background: #fff; 411 background: #fff;
157 border-radius: 4px; 412 border-radius: 4px;
......
1 /** 用户登录token储存的key */
2 export const TOKEN_KEY = "SEAT_TOKEN";
3
4 /** 设置token */
5 export const setToken = (token) => localStorage.setItem(TOKEN_KEY, token);
6
7 /**
8 * 获取登录token
9 * @param drop 是否清空
10 */
11 export const getToken = (drop = false) => {
12 let token = localStorage.getItem(TOKEN_KEY);
13 if (!token) return null;
14 if (drop) localStorage.removeItem(TOKEN_KEY);
15 return token;
16 };
1 // http.js
2
3 import axios from "axios";
4 import { getToken } from "./local-store";
5 import { ElMessage } from "element-plus";
6
7 const baseURL = "http://101.43.15.205:8084"; //"http://book.xiaojinyu.games"; // 这里填入你的基础 API URL
8 const timeout = 15000; // 请求超时时间
9
10 const http = axios.create({
11 baseURL,
12 timeout,
13 headers: {
14 "Content-Type": "application/json",
15 },
16 });
17
18 // 请求拦截器
19 http.interceptors.request.use(
20 (config) => {
21 // 在发送请求之前做些什么
22 const TOKEN = getToken();
23 config.headers.Authorization = TOKEN;
24 if (config.method == "get") config.params = config.data;
25 return config;
26 },
27 (error) => {
28 return Promise.reject(error);
29 }
30 );
31
32 // 响应拦截器
33 http.interceptors.response.use(
34 (response) => {
35 // 判断是否有异常
36 let error = null; // 若无异常此值为null
37 if (response.status !== 200) {
38 error = Error(`Request failed with statuCode ${response.status}`);
39 }
40
41 if (response.data.code != 200) {
42 return ElMessage({ type: "error", message: response.data.msg });
43 }
44
45 return response.data;
46 },
47 (error) => {
48 // 对响应错误做点什么
49 return Promise.reject(error);
50 }
51 );
52
53 // 封装请求函数
54 const request = (method, url, data = null) => {
55 return http({
56 method,
57 url,
58 data,
59 });
60 };
61
62 export default request;
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!