提交 2daf00e0 authored 作者: matian's avatar matian

updates

上级 509e6f92
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { Check } from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
import { useDevice } from '@/composables/useDevice'
import { wxJSPay, getOpenId } from '@/utils/wxpay'
import { createOrder, getOrderList } from '../api'
import queryString from 'query-string'
const router = useRouter()
const { mobile, wechat, alipay } = useDevice()
const user = useUserStore()
const props = defineProps({
shopItem: {
type: Object
}
})
const dialogVisible = ref(false)
const item = ref({
url: 'https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/%E7%B4%AB%E8%8D%86%E6%95%99%E8%82%B2%E7%94%A8%E6%88%B7%E5%85%A5%E9%A9%BB%E5%8F%8A%E7%BD%91%E7%BB%9C%E6%95%99%E5%AD%A6%E8%B5%84%E6%BA%90%E5%8D%8F%E8%AE%AE(1).docx'
})
const orderInfo: any = ref({})
const payMode = ref(1)
const isAgree = ref(false)
const isAgreeText = ref(false)
const currentCheck = ref('4')
const orderInfoDetail: any = ref([])
function getDateTime(dayNum: any) {
const dateDay = new Date()
dateDay.setDate(dateDay.getDate() + dayNum) //获取dayNum天后的日期
console.log(dateDay)
const y = dateDay.getFullYear()
const m =
dateDay.getMonth() + 1 < 10
? '0' + (dateDay.getMonth() + 1)
: dateDay.getMonth() + 1 //获取当前月份的日期,不足10补0
const d = dateDay.getDate() < 10 ? '0' + dateDay.getDate() : dateDay.getDate() //获取当前几号,不足10补0
return y + '-' + m + '-' + d
}
const start_time = getDateTime(0)
const end_time = getDateTime(90)
const emit = defineEmits<{
(e: 'success', params: object): void
}>()
const checkdChange = (val: string) => {
currentCheck.value = val
}
const optionParams = reactive({
shop_id: '6998523899570814976',
spu_id: '6998525810348916736',
sku_id: '6998525810365693952',
redirect_url: '',
buy_count: '1',
payment_method: '',
notify_url: `https://ep-lms-api.ezijing.com/v2/student/push?tenant=paa&sso_id=${user.user?.id}&class_id=${props.shopItem?.class_id}&course_flag=1&course_id=${props.shopItem?.course_id}`
})
// 点击立即购买
const handlePay = () => {
if (isAgree.value === false) {
ElMessage.warning('请先勾选紫荆金保服务协议')
isAgreeText.value = true
} else {
if (user.isLogin) {
if (!mobile.value) {
//pc
const params = {
payMode: payMode.value,
status: 'order'
}
emit('success', params)
} else {
//H5
if (mobile && (wechat || alipay)) {
pay()
}
}
} else {
window.location.href = `${
import.meta.env.VITE_LOGIN_URL
}?rd=${encodeURIComponent(location.href)}`
}
}
}
// 去支付
const pay = () => {
console.log('999')
createOrderHandle().then((order: any) => {
orderInfo.value = order
if (wechat) {
wxJSPay(order, payCallback(optionParams))
} else {
location.href = order.payment_url // '4' \ '12'
getOrder()
}
})
}
// 支付回调
const payCallback = async (options: any) => {
const { callback } = options
const order = await getOrder()
callback && callback(order)
const params = {
status: 'success',
orderId: order.order_id,
payPrice: order.payment_money,
payStatus: order.order_status
}
orderInfoDetail.value = order.order_status
emit('success', params)
}
// 创建订单
const createOrderHandle = () => {
let defaultParams = {}
// 微信内
if (wechat) {
const openId = localStorage.getItem('openId')
if (!openId) {
getOpenId(
queryString.parse(location.search, { parseBooleans: true }).code,
pay
)
return Promise.reject('openId不存在')
}
defaultParams = { open_id: openId, payment_method: '3' }
}
// 支付宝网页支付
if (currentCheck.value === '12') {
defaultParams = { payment_method: '12' }
}
//微信外微信h5支付
if (currentCheck.value === '4') {
defaultParams = { payment_method: '4' }
}
const params = Object.assign(optionParams, defaultParams)
return createOrder(params).then((resp: any) => resp.data)
}
// 获取订单
function getOrder() {
return getOrderList({
order_detail_id: orderInfo.value.order_detail_id
}).then((resp) => {
return resp.data[0]
})
}
const handlePrev = () => {
router.push({
path: `/shop/detail/${props.shopItem?.id}`,
query: {
payStatus: orderInfoDetail.value.order_status
}
})
}
const changeProtocol = () => {
dialogVisible.value = false
isAgree.value = true
isAgreeText.value = false
}
const handleAgree = (val: any) => {
isAgree.value = val
if (val === true) {
isAgreeText.value = false
}
}
</script>
<template>
<div>
<div class="main_con" v-if="!mobile">
<div class="con_tit">课程信息确认</div>
<div class="con_pay">
<div class="pay_course">
<img
:src="
shopItem?.image_url ||
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F56e7995e3501f.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1671671981&t=0eb627c761e6567a3a0a29163b31aac0'
"
alt=""
/>
<div class="course_info">
<div class="info_tit">{{ shopItem?.title }}</div>
<div class="info_range">
有效期:{{ start_time }}{{ end_time }}
</div>
<div class="info_price">
<div class="price_icon">¥</div>
<div class="price_num">{{ shopItem?.price }}</div>
</div>
</div>
</div>
<div class="con_message" v-if="user.isLogin">
课程提醒将发送到您的手机:{{ user?.mobile }}
</div>
<div class="con_mode">
<div class="mode_tit">支付方式</div>
<div class="mode_radio">
<el-radio-group v-model="payMode">
<el-radio :label="1" size="large" border>
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_ali.png"
/>
<span class="radio_tit">支付宝支付</span>
</el-radio>
<el-radio :label="2" size="large" border>
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_wechat.png"
/>
<span class="radio_tit">微信支付</span>
</el-radio>
</el-radio-group>
</div>
</div>
<div class="con_footer">
<div class="footer_left">
<div class="left_top">
<el-checkbox v-model="isAgree" @change="handleAgree">
<span>同意</span></el-checkbox
><a @click="dialogVisible = true">紫荆金保服务协议</a>
</div>
<div
class="left_desc"
:class="isAgreeText === true ? 'left_desc_active' : ''"
>
请先勾选紫荆金保服务协议
</div>
</div>
<div class="footer_right">
<div class="right_top">
<div class="top_tit">需付金额:</div>
<div class="top_price">
<div class="price_icon">¥</div>
<div class="price_num">{{ shopItem?.price }}</div>
</div>
</div>
<div class="right_btn" @click="handlePay">立即支付</div>
</div>
</div>
</div>
</div>
<div class="main_con" v-else>
<div class="con_nav" @click="handlePrev">
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/prev_mini.png"
/>
<div class="nav_title">确认订单</div>
</div>
<div class="course_con">
<img
:src="
shopItem?.image_url ||
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F56e7995e3501f.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1671671981&t=0eb627c761e6567a3a0a29163b31aac0'
"
alt=""
/>
<div class="course_dec">
<div class="info_title">{{ shopItem?.title }}</div>
<div class="info_date">
有效期:{{ start_time }}{{ end_time }}
</div>
</div>
</div>
<div class="pay_con">
<div class="pay_phone" v-if="user?.isLogin">
课程提醒将发送到您的手机:<i style="font-weight: bold">{{
user?.mobile
}}</i>
</div>
<div class="pay_line"></div>
<div class="pay_mode">
<div class="mode_item">
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_ali.png"
/>
<div class="radio_tit">支付宝支付</div>
<div
:class="
currentCheck === '12' ? 'radio_check_active' : 'radio_check'
"
@click="checkdChange('12')"
>
<template v-if="currentCheck === '12'">
<el-icon><Check /></el-icon>
</template>
</div>
</div>
<div class="mode_item">
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_wechat.png"
/>
<div class="radio_tit">微信支付</div>
<div
:class="
currentCheck === '4' ? 'radio_check_active' : 'radio_check'
"
@click="checkdChange('4')"
>
<template v-if="currentCheck === '4'">
<el-icon><Check /></el-icon>
</template>
</div>
</div>
</div>
</div>
<div class="argreement_con">
<div class="left_top">
<el-checkbox v-model="isAgree" @change="handleAgree">
<span>同意</span>
</el-checkbox>
<a @click="dialogVisible = true">紫荆金保服务协议</a>
</div>
<div
class="left_desc"
:class="isAgreeText === true ? 'left_desc_active' : ''"
>
请先勾选紫荆金保服务协议
</div>
</div>
<div class="to_pay_main" @click="handlePay">
<div class="pay_price">
<span class="to_pay">立即支付</span>
<span class="to_price"><i style="font-size: 12px">¥</i>1999.00</span>
</div>
</div>
</div>
<el-dialog v-model="dialogVisible" :width="!mobile ? '50%' : '90%'">
<div style="height: 600px" v-if="!mobile">
<iframe
:src="`https://view.officeapps.live.com/op/view.aspx?src=${item?.url}`"
frameborder="0"
width="100%"
height="100%"
></iframe>
</div>
<div v-else style="height: 8rem">
<iframe
:src="`https://view.xdocin.com/xdoc?_xdoc=${item?.url}`"
frameborder="0"
width="100%"
height="100%"
></iframe>
</div>
<template #footer>
<el-button
type="primary"
@click="changeProtocol"
style="background-color: #e3a232; border: none"
>我已阅读并同意</el-button
>
</template>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.is-h5 {
.main_con {
padding: 0 0.28rem;
.con_nav {
display: flex;
align-items: center;
justify-content: center;
position: relative;
img {
position: absolute;
left: 0;
}
.nav_title {
font-size: 0.32rem;
font-weight: 500;
line-height: 0.34rem;
color: #333333;
}
}
.course_con {
margin: 0.3rem 0;
height: 1.97rem;
background: #ffffff;
opacity: 1;
border-radius: 0.12rem;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.28rem 0.2rem;
box-sizing: border-box;
gap: 0.2rem;
img {
width: 2.2rem;
height: 1.4rem;
}
.course_dec {
display: flex;
flex-direction: column;
gap: 0.2rem;
.info_title {
height: 0.64rem;
font-size: 0.28rem;
font-weight: 500;
line-height: 0.36rem;
color: #333333;
}
.info_date {
font-size: 0.22rem;
font-weight: 400;
line-height: 0.3rem;
color: #999999;
white-space: nowrap;
}
}
}
.pay_con {
width: 6.9rem;
box-sizing: border-box;
margin-bottom: 0.53rem;
background: #fff;
border-radius: 0.12rem;
padding: 0.54rem 0.4rem;
.pay_phone {
text-align: center;
font-size: 0.24rem;
color: #333333;
}
.pay_line {
height: 0px;
border: 1px solid #f8f8f8;
opacity: 1;
margin: 0.57rem 0 0.54rem 0;
}
.pay_mode {
display: flex;
flex-direction: column;
gap: 0.4rem;
.mode_item {
display: flex;
align-items: center;
position: relative;
img {
width: 0.3rem;
height: 0.3rem;
}
.radio_tit {
margin-left: 0.2rem;
}
.radio_check_active {
position: absolute;
right: 0;
width: 0.25rem;
height: 0.25rem;
border-radius: 50%;
display: flex;
align-items: center;
font-size: 12px;
color: #fff;
background-color: #f1b44e;
box-sizing: border-box;
}
.radio_check {
position: absolute;
right: 0;
width: 0.25rem;
height: 0.25rem;
border: 1px solid #707070;
border-radius: 50%;
display: flex;
align-items: center;
font-size: 12px;
color: #fff;
box-sizing: border-box;
}
}
}
}
.argreement_con {
text-align: center;
.left_top {
display: flex;
justify-content: center;
align-items: center;
.el-checkbox__label {
span {
color: #666666;
font-size: 0.24rem;
font-weight: 400;
}
}
a {
font-weight: 400;
font-size: 0.24rem;
color: #e3a232 !important;
margin-top: 0.02rem;
cursor: pointer;
}
}
.left_desc {
color: #999999;
font-size: 0.24rem;
margin-left: 0.9rem;
}
.left_desc_active {
color: #aa1941;
}
}
.to_pay_main {
margin: 3.5rem -0.3rem 0;
height: 1.2rem;
background: #fff;
opacity: 1;
border-radius: 0.2rem 0.2rem 0px 0px;
padding: 0.24rem 0.3rem 0.16rem 0.3rem;
box-sizing: border-box;
.pay_price {
width: 100%;
height: 0.8rem;
background: linear-gradient(102deg, #f2ca8c 0%, #e69b1c 100%);
border-radius: 0.4rem;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
gap: 0.18rem;
.to_pay {
font-size: 0.28rem;
}
.to_price {
font-size: 0.4rem;
}
}
}
}
}
.is-pc {
.main_con {
width: 1200px;
margin: auto;
.con_tit {
font-size: 28px;
font-weight: 500;
line-height: 34px;
color: #333333;
padding-top: 39px;
}
.con_pay {
height: 721px;
background: #ffffff;
margin-top: 26px;
padding: 52px 60px 107px 40px;
box-sizing: border-box;
.pay_course {
display: flex;
padding-bottom: 41px;
border-bottom: 1px solid #e6e6e6;
img {
width: 257px;
height: 166px;
}
.course_info {
margin-left: 35px;
.info_tit {
font-size: 24px;
font-weight: 500;
line-height: 34px;
color: #333333;
}
.info_range {
font-size: 14px;
font-weight: 400;
line-height: 34px;
color: #666666;
margin-top: 26px;
}
.info_price {
display: flex;
align-items: flex-end;
margin-top: 42px;
.price_icon {
font-size: 20px;
font-weight: 500;
color: #aa1941;
}
.price_num {
font-size: 30px;
font-weight: normal;
line-height: 34px;
color: #aa1941;
}
}
}
}
}
.con_message {
margin-top: 30px;
font-size: 18px;
font-weight: 500;
line-height: 34px;
color: #333333;
}
.con_mode {
margin-top: 43px;
display: flex;
align-items: center;
.mode_tit {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #333333;
}
.mode_radio {
margin-left: 44px;
}
}
.con_footer {
margin-top: 74px;
display: flex;
justify-content: space-between;
.footer_left {
padding-top: 12px;
.left_top {
display: flex;
align-items: center;
.el-checkbox__label {
span {
color: #666666;
font-size: 16px;
font-weight: 400;
}
}
a {
color: #e3a232;
font-size: 16px;
font-weight: 400;
margin-top: -1px;
cursor: pointer;
}
}
.left_desc {
font-size: 14px;
font-weight: 400;
color: #999999;
margin: 14px 0 0 21px;
}
.left_desc_active {
color: #aa1941;
}
}
.footer_right {
display: flex;
flex-direction: column;
align-items: flex-end;
.right_top {
display: flex;
.top_tit {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #333333;
}
.top_price {
display: flex;
margin-left: 53px;
.price_icon {
font-size: 22px;
font-weight: 500;
line-height: 34px;
color: #aa1941;
}
.price_num {
font-size: 36px;
font-weight: normal;
line-height: 34px;
color: #aa1941;
}
}
}
.right_btn {
width: 153px;
height: 48px;
background: #edb24c;
border-radius: 24px;
font-size: 18px;
font-weight: 400;
line-height: 48px;
color: #ffffff;
text-align: center;
margin-top: 20px;
cursor: pointer;
}
}
}
}
}
:deep(.el-radio) {
width: 220px;
height: 83px;
background: #ffffff;
border: 2px solid #e2e2e2;
display: flex;
align-items: center;
justify-content: center;
}
:deep(.el-radio.is-bordered.is-checked) {
border: 2px solid #ebaf48;
background: rgba(255, 251, 245, 0.39);
}
:deep(.el-radio__input) {
display: none;
}
:deep(.el-radio__label) {
img {
margin-right: 10px;
}
.radio_tit {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #666666;
}
}
:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
background: #e3a232;
border-color: #e3a232;
}
</style>
<script setup lang="ts">
import { Check } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { getDateTime } from '@/utils'
import { useUserStore } from '@/stores/user'
import { usePay } from '../composables/usePay'
import { useStorage } from '@vueuse/core'
const props = defineProps({ shopItem: { type: Object, default: () => ({}) } })
const emit = defineEmits(['success'])
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const params = $(useStorage('params', { payment_method: '11' }))
const start_time = getDateTime()
const end_time = getDateTime(90)
const isAgree = $ref(false)
let isAgreeText = $ref(false)
const dialogVisible = $ref(false)
const { order, pay } = usePay()
onMounted(() => {
if (route.query.is_pay) {
pay(params)
}
})
watchEffect(() => {
if (order.value?.order_status === '4') {
// 支付成功
console.log('支付成功')
emit('success', order.value)
}
})
// 去支付
function handlePay() {
if (!isAgree) {
isAgreeText = true
ElMessage.warning('请先勾选紫荆金保服务协议')
return
}
pay(params)
}
const handlePrev = () => {
router.push({
path: `/shop/detail/${props.shopItem?.id}`
})
}
const checkedChange = (val: string) => {
params.payment_method = val
}
</script>
<template>
<div>
<div class="main_con">
<div class="con_nav" @click="handlePrev">
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/prev_mini.png"
/>
<div class="nav_title">确认订单</div>
</div>
<div class="course_con">
<img
:src="
shopItem?.image_url ||
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F56e7995e3501f.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1671671981&t=0eb627c761e6567a3a0a29163b31aac0'
"
/>
<div class="course_dec">
<div class="info_title">{{ shopItem.title }}</div>
<div class="info_date">
有效期:{{ start_time }}{{ end_time }}
</div>
</div>
</div>
<div class="pay_con">
<div class="pay_phone">
课程提醒将发送到您的手机:<i style="font-weight: bold">{{
userStore.user?.mobile
}}</i>
</div>
<div class="pay_line"></div>
<div class="pay_mode">
<div class="mode_item">
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_ali.png"
/>
<div class="radio_tit">支付宝支付</div>
<div
:class="
params.payment_method === '12'
? 'radio_check_active'
: 'radio_check'
"
@click="checkedChange('12')"
>
<template v-if="params.payment_method === '12'">
<el-icon><Check /></el-icon>
</template>
</div>
</div>
<div class="mode_item">
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_wechat.png"
/>
<div class="radio_tit">微信支付</div>
<div
:class="
params.payment_method === '4'
? 'radio_check_active'
: 'radio_check'
"
@click="checkedChange('4')"
>
<template v-if="params.payment_method === '4'">
<el-icon><Check /></el-icon>
</template>
</div>
</div>
</div>
</div>
<div class="argreement_con">
<div class="left_top">
<el-checkbox v-model="isAgree">
<span>同意</span>
</el-checkbox>
<a @click="dialogVisible = true">紫荆金保服务协议</a>
</div>
<div
class="left_desc"
:class="isAgreeText === true ? 'left_desc_active' : ''"
>
请先勾选紫荆金保服务协议
</div>
</div>
<div class="to_pay_main" @click="handlePay">
<div class="pay_price">
<span class="to_pay">立即支付</span>
<span class="to_price"><i style="font-size: 12px">¥</i>1999.00</span>
</div>
</div>
</div>
<!-- <el-dialog v-model="dialogVisible" :width="!mobile ? '50%' : '90%'">
<div v-else style="height: 8rem">
<iframe
:src="`https://view.xdocin.com/xdoc?_xdoc=${item?.url}`"
frameborder="0"
width="100%"
height="100%"></iframe>
</div>
<template #footer>
<el-button type="primary" @click="changeProtocol" style="background-color: #e3a232; border: none"
>我已阅读并同意</el-button
>
</template>
</el-dialog> -->
</div>
</template>
<style lang="scss" scoped>
.main_con {
padding: 0 0.28rem;
.con_nav {
display: flex;
align-items: center;
justify-content: center;
position: relative;
img {
position: absolute;
left: 0;
}
.nav_title {
font-size: 0.32rem;
font-weight: 500;
line-height: 0.34rem;
color: #333333;
}
}
.course_con {
margin: 0.3rem 0;
height: 1.97rem;
background: #ffffff;
opacity: 1;
border-radius: 0.12rem;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.28rem 0.2rem;
box-sizing: border-box;
gap: 0.2rem;
img {
width: 2.2rem;
height: 1.4rem;
}
.course_dec {
display: flex;
flex-direction: column;
gap: 0.2rem;
.info_title {
height: 0.64rem;
font-size: 0.28rem;
font-weight: 500;
line-height: 0.36rem;
color: #333333;
}
.info_date {
font-size: 0.22rem;
font-weight: 400;
line-height: 0.3rem;
color: #999999;
white-space: nowrap;
}
}
}
.pay_con {
width: 6.9rem;
box-sizing: border-box;
margin-bottom: 0.53rem;
background: #fff;
border-radius: 0.12rem;
padding: 0.54rem 0.4rem;
.pay_phone {
text-align: center;
font-size: 0.24rem;
color: #333333;
}
.pay_line {
height: 0px;
border: 1px solid #f8f8f8;
opacity: 1;
margin: 0.57rem 0 0.54rem 0;
}
.pay_mode {
display: flex;
flex-direction: column;
gap: 0.4rem;
.mode_item {
display: flex;
align-items: center;
position: relative;
img {
width: 0.3rem;
height: 0.3rem;
}
.radio_tit {
margin-left: 0.2rem;
}
.radio_check_active {
position: absolute;
right: 0;
width: 0.25rem;
height: 0.25rem;
border-radius: 50%;
display: flex;
align-items: center;
font-size: 12px;
color: #fff;
background-color: #f1b44e;
box-sizing: border-box;
}
.radio_check {
position: absolute;
right: 0;
width: 0.25rem;
height: 0.25rem;
border: 1px solid #707070;
border-radius: 50%;
display: flex;
align-items: center;
font-size: 12px;
color: #fff;
box-sizing: border-box;
}
}
}
}
.argreement_con {
text-align: center;
.left_top {
display: flex;
justify-content: center;
align-items: center;
.el-checkbox__label {
span {
color: #666666;
font-size: 0.24rem;
font-weight: 400;
}
}
a {
font-weight: 400;
font-size: 0.24rem;
color: #e3a232 !important;
margin-top: 0.02rem;
cursor: pointer;
}
}
.left_desc {
color: #999999;
font-size: 0.24rem;
margin-left: 0.9rem;
}
.left_desc_active {
color: #aa1941;
}
}
.to_pay_main {
margin: 3.5rem -0.3rem 0;
height: 1.2rem;
background: #fff;
opacity: 1;
border-radius: 0.2rem 0.2rem 0px 0px;
padding: 0.24rem 0.3rem 0.16rem 0.3rem;
box-sizing: border-box;
.pay_price {
width: 100%;
height: 0.8rem;
background: linear-gradient(102deg, #f2ca8c 0%, #e69b1c 100%);
border-radius: 0.4rem;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
gap: 0.18rem;
.to_pay {
font-size: 0.28rem;
}
.to_price {
font-size: 0.4rem;
}
}
}
}
:deep(.el-radio) {
width: 220px;
height: 83px;
background: #ffffff;
border: 2px solid #e2e2e2;
display: flex;
align-items: center;
justify-content: center;
}
:deep(.el-radio.is-bordered.is-checked) {
border: 2px solid #ebaf48;
background: rgba(255, 251, 245, 0.39);
}
:deep(.el-radio__input) {
display: none;
}
:deep(.el-radio__label) {
img {
margin-right: 10px;
}
.radio_tit {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #666666;
}
}
:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
background: #e3a232;
border-color: #e3a232;
}
</style>
<script setup lang="ts">
import QrcodeVue from 'qrcode.vue'
import { ElMessage } from 'element-plus'
import { getDateTime } from '@/utils'
import { useUserStore } from '@/stores/user'
import { usePay } from '../composables/usePay'
defineProps({ shopItem: { type: Object, default: () => ({}) } })
const emit = defineEmits(['success'])
const userStore = useUserStore()
const params = reactive({
payment_method: '11'
})
const start_time = getDateTime()
const end_time = getDateTime(90)
let isAgree = $ref(false)
let isAgreeText = $ref(false)
const { order, payOrder, pay } = usePay()
watchEffect(() => {
if (order.value?.order_status === '4') {
// 支付成功
console.log('支付成功')
emit('success', order.value)
}
})
// 去支付
function handlePay() {
if (!isAgree) {
isAgreeText = true
ElMessage.warning('请先勾选紫荆金保服务协议')
return
}
pay(params)
}
const handleAgree = (val: any) => {
console.log(val)
isAgree = val
if (val === true) {
isAgreeText = false
}
}
const handleClose = () => {
isAgree = true
isAgreeText = false
}
const handleAgreement = () => {
window.open(
'https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/sbu-plus/%E8%AF%AD%E8%A8%80%E5%BC%BA%E5%8C%96%E6%A8%A1%E5%9D%97%E4%BB%8B%E7%BB%8D.pdf'
)
}
</script>
<template>
<div class="main_con" v-if="!order">
<div class="con_tit">课程信息确认</div>
<div class="con_pay">
<div class="pay_course">
<img
:src="
shopItem.image_url ||
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F56e7995e3501f.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1671671981&t=0eb627c761e6567a3a0a29163b31aac0'
"
/>
<div class="course_info">
<div class="info_tit">{{ shopItem.title }}</div>
<div class="info_range">
有效期:{{ start_time }}{{ end_time }}
</div>
<div class="info_price">
<div class="price_icon">¥</div>
<div class="price_num">{{ shopItem.price }}</div>
</div>
</div>
</div>
<div class="con_message">
课程提醒将发送到您的手机:{{ userStore.user?.mobile }}
</div>
<div class="con_mode">
<div class="mode_tit">支付方式</div>
<div class="mode_radio">
<el-radio-group v-model="params.payment_method">
<el-radio label="11" size="large" border>
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_ali.png"
/>
<span class="radio_tit">支付宝支付</span>
</el-radio>
<el-radio label="1" size="large" border>
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/pay_wechat.png"
/>
<span class="radio_tit">微信支付</span>
</el-radio>
</el-radio-group>
</div>
</div>
<div class="con_footer">
<div class="footer_left">
<div class="left_top">
<el-checkbox v-model="isAgree" @change="handleAgree">
<span>同意</span></el-checkbox
>
<a @click="handleAgreement">紫荆金保服务协议</a>
</div>
<div class="left_desc" :class="isAgreeText ? 'left_desc_active' : ''">
请先勾选紫荆金保服务协议
</div>
</div>
<div class="footer_right">
<div class="right_top">
<div class="top_tit">需付金额:</div>
<div class="top_price">
<div class="price_icon">¥</div>
<div class="price_num">{{ shopItem.price }}</div>
</div>
</div>
<div class="right_btn" @click="handlePay">立即支付</div>
</div>
</div>
</div>
</div>
<div class="main" v-else>
<div class="main_order">
<div class="order_id">
<div class="id_tit">商品订单:</div>
<div class="id_num">{{ order.order_id }}</div>
</div>
<div class="order_price">
<div class="price_tit">支付金额:</div>
<div class="price_con">
<div class="con_icon">¥</div>
<div class="con_num">{{ order.payment_money }}</div>
</div>
</div>
<div class="line"></div>
<div class="order_mode">
<div class="mode_tit">支付方式:</div>
<div class="mode_con">
<img
:src="
order.payment_method === '11'
? 'https://webapp-pub.ezijing.com/project_online/fi/pay_ali.png'
: 'https://webapp-pub.ezijing.com/project_online/fi/pay_wechat.png'
"
class="con_style"
/>
<span class="radio_tit">{{
order.payment_method === '11' ? '支付宝支付' : '微信支付'
}}</span>
<img
src="https://webapp-pub.ezijing.com/project_online/fi/icon_pay_checked.png"
class="checked_img"
/>
</div>
</div>
<div class="order_qaCode">
<div class="qaCode_left">
<div class="left_code">
<qrcode-vue
:value="payOrder?.payment_url"
:size="197"
level="H"
></qrcode-vue>
</div>
<div
class="left_desc"
:class="
order.payment_method === '11'
? 'left_desc_ali'
: 'left_desc_wechat'
"
>
{{
order.payment_method === '11'
? '请打开手机支付宝,扫一扫完成支付'
: '请打开手机微信,扫一扫完成支付'
}}
</div>
</div>
<img
:src="
order.payment_method === '11'
? 'https://webapp-pub.ezijing.com/project_online/fi/icon_aliPay_img1.png'
: 'https://webapp-pub.ezijing.com/project_online/fi/icon_wechat_img1.png'
"
class="right_img"
/>
</div>
</div>
</div>
<AgreementDialog
v-if="dialogVisible === true"
v-model:dialogVisible="dialogVisible"
:mobile="'1'"
@close="handleClose"
/>
</template>
<style lang="scss" scoped>
.main_con {
width: 1200px;
margin: auto;
.con_tit {
font-size: 28px;
font-weight: 500;
line-height: 34px;
color: #333333;
padding-top: 39px;
}
.con_pay {
height: 721px;
background: #ffffff;
margin-top: 26px;
padding: 52px 60px 107px 40px;
box-sizing: border-box;
.pay_course {
display: flex;
padding-bottom: 41px;
border-bottom: 1px solid #e6e6e6;
img {
width: 257px;
height: 166px;
}
.course_info {
margin-left: 35px;
.info_tit {
font-size: 24px;
font-weight: 500;
line-height: 34px;
color: #333333;
}
.info_range {
font-size: 14px;
font-weight: 400;
line-height: 34px;
color: #666666;
margin-top: 26px;
}
.info_price {
display: flex;
align-items: flex-end;
margin-top: 42px;
.price_icon {
font-size: 20px;
font-weight: 500;
color: #aa1941;
}
.price_num {
font-size: 30px;
font-weight: normal;
line-height: 34px;
color: #aa1941;
}
}
}
}
}
.con_message {
margin-top: 30px;
font-size: 18px;
font-weight: 500;
line-height: 34px;
color: #333333;
}
.con_mode {
margin-top: 43px;
display: flex;
align-items: center;
.mode_tit {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #333333;
}
.mode_radio {
margin-left: 44px;
}
}
.con_footer {
margin-top: 74px;
display: flex;
justify-content: space-between;
.footer_left {
padding-top: 12px;
.left_top {
display: flex;
align-items: center;
.el-checkbox__label {
span {
color: #666666;
font-size: 16px;
font-weight: 400;
}
}
a {
color: #e3a232;
font-size: 16px;
font-weight: 400;
margin-top: -1px;
cursor: pointer;
}
}
.left_desc {
font-size: 14px;
font-weight: 400;
color: #999999;
margin: 14px 0 0 21px;
}
.left_desc_active {
color: #aa1941;
}
}
.footer_right {
display: flex;
flex-direction: column;
align-items: flex-end;
.right_top {
display: flex;
.top_tit {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #333333;
}
.top_price {
display: flex;
margin-left: 53px;
.price_icon {
font-size: 22px;
font-weight: 500;
line-height: 34px;
color: #aa1941;
}
.price_num {
font-size: 36px;
font-weight: normal;
line-height: 34px;
color: #aa1941;
}
}
}
.right_btn {
width: 153px;
height: 48px;
background: #edb24c;
border-radius: 24px;
font-size: 18px;
font-weight: 400;
line-height: 48px;
color: #ffffff;
text-align: center;
margin-top: 20px;
cursor: pointer;
}
}
}
}
:deep(.el-radio) {
width: 220px;
height: 83px;
background: #ffffff;
border: 2px solid #e2e2e2;
display: flex;
align-items: center;
justify-content: center;
}
:deep(.el-radio.is-bordered.is-checked) {
border: 2px solid #ebaf48;
background: rgba(255, 251, 245, 0.39);
}
:deep(.el-radio__input) {
display: none;
}
:deep(.el-radio__label) {
img {
margin-right: 10px;
}
.radio_tit {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #666666;
}
}
:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
background: #e3a232;
border-color: #e3a232;
}
.main {
width: 100%;
padding: 50px 0 46px 0;
.main_order {
width: 1200px;
background: #ffffff;
margin: auto;
padding: 59px 0 137px 40px;
.order_id {
display: flex;
font-size: 16px;
font-weight: 400;
line-height: 34px;
.id_tit {
color: #333333;
}
.id_num {
color: #999999;
}
}
.order_price {
display: flex;
font-size: 16px;
font-weight: 400;
line-height: 34px;
margin-top: 22px;
.price_tit {
color: #333333;
}
.price_con {
display: flex;
.con_icon {
font-size: 22px;
font-weight: 400;
line-height: 34px;
color: #aa1941;
}
.con_num {
font-size: 36px;
font-weight: normal;
line-height: 34px;
color: #aa1941;
}
}
}
.line {
margin-top: 26px;
border-bottom: 1px solid #e6e6e6;
}
.order_mode {
.mode_tit {
font-size: 16px;
font-weight: 500;
line-height: 34px;
color: #333333;
}
.mode_con {
margin-top: 29px;
width: 160px;
height: 66px;
border: 1px solid #4586d0;
display: flex;
justify-content: center;
align-items: center;
position: relative;
.con_style {
margin-right: 10px;
}
.checked_img {
position: absolute;
right: -1px;
bottom: -1px;
}
}
}
.order_qaCode {
display: flex;
margin-top: 39px;
.qaCode_left {
.left_code {
width: 197px;
}
.left_desc {
width: 197px;
height: 31px;
font-size: 12px;
font-weight: 400;
line-height: 31px;
color: #ffffff;
text-align: center;
}
.left_desc_ali {
background: #0f76fb;
}
.left_desc_wechat {
background: #01c71e;
}
}
.right_img {
margin: -11px 0 0 124px;
}
}
}
}
</style>
import type { PayOrder, Order } from '../types'
import * as api from '../api'
import { useUserStore } from '@/stores/user'
import { useShopStore } from '@/stores/shop'
import { useStorage } from '@vueuse/core'
import { useDevice } from '@/composables/useDevice'
const { wechat } = useDevice()
export function usePay() {
const route = useRoute()
const userStore = useUserStore()
const shopStore = useShopStore()
// 订单信息
const order = ref<Order>()
// 支付的订单信息
const payOrder = ref<PayOrder>()
const openId = useStorage('openId', '')
// 支付
async function pay(options = {}) {
// 默认参数
const defaultParams: Record<string, any> = reactive({
shop_id: shopStore.shopItem?.shop_id || '6998523899570814976',
spu_id: shopStore.shopItem?.spu_id || '6998525810348916736',
sku_id: shopStore.shopItem?.sku_id || '6998525810365693952',
buy_count: '1',
redirect_url: `${location.origin}/shop/order/${shopStore.shopItem?.id}`,
notify_url: `https://ep-lms-api.ezijing.com/v2/student/push?tenant=paa&sso_id=${userStore.user?.id}&class_id=${shopStore.shopItem?.class_id}&course_flag=1&course_id=${shopStore.shopItem?.course_id}`
})
const params = Object.assign(defaultParams, options)
// 微信JS支付参数设置
if (wechat.value && params.payment_method === '4') {
params.payment_method = '3'
params.open_id = await getOpenId()
}
// 创建订单
await createOrder(params)
if (!payOrder.value) return
// 网页支付,直接唤起对应支付网页
if (params.payment_method === '4' || params.payment_method === '12') {
location.href = payOrder.value.payment_url
return
}
// 微信JS支付
if (params.payment_method === '3') {
wxJSPay()
}
// 检测订单信息
checkOrder()
}
// 创建订单
async function createOrder(params: any) {
const res: any = await api.createOrder(params)
payOrder.value = res
localStorage.setItem('order_detail_id', res.order_detail_id)
await getOrder()
return res
}
// 获取订单信息
async function getOrder() {
if (!payOrder.value) return
const res = await api.getOrderList({ order_detail_id: payOrder.value.order_detail_id })
const currentOrder = res.data[0]
order.value = currentOrder
return currentOrder
}
// 检测订单状态
let timer = 0
async function checkOrder() {
if (!payOrder.value) return
timer && clearInterval(timer)
timer = setInterval(async () => {
const currentOrder = await getOrder()
if (currentOrder?.order_status === '4') clearInterval(timer)
}, 2000)
}
onUnmounted(() => {
timer && clearInterval(timer)
})
// 微信支付相关
// 获取code
function getCode() {
const href = location.href.includes('?') ? `${location.href}&is_pay=true` : `${location.href}?is_pay=true`
const redirectURI = `https://pages.ezijing.com/given/auth.html?redirect_uri=${encodeURIComponent(href)}`
location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx451c01d40d090d7a&redirect_uri=${redirectURI}&response_type=code&scope=snsapi_base`
}
// 获取openId
async function getOpenId() {
if (openId.value) return openId.value
const code = route.query.code || getCode()
return api
.getOpenId({ code, identity: 'ezijing' })
.then((res: any) => {
openId.value = res.openid
return res.data.openid
})
.catch(getCode)
}
function wxJSPay() {
if (!payOrder.value?.payment_more_info) {
alert('订单创建错误')
return
}
const payInfo: any = JSON.parse(payOrder.value.payment_more_info)
;(window as any).WeixinJSBridge?.invoke('getBrandWCPayRequest', payInfo, (res: any) => {
console.log(res)
})
}
return { order, payOrder, pay }
}
...@@ -5,6 +5,19 @@ export const routes: Array<RouteRecordRaw> = [ ...@@ -5,6 +5,19 @@ export const routes: Array<RouteRecordRaw> = [
{ {
path: '/shop/pay', path: '/shop/pay',
component: AppLayout, component: AppLayout,
children: [{ path: '/shop/pay/:id', component: () => import('./views/Index.vue'), props: true }] children: [
{
path: '/shop/pay/:id',
component: () => import('./views/Index.vue'),
props: true,
meta: { loginRequired: true }
},
{
path: '/shop/order/:id',
component: () => import('./views/Order.vue'),
props: true,
meta: { loginRequired: true }
}
]
} }
] ]
// 创建订单之后生成的订单信息
export interface PayOrder {
order_id: string
order_detail_id: string
payment_order_id: string
pay_order_id: string
payment_url: string
payment_more_info: string
}
// 订单信息
export interface Order {
order_id: string
order_detail_id: string
shop_id: string
spu_id: string
sku_id: string
spu_name: string
chart_oss: string
buy_count: string
customer_id: string
customer_phone: string
product_price: string
district_money: string
payment_money: string
shipping_user: string
shipping_phone: string
payment_method: string
app_button_text: string
payment_order_id: string
pay_order_id: string
create_time: string
order_status: string
update_time: string
pay_time: string
}
\ No newline at end of file
<script setup lang="ts"> <script setup lang="ts">
import Confirm from '../components/Confirm.vue' import type { Order } from '../types'
import Order from '../components/Order.vue'
import PaySucess from '../components/PaySucess.vue'
import { useShopStore } from '@/stores/shop' import { useShopStore } from '@/stores/shop'
import { useDevice } from '@/composables/useDevice' import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const PayH5 = defineAsyncComponent(() => import('../components/PayH5.vue'))
const PayPC = defineAsyncComponent(() => import('../components/PayPC.vue'))
const { shopItem } = useShopStore() const { shopItem } = useShopStore()
const status = ref('confirm') // confirm | order | success const { mobile } = useDevice()
const payMethod = ref(0)
const payInfo = ref({}) const router = useRouter()
const handleSuccess = (data: any) => { const handleSuccess = (data: Order) => {
payMethod.value = data.payMode router.replace({
status.value = data.status path: `/shop/order/${shopItem?.id}`,
} query: { order_detail_id: data.order_detail_id }
const handleOrder = (data: any) => { })
payInfo.value = data
status.value = data.status
}
const handleSuccessH5 = (data: any) => {
payInfo.value = data
status.value = data.status
} }
</script> </script>
<template> <template>
<div class="pay_main" v-if="!mobile"> <div class="pay_main">
<Confirm <PayH5 :shopItem="shopItem" @success="handleSuccess" v-if="mobile"></PayH5>
:shopItem="shopItem" <PayPC :shopItem="shopItem" @success="handleSuccess" v-else></PayPC>
@success="handleSuccess"
v-if="status === 'confirm'"
/>
<Order
:shopItem="shopItem"
:payMethod="payMethod"
@update="handleOrder"
v-if="status === 'order'"
/>
<PaySucess
:shopItem="shopItem"
:payInfo="payInfo"
v-if="status === 'success'"
/>
</div>
<div v-else>
<Confirm
:shopItem="shopItem"
@success="handleSuccessH5"
v-if="status === 'confirm'"
/>
<PaySucess
:shopItem="shopItem"
:payInfo="payInfo"
v-if="status === 'success'"
/>
</div> </div>
</template> </template>
......
<script setup lang="ts"> <script setup lang="ts">
import type { Order } from '../types'
import { getDateTime } from '@/utils'
import { getOrderList } from '../api'
import { useDevice } from '@/composables/useDevice' import { useDevice } from '@/composables/useDevice'
import { useShopStore } from '@/stores/shop'
import { useUserStore } from '@/stores/user'
interface Props {
id: string
}
const props = defineProps<Props>()
const { shopItem } = useShopStore()
const { mobile } = useDevice() const { mobile } = useDevice()
const router = useRouter() const router = useRouter()
const props = defineProps({ const route = useRoute()
payInfo: { const orderId = useStorage('order_detail_id', route.query.order_detail_id)
type: Object const order = ref<Order>()
}, async function getOrder() {
shopItem: { getOrderList({ order_detail_id: orderId.value })
type: Object .then((res) => {
} order.value = res.data[0]
}) if (order.value?.order_status === '4') {
function getDateTime(dayNum: any) { // 支付成功
const dateDay = new Date() // 刷新已购买的课程列表
dateDay.setDate(dateDay.getDate() + dayNum) //获取dayNum天后的日期 useUserStore().getCourse()
console.log(dateDay) } else {
const y = dateDay.getFullYear() // 未支付,返回支付页面
const m = router.replace(`/shop/pay/${props.id}`)
dateDay.getMonth() + 1 < 10 }
? '0' + (dateDay.getMonth() + 1) })
: dateDay.getMonth() + 1 //获取当前月份的日期,不足10补0 .catch(() => {
const d = dateDay.getDate() < 10 ? '0' + dateDay.getDate() : dateDay.getDate() //获取当前几号,不足10补0 router.replace(`/shop/pay/${props.id}`)
return y + '-' + m + '-' + d })
} }
onMounted(() => {
getOrder()
})
const start_time = getDateTime(0) const start_time = getDateTime(0)
const end_time = getDateTime(90) const end_time = getDateTime(90)
const handleStudy = () => { const handleStudy = () => {
window.open('https://paa-learning.ezijing.com') window.open('https://paa-learning.ezijing.com')
} }
const handlePrev = () => { const handlePrev = () => {
router.replace({ router.replace({ path: `/shop/detail/${shopItem?.id}` })
path: `/shop/detail/${props.shopItem?.id}`,
query: {
payStatus: props.payInfo?.payStatus
}
})
} }
</script> </script>
<template> <template>
<div class="main_pay" v-if="!mobile"> <div class="pay_main" v-if="order">
<div class="pay_con"> <div class="main_pay" v-if="!mobile">
<div class="con_top"> <div class="pay_con">
<img <div class="con_top">
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_sucess.png" <img
alt="" src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_sucess.png"
/> />
<div class="top_tit">支付成功!</div> <div class="top_tit">支付成功!</div>
</div>
<div class="con_info">
<div class="info_order">
<div class="order_tit">商品订单:</div>
<div class="order_id">{{ payInfo?.orderId }}</div>
</div> </div>
<div class="info_price"> <div class="con_info">
<div class="price_tit">支付金额:</div> <div class="info_order">
<div class="price_id">¥{{ payInfo?.payPrice }}</div> <div class="order_tit">商品订单:</div>
</div> <div class="order_id">{{ order.order_id }}</div>
<div class="info_tips"> </div>
若有疑问请与客服联系,我们将尽快为您提供服务 <div class="info_price">
</div> <div class="price_tit">支付金额:</div>
<div class="info_btn"> <div class="price_id">¥{{ order.payment_money }}</div>
<div class="btn_prev" @click="handlePrev">返回</div> </div>
<div class="btn_study" @click="handleStudy">开始学习</div> <div class="info_tips">
若有疑问请与客服联系,我们将尽快为您提供服务
</div>
<div class="info_btn">
<div class="btn_prev" @click="handlePrev">返回</div>
<div class="btn_study" @click="handleStudy">开始学习</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <div class="main_pay_mobile" v-else>
<div class="main_pay_mobile" v-else> <div class="con_nav">
<div class="con_nav">
<img
class="img1"
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/prev_mini.png"
alt=""
srcset=""
@click="handlePrev"
/>
<div class="nav_title">
<img <img
class="img2" class="img1"
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_sucess.png" src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/prev_mini.png"
alt="" @click="handlePrev"
/> />
支付成功 <div class="nav_title">
</div> <img
</div> class="img2"
<div class="course_con"> src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_sucess.png"
<img />
src="https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500" 支付成功
@click="handlePrev" </div>
/>
<div class="course_dec">
<div class="info_title">{{ shopItem?.title }}</div>
<div class="info_date">有效期:{{ start_time }}{{ end_time }}</div>
</div> </div>
</div> <div class="course_con">
<div class="order_main"> <img
<div class="order_num"> src="https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
商品订单:<span>{{ payInfo?.orderId }}</span> @click="handlePrev"
/>
<div class="course_dec">
<div class="info_title">{{ shopItem?.title }}</div>
<div class="info_date">
有效期:{{ start_time }}{{ end_time }}
</div>
</div>
</div> </div>
<div class="order_price"> <div class="order_main">
支付金额:<span>{{ payInfo?.payPrice }}</span> <div class="order_num">
商品订单:<span>{{ order.order_id }}</span>
</div>
<div class="order_price">
支付金额:<span>{{ order.payment_money }}</span>
</div>
<div class="order_after_sales">
若有疑问请与客服联系,我们将尽快为您提供服务
</div>
</div> </div>
<div class="order_after_sales"> <div class="start_study">
若有疑问请与客服联系,我们将尽快为您提供服务 <div class="study_con" @click="handleStudy">开始学习</div>
</div> </div>
</div> </div>
<div class="start_study">
<div class="study_con" @click="handleStudy">开始学习</div>
</div>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.pay_main {
background: #f7f8fa;
}
.is-h5 { .is-h5 {
.main_pay_mobile { .main_pay_mobile {
padding: 0 0.28rem; padding: 0 0.28rem;
......
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
// import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
const router = createRouter({ const router = createRouter({
scrollBehavior(to) { scrollBehavior(to) {
...@@ -13,10 +13,20 @@ const router = createRouter({ ...@@ -13,10 +13,20 @@ const router = createRouter({
routes: [{ path: '/:pathMatch(.*)*', redirect: '/home' }] routes: [{ path: '/:pathMatch(.*)*', redirect: '/home' }]
}) })
// router.beforeEach((to, from, next) => { router.beforeEach(async (to, from, next) => {
// const user = useUserStore() const user = useUserStore()
// user.getUser() if (to.meta.loginRequired && !user.isLogin) {
// next() try {
// }) await user.getUser()
} catch (e) {
console.error(e)
}
if (!user.isLogin) {
location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}`
return
}
}
next()
})
export default router export default router
...@@ -26,17 +26,17 @@ export const useUserStore = defineStore({ ...@@ -26,17 +26,17 @@ export const useUserStore = defineStore({
actions: { actions: {
async getUser() { async getUser() {
const res = await getUser() const res = await getUser()
try { await this.getCourse()
this.courses = await getBuyShop()
} catch (error) {
console.log(error)
}
this.user = res.data this.user = res.data
}, },
async logout() { async logout() {
await logout() await logout()
this.user = null this.user = null
},
async getCourse() {
this.courses = await getBuyShop()
} }
} }
}) })
export function getDateTime(dayNum = 0) {
const dateDay = new Date()
dateDay.setDate(dateDay.getDate() + dayNum) //获取dayNum天后的日期
const y = dateDay.getFullYear()
const m = dateDay.getMonth() + 1 < 10 ? '0' + (dateDay.getMonth() + 1) : dateDay.getMonth() + 1 //获取当前月份的日期,不足10补0
const d = dateDay.getDate() < 10 ? '0' + dateDay.getDate() : dateDay.getDate() //获取当前几号,不足10补0
return y + '-' + m + '-' + d
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论