123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- import OHeader from '@/components/m-header';
- import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
- import styles from './order-detail.module.less';
- import Addres from './component/addres';
- import OSticky from '@/components/m-sticky';
- import { Button, Cell, CellGroup, Image, Popup, showToast, Tag } from 'vant';
- import Payment from '@/views/adapay/payment';
- import { useRoute, useRouter } from 'vue-router';
- import request from '@/helpers/request';
- import { state as baseState } from '@/state';
- import { browser, moneyFormat } from '@/helpers/utils';
- import OProtocol from '@/components/m-protocol';
- import OPopup from '@/components/m-popup';
- import UserAuth from './component/user-auth';
- import qs from 'query-string';
- import ODialog from '@/components/m-dialog';
- import { orderStatus } from '@/helpers/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, // 是否进行实名认证
- selectGoodsId: null as any,
- currentPrice: 0,
- hasInstrument: false, // 是否有乐器
- dialogStatus: false,
- dialogMessage: '',
- submitStatus: false
- });
- const orderType = computed(() => {
- return state.orderInfo.orderType;
- });
- const addressDetails = ref<any>({});
- const getOrderDetails = async () => {
- try {
- const { data } = await request.get(
- '/edu-app/userPaymentOrder/detail/' + state.orderNo
- );
- const goodsInfos = data.goodsInfos || [];
- state.orderInfo = data;
- let hasInstrument = false; // 是否有乐器
- goodsInfos.forEach((item: any) => {
- const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : '';
- item.goodsUrl = img;
- if (item.goodsType === 'INSTRUMENTS') {
- hasInstrument = true;
- }
- });
- state.goodsInfos = goodsInfos;
- if (!addressDetails.value.id) {
- addressDetails.value = data.addresses || {};
- }
- // 判断运费状态
- // 如果没有购买商品,有购买教材则『到付』 其它则免运费
- state.hasInstrument = hasInstrument;
- if (hasInstrument) {
- 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];
- }
- } 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,
- paymentType: state.paymentType,
- body: config.body,
- price: config.price,
- orderNo: config.merOrderNo,
- userId: config.userId
- });
- if (val.payCode === 'payResult') {
- window.location.href =
- window.location.origin + '/classroom-app/#/payResult?' + params;
- } else {
- state.qrCodeUrl =
- window.location.origin + '/classroom-app/#/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 != 'order-detail') {
- clearInterval(orderTimer);
- return;
- }
- state.orderTimer = orderTimer;
- try {
- const { data } = await request.post(
- '/edu-app/open/userOrder/paymentStatus/' + state.orderNo,
- {
- hideLoading: true
- }
- );
- if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
- // 默认关闭支付二维码弹窗
- state.showQrcode = false;
- clearInterval(state.orderTimer);
- 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 {
- // 直接去拉取微信支付
- onConfirm({
- payCode: 'payResult',
- pay_channel: 'wx_pub'
- });
- }
- }
- };
- /**
- * @description 会员购买
- * @param callback 回调方式
- */
- const buyVip = async (callback?: any) => {
- try {
- if (!state.agreeStatus) {
- showToast('请先阅读并同意《音乐数字课堂服务协议》');
- return;
- }
- const users = baseState.user.data;
- // 判断是否需要实名认证, 姓名,卡号
- if (!users?.account.realName || !users?.account.idCardNo) {
- state.authShow = true;
- return;
- }
- state.submitStatus = true;
- // const { data } = await request.get(
- // '/edu-app/userPaymentOrder/detail/' + state.orderNo,
- // {
- // hideLoading: false
- // }
- // );
- const { data } = await request.post(
- '/edu-app/userPaymentOrder/updateReceiveAddress',
- {
- hideLoading: false,
- data: {
- orderNo: state.orderNo,
- orderType: 'VIP'
- }
- }
- );
- state.pay_channel = data.paymentChannel;
- if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
- router.replace({
- path: '/payment-result',
- query: {
- orderNo: state.orderNo
- }
- });
- } else {
- callback && callback();
- state.submitStatus = false;
- }
- } catch {
- //
- state.submitStatus = false;
- }
- };
- /**
- * @description 学生登记 - 汇付
- * @param callback 回调方式
- */
- const buyOrchestra = async (callback: any) => {
- // 请选择收货地址
- if (!addressDetails.value.id && state.hasInstrument) {
- showToast('请选择收货地址');
- return;
- }
- if (!state.agreeStatus) {
- showToast('请先阅读并同意《音乐数字课堂服务协议》');
- return;
- }
- const users = baseState.user.data;
- // 判断是否需要实名认证, 姓名,卡号
- if (!users?.account.realName || !users?.account.idCardNo) {
- state.authShow = true;
- return;
- }
- state.submitStatus = true;
- try {
- const { data } = await request.post(
- '/edu-app/userPaymentOrder/updateReceiveAddress',
- {
- hideLoading: false,
- data: {
- orderNo: state.orderNo,
- orderType: 'SCHOOL_REGISTER',
- receiveAddress: addressDetails.value.id || ''
- }
- }
- );
- state.pay_channel = data.paymentChannel;
- if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
- checkOrderTypeJump();
- } else {
- callback && callback();
- state.submitStatus = false;
- }
- } catch {
- //
- state.submitStatus = false;
- }
- };
- // 有支付结果后回调
- const checkOrderTypeJump = () => {
- // 判断是否是乐团报名
- // if (orderType.value === 'SCHOOL_REGISTER') {
- // 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(
- '/edu-app/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 === 'SCHOOL_REGISTER' && } */}
- {state.hasInstrument && (
- <div class={styles.cartConfirmBox}>
- <Addres item={addressDetails.value} />
- </div>
- )}
- <CellGroup style={{ margin: 0 }}>
- {state.goodsInfos &&
- state.goodsInfos.map((goods: any) => (
- <Cell class={styles.cellItem}>
- {{
- icon: () => (
- <Image class={styles.img} src={goods.goodsUrl} />
- ),
- title: () => (
- <div class={styles.goodsContent}>
- <h2>
- <span>{goods.goodsName}</span>
- <span class={styles.goodsNum}>
- x {goods.goodsNum}
- </span>
- </h2>
- <div class={styles.goodsPrice}>
- <Tag class={styles.brandName}>
- {goods.goodsType === 'VIP'
- ? '12个月'
- : goods.brandName}
- </Tag>
- <span
- class={[
- styles.goodsNums,
- goods.paymentCashAmount > 0
- ? styles.numFont
- : styles.free
- ]}>
- {goods.paymentCashAmount > 0 ? (
- <>
- <span class={styles.numPrefix}>¥ </span>
- {moneyFormat(goods.paymentCashAmount)}
- </>
- ) : (
- '免费'
- )}
- </span>
- </div>
- <p class={styles.model}>{goods.description}</p>
- </div>
- )
- }}
- </Cell>
- ))}
- </CellGroup>
- {orderType.value === 'SCHOOL_REGISTER' && (
- <Cell
- class={styles.freight}
- title="运费"
- value={state.freight}></Cell>
- )}
- </div>
- <OSticky position="bottom">
- {/* <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>
- <i>¥</i>
- {moneyFormat(state.orderInfo.currentPrice)}
- </span>
- </p>
- </div>
- <div class={styles.paymentBtn}>
- <Button
- round
- class={[
- styles.submitBtn
- // orderType.value === 'VIP' ? styles.vipBtn : '',
- // orderType.value === 'SCHOOL_REGISTER' ? styles.otherBtn : ''
- ]}
- 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>
- <Popup
- v-model:show={state.showQrcode}
- round
- onClose={() => {
- // 二维码关闭时清除定时器
- clearInterval(state.orderTimer);
- }}>
- <QrcodePayment
- url={state.qrCodeUrl}
- pay_channel={state.pay_channel}
- orderType={orderType.value}
- />
- </Popup>
- <OPopup v-model:modelValue={state.authShow}>
- <UserAuth onSuccess={onAuthSuccess} hideHeader={!browser().isApp} />
- </OPopup>
- <ODialog
- title="提示"
- v-model:show={state.dialogStatus}
- message={state.dialogMessage}
- confirmButtonText="确定"
- onConfirm={() => {
- checkOrderTypeJump();
- }}
- />
- </>
- );
- }
- });
|