|
@@ -0,0 +1,359 @@
|
|
|
+import MHeader from '@/components/m-header';
|
|
|
+import { defineComponent, onMounted, reactive } from 'vue';
|
|
|
+import {
|
|
|
+ Button,
|
|
|
+ Cell,
|
|
|
+ CellGroup,
|
|
|
+ Field,
|
|
|
+ Image,
|
|
|
+ Popup,
|
|
|
+ Radio,
|
|
|
+ RadioGroup,
|
|
|
+ Tag,
|
|
|
+ showToast
|
|
|
+} from 'vant';
|
|
|
+import styles from './index.module.less';
|
|
|
+import iconRefunding from './images/icon_refunding.svg';
|
|
|
+import icon_success from './images/icon_success.svg';
|
|
|
+import iconClose from './images/icon_close.svg';
|
|
|
+import iconTradeing from './images/icon_tradeing.svg';
|
|
|
+import { useRoute, useRouter } from 'vue-router';
|
|
|
+import { browser, moneyFormat } from '@/helpers/utils';
|
|
|
+import { useEventListener, useWindowScroll } from '@vueuse/core';
|
|
|
+import {
|
|
|
+ api_userPaymentOrderCancelRefund,
|
|
|
+ api_userPaymentOrderDetail,
|
|
|
+ api_userPaymentOrderRefundPayment
|
|
|
+} from '../collection-record/api';
|
|
|
+import * as detailState from '@/state';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'collection-record-detail',
|
|
|
+ setup() {
|
|
|
+ const route = useRoute();
|
|
|
+ const router = useRouter();
|
|
|
+ const state = reactive({
|
|
|
+ refund: route.query.refund,
|
|
|
+ orders: {} as any,
|
|
|
+ goodsInfos: [] as any,
|
|
|
+ background: 'transparent',
|
|
|
+ color: '#fff',
|
|
|
+ backIconColor: 'white' as any,
|
|
|
+ timer: null as any,
|
|
|
+ timerCount: 0 // 执行次数
|
|
|
+ });
|
|
|
+ const getDetails = async () => {
|
|
|
+ try {
|
|
|
+ if (!route.query.orderNo) return;
|
|
|
+ const { data } = await api_userPaymentOrderDetail(route.query.orderNo);
|
|
|
+
|
|
|
+ state.orders = data || {};
|
|
|
+ // state.orders.status = 'REFUNDED'
|
|
|
+ const tempGoods = data.goodsInfos || [];
|
|
|
+ tempGoods.forEach((item: any) => {
|
|
|
+ const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : '';
|
|
|
+ item.goodsUrl = img;
|
|
|
+ });
|
|
|
+ state.goodsInfos = tempGoods;
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 定时任务
|
|
|
+ const onTimeout = async () => {
|
|
|
+ // 判断订单状态,如果未支付则刷新
|
|
|
+ if (
|
|
|
+ ['WAIT_PAY', 'PAYING'].includes(state.orders.status) &&
|
|
|
+ state.timerCount <= 10
|
|
|
+ ) {
|
|
|
+ state.timer = setTimeout(async () => {
|
|
|
+ state.timerCount += 1;
|
|
|
+ await getDetails();
|
|
|
+ onTimeout();
|
|
|
+ }, 3000);
|
|
|
+ } else {
|
|
|
+ clearTimeout(state.timer);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const formatImg = (type: any) => {
|
|
|
+ const template: any = {
|
|
|
+ WAIT_PAY: iconTradeing,
|
|
|
+ PAYING: iconTradeing,
|
|
|
+ PAID: icon_success,
|
|
|
+ TIMEOUT: iconClose,
|
|
|
+ FAIL: iconClose,
|
|
|
+ CLOSED: iconClose,
|
|
|
+ REFUNDING: iconRefunding,
|
|
|
+ REFUNDED: icon_success
|
|
|
+ };
|
|
|
+ return template[type] || icon_success;
|
|
|
+ };
|
|
|
+
|
|
|
+ const formatOrderStatus = (status: string) => {
|
|
|
+ const temp: any = {
|
|
|
+ WAIT_PAY: '支付中',
|
|
|
+ PAYING: '支付中',
|
|
|
+ PAID: '支付成功',
|
|
|
+ TIMEOUT: '订单超时',
|
|
|
+ FAIL: '支付失败',
|
|
|
+ CLOSED: '订单关闭',
|
|
|
+ REFUNDING: '退款中',
|
|
|
+ REFUNDED: '已退款'
|
|
|
+ };
|
|
|
+ return temp[status];
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(async () => {
|
|
|
+ await getDetails();
|
|
|
+ await onTimeout();
|
|
|
+ useEventListener(document, 'scroll', () => {
|
|
|
+ const { y } = useWindowScroll();
|
|
|
+ if (y.value > 52) {
|
|
|
+ state.background = '#fff';
|
|
|
+ state.color = '#323333';
|
|
|
+ state.backIconColor = 'black';
|
|
|
+ } else {
|
|
|
+ state.background = 'transparent';
|
|
|
+ state.color = '#fff';
|
|
|
+ state.backIconColor = 'white';
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ const data = reactive({
|
|
|
+ open: false
|
|
|
+ });
|
|
|
+ const forms = reactive({
|
|
|
+ refundReason: '',
|
|
|
+ refundReasonDes: ''
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 取消订单 */
|
|
|
+ const handleCancel = async () => {
|
|
|
+ await api_userPaymentOrderRefundPayment({
|
|
|
+ merOrderNo: state.orders.orderNo,
|
|
|
+ serviceCharge: true,
|
|
|
+ paymentClient: 'STUDENT',
|
|
|
+ userId: detailState.state?.user?.data?.id,
|
|
|
+ refundReason:
|
|
|
+ forms.refundReason === '其他原因'
|
|
|
+ ? forms.refundReasonDes
|
|
|
+ : forms.refundReason,
|
|
|
+ userRefundOrderDetails: state.goodsInfos.map((goods: any) => ({
|
|
|
+ userPaymentOrderDetailId: goods.userPaymentOrderId,
|
|
|
+ num: goods.goodsNum
|
|
|
+ }))
|
|
|
+ });
|
|
|
+ showToast('申请退回成功');
|
|
|
+ getDetails();
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 取消退款申请 */
|
|
|
+ const handleBack = async () => {
|
|
|
+ await api_userPaymentOrderCancelRefund(state.orders.orderNo)
|
|
|
+ showToast('撤销退回成功');
|
|
|
+ }
|
|
|
+ return () => (
|
|
|
+ <div class={styles.paymentResult}>
|
|
|
+ <div class={[styles.paymentTitle]}>
|
|
|
+ <MHeader background="transparent" />
|
|
|
+
|
|
|
+ {state.orders.id && (
|
|
|
+ <>
|
|
|
+ <div class={styles.orderType}>
|
|
|
+ <Image
|
|
|
+ class={styles.img}
|
|
|
+ src={formatImg(state.orders.status)}
|
|
|
+ />
|
|
|
+ <div class={styles.orderInfo}>
|
|
|
+ <span>{formatOrderStatus(state.orders.status)}</span>
|
|
|
+ {state.orders.status === 'PAID' ||
|
|
|
+ state.orders.status === 'REFUNDING' ? (
|
|
|
+ <div class={styles.orderPrice}>
|
|
|
+ 实付金额:¥ {moneyFormat(state.orders.paymentCashAmount)}
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ ''
|
|
|
+ )}
|
|
|
+
|
|
|
+ {state.orders.status === 'REFUNDED' && (
|
|
|
+ <div class={styles.orderPrice}>
|
|
|
+ 退款金额:¥ {moneyFormat(state.orders.paymentCashAmount)}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <CellGroup inset class={[styles.cellGroup, styles.mTop]}>
|
|
|
+ <Cell>
|
|
|
+ {{
|
|
|
+ title: () => '付款时间',
|
|
|
+ value: () => <span>{state.orders.payTime || '--'}</span>
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ <Cell>
|
|
|
+ {{
|
|
|
+ title: () => '订单编号',
|
|
|
+ value: () => <span>{state.orders.orderNo}</span>
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ </CellGroup>
|
|
|
+
|
|
|
+ <CellGroup inset class={styles.cellGroup}>
|
|
|
+ <div class={styles.buyDetail}>
|
|
|
+ <div class={styles.buyDetailTitle}>
|
|
|
+ <i></i> 购买详情
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {state.goodsInfos.map((goods: any) => (
|
|
|
+ <Cell>
|
|
|
+ {{
|
|
|
+ icon: () => (
|
|
|
+ <Image class={styles.buyImg} src={goods.goodsUrl} />
|
|
|
+ ),
|
|
|
+ title: () => (
|
|
|
+ <div class={styles.buyContent}>
|
|
|
+ <p class={styles.goodsTitle}>{goods.goodsName}</p>
|
|
|
+ <Tag class={styles.brandName}>
|
|
|
+ {state.orders.orderType === 'VIP'
|
|
|
+ ? '12个月'
|
|
|
+ : goods.brandName}
|
|
|
+ </Tag>
|
|
|
+ </div>
|
|
|
+ ),
|
|
|
+ value: () => <span>x {goods.goodsNum}</span>
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ ))}
|
|
|
+ </CellGroup>
|
|
|
+
|
|
|
+ {state.orders.refundAudit === 'ING' && (
|
|
|
+ <Button
|
|
|
+ class={styles.cancelBtn}
|
|
|
+ block
|
|
|
+ round
|
|
|
+ type="primary"
|
|
|
+ onClick={() => handleBack()}>
|
|
|
+ 撤销退回
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
+ {state.orders.refundable && (
|
|
|
+ <Button
|
|
|
+ class={[styles.cancelBtn, styles.orderNo]}
|
|
|
+ block
|
|
|
+ round
|
|
|
+ type="primary"
|
|
|
+ onClick={() => (data.open = true)}>
|
|
|
+ 申请退回
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <Popup
|
|
|
+ teleport="body"
|
|
|
+ v-model:show={data.open}
|
|
|
+ class={['popup-custom', 'van-scale']}
|
|
|
+ transition="van-scale">
|
|
|
+ <div class={styles.cancelBox}>
|
|
|
+ <div class={styles.boxContent}>
|
|
|
+ <div class={styles.title}>
|
|
|
+ <div class={styles.titleTag}></div> 申请退回
|
|
|
+ </div>
|
|
|
+ <div class={styles.des}>
|
|
|
+ 您将要发起退回,退回需承担千分之六的手续费,确认退回后款项将原路返还到您的付款账户中。
|
|
|
+ </div>
|
|
|
+ <div class={styles.radioTitle}>
|
|
|
+ <span style={{ color: 'rgba(244, 69, 65, 1)' }}>*</span>
|
|
|
+ 请选择您的退回原因
|
|
|
+ </div>
|
|
|
+ <RadioGroup v-model={forms.refundReason}>
|
|
|
+ <Cell>
|
|
|
+ {{
|
|
|
+ title: () => (
|
|
|
+ <div>
|
|
|
+ <Radio name="价格太贵了">价格太贵了</Radio>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ <Cell>
|
|
|
+ {{
|
|
|
+ title: () => (
|
|
|
+ <div>
|
|
|
+ <Radio name="不喜欢/不想要">不喜欢/不想要</Radio>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ <Cell>
|
|
|
+ {{
|
|
|
+ title: () => (
|
|
|
+ <div>
|
|
|
+ <Radio name="七天无理由退货">七天无理由退货</Radio>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ <Cell>
|
|
|
+ {{
|
|
|
+ title: () => (
|
|
|
+ <div>
|
|
|
+ <Radio name="其他原因">其他原因</Radio>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ </RadioGroup>
|
|
|
+ <div
|
|
|
+ class={styles.radioDes}
|
|
|
+ style={{
|
|
|
+ display: forms.refundReason === '其他原因' ? '' : 'none'
|
|
|
+ }}>
|
|
|
+ <Field
|
|
|
+ v-model={forms.refundReasonDes}
|
|
|
+ rows="2"
|
|
|
+ autosize
|
|
|
+ label=""
|
|
|
+ type="textarea"
|
|
|
+ maxlength="50"
|
|
|
+ placeholder="在这里填写退回原因"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class={styles.radioBtns}>
|
|
|
+ <Button
|
|
|
+ block
|
|
|
+ onClick={() => {
|
|
|
+ if (!forms.refundReason) {
|
|
|
+ showToast('请选择退回原因');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ forms.refundReason === '其他原因' &&
|
|
|
+ !forms.refundReasonDes
|
|
|
+ ) {
|
|
|
+ showToast('请输入退回原因');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ handleCancel();
|
|
|
+ }}>
|
|
|
+ 确认退回
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ block
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ onClick={() => (data.open = false)}>
|
|
|
+ 取消
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Popup>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|