|
@@ -4,6 +4,21 @@
|
|
|
-->
|
|
-->
|
|
|
<template>
|
|
<template>
|
|
|
<view class="refund-page">
|
|
<view class="refund-page">
|
|
|
|
|
+ <!-- 该售后关联的原单非当天单/欠款已结清,通过后将按冲销单方式退款(提示,不影响驳回) -->
|
|
|
|
|
+ <view class="warning-tip forward-tip" v-if="info.status == 0 && isForwardEligible && !forwardExhausted">
|
|
|
|
|
+ <view class="warning-icon">ℹ</view>
|
|
|
|
|
+ <view class="warning-content">
|
|
|
|
|
+ <text class="warning-text">该售后将以冲销单方式通过</text>
|
|
|
|
|
+ <text class="warning-amount">点通过后弹框选择剩余选项,退款方式将锁定为原支付渠道</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="warning-tip" v-if="info.status == 0 && isForwardEligible && forwardExhausted">
|
|
|
|
|
+ <view class="warning-icon">⚠</view>
|
|
|
|
|
+ <view class="warning-content">
|
|
|
|
|
+ <text class="warning-text">该订单已冲销完,无法再通过此售后</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
<view class="refund-card">
|
|
<view class="refund-card">
|
|
|
<view class="refund-row">
|
|
<view class="refund-row">
|
|
|
<view class="refund-label">退款方式</view>
|
|
<view class="refund-label">退款方式</view>
|
|
@@ -74,6 +89,12 @@
|
|
|
<view class="refund-value refund-value--multiline">{{ info.rejectReason || '' }}</view>
|
|
<view class="refund-value refund-value--multiline">{{ info.rejectReason || '' }}</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
|
|
+ <!-- 该售后已被转成冲销单处理:说明退款不是走本条售后原路退回的,实际的退款/退货/返余额在冲销单里 -->
|
|
|
|
|
+ <view class="refund-row refund-row--top" v-if="isConvertedToForward">
|
|
|
|
|
+ <view class="refund-label">处理说明</view>
|
|
|
|
|
+ <view class="refund-value refund-value--multiline forward-remark">{{ info.hdRemark || '' }}</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
<view class="refund-row refund-row--top" v-if="!$util.isEmpty(info.remark)">
|
|
<view class="refund-row refund-row--top" v-if="!$util.isEmpty(info.remark)">
|
|
|
<view class="refund-label">备注信息</view>
|
|
<view class="refund-label">备注信息</view>
|
|
|
<view class="refund-value refund-value--multiline">{{ info.remark || '' }}</view>
|
|
<view class="refund-value refund-value--multiline">{{ info.remark || '' }}</view>
|
|
@@ -103,7 +124,13 @@
|
|
|
|
|
|
|
|
<view class="refund-actions">
|
|
<view class="refund-actions">
|
|
|
<button
|
|
<button
|
|
|
- v-if="info.status == 0"
|
|
|
|
|
|
|
+ v-if="info.status == 0 && isForwardEligible"
|
|
|
|
|
+ class="admin-button-com big refund-actions__btn refund-actions__btn--pass"
|
|
|
|
|
+ :disabled="forwardExhausted"
|
|
|
|
|
+ @click="openForwardPass()"
|
|
|
|
|
+ >通过(转冲销单)</button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ v-if="info.status == 0 && !isForwardEligible"
|
|
|
class="admin-button-com big refund-actions__btn refund-actions__btn--pass"
|
|
class="admin-button-com big refund-actions__btn refund-actions__btn--pass"
|
|
|
@click="pass(0)"
|
|
@click="pass(0)"
|
|
|
>通过</button>
|
|
>通过</button>
|
|
@@ -151,12 +178,27 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</uni-popup>
|
|
</uni-popup>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 售后转冲销单:点"通过(转冲销单)"直接弹框选剩余选项并提交,商品明细以本售后申请为准,后端自动取,不用再选一遍 -->
|
|
|
|
|
+ <forward-options-popup
|
|
|
|
|
+ ref="forwardPopup"
|
|
|
|
|
+ :pay-way-name="getPayWayName(info.orderInfo && info.orderInfo.payWay)"
|
|
|
|
|
+ :amount="refundPrice"
|
|
|
|
|
+ :submitting="forwardSubmitting"
|
|
|
|
|
+ @confirm="submitForwardOrder"
|
|
|
|
|
+ />
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
<script>
|
|
<script>
|
|
|
import { refundDetail, passRefund, rejectRefund, modifyCause, modifyAmount } from '@/api/refund'
|
|
import { refundDetail, passRefund, rejectRefund, modifyCause, modifyAmount } from '@/api/refund'
|
|
|
|
|
+import { createForwardOrder } from '@/api/order/index'
|
|
|
|
|
+import ForwardOptionsPopup from '@/components/forward-options-popup'
|
|
|
|
|
+import dayjs from 'dayjs'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
|
|
+ components: {
|
|
|
|
|
+ ForwardOptionsPopup
|
|
|
|
|
+ },
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
product: '',
|
|
product: '',
|
|
@@ -167,10 +209,35 @@ export default {
|
|
|
rejectReason: '',
|
|
rejectReason: '',
|
|
|
from: 0,
|
|
from: 0,
|
|
|
refundAmount: '',
|
|
refundAmount: '',
|
|
|
- showChoice: false
|
|
|
|
|
|
|
+ showChoice: false,
|
|
|
|
|
+ //冲销单提交中,防止连点/重复请求
|
|
|
|
|
+ forwardSubmitting: false
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 是否走"售后转冲销单":该售后关联的原单非当天单,或者原单曾有欠款且现已结清完毕。
|
|
|
|
|
+ * 满足任一条件时,点"通过"不再走老的 passRefund 流程,改为直接弹框选项后生成冲销单。
|
|
|
|
|
+ */
|
|
|
|
|
+ isForwardEligible() {
|
|
|
|
|
+ const orderInfo = this.info.orderInfo
|
|
|
|
|
+ if (this.$util.isEmpty(orderInfo) || this.$util.isEmpty(orderInfo.payTime)) {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ const notToday = dayjs(orderInfo.payTime).format('YYYY-MM-DD') !== dayjs().format('YYYY-MM-DD')
|
|
|
|
|
+ const debtCleared = Number(orderInfo.debtPrice) > 0 && Number(orderInfo.remainDebtPrice) == 0
|
|
|
|
|
+ return notToday || debtCleared
|
|
|
|
|
+ },
|
|
|
|
|
+ /** 累计冲销金额已达原单实付金额,不能再通过该售后 */
|
|
|
|
|
+ forwardExhausted() {
|
|
|
|
|
+ if (!this.isForwardEligible) {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ const orderInfo = this.info.orderInfo || {}
|
|
|
|
|
+ const actPrice = Number(orderInfo.actPrice) || 0
|
|
|
|
|
+ const forwardPrice = Number(orderInfo.forwardPrice) || 0
|
|
|
|
|
+ return actPrice <= forwardPrice
|
|
|
|
|
+ },
|
|
|
/** 申请原因文案 */
|
|
/** 申请原因文案 */
|
|
|
causeText() {
|
|
causeText() {
|
|
|
const causeMap = {
|
|
const causeMap = {
|
|
@@ -181,8 +248,18 @@ export default {
|
|
|
}
|
|
}
|
|
|
return causeMap[this.info.cause] || '其它'
|
|
return causeMap[this.info.cause] || '其它'
|
|
|
},
|
|
},
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 该售后申请是否已被转成冲销单处理:以后端结构化字段 forwardOrderId(>0) 为准,
|
|
|
|
|
+ * 区别于客户自己在花店端主动取消申请(那种情况 forwardOrderId 为0)。ssh 冲销单功能
|
|
|
|
|
+ */
|
|
|
|
|
+ isConvertedToForward() {
|
|
|
|
|
+ return this.info.status == 3 && Number(this.info.forwardOrderId) > 0
|
|
|
|
|
+ },
|
|
|
/** 退款状态文案 */
|
|
/** 退款状态文案 */
|
|
|
statusText() {
|
|
statusText() {
|
|
|
|
|
+ if (this.isConvertedToForward) {
|
|
|
|
|
+ return '已转冲销单'
|
|
|
|
|
+ }
|
|
|
const statusMap = {
|
|
const statusMap = {
|
|
|
0: '待审核',
|
|
0: '待审核',
|
|
|
1: '已通过',
|
|
1: '已通过',
|
|
@@ -193,6 +270,9 @@ export default {
|
|
|
},
|
|
},
|
|
|
/** 退款状态样式 */
|
|
/** 退款状态样式 */
|
|
|
statusClass() {
|
|
statusClass() {
|
|
|
|
|
+ if (this.isConvertedToForward) {
|
|
|
|
|
+ return 'refund-status refund-status--forward'
|
|
|
|
|
+ }
|
|
|
const classMap = {
|
|
const classMap = {
|
|
|
0: 'refund-status refund-status--pending',
|
|
0: 'refund-status refund-status--pending',
|
|
|
1: 'refund-status refund-status--pass',
|
|
1: 'refund-status refund-status--pass',
|
|
@@ -249,6 +329,68 @@ export default {
|
|
|
goToOrder(info) {
|
|
goToOrder(info) {
|
|
|
this.$util.pageTo({ url: '/pagesOrder/detail?id=' + info.relateOrderId })
|
|
this.$util.pageTo({ url: '/pagesOrder/detail?id=' + info.relateOrderId })
|
|
|
},
|
|
},
|
|
|
|
|
+ /** payWay数字编码转文字,用于冲销单确认弹框只读展示原单支付渠道 */
|
|
|
|
|
+ getPayWayName(payWay) {
|
|
|
|
|
+ const map = { 0: '微信', 1: '支付宝', 2: '余额', 3: '挂账', 4: '现金', 5: '银行卡' }
|
|
|
|
|
+ return map[payWay] !== undefined ? map[payWay] : '--'
|
|
|
|
|
+ },
|
|
|
|
|
+ /** 点"通过(转冲销单)":弹框选剩余选项,商品明细以本售后申请为准,由后端自动取,不用再选一遍 */
|
|
|
|
|
+ openForwardPass() {
|
|
|
|
|
+ this.$refs.forwardPopup.open()
|
|
|
|
|
+ },
|
|
|
|
|
+ /** 冲销单弹框确认后提交:只传 refundOrderId,后端按该售后申请的商品明细自动生成冲销单并把本售后标记为已通过 */
|
|
|
|
|
+ async submitForwardOrder({ forwardStock, returnBalance, needPrint }) {
|
|
|
|
|
+ if (this.forwardSubmitting) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.forwardSubmitting = true
|
|
|
|
|
+ let pendingMsg = ''
|
|
|
|
|
+ uni.showLoading({ mask: true })
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await createForwardOrder({
|
|
|
|
|
+ customId: this.info.customId,
|
|
|
|
|
+ refundOrderId: this.option.id,
|
|
|
|
|
+ remark: this.remark,
|
|
|
|
|
+ forwardStock: forwardStock,
|
|
|
|
|
+ returnBalance: returnBalance,
|
|
|
|
|
+ needPrint: needPrint
|
|
|
|
|
+ }, { hideError: true })
|
|
|
|
|
+ if (!res || typeof res !== 'object') {
|
|
|
|
|
+ pendingMsg = '提交失败,请重试'
|
|
|
|
|
+ } else if (res.code == 1 && res.data && res.data.id) {
|
|
|
|
|
+ this.$refs.forwardPopup.close()
|
|
|
|
|
+ const { id, orderSn, actPrice, customBalance, customName } = res.data
|
|
|
|
|
+ if (returnBalance == 1) {
|
|
|
|
|
+ this.$util.pageTo({
|
|
|
|
|
+ url: '/admin/billing/forwardResult',
|
|
|
|
|
+ type: 2,
|
|
|
|
|
+ query: {
|
|
|
|
|
+ orderId: id,
|
|
|
|
|
+ orderSn: orderSn,
|
|
|
|
|
+ actPrice: Math.abs(Number(actPrice)),
|
|
|
|
|
+ customId: this.info.customId,
|
|
|
|
|
+ customName: customName,
|
|
|
|
|
+ customBalance: customBalance
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$util.pageTo({ url: '/admin/billing/result', type: 2, query: { orderId: id, orderSn: orderSn, title: '冲销成功' } })
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (res.msg) {
|
|
|
|
|
+ pendingMsg = res.msg
|
|
|
|
|
+ } else {
|
|
|
|
|
+ pendingMsg = '提交失败'
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ pendingMsg = '提交失败,请重试'
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ uni.hideLoading()
|
|
|
|
|
+ this.forwardSubmitting = false
|
|
|
|
|
+ if (pendingMsg) {
|
|
|
|
|
+ this.$msg(pendingMsg)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
cancelReject() {
|
|
cancelReject() {
|
|
|
this.$refs.rejectRef.close()
|
|
this.$refs.rejectRef.close()
|
|
|
},
|
|
},
|
|
@@ -348,6 +490,56 @@ export default {
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 冲销单提示条:与 pagesOrder/refund.vue 的 warning-tip/forward-tip 保持一致的视觉语言
|
|
|
|
|
+.warning-tip {
|
|
|
|
|
+ background: #fff2f0;
|
|
|
|
|
+ border: 1upx solid #ffccc7;
|
|
|
|
|
+ border-radius: 12upx;
|
|
|
|
|
+ margin-bottom: 20upx;
|
|
|
|
|
+ padding: 20upx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+
|
|
|
|
|
+ .warning-icon {
|
|
|
|
|
+ font-size: 40upx;
|
|
|
|
|
+ color: #ff4757;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ line-height: 1;
|
|
|
|
|
+ min-width: 50upx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .warning-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .warning-text {
|
|
|
|
|
+ font-size: 28upx;
|
|
|
|
|
+ color: #ff4757;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .warning-amount {
|
|
|
|
|
+ margin-top: 8upx;
|
|
|
|
|
+ font-size: 24upx;
|
|
|
|
|
+ color: #ff4757;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.forward-tip {
|
|
|
|
|
+ background: rgba(51, 133, 255, 0.08);
|
|
|
|
|
+ border: 1upx solid rgba(51, 133, 255, 0.3);
|
|
|
|
|
+
|
|
|
|
|
+ .warning-icon,
|
|
|
|
|
+ .warning-text {
|
|
|
|
|
+ color: #3385ff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .warning-amount {
|
|
|
|
|
+ color: #3385ff;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.refund-card {
|
|
.refund-card {
|
|
|
background: #ffffff;
|
|
background: #ffffff;
|
|
|
border-radius: 16upx;
|
|
border-radius: 16upx;
|
|
@@ -437,6 +629,14 @@ export default {
|
|
|
&--cancel {
|
|
&--cancel {
|
|
|
color: #909399;
|
|
color: #909399;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ &--forward {
|
|
|
|
|
+ color: #3385ff;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.forward-remark {
|
|
|
|
|
+ color: #3385ff;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.refund-section {
|
|
.refund-section {
|