123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- import OHeader from '@/components/o-header'
- import { computed, defineComponent, onMounted, reactive } from 'vue'
- import styles from './order-detail.module.less'
- // import Addres from './component/addres'
- import OSticky from '@/components/o-sticky'
- import { Button, Cell, CellGroup, Image, Popup, showToast, Tag } from 'vant'
- import Payment from '@/views/adapay/payment'
- import { useRoute, useRouter } from 'vue-router'
- // import OQrcode from '@/components/o-qrcode'
- import request from '@/helpers/request'
- import { state as baseState } from '@/state'
- import { browser, moneyFormat } from '@/helpers/utils'
- import OProtocol from '@/components/o-protocol'
- import OPopup from '@/components/o-popup'
- import UserAuth from './component/user-auth'
- import qs from 'query-string'
- import MemberBao from '../member-bao'
- import GoodsDetail from '../goods-detail'
- import ODialog from '@/components/o-dialog'
- import { orderStatus } from '@/constant'
- import QrcodePayment from './qrcode-payment'
- import { beforeSubmit } from './order-state'
- /**
- * 接入jsdk
- * 乐团报名-原生js支付
- * 会员购买-汇付
- */
- export default defineComponent({
- name: 'order-detail',
- setup() {
- const route = useRoute()
- const router = useRouter()
- const state = reactive({
- paymentType: 'adapay' as 'wxpay' | 'adapay', // 支付方式
- orderTimer: null as any,
- paymentStatus: false,
- showQrcode: false,
- qrCodeUrl: '',
- pay_channel: '',
- orderNo: route.query.orderNo,
- orderInfo: {} as any, // 订单信息
- goodsInfos: [] as any, // 订单信息列表
- config: route.query.config ? JSON.parse(route.query.config as any) : {},
- hasFreight: route.query.hf ? false : true, // 是否显示
- freight: '', // 运费
- agreeStatus: true, //是否勾选协议
- showHeader: false,
- authShow: false, // 是否进行实名认证
- memberBaoStatus: false, // 团练宝详情状态
- goodsStatus: false, //
- selectGoodsId: null as any,
- currentPrice: 0,
- dialogStatus: false,
- dialogMessage: '',
- dialogType: '',
- submitStatus: false
- })
- const orderType = computed(() => {
- return state.orderInfo.orderType
- })
- // const addressDetails = ref<any>({})
- const getOrderDetails = async () => {
- try {
- const { data } = await request.get('/api-student/userPaymentOrder/detail/' + state.orderNo)
- const goodsInfos = data.goodsInfos || []
- state.orderInfo = data
- let hasInstrument = false // 是否有乐器
- let hasTextbook = false // 是否购买教材
- goodsInfos.forEach((item: any) => {
- const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : ''
- item.goodsUrl = img
- if (item.goodsType === 'INSTRUMENTS') {
- hasInstrument = true
- } else if (item.goodsType === 'TEXTBOOK') {
- hasTextbook = true
- }
- })
- state.goodsInfos = goodsInfos
- // if (!addressDetails.value.id) {
- // addressDetails.value = data.addresses || {}
- // }
- // 判断运费状态
- // 如果没有购买商品,有购买教材则『到付』 其它则免运费
- // console.log(hasInstrument, hasTextbook)
- if (!hasInstrument && hasTextbook) {
- state.freight = '到付'
- } else {
- state.freight = '免运费'
- }
- // 判断订单状态,如果不是待支付则返回
- // WAIT_PAY: '待支付',
- // PAYING: '支付中',
- // PAID: '已付款',
- // TIMEOUT: '订单超时',
- // FAIL: '支付失败',
- // CLOSED: '订单关闭',
- // REFUNDING: '退款中',
- // REFUNDED: '已退款'
- if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
- // status
- state.dialogStatus = true
- state.dialogMessage = '订单' + orderStatus[data.status]
- state.dialogType = data.status
- }
- } catch {
- //
- }
- }
- const onConfirm = (val: any) => {
- const config: any = state.config
- state.pay_channel = val.pay_channel
- const params = qs.stringify({
- pay_channel: val.pay_channel,
- wxAppId: config.wxAppId,
- alipayAppId: config.alipayAppId,
- body: config.body,
- price: config.price,
- paymentType: config.paymentType,
- orderNo: config.merOrderNo,
- userId: config.userId
- })
- if (val.payCode === 'payResult') {
- window.location.href = window.location.origin + '/orchestra-student/#/payResult?' + params
- } else {
- state.qrCodeUrl = window.location.origin + '/orchestra-student/#/payDefine?' + params
- state.showQrcode = true
- state.paymentStatus = false
- setTimeout(() => {
- getPaymentOrderStatus()
- }, 300)
- }
- }
- // 轮询查询订单状态
- const getPaymentOrderStatus = async () => {
- // 循环查询订单
- // const orderNo = state.orderNo
- const orderTimer = setInterval(async () => {
- // 判断是否在当前路由,如果不是则清除定时器
- if (route.name != 'orderDetail') {
- clearInterval(orderTimer)
- return
- }
- state.orderTimer = orderTimer
- try {
- const { data } = await request.post(
- '/api-student/open/userOrder/paymentStatus/' + state.orderNo,
- {
- hideLoading: true
- }
- )
- // console.log(data)
- if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
- // 默认关闭支付二维码弹窗
- state.showQrcode = false
- clearInterval(state.orderTimer)
- // window.location.replace(
- // window.location.origin + '/#/payment-result?orderNo=' + state.orderNo
- // )
- setTimeout(() => {
- checkOrderTypeJump()
- }, 100)
- }
- } catch {
- //
- clearInterval(state.orderTimer)
- }
- }, 5000)
- }
- // 确定支付
- const onSubmit = async () => {
- clearInterval(state.orderTimer)
- if (orderType.value === 'VIP') {
- buyVip(onCallback)
- } else {
- buyOrchestra(onCallback)
- }
- }
- /**
- * @description 回调,判断是否有支付渠道,如果有则直接去支付
- * @returns void
- */
- const onCallback = () => {
- const pt = state.pay_channel
- // 判断是否有支付方式
- if (pt) {
- const payCode: string = beforeSubmit(state.pay_channel)
- onConfirm({
- payCode,
- pay_channel: pt
- })
- } else {
- if (orderType.value === 'VIP') {
- state.paymentStatus = true
- } else {
- if (browser().isApp) {
- state.paymentStatus = true
- } else {
- // 直接去拉取微信支付
- onConfirm({
- payCode: 'payResult',
- pay_channel: 'wx_pub'
- })
- }
- }
- }
- }
- /**
- * @description 会员购买
- * @param callback 回调方式
- */
- const buyVip = async (callback?: any) => {
- try {
- state.submitStatus = true
- const { data } = await request.get(
- '/api-student/userPaymentOrder/detail/' + state.orderNo,
- {
- hideLoading: false
- }
- )
- state.pay_channel = data.paymentChannel
- state.submitStatus = false
- if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
- router.replace({
- path: '/payment-result',
- query: {
- orderNo: state.orderNo
- }
- })
- } else {
- callback && callback()
- }
- } catch {
- //
- state.submitStatus = false
- }
- }
- /**
- * @description 乐团报名 - 汇付
- * @param callback 回调方式
- */
- const buyOrchestra = async (callback: any) => {
- // 请选择收货地址
- // if (!addressDetails.value.id) {
- // showToast('请选择收货地址')
- // return
- // }
- if (!state.agreeStatus) {
- showToast('请先阅读并同意《管乐团平台服务协议》')
- return
- }
- const users = baseState.user.data
- // console.group(users)
- // 判断是否需要实名认证, 姓名,卡号
- if (!users?.account.realName || !users?.account.idCardNo) {
- state.authShow = true
- return
- }
- state.submitStatus = true
- try {
- const { data } = await request.post('/api-student/userPaymentOrder/updateReceiveAddress', {
- hideLoading: false,
- data: {
- orderNo: state.orderNo,
- orderType: 'ORCHESTRA',
- receiveAddress: null
- }
- })
- if (data.status == 'CLOSED') {
- state.dialogStatus = true
- state.dialogMessage = '订单已关闭'
- state.dialogType = 'CLOSED'
- } else if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
- checkOrderTypeJump()
- } else {
- callback && callback()
- }
- } catch {
- //
- } finally {
- state.submitStatus = false
- }
- }
- // 有支付结果后回调
- const checkOrderTypeJump = () => {
- // 判断是否是乐团报名 并且在不在app里面
- if (orderType.value === 'ORCHESTRA' && !browser().isApp) {
- if (state.dialogType === 'CLOSED') {
- router.back()
- } else {
- window.location.replace(
- 'https://mp.weixin.qq.com/s?__biz=MzkxMDMwOTI5Nw==&mid=2247485362&idx=3&sn=9b265d36b5dabe7f9393fc679c367540&chksm=c12c256cf65bac7ae2a865435b950f6e1285afd226356db0ffde815b1ee345f29cfcdb798cc9#rd'
- )
- }
- } else {
- router.replace({
- path: '/payment-result',
- query: {
- orderNo: state.orderNo
- }
- })
- }
- }
- // 放弃支付时,则取消订单
- const onBackOut = async () => {
- try {
- await request.post('/api-student/userPaymentOrder/cancelPayment/' + state.orderNo)
- router.back()
- } catch {
- //
- }
- }
- // 实名认证成功
- const onAuthSuccess = () => {
- //
- state.authShow = false
- onSubmit() // 实名成功后自动支付
- }
- onMounted(() => {
- if (browser().isApp) {
- state.showHeader = true
- } else {
- state.showHeader = false
- }
- // 获取收货地址
- // let details = sessionStorage.getItem('addressDetails')
- // details = details ? JSON.parse(details) : {}
- // addressDetails.value = details
- // sessionStorage.removeItem('addressDetails')
- getOrderDetails()
- })
- return () => (
- <>
- {browser().isApp && <OHeader border={false} />}
- <div class={styles.cartConfirm}>
- {/* 只有乐团购买的时候显示收货地址 */}
- {/* {orderType.value === 'ORCHESTRA' && (
- <div class={styles.cartConfirmBox}>
- <Addres item={addressDetails.value} />
- </div>
- )} */}
- <CellGroup style={{ margin: 0 }} border={false}>
- {state.goodsInfos &&
- state.goodsInfos.map((goods: any) => (
- <Cell
- class={styles.cellItem}
- // center
- onClick={() => {
- if (goods.goodsType === 'INSTRUMENTS' || goods.goodsType === 'TEXTBOOK') {
- // console.log(goods)
- state.selectGoodsId = goods.goodsId
- state.currentPrice = goods.currentPrice
- state.goodsStatus = true
- } else if (goods.goodsType === 'VIP') {
- state.memberBaoStatus = true
- }
- }}
- >
- {{
- icon: () => <Image class={styles.img} src={goods.goodsUrl} />,
- title: () => (
- <div class={styles.goodsContent}>
- <h2>
- <span>{goods.goodsName}</span>
- {/* <span class={styles.goodsNum}>
- {goods.goodsType === 'VIP' ? '6个月' : 'x 1'}
- </span> */}
- <span
- class={[
- styles.goodsNums,
- goods.paymentCashAmount > 0 ? styles.numFont : styles.free
- ]}
- >
- {goods.paymentCashAmount > 0 ? (
- <>
- <span class={styles.numPrefix}>¥ </span>
- {moneyFormat(goods.paymentCashAmount)}
- </>
- ) : state.orderInfo.orchestraRegisterType === 'GROUP_BUY' &&
- goods.goodsType === 'INSTRUMENTS' ? (
- '免费提供'
- ) : (
- '免费'
- )}
- </span>
- </h2>
- <div class={styles.goodsPrice}>
- {/* {goods.goodsType === 'INSTRUMENT_INSPECT' ? (
- <span>1-2次/学期</span>
- ) : (
- <Tag
- color="linear-gradient(135deg, #FF8C4A 0%, #FF531C 100%)"
- textColor="#fff"
- class={styles.brandName}
- >
- {goods.brandName}
- </Tag>
- )} */}
- {goods.goodsType === 'INSTRUMENT_INSPECT' ? (
- <span class={[styles.model, 'van-multi-ellipsis--l2']}>1-2次/学期</span>
- ) : (
- <span class={[styles.model, 'van-multi-ellipsis--l2']}>
- {goods.description}
- </span>
- )}
- <span class={styles.goodsNum}>
- {goods.goodsType === 'VIP' ? '6个月' : 'x 1'}
- </span>
- </div>
- {/* <p class={styles.model}>{goods.description}</p> */}
- </div>
- )
- }}
- </Cell>
- ))}
- </CellGroup>
- {/* {orderType.value === 'ORCHESTRA' && (
- <Cell class={styles.freight} title="运费" value={state.freight}></Cell>
- )} */}
- </div>
- <OSticky position="bottom" background="white-only">
- <div class={styles.protocol}>
- <OProtocol
- v-model:modelValue={state.agreeStatus}
- showHeader={state.showHeader}
- style={{ paddingTop: 0, paddingBottom: 0 }}
- />
- </div>
- <div class={styles.paymentContainer}>
- <div class={styles.payemntPrice}>
- <p class={styles.needPrice}>
- 支付金额:<span>¥ {moneyFormat(state.orderInfo.currentPrice)}</span>
- </p>
- </div>
- <div class={styles.paymentBtn}>
- <Button
- color="linear-gradient(135deg, #FF8C4A 0%, #FF531C 100%)"
- round
- onClick={onSubmit}
- loading={state.submitStatus}
- disabled={state.submitStatus}
- >
- 立即购买
- </Button>
- </div>
- </div>
- </OSticky>
- <Popup
- show={state.paymentStatus}
- closeOnClickOverlay={false}
- position="bottom"
- round
- closeOnPopstate
- safeAreaInsetBottom
- style={{ minHeight: '30%' }}
- >
- <Payment
- paymentConfig={state.orderInfo}
- onClose={() => (state.paymentStatus = false)}
- onBackOut={onBackOut}
- onConfirm={(val: any) => onConfirm(val)}
- />
- </Popup>
- <OPopup
- v-model:modelValue={state.showQrcode}
- onClose={() => {
- // 二维码关闭时清除定时器
- clearInterval(state.orderTimer)
- }}
- >
- <QrcodePayment
- url={state.qrCodeUrl}
- pay_channel={state.pay_channel}
- orderType={orderType.value}
- />
- </OPopup>
- <OPopup v-model:modelValue={state.authShow}>
- <UserAuth onSuccess={onAuthSuccess} hideHeader={!browser().isApp} />
- </OPopup>
- <OPopup v-model:modelValue={state.memberBaoStatus} position="right">
- <MemberBao />
- </OPopup>
- <OPopup v-model:modelValue={state.goodsStatus} position="right" destroy>
- {state.goodsStatus && (
- <GoodsDetail id={state.selectGoodsId} groupPrice={state.currentPrice} />
- )}
- </OPopup>
- <ODialog
- title="提示"
- v-model:show={state.dialogStatus}
- message={state.dialogMessage}
- confirmButtonText="确定"
- onConfirm={() => {
- checkOrderTypeJump()
- // if (state.dialogType === 'CLOSED') {
- // } else {
- // checkOrderTypeJump()
- // }
- }}
- />
- </>
- )
- }
- })
|