1
Showing
8 changed files
with
181 additions
and
27 deletions
| ... | @@ -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,11 +36,101 @@ const status = reactive({ | ... | @@ -31,11 +36,101 @@ 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); | ||
| 52 | }); | ||
| 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 | }); | ||
| 38 | }); | 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(() => {}); | ||
| 39 | }, | 134 | }, |
| 40 | }); | 135 | }); |
| 41 | 136 | ||
| ... | @@ -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 | // 主流程开始 |
| 187 | watch( | ||
| 188 | () => props.activityId, | ||
| 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 | |||
| 184 | detail.fetchData(); | 213 | detail.fetchData(); |
| 185 | timeVenue.fetchData(); | 214 | timeVenue.fetchData(); |
| 186 | }); | 215 | }, |
| 216 | { immediate: true } | ||
| 217 | ); | ||
| 187 | </script> | 218 | </script> |
| 188 | 219 | ||
| 189 | <template> | 220 | <template> | ... | ... |
-
Please register or sign in to post a comment