|
@@ -6,13 +6,58 @@
|
|
|
<div class="px-5 py-3">
|
|
|
<div class="color-666">活动时间:{{ timesTampChange(k.startTime, 'Y-M-D') }}至{{ timesTampChange(k.endTime, 'Y-M-D') }}</div>
|
|
|
<div class="text-end">
|
|
|
- <v-btn color="primary" variant="outlined" @click.stop="handleBlockEnterprise(k.id)">立即加入</v-btn>
|
|
|
+ <v-btn color="primary" variant="outlined" @click.stop="handleBlockEnterprise(k)">立即加入</v-btn>
|
|
|
</div>
|
|
|
</div>
|
|
|
</v-card>
|
|
|
</div>
|
|
|
- <Empty v-else message="暂无进行中的招聘会,去看看其他吧~" />
|
|
|
+ <Empty v-else :elevation="false" message="暂无进行中的招聘会,去看看其他吧~" />
|
|
|
</v-card>
|
|
|
+
|
|
|
+ <CtDialog
|
|
|
+ :visible="showDialog"
|
|
|
+ :widthType="3"
|
|
|
+ :footer="false"
|
|
|
+ titleClass="text-h6"
|
|
|
+ title="购买招聘会门票"
|
|
|
+ @close="handleClose"
|
|
|
+ >
|
|
|
+ <div class="color-warning mb-5">
|
|
|
+ <p>鉴于您当前没有参加招聘会的权限</p>
|
|
|
+ <p>您可以通过下方扫码购买招聘会门票参与~</p>
|
|
|
+ </div>
|
|
|
+ <div v-if="payType" id="codeBox" class="code pa-0 resume-box">
|
|
|
+ <div class="resume-header px-3 pt-5">
|
|
|
+ <div class="resume-title">扫码支付</div>
|
|
|
+ </div>
|
|
|
+ <div class="d-flex justify-center mt-3">
|
|
|
+ <div id="codeItem" class="d-flex flex-column align-center my-2">
|
|
|
+ <div class="d-flex align-center">
|
|
|
+ <div class="color-666 font-weight-bold">支付方式:</div>
|
|
|
+ <v-chip-group v-model="payType" selected-class="text-primary" column mandatory @update:modelValue="payTypeChange">
|
|
|
+ <v-chip filter v-for="k in payTypeList" :key="k.code" :value="k.code" class="mr-3" label>
|
|
|
+ {{ k.name }}
|
|
|
+ <svg-icon v-if="k.icon" class="ml-1" :name="k.icon" :size="k.size"></svg-icon>
|
|
|
+ </v-chip>
|
|
|
+ </v-chip-group>
|
|
|
+ </div>
|
|
|
+ <div class="code-right">
|
|
|
+ <div class="price">
|
|
|
+ <span class="font-size-13">¥</span>
|
|
|
+ {{ FenYuanTransform(info?.admissionPrice || 0) }}元
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="code-left" v-if="payQrCodeTxt">
|
|
|
+ <QrCode :text="payQrCodeTxt" :disabled="!remainderTimer" :width="170" @refresh="refreshQRCode" />
|
|
|
+ </div>
|
|
|
+ <div class="mt-52" style="color: var(--v-error-base);">
|
|
|
+ 扫码支付时请勿离开
|
|
|
+ <span v-if="remainderZhShow">{{ remainderZhShow }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </CtDialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
@@ -23,6 +68,10 @@ import { getJobFairList } from '@/api/recruit/enterprise/jobFair'
|
|
|
import { getCheckJobFairPermission } from '@/api/recruit/enterprise/jobFair'
|
|
|
import Snackbar from '@/plugins/snackbar'
|
|
|
import { timesTampChange } from '@/utils/date'
|
|
|
+import { FenYuanTransform } from '@/utils/position'
|
|
|
+import { getEnableCodeList, payOrderSubmit, getOrderPayStatus, getUnpaidOrder } from '@/api/common'
|
|
|
+import { definePayTypeList, qrCodePay } from '@/utils/payType'
|
|
|
+import { createTradeOrder } from '@/api/position'
|
|
|
|
|
|
const router = useRouter()
|
|
|
const list = ref([])
|
|
@@ -33,11 +82,172 @@ const getList = async () => {
|
|
|
}
|
|
|
getList()
|
|
|
|
|
|
+const timer = ref(null)
|
|
|
+const showDialog = ref(false)
|
|
|
+
|
|
|
+// 1.支付方式
|
|
|
+const payType = ref('')
|
|
|
+const payTypeList = ref([])
|
|
|
+const codeList = ref([])
|
|
|
+const getCodeList = async () => {
|
|
|
+ try {
|
|
|
+ const list = await getEnableCodeList({ appId: 11 })
|
|
|
+ codeList.value = list || []
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ } finally {
|
|
|
+ if (definePayTypeList?.length && codeList.value?.length) {
|
|
|
+ codeList.value.forEach(code => {
|
|
|
+ const item = definePayTypeList.find(p => p.code === code)
|
|
|
+ if (item) {
|
|
|
+ if (!payType.value) {
|
|
|
+ const bool = qrCodePay.includes(code)
|
|
|
+ if (bool) {
|
|
|
+ payType.value = code
|
|
|
+ getUnpaidOrderList()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ payTypeList.value.push(item)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const payQrCodeTxt = ref('')
|
|
|
+
|
|
|
+// 2.发起充值
|
|
|
+const payOrder = ref({})
|
|
|
+let maxCount = 0
|
|
|
+const getUnpaidOrderList = async () => {
|
|
|
+ const data = await getUnpaidOrder({ spuId: info.value.id, type: 5 })
|
|
|
+ if (!data) {
|
|
|
+ await createTradeOrder({ price: (info.value.admissionPrice - 0), spuId: info.value.id, spuName: info.value.title, type: 5 })
|
|
|
+ if (maxCount > 3) return // 避免死循环
|
|
|
+ maxCount++
|
|
|
+ setTimeout(() => {
|
|
|
+ getUnpaidOrderList()
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+ payOrder.value = data?.payOrder || null
|
|
|
+ paySubmit()
|
|
|
+}
|
|
|
+
|
|
|
+const payStatus = async () => {
|
|
|
+ try {
|
|
|
+ const data = await getOrderPayStatus({ id: payOrder.value.id })
|
|
|
+ if ((data?.status - 0) === 10) {
|
|
|
+ // 支付成功
|
|
|
+ if (timer.value) clearInterval(timer.value); timer.value = null
|
|
|
+ setTimeout(() => {
|
|
|
+ // 清除定时器
|
|
|
+ clearTimer()
|
|
|
+ // 支付成功,跳转招聘会详情
|
|
|
+ Snackbar.success('购买成功')
|
|
|
+ handleBlockEnterprise(info.value)
|
|
|
+ }, 2000);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const payTypeChange = (val) => {
|
|
|
+ payType.value = val
|
|
|
+ getUnpaidOrderList()
|
|
|
+}
|
|
|
+
|
|
|
+const paySubmit = async () => {
|
|
|
+ if (!payType.value) return
|
|
|
+ try {
|
|
|
+ // 提交支付订单
|
|
|
+ const params = {
|
|
|
+ channelCode: payType.value, // 支付渠道
|
|
|
+ id: payOrder.value.id
|
|
|
+ }
|
|
|
+ const res = await payOrderSubmit(params)
|
|
|
+ payQrCodeTxt.value = res?.displayContent || '' // 生成二维码内容
|
|
|
+
|
|
|
+ // 弹窗关闭后不执行
|
|
|
+ if (!showDialog.value) {
|
|
|
+ if (timer.value) clearInterval(timer.value); timer.value = null
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ initIntervalFun()
|
|
|
+ if (timer.value) clearInterval(timer.value); timer.value = null
|
|
|
+ timer.value = setInterval(() => { payStatus() }, 1000) // 轮巡查询用户是否支付
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const refreshQRCode =() => { // 刷新二维码
|
|
|
+ getUnpaidOrderList()
|
|
|
+}
|
|
|
+
|
|
|
+const remainderTimer = ref(null)
|
|
|
+const countdownTime = 60000 * 3 // 倒计时三分钟
|
|
|
+let remainder = 0
|
|
|
+// 初始化倒计时
|
|
|
+const initIntervalFun = () => {
|
|
|
+ remainder = countdownTime // 初始倒计时时间
|
|
|
+ if (remainderTimer.value) clearInterval(remainderTimer.value); remainderTimer.value = null // 每一次点击都清除上一个轮询
|
|
|
+ // 倒计时计算
|
|
|
+ remainderCalc()
|
|
|
+ remainderTimer.value = setInterval(() => { remainderCalc() }, 1000)
|
|
|
+
|
|
|
+ if (timer.value) clearInterval(timer.value); timer.value = null
|
|
|
+ timer.value = setInterval(() => { payStatus() }, 2000) // 轮巡查询用户是否支付
|
|
|
+}
|
|
|
+
|
|
|
+const formatDuration = (remainder) => {
|
|
|
+ // 将毫秒转换为秒
|
|
|
+ var seconds = Math.floor(remainder / 1000)
|
|
|
+ // 计算分钟和剩余的秒数
|
|
|
+ var minutes = Math.floor(seconds / 60)
|
|
|
+ var remainingSeconds = seconds % 60
|
|
|
+ // 格式化分钟和秒数,确保秒数为两位数(如果小于10,则前面补0)
|
|
|
+ minutes = minutes.toString().padStart(2, '0')
|
|
|
+ remainingSeconds = remainingSeconds.toString().padStart(2, '0')
|
|
|
+ // 返回格式化的字符串
|
|
|
+ return `${minutes}分${remainingSeconds}秒`
|
|
|
+}
|
|
|
+
|
|
|
+const remainderZhShow = ref('')
|
|
|
+const clearTimer = () => {
|
|
|
+ if (timer.value) clearInterval(timer.value); timer.value = null
|
|
|
+ if (remainderTimer.value) clearInterval(remainderTimer.value); remainderTimer.value = null
|
|
|
+ remainderZhShow.value = ''
|
|
|
+}
|
|
|
+
|
|
|
+const remainderCalc = () => {
|
|
|
+ remainder -= 1000
|
|
|
+ remainderZhShow.value = formatDuration(remainder)
|
|
|
+ if (remainder <= 0) clearTimer()
|
|
|
+}
|
|
|
+
|
|
|
+const handleClose = () => {
|
|
|
+ clearTimer()
|
|
|
+ payType.value = ''
|
|
|
+ payQrCodeTxt.value = ''
|
|
|
+ payTypeList.value = []
|
|
|
+ showDialog.value = false
|
|
|
+}
|
|
|
+
|
|
|
// 立即加入
|
|
|
-const handleBlockEnterprise = async (id) => {
|
|
|
- const data = await getCheckJobFairPermission(id)
|
|
|
- if (!data) return Snackbar.warning('您没有权限参加该招聘会') // 只有返回true才能进入双选会
|
|
|
- router.push(`/recruit/enterprise/jobFair/details/${id}`)
|
|
|
+const info = ref(0)
|
|
|
+const handleBlockEnterprise = async (val) => {
|
|
|
+ try {
|
|
|
+ const data = await getCheckJobFairPermission(val.id)
|
|
|
+ if (data) router.push(`/recruit/enterprise/jobFair/details/${val.id}`)
|
|
|
+ } catch {
|
|
|
+ // 购买门票
|
|
|
+ info.value = val
|
|
|
+ if (timer.value) clearInterval(timer.value); timer.value = null
|
|
|
+ await getCodeList()
|
|
|
+ showDialog.value = true
|
|
|
+ }
|
|
|
}
|
|
|
</script>
|
|
|
|
|
@@ -48,4 +258,21 @@ const handleBlockEnterprise = async (id) => {
|
|
|
gap: 20px;
|
|
|
min-height: auto;
|
|
|
}
|
|
|
+.code {
|
|
|
+ background-color: #f7f8fa;
|
|
|
+ border-radius: 6px;
|
|
|
+ margin: 0 auto;
|
|
|
+ &-left {
|
|
|
+ border: 1px solid #00B760;
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 5px;
|
|
|
+ }
|
|
|
+ &-right {
|
|
|
+ .price {
|
|
|
+ font-size: 30px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: var(--v-error-base);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|