1
Showing
5 changed files
with
145 additions
and
30 deletions
| ... | @@ -46,3 +46,6 @@ export const cancelOrder = (data) => | ... | @@ -46,3 +46,6 @@ export const cancelOrder = (data) => |
| 46 | /** 订单详情 */ | 46 | /** 订单详情 */ |
| 47 | export const getOrderDetail = (data) => | 47 | export const getOrderDetail = (data) => |
| 48 | request("GET", `/api/order/detail/${data.orderSn}`, data); | 48 | request("GET", `/api/order/detail/${data.orderSn}`, data); |
| 49 | /** 检查是否支付成功 */ | ||
| 50 | export const checkPaySuccess = (data) => | ||
| 51 | request("POST", `/api/order/checkOrderIsPay/${data.orderSn}`, data); | ... | ... |
| 1 | <script setup> | 1 | <script setup> |
| 2 | import { confirmOrder } from "./api/index.js"; | 2 | import { confirmOrder } from "./api/index.js"; |
| 3 | import { ElMessage } from "element-plus"; | 3 | import { ElMessage } from "element-plus"; |
| 4 | import { payOrder, viewPeopleList } from "./api/index.js"; | 4 | import { payOrder, viewPeopleList, checkPaySuccess } from "./api/index.js"; |
| 5 | import { reactive } from "vue"; | ||
| 6 | import qrCodeDialog from "./components/qrCodeDialog.vue"; | 5 | import qrCodeDialog from "./components/qrCodeDialog.vue"; |
| 6 | import qrcode from "qrcode"; | ||
| 7 | import { onUnmounted } from "vue"; | ||
| 7 | 8 | ||
| 8 | const route = useRoute(); | 9 | const route = useRoute(); |
| 9 | const router = useRouter(); | 10 | const router = useRouter(); |
| ... | @@ -12,6 +13,25 @@ const props = defineProps({ | ... | @@ -12,6 +13,25 @@ const props = defineProps({ |
| 12 | activityId: [String, Number], | 13 | activityId: [String, Number], |
| 13 | }); | 14 | }); |
| 14 | 15 | ||
| 16 | let timer = null; | ||
| 17 | const startCheckSuccessListener = (orderSn, actId) => { | ||
| 18 | timer = setInterval(() => { | ||
| 19 | checkPaySuccess({ orderSn }).then((res) => { | ||
| 20 | if (res.data) { | ||
| 21 | clearInterval(timer); | ||
| 22 | timer = null; | ||
| 23 | // 支付成功 | ||
| 24 | payment.showCodeDialog = false; | ||
| 25 | router.push({ | ||
| 26 | path: "/seat/order", | ||
| 27 | }); | ||
| 28 | } else { | ||
| 29 | return false; | ||
| 30 | } | ||
| 31 | }); | ||
| 32 | }, 3000); | ||
| 33 | }; | ||
| 34 | |||
| 15 | const payment = reactive({ | 35 | const payment = reactive({ |
| 16 | showCodeDialog: false, | 36 | showCodeDialog: false, |
| 17 | btn_loading: false, | 37 | btn_loading: false, |
| ... | @@ -20,6 +40,7 @@ const payment = reactive({ | ... | @@ -20,6 +40,7 @@ const payment = reactive({ |
| 20 | phone: "", | 40 | phone: "", |
| 21 | }, | 41 | }, |
| 22 | qrInfo: {}, | 42 | qrInfo: {}, |
| 43 | qrCodeData: "", | ||
| 23 | paymentHandle() { | 44 | paymentHandle() { |
| 24 | if (payment.form.viewers.length != order.data?.seatInfo?.length) | 45 | if (payment.form.viewers.length != order.data?.seatInfo?.length) |
| 25 | return ElMessage({ type: "warning", message: "观看人与购买票数不符" }); | 46 | return ElMessage({ type: "warning", message: "观看人与购买票数不符" }); |
| ... | @@ -32,17 +53,22 @@ const payment = reactive({ | ... | @@ -32,17 +53,22 @@ const payment = reactive({ |
| 32 | payType: 1, | 53 | payType: 1, |
| 33 | paymentAmount: order.data?.paymentAmount, | 54 | paymentAmount: order.data?.paymentAmount, |
| 34 | }).then((res) => { | 55 | }).then((res) => { |
| 35 | // TODO: 这里有一个二维码 | ||
| 36 | payment.qrInfo = res.data; | 56 | payment.qrInfo = res.data; |
| 37 | payment.showCodeDialog = true; | 57 | qrcode.toDataURL(res.data.scanCodeUrl, (err, url) => { |
| 38 | router.replace({ | 58 | if (url) { |
| 39 | path: "/seat/order", | 59 | payment.qrCodeData = url; |
| 40 | query: { | 60 | } |
| 41 | id: props.activityId, | ||
| 42 | }, | ||
| 43 | }); | 61 | }); |
| 62 | payment.showCodeDialog = true; | ||
| 63 | startCheckSuccessListener(res.data.orderSn, props.activityId); | ||
| 44 | }); | 64 | }); |
| 45 | }, | 65 | }, |
| 66 | handleCloce() { | ||
| 67 | payment.showCodeDialog = false; | ||
| 68 | payment.qrCodeData = ""; | ||
| 69 | clearInterval(timer); | ||
| 70 | timer = null; | ||
| 71 | }, | ||
| 46 | }); | 72 | }); |
| 47 | 73 | ||
| 48 | const order = reactive({ | 74 | const order = reactive({ |
| ... | @@ -70,6 +96,10 @@ const audience = reactive({ | ... | @@ -70,6 +96,10 @@ const audience = reactive({ |
| 70 | }, | 96 | }, |
| 71 | }); | 97 | }); |
| 72 | 98 | ||
| 99 | onUnmounted(() => { | ||
| 100 | clearInterval(timer) | ||
| 101 | }) | ||
| 102 | |||
| 73 | audience.fetchData(); | 103 | audience.fetchData(); |
| 74 | order.fetchData(); | 104 | order.fetchData(); |
| 75 | </script> | 105 | </script> |
| ... | @@ -175,10 +205,16 @@ order.fetchData(); | ... | @@ -175,10 +205,16 @@ order.fetchData(); |
| 175 | <div class="pay" @click="payment.paymentHandle()">立即支付</div> | 205 | <div class="pay" @click="payment.paymentHandle()">立即支付</div> |
| 176 | </div> | 206 | </div> |
| 177 | 207 | ||
| 178 | <qrCodeDialog | 208 | <el-dialog |
| 179 | :showCodeDialog="payment.showCodeDialog" | 209 | v-model="payment.showCodeDialog" |
| 180 | :qrCode="payment.qrInfo?.scanCodeUrl" | 210 | title="支付" |
| 181 | /> | 211 | width="300" |
| 212 | @closed="payment.handleCloce()" | ||
| 213 | > | ||
| 214 | <div> | ||
| 215 | <img class="qrcode" :src="payment.qrCodeData" /> | ||
| 216 | </div> | ||
| 217 | </el-dialog> | ||
| 182 | </div> | 218 | </div> |
| 183 | </template> | 219 | </template> |
| 184 | 220 | ||
| ... | @@ -187,9 +223,8 @@ div { | ... | @@ -187,9 +223,8 @@ div { |
| 187 | box-sizing: border-box; | 223 | box-sizing: border-box; |
| 188 | } | 224 | } |
| 189 | .qrcode { | 225 | .qrcode { |
| 190 | width: 150px; | 226 | width: 200px; |
| 191 | height: 150px; | 227 | height: 200px; |
| 192 | background-color: #8623fc; | ||
| 193 | margin: 0 auto; | 228 | margin: 0 auto; |
| 194 | } | 229 | } |
| 195 | .container { | 230 | .container { |
| ... | @@ -405,6 +440,7 @@ div { | ... | @@ -405,6 +440,7 @@ div { |
| 405 | line-height: 40px; | 440 | line-height: 40px; |
| 406 | text-align: center; | 441 | text-align: center; |
| 407 | cursor: pointer; | 442 | cursor: pointer; |
| 443 | user-select: none; | ||
| 408 | } | 444 | } |
| 409 | } | 445 | } |
| 410 | } | 446 | } | ... | ... |
| 1 | <script setup> | 1 | <script setup> |
| 2 | import { reactive } from "vue"; | 2 | import { onBeforeUnmount, reactive } from "vue"; |
| 3 | import { | 3 | import { |
| 4 | cancelOrder, | 4 | cancelOrder, |
| 5 | getOrderDetail, | 5 | getOrderDetail, |
| 6 | immediatePay, | 6 | immediatePay, |
| 7 | cancelPay, | 7 | cancelPay, |
| 8 | checkPaySuccess, | ||
| 8 | } from "./api/index.js"; | 9 | } from "./api/index.js"; |
| 9 | import qrCodeDialog from "./components/qrCodeDialog.vue"; | 10 | import qrCodeDialog from "./components/qrCodeDialog.vue"; |
| 10 | import { ElMessageBox, ElMessage } from "element-plus"; | 11 | import { ElMessageBox, ElMessage } from "element-plus"; |
| 12 | import qrcode from "qrcode"; | ||
| 11 | 13 | ||
| 12 | const route = useRoute(); | 14 | const route = useRoute(); |
| 13 | const router = useRouter(); | 15 | const router = useRouter(); |
| ... | @@ -48,8 +50,26 @@ const props = defineProps({ | ... | @@ -48,8 +50,26 @@ const props = defineProps({ |
| 48 | activityId: [String, Number], | 50 | activityId: [String, Number], |
| 49 | }); | 51 | }); |
| 50 | 52 | ||
| 53 | let timer = null; | ||
| 54 | const startCheckSuccessListener = (orderSn, actId) => { | ||
| 55 | timer = setInterval(() => { | ||
| 56 | checkPaySuccess({ orderSn }).then((res) => { | ||
| 57 | if (res.data) { | ||
| 58 | clearInterval(timer); | ||
| 59 | timer = null; | ||
| 60 | // 支付成功 | ||
| 61 | detail.showCodeDialog = false; | ||
| 62 | detail.fetchData(); | ||
| 63 | } else { | ||
| 64 | return false; | ||
| 65 | } | ||
| 66 | }); | ||
| 67 | }, 3000); | ||
| 68 | }; | ||
| 69 | |||
| 51 | const detail = reactive({ | 70 | const detail = reactive({ |
| 52 | showCodeDialog: false, | 71 | showCodeDialog: false, |
| 72 | qrCodeData: "", | ||
| 53 | pay_loading: false, | 73 | pay_loading: false, |
| 54 | qrInfo: {}, | 74 | qrInfo: {}, |
| 55 | data: null, | 75 | data: null, |
| ... | @@ -92,7 +112,8 @@ const detail = reactive({ | ... | @@ -92,7 +112,8 @@ const detail = reactive({ |
| 92 | totalTime -= 1000; | 112 | totalTime -= 1000; |
| 93 | // console.log(totalTime) | 113 | // console.log(totalTime) |
| 94 | } else { | 114 | } else { |
| 95 | clearInterval(timer); // 停止调用函数 | 115 | clearInterval(detail.timer); // 停止调用函数 |
| 116 | detail.fetchData(); | ||
| 96 | } | 117 | } |
| 97 | }, 1000); | 118 | }, 1000); |
| 98 | } | 119 | } |
| ... | @@ -103,10 +124,22 @@ const detail = reactive({ | ... | @@ -103,10 +124,22 @@ const detail = reactive({ |
| 103 | immediatePay({ orderSn: detail.data.orderSn, payType: 1 }) | 124 | immediatePay({ orderSn: detail.data.orderSn, payType: 1 }) |
| 104 | .then((res) => { | 125 | .then((res) => { |
| 105 | detail.qrInfo = res.data; | 126 | detail.qrInfo = res.data; |
| 127 | qrcode.toDataURL(res.data.scanCodeUrl, (err, url) => { | ||
| 128 | if (url) { | ||
| 129 | detail.qrCodeData = url; | ||
| 130 | } | ||
| 131 | }); | ||
| 132 | startCheckSuccessListener(detail.data.orderSn); | ||
| 106 | detail.showCodeDialog = true; | 133 | detail.showCodeDialog = true; |
| 107 | }) | 134 | }) |
| 108 | .finally(() => (detail.pay_loading = false)); | 135 | .finally(() => (detail.pay_loading = false)); |
| 109 | }, | 136 | }, |
| 137 | handleClose() { | ||
| 138 | detail.showCodeDialog = false; | ||
| 139 | detail.qrCodeData = ""; | ||
| 140 | clearInterval(timer); | ||
| 141 | timer = null; | ||
| 142 | }, | ||
| 110 | // 取消支付 | 143 | // 取消支付 |
| 111 | cancelPay() { | 144 | cancelPay() { |
| 112 | ElMessageBox.confirm("确定取消支付吗?", "提示", { | 145 | ElMessageBox.confirm("确定取消支付吗?", "提示", { |
| ... | @@ -153,6 +186,11 @@ const detail = reactive({ | ... | @@ -153,6 +186,11 @@ const detail = reactive({ |
| 153 | }, | 186 | }, |
| 154 | }); | 187 | }); |
| 155 | 188 | ||
| 189 | onBeforeUnmount(() => { | ||
| 190 | clearInterval(detail.timer); | ||
| 191 | clearInterval(timer); | ||
| 192 | }); | ||
| 193 | |||
| 156 | detail.fetchData(); | 194 | detail.fetchData(); |
| 157 | </script> | 195 | </script> |
| 158 | 196 | ||
| ... | @@ -271,14 +309,30 @@ detail.fetchData(); | ... | @@ -271,14 +309,30 @@ detail.fetchData(); |
| 271 | </div> | 309 | </div> |
| 272 | </div> | 310 | </div> |
| 273 | 311 | ||
| 274 | <qrCodeDialog | 312 | <!-- <qrCodeDialog |
| 275 | :showCodeDialog="detail.showCodeDialog" | 313 | :showCodeDialog="detail.showCodeDialog" |
| 276 | :qrCode="detail.qrInfo?.scanCodeUrl" | 314 | :qrCode="detail.qrCodeData" |
| 277 | /> | 315 | /> --> |
| 316 | |||
| 317 | <el-dialog | ||
| 318 | v-model="detail.showCodeDialog" | ||
| 319 | title="支付" | ||
| 320 | width="300" | ||
| 321 | @closed="detail.handleClose()" | ||
| 322 | > | ||
| 323 | <div> | ||
| 324 | <img class="qrcode" :src="detail.qrCodeData" /> | ||
| 325 | </div> | ||
| 326 | </el-dialog> | ||
| 278 | </div> | 327 | </div> |
| 279 | </template> | 328 | </template> |
| 280 | 329 | ||
| 281 | <style scoped lang="scss"> | 330 | <style scoped lang="scss"> |
| 331 | .qrcode { | ||
| 332 | width: 200px; | ||
| 333 | height: 200px; | ||
| 334 | margin: 0 auto; | ||
| 335 | } | ||
| 282 | .container { | 336 | .container { |
| 283 | width: 1200px; | 337 | width: 1200px; |
| 284 | margin: 0 auto; | 338 | margin: 0 auto; | ... | ... |
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | import { getOrderList, immediatePay, cancelPay } from "./api/index.js"; | 2 | import { getOrderList, immediatePay, cancelPay } from "./api/index.js"; |
| 3 | import qrCodeDialog from "./components/qrCodeDialog.vue"; | 3 | import qrCodeDialog from "./components/qrCodeDialog.vue"; |
| 4 | import { ElMessageBox, ElMessage } from "element-plus"; | 4 | import { ElMessageBox, ElMessage } from "element-plus"; |
| 5 | 5 | import qrcode from "qrcode"; | |
| 6 | const status = reactive({ | 6 | const status = reactive({ |
| 7 | 0: { | 7 | 0: { |
| 8 | txt: "待支付", | 8 | txt: "待支付", |
| ... | @@ -51,6 +51,7 @@ const order = reactive({ | ... | @@ -51,6 +51,7 @@ const order = reactive({ |
| 51 | seconds: 0, | 51 | seconds: 0, |
| 52 | data: [], | 52 | data: [], |
| 53 | timer: null, | 53 | timer: null, |
| 54 | qrCodeData: "", | ||
| 54 | fetchData() { | 55 | fetchData() { |
| 55 | getOrderList({ pageNo: order.pageNo, pageSize: order.pageSize }).then( | 56 | getOrderList({ pageNo: order.pageNo, pageSize: order.pageSize }).then( |
| 56 | (res) => { | 57 | (res) => { |
| ... | @@ -67,10 +68,21 @@ const order = reactive({ | ... | @@ -67,10 +68,21 @@ const order = reactive({ |
| 67 | immediatePay({ orderSn: it.orderSn, payType: 1 }) | 68 | immediatePay({ orderSn: it.orderSn, payType: 1 }) |
| 68 | .then((res) => { | 69 | .then((res) => { |
| 69 | order.qrInfo = res.data; | 70 | order.qrInfo = res.data; |
| 71 | qrcode.toDataURL(res.data.scanCodeUrl, (err, url) => { | ||
| 72 | if (err) { | ||
| 73 | console.error(err); | ||
| 74 | } else { | ||
| 75 | order.qrCodeData = url; | ||
| 76 | } | ||
| 77 | }); | ||
| 70 | order.showCodeDialog = true; | 78 | order.showCodeDialog = true; |
| 71 | }) | 79 | }) |
| 72 | .finally(() => (order.pay_loading = false)); | 80 | .finally(() => (order.pay_loading = false)); |
| 73 | }, | 81 | }, |
| 82 | handleClose() { | ||
| 83 | order.showCodeDialog = false; | ||
| 84 | order.qrCodeData = ""; | ||
| 85 | }, | ||
| 74 | // 取消支付 | 86 | // 取消支付 |
| 75 | cancelPayment(it) { | 87 | cancelPayment(it) { |
| 76 | ElMessageBox.confirm("确定取消支付吗?", "提示", { | 88 | ElMessageBox.confirm("确定取消支付吗?", "提示", { |
| ... | @@ -179,19 +191,13 @@ order.fetchData(); | ... | @@ -179,19 +191,13 @@ order.fetchData(); |
| 179 | </div> | 191 | </div> |
| 180 | </div> | 192 | </div> |
| 181 | <div v-if="it.state == 0" class="btn_box"> | 193 | <div v-if="it.state == 0" class="btn_box"> |
| 182 | <div class="pay" @click.stop="order.payment(it)">立即支付</div> | 194 | <div class="pay">立即支付</div> |
| 183 | <div class="can_pay" @click.stop="order.cancelPayment(it)"> | 195 | <div class="can_pay" @click.stop="order.cancelPayment(it)"> |
| 184 | 取消支付 | 196 | 取消支付 |
| 185 | </div> | 197 | </div> |
| 186 | </div> | 198 | </div> |
| 187 | </div> | 199 | </div> |
| 188 | 200 | ||
| 189 | <qrCodeDialog | ||
| 190 | :showCodeDialog="order.showCodeDialog" | ||
| 191 | :qrCode="order.qrInfo?.scanCodeUrl" | ||
| 192 | @closeDialog="order.showCodeDialog = false" | ||
| 193 | /> | ||
| 194 | |||
| 195 | <div class="pagination"> | 201 | <div class="pagination"> |
| 196 | <el-pagination | 202 | <el-pagination |
| 197 | v-show="order.total > 0" | 203 | v-show="order.total > 0" |
| ... | @@ -203,10 +209,26 @@ order.fetchData(); | ... | @@ -203,10 +209,26 @@ order.fetchData(); |
| 203 | @current-change="order.fetchData()" | 209 | @current-change="order.fetchData()" |
| 204 | /> | 210 | /> |
| 205 | </div> | 211 | </div> |
| 212 | |||
| 213 | <el-dialog | ||
| 214 | v-model="order.showCodeDialog" | ||
| 215 | title="支付" | ||
| 216 | width="300" | ||
| 217 | @closed="order.handleClose()" | ||
| 218 | > | ||
| 219 | <div> | ||
| 220 | <img class="qrcode" :src="order.qrCodeData" /> | ||
| 221 | </div> | ||
| 222 | </el-dialog> | ||
| 206 | </div> | 223 | </div> |
| 207 | </template> | 224 | </template> |
| 208 | 225 | ||
| 209 | <style scoped lang="scss"> | 226 | <style scoped lang="scss"> |
| 227 | .qrcode { | ||
| 228 | width: 150px; | ||
| 229 | height: 150px; | ||
| 230 | margin: 0 auto; | ||
| 231 | } | ||
| 210 | .container { | 232 | .container { |
| 211 | width: 1200px; | 233 | width: 1200px; |
| 212 | margin: 0 auto; | 234 | margin: 0 auto; | ... | ... |
| ... | @@ -231,7 +231,7 @@ const toConfirmOrder = () => { | ... | @@ -231,7 +231,7 @@ const toConfirmOrder = () => { |
| 231 | }); | 231 | }); |
| 232 | }) | 232 | }) |
| 233 | .catch((e) => { | 233 | .catch((e) => { |
| 234 | if (e.code == 405) { | 234 | if (e.code == 'B001') { |
| 235 | router.push({ | 235 | router.push({ |
| 236 | path: "/seat/order", | 236 | path: "/seat/order", |
| 237 | query: { | 237 | query: { | ... | ... |
-
Please register or sign in to post a comment