547289a7 by yyx

1

1 parent 6fe7ecb0
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
30 "jszip": "^3.10.1", 30 "jszip": "^3.10.1",
31 "katex": "^0.16.6", 31 "katex": "^0.16.6",
32 "lodash": "^4.17.21", 32 "lodash": "^4.17.21",
33 "md5js": "^1.0.7",
33 "nprogress": "0.2.0", 34 "nprogress": "0.2.0",
34 "pinia": "2.0.35", 35 "pinia": "2.0.35",
35 "qrcode": "^1.5.3", 36 "qrcode": "^1.5.3",
......
...@@ -65,6 +65,9 @@ importers: ...@@ -65,6 +65,9 @@ importers:
65 lodash: 65 lodash:
66 specifier: ^4.17.21 66 specifier: ^4.17.21
67 version: 4.17.21 67 version: 4.17.21
68 md5js:
69 specifier: ^1.0.7
70 version: 1.0.7
68 nprogress: 71 nprogress:
69 specifier: 0.2.0 72 specifier: 0.2.0
70 version: 0.2.0 73 version: 0.2.0
...@@ -2367,6 +2370,9 @@ packages: ...@@ -2367,6 +2370,9 @@ packages:
2367 resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} 2370 resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
2368 engines: {node: '>=0.10.0'} 2371 engines: {node: '>=0.10.0'}
2369 2372
2373 md5js@1.0.7:
2374 resolution: {integrity: sha512-97fZ6+8JijezAk/n37Lnswo4aJ67utCeCXlIsDid3uZ/khIeof0hWpIYeSvf0kiyqB0i9XfQvOyZPuBSR7g2Ng==}
2375
2370 mdn-data@2.0.14: 2376 mdn-data@2.0.14:
2371 resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} 2377 resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
2372 2378
...@@ -5828,6 +5834,8 @@ snapshots: ...@@ -5828,6 +5834,8 @@ snapshots:
5828 dependencies: 5834 dependencies:
5829 object-visit: 1.0.1 5835 object-visit: 1.0.1
5830 5836
5837 md5js@1.0.7: {}
5838
5831 mdn-data@2.0.14: {} 5839 mdn-data@2.0.14: {}
5832 5840
5833 memoize-one@6.0.0: {} 5841 memoize-one@6.0.0: {}
......
...@@ -511,7 +511,10 @@ export const constantRoutes = [ ...@@ -511,7 +511,10 @@ export const constantRoutes = [
511 path: 'detail', 511 path: 'detail',
512 name: 'seat_detail', 512 name: 'seat_detail',
513 component: () => import('@/viewsPc/seat/ticket-detail'), 513 component: () => import('@/viewsPc/seat/ticket-detail'),
514 meta: { title: '购票详情' } 514 meta: { title: '购票详情' },
515 props: route => ({
516 activityId:route.query.id,
517 })
515 }, 518 },
516 { 519 {
517 path: 'seat_picker', 520 path: 'seat_picker',
......
1 <script setup> 1 <script setup>
2 import { reactive } from "vue"; 2 import { reactive } from "vue";
3 import { cancelOrder, getOrderDetail } from "./api/index.js"; 3 import {
4 cancelOrder,
5 getOrderDetail,
6 immediatePay,
7 cancelPay,
8 } from "./api/index.js";
4 import qrCodeDialog from "./components/qrCodeDialog.vue"; 9 import qrCodeDialog from "./components/qrCodeDialog.vue";
5 import { ElMessageBox, ElMessage } from "element-plus"; 10 import { ElMessageBox, ElMessage } from "element-plus";
6 11
...@@ -31,12 +36,102 @@ const status = reactive({ ...@@ -31,12 +36,102 @@ const status = reactive({
31 }); 36 });
32 37
33 const detail = reactive({ 38 const detail = reactive({
39 showCodeDialog: false,
40 pay_loading: false,
41 qrInfo: {},
34 data: null, 42 data: null,
43 timer: null,
44
45 // 分钟
46 minutes: 0,
47 seconds: 0,
35 fetchData() { 48 fetchData() {
36 getOrderDetail({ orderSn: route.query.orderSn }).then((res) => { 49 getOrderDetail({ orderSn: route.query.orderSn }).then((res) => {
37 detail.data = res.data; 50 detail.data = res.data;
51 detail.countDown(detail.data?.payEndTime);
38 }); 52 });
39 }, 53 },
54 // 倒计时
55 countDown(time) {
56 // 当前时间
57 let nowTime = new Date();
58 let endTime = new Date(time);
59 // 两个日期相差的时间戳,以毫秒为单位(1000ms = 1s)
60 let totalTime = endTime - nowTime;
61 // 结束时间大于现在的时间
62 if (totalTime > 0) {
63 detail.timer = setInterval(() => {
64 if (totalTime >= 0) {
65 //获取分钟数
66 let minutes = Math.floor(
67 (((totalTime % (3600 * 24 * 1000)) / 1000) % 3600) / 60
68 );
69 //获取秒数
70 let seconds = Math.floor(
71 (((totalTime % (3600 * 24 * 1000)) / 1000) % 3600) % 60
72 )
73 .toString()
74 .padStart(2, "0");
75
76 detail.minutes = minutes;
77 detail.seconds = seconds;
78
79 totalTime -= 1000;
80 // console.log(totalTime)
81 } else {
82 clearInterval(timer); // 停止调用函数
83 }
84 }, 1000);
85 }
86 },
87 payment() {
88 if (detail.pay_loading) return;
89 detail.pay_loading = true;
90 immediatePay({ orderSn: detail.data.orderSn, payType: 1 })
91 .then((res) => {
92 detail.qrInfo = res.data;
93 detail.showCodeDialog = true;
94 })
95 .finally(() => (detail.pay_loading = false));
96 },
97 // 取消支付
98 cancelPay() {
99 ElMessageBox.confirm("确定取消支付吗?", "提示", {
100 confirmButtonText: "确认",
101 cancelButtonText: "取消",
102 type: "warning",
103 draggable: true,
104 })
105 .then(() => {
106 cancelPay({ orderSn: detail.data.orderSn }).then(() => {
107 detail.fetchData();
108 ElMessage({
109 type: "success",
110 message: "操作成功",
111 });
112 });
113 })
114 .catch(() => {});
115 },
116 // 取消购票
117 cancelOrder() {
118 ElMessageBox.confirm("确定取消购票吗?", "提示", {
119 confirmButtonText: "确认",
120 cancelButtonText: "取消",
121 type: "warning",
122 draggable: true,
123 })
124 .then(() => {
125 cancelOrder({ orderSn: detail.data.orderSn }).then((res) => {
126 detail.fetchData();
127 ElMessage({
128 type: "success",
129 message: "操作成功",
130 });
131 });
132 })
133 .catch(() => {});
134 },
40 }); 135 });
41 136
42 detail.fetchData(); 137 detail.fetchData();
...@@ -124,13 +219,21 @@ detail.fetchData(); ...@@ -124,13 +219,21 @@ detail.fetchData();
124 </div> 219 </div>
125 <!-- button --> 220 <!-- button -->
126 <div v-if="detail.data?.state == 0" class="btn_box"> 221 <div v-if="detail.data?.state == 0" class="btn_box">
127 <div class="can_pay">取消支付</div> 222 <div class="can_pay" @click="detail.cancelPay()">取消支付</div>
128 <div class="pay">立即支付</div> 223 <div class="pay" @click="detail.payment()">立即支付</div>
129 </div> 224 </div>
130 <div v-else> 225 <div v-else>
131 <div v-if="detail.data?.state == 1 && detail.data?.isRefund" class="btn_box"> 226 <div
132 <div class="can_pay">取消购票</div> 227 v-if="detail.data?.state == 1 && detail.data?.isRefund"
133 <div class="pay">再来一单</div> 228 class="btn_box"
229 >
230 <div class="can_pay" @click="detail.cancelOrder()">取消购票</div>
231 <div
232 class="pay"
233 @click="$router.push({ path: '/seat/seat-picker' })"
234 >
235 再来一单
236 </div>
134 </div> 237 </div>
135 238
136 <div v-else class="btn_box"> 239 <div v-else class="btn_box">
...@@ -139,9 +242,14 @@ detail.fetchData(); ...@@ -139,9 +242,14 @@ detail.fetchData();
139 </div> 242 </div>
140 </div> 243 </div>
141 <div v-if="detail.data?.state == 0" class="tip"> 244 <div v-if="detail.data?.state == 0" class="tip">
142 请尽快完成支付,还剩15分00 245 请尽快完成支付,还剩{{ detail.minutes }}{{ detail.seconds }}
143 </div> 246 </div>
144 </div> 247 </div>
248
249 <qrCodeDialog
250 :showCodeDialog="detail.showCodeDialog"
251 :qrCode="detail.qrInfo?.scanCodeUrl"
252 />
145 </div> 253 </div>
146 </template> 254 </template>
147 255
...@@ -283,10 +391,11 @@ detail.fetchData(); ...@@ -283,10 +391,11 @@ detail.fetchData();
283 padding-top: 20px; 391 padding-top: 20px;
284 display: flex; 392 display: flex;
285 gap: 20px; 393 gap: 20px;
394 user-select: none;
286 .pay_dis { 395 .pay_dis {
287 width: 360px; 396 width: 360px;
288 height: 40px; 397 height: 40px;
289 background: #A09DFF; 398 background: #a09dff;
290 border-radius: 20px; 399 border-radius: 20px;
291 font-weight: 500; 400 font-weight: 500;
292 font-size: 16px; 401 font-size: 16px;
......
...@@ -52,8 +52,9 @@ const order = reactive({ ...@@ -52,8 +52,9 @@ const order = reactive({
52 }) 52 })
53 .finally(() => (order.pay_loading = false)); 53 .finally(() => (order.pay_loading = false));
54 }, 54 },
55 // 取消支付
55 cancelPayment(it) { 56 cancelPayment(it) {
56 ElMessageBox.confirm("确定取消支付吗?", "Warning", { 57 ElMessageBox.confirm("确定取消支付吗?", "提示", {
57 confirmButtonText: "确认", 58 confirmButtonText: "确认",
58 cancelButtonText: "取消", 59 cancelButtonText: "取消",
59 type: "warning", 60 type: "warning",
...@@ -111,7 +112,7 @@ order.fetchData(); ...@@ -111,7 +112,7 @@ order.fetchData();
111 {{ status[it.state].txt }} 112 {{ status[it.state].txt }}
112 </div> 113 </div>
113 <div v-if="it.state == 0" class="tip"> 114 <div v-if="it.state == 0" class="tip">
114 请尽快完成支付,还剩15分00 115 请尽快完成支付,还剩{{ it.min }}{{ it.sec }}
115 </div> 116 </div>
116 </div> 117 </div>
117 </div> 118 </div>
...@@ -159,6 +160,7 @@ order.fetchData(); ...@@ -159,6 +160,7 @@ order.fetchData();
159 box-shadow: 0px 0px 46px 0px rgba(1, 16, 64, 0.08); 160 box-shadow: 0px 0px 46px 0px rgba(1, 16, 64, 0.08);
160 border-radius: 8px; 161 border-radius: 8px;
161 margin-bottom: 30px; 162 margin-bottom: 30px;
163 cursor: pointer;
162 .info_box { 164 .info_box {
163 display: flex; 165 display: flex;
164 gap: 20px; 166 gap: 20px;
......
...@@ -12,7 +12,7 @@ const audience = reactive({ ...@@ -12,7 +12,7 @@ const audience = reactive({
12 }, 12 },
13 13
14 deletePeople(id) { 14 deletePeople(id) {
15 ElMessageBox.confirm("确定删除该观看人吗?", "Warning", { 15 ElMessageBox.confirm("确定删除该观看人吗?", "提示", {
16 confirmButtonText: "确认", 16 confirmButtonText: "确认",
17 cancelButtonText: "取消", 17 cancelButtonText: "取消",
18 type: "warning", 18 type: "warning",
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
2 import { ElMessage } from "element-plus"; 2 import { ElMessage } from "element-plus";
3 import { getPriceLevelInfo, getSiteConfig } from "./api/index.js"; 3 import { getPriceLevelInfo, getSiteConfig } from "./api/index.js";
4 const route = useRoute(); 4 const route = useRoute();
5 const router = useRouter() 5 const router = useRouter();
6 6
7 const iframeRef = ref(); 7 const iframeRef = ref();
8 8
...@@ -33,7 +33,7 @@ const price = reactive({ ...@@ -33,7 +33,7 @@ const price = reactive({
33 33
34 // 座位禁用时图标地址 34 // 座位禁用时图标地址
35 const disabledIconUrl = 35 const disabledIconUrl =
36 "http://book.xiaojinyu.games/api/uploads/image/20240511/unselect_default.png"; 36 "http://114.55.227.212:8083/images/20240511/unselect_default.png";
37 37
38 const siteConfig = reactive({ 38 const siteConfig = reactive({
39 loading: false, 39 loading: false,
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
2 import dayjs from "dayjs"; 2 import dayjs from "dayjs";
3 import useUserStore from "@/store/modules/user"; 3 import useUserStore from "@/store/modules/user";
4 import { setToken, getToken } from "./utils/local-store.js"; 4 import { setToken, getToken } from "./utils/local-store.js";
5 import { md5 } from "md5js";
6 import { ElMessageBox, ElMessage } from "element-plus";
5 import { 7 import {
6 loginFree, 8 loginFree,
7 activityDetail, 9 activityDetail,
...@@ -9,24 +11,25 @@ import { ...@@ -9,24 +11,25 @@ import {
9 getSitePlaceInfo, 11 getSitePlaceInfo,
10 getPriceLevelInfo, 12 getPriceLevelInfo,
11 } from "./api/index.js"; 13 } from "./api/index.js";
12 import { ElMessage } from "element-plus";
13 import { reactive } from "vue";
14 14
15 const route = useRoute(); 15 const route = useRoute();
16 const router = useRouter(); 16 const router = useRouter();
17 const userStore = useUserStore(); 17 const userStore = useUserStore();
18 const actId = 1; 18
19 const props = defineProps({
20 activityId: [String, Number],
21 });
19 22
20 // 用户免登录 23 // 用户免登录
21 const login = () => { 24 const login = async (userId) => {
22 return new Promise((resolve, reject) => { 25 const sign = md5(`uid=${userId}lgo1acfkw51jfo`);
23 return loginFree({ 26 return loginFree({
24 userId: 1, 27 userId: userId,
25 sign: "e00363b5016dbb6ee6cf78626a149f9c", 28 sign,
26 }).then((res) => { 29 }).then((res) => {
27 setToken(res.data.token); 30 setToken(res.data.token);
28 resolve(res.data); 31 resolve(res.data);
29 }); 32 console.log(33333, res);
30 }); 33 });
31 }; 34 };
32 35
...@@ -106,7 +109,7 @@ const detail = reactive({ ...@@ -106,7 +109,7 @@ const detail = reactive({
106 data: null, 109 data: null,
107 fetchData() { 110 fetchData() {
108 this.loading = true; 111 this.loading = true;
109 activityDetail({ actId: route.query?.actId ?? actId }) 112 activityDetail({ actId: props.activityId })
110 .then((res) => { 113 .then((res) => {
111 this.data = res.data; 114 this.data = res.data;
112 }) 115 })
...@@ -120,7 +123,7 @@ const timeVenue = reactive({ ...@@ -120,7 +123,7 @@ const timeVenue = reactive({
120 data: [], 123 data: [],
121 fetchData() { 124 fetchData() {
122 this.loading = true; 125 this.loading = true;
123 sessionDetail({ actId: route.query?.actId ?? actId }) 126 sessionDetail({ actId: props.activityId })
124 .then((res) => { 127 .then((res) => {
125 this.data = res.data; 128 this.data = res.data;
126 }) 129 })
...@@ -150,7 +153,7 @@ const price = reactive({ ...@@ -150,7 +153,7 @@ const price = reactive({
150 data: [], 153 data: [],
151 fetchData() { 154 fetchData() {
152 getPriceLevelInfo({ 155 getPriceLevelInfo({
153 actId: route.query?.actId ?? actId, 156 actId: props.activityId,
154 sessionId: select_form.venueItem?.id, 157 sessionId: select_form.venueItem?.id,
155 openType: select_form.session, 158 openType: select_form.session,
156 sitePlace: select_form.place, 159 sitePlace: select_form.place,
...@@ -180,10 +183,38 @@ watchEffect(() => { ...@@ -180,10 +183,38 @@ watchEffect(() => {
180 } 183 }
181 }); 184 });
182 185
183 login().then((res) => { 186 // 主流程开始
184 detail.fetchData(); 187 watch(
185 timeVenue.fetchData(); 188 () => props.activityId,
186 }); 189 async (activityId) => {
190 if (!activityId) {
191 // [TODO] dialog提示缺少活動ID讓然後返回
192 ElMessageBox.confirm("缺少活动id", "提示", {
193 confirmButtonText: "确认",
194 type: "warning",
195 draggable: true,
196 }).then((res) => {
197 router.push("/");
198 });
199 return;
200 }
201
202 // 检查登录
203 const ticketUserToken = getToken();
204 if (!ticketUserToken) {
205 const userId = 1; // [TODO] 从原项目中取已登录的用户ID
206 if (!userId) {
207 // 未登录,跳转登录 [TODO]
208 return;
209 }
210 await login(userId);
211 }
212
213 detail.fetchData();
214 timeVenue.fetchData();
215 },
216 { immediate: true }
217 );
187 </script> 218 </script>
188 219
189 <template> 220 <template>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!