|
@@ -2,6 +2,7 @@
|
|
|
商城订单申请售后页
|
|
商城订单申请售后页
|
|
|
供订单详情「申请售后」进入;顾客勾选商品/金额后提交待审核申请,商家在 hdApp 审核
|
|
供订单详情「申请售后」进入;顾客勾选商品/金额后提交待审核申请,商家在 hdApp 审核
|
|
|
撤销后仍可重新申请:把已取消记录改回待审核
|
|
撤销后仍可重新申请:把已取消记录改回待审核
|
|
|
|
|
+ 退货并退款金额:普通商品按勾选原价分摊会员折/满减;秒杀、团购按活动单价退,不再叠整单优惠
|
|
|
-->
|
|
-->
|
|
|
<template>
|
|
<template>
|
|
|
<view class="refund-page">
|
|
<view class="refund-page">
|
|
@@ -92,6 +93,7 @@
|
|
|
<text class="product-name-compact">{{ res.name }}</text>
|
|
<text class="product-name-compact">{{ res.name }}</text>
|
|
|
<view class="product-meta">
|
|
<view class="product-meta">
|
|
|
<text class="stock-info">{{ parseFloat(res.num) }}份 × ¥{{ parseFloat(res.unitPrice) }}</text>
|
|
<text class="stock-info">{{ parseFloat(res.num) }}份 × ¥{{ parseFloat(res.unitPrice) }}</text>
|
|
|
|
|
+ <text class="activity-info" v-if="goodsActivityLabel(res)">{{ goodsActivityLabel(res) }}</text>
|
|
|
<text class="available-info">可退 {{ getRemainNum(res) }}份</text>
|
|
<text class="available-info">可退 {{ getRemainNum(res) }}份</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -117,6 +119,7 @@
|
|
|
<text class="product-name-compact">{{ res.name }}</text>
|
|
<text class="product-name-compact">{{ res.name }}</text>
|
|
|
<view class="product-meta">
|
|
<view class="product-meta">
|
|
|
<text class="stock-info">{{ parseFloat(res.num) }}{{ res.unitName || '份' }} × ¥{{ parseFloat(res.unitPrice) }}</text>
|
|
<text class="stock-info">{{ parseFloat(res.num) }}{{ res.unitName || '份' }} × ¥{{ parseFloat(res.unitPrice) }}</text>
|
|
|
|
|
+ <text class="activity-info" v-if="goodsActivityLabel(res)">{{ goodsActivityLabel(res) }}</text>
|
|
|
<text class="available-info">可退 {{ getRemainNum(res) }}{{ res.unitName || '份' }}</text>
|
|
<text class="available-info">可退 {{ getRemainNum(res) }}{{ res.unitName || '份' }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -160,6 +163,14 @@
|
|
|
<text class="amount-label">可退金额</text>
|
|
<text class="amount-label">可退金额</text>
|
|
|
<text class="amount-value available">¥{{ couldRefundPrice }}</text>
|
|
<text class="amount-value available">¥{{ couldRefundPrice }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+ <view class="amount-row" v-if="hasDiscountAmount">
|
|
|
|
|
+ <text class="amount-label">优惠金额</text>
|
|
|
|
|
+ <text class="amount-value">¥{{ parseFloat(orderInfo.discountAmount) || 0 }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="amount-row" v-if="hasMeetCut">
|
|
|
|
|
+ <text class="amount-label">订单满减</text>
|
|
|
|
|
+ <text class="amount-value">¥{{ parseFloat(orderInfo.orderReachDiscountPrice) || 0 }}</text>
|
|
|
|
|
+ </view>
|
|
|
<view class="amount-row" v-if="hasHbAmount">
|
|
<view class="amount-row" v-if="hasHbAmount">
|
|
|
<text class="amount-label">红包减免</text>
|
|
<text class="amount-label">红包减免</text>
|
|
|
<text class="amount-value">¥{{ parseFloat(orderInfo.hbAmount) || 0 }}</text>
|
|
<text class="amount-value">¥{{ parseFloat(orderInfo.hbAmount) || 0 }}</text>
|
|
@@ -168,7 +179,7 @@
|
|
|
<text class="amount-label required">退款金额</text>
|
|
<text class="amount-label required">退款金额</text>
|
|
|
<text class="amount-value refund-money">¥{{ refundMoney }}</text>
|
|
<text class="amount-value refund-money">¥{{ refundMoney }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="amount-hint" v-if="refundType == 1">按勾选数量自动计算,不可修改</view>
|
|
|
|
|
|
|
+ <view class="amount-hint" v-if="refundType == 1">秒杀/团购按活动价,其余已计入优惠与满减,不可修改</view>
|
|
|
<view class="amount-hint" v-else>仅退款默认按可退金额申请,全额退清后未过期红包将自动退回</view>
|
|
<view class="amount-hint" v-else>仅退款默认按可退金额申请,全额退清后未过期红包将自动退回</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -243,27 +254,38 @@ export default {
|
|
|
hasHbAmount() {
|
|
hasHbAmount() {
|
|
|
return this.orderInfo.hbAmount && Number(this.orderInfo.hbAmount) > 0
|
|
return this.orderInfo.hbAmount && Number(this.orderInfo.hbAmount) > 0
|
|
|
},
|
|
},
|
|
|
|
|
+ /** 是否展示优惠金额(会员折等整单优惠) */
|
|
|
|
|
+ hasDiscountAmount() {
|
|
|
|
|
+ return Number(this.orderInfo.discountAmount) > 0
|
|
|
|
|
+ },
|
|
|
|
|
+ /** 是否展示订单满减 */
|
|
|
|
|
+ hasMeetCut() {
|
|
|
|
|
+ return Number(this.orderInfo.orderReachDiscountPrice) > 0
|
|
|
|
|
+ },
|
|
|
|
|
+ /** 整单拼团:下单已跳过会员折/满减,商品按团购价退 */
|
|
|
|
|
+ isGroupBuyOrder() {
|
|
|
|
|
+ return Number(this.orderInfo.groupBuyId) > 0
|
|
|
|
|
+ },
|
|
|
/**
|
|
/**
|
|
|
- * 退款金额:退货并退款按勾选数量×单价;仅退款用可退金额
|
|
|
|
|
|
|
+ * 退款金额:仅退款用可退金额;退货并退款时秒杀/团购按活动价,其余分摊整单优惠
|
|
|
*/
|
|
*/
|
|
|
refundMoney() {
|
|
refundMoney() {
|
|
|
if (this.refundType == 2) {
|
|
if (this.refundType == 2) {
|
|
|
return this.couldRefundPrice
|
|
return this.couldRefundPrice
|
|
|
}
|
|
}
|
|
|
- let price = 0
|
|
|
|
|
- ;(this.goodsInfoList || []).forEach(item => {
|
|
|
|
|
- const count = Number(item.refundCount) || 0
|
|
|
|
|
- if (count > 0) {
|
|
|
|
|
- price += count * Number(item.unitPrice || 0)
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- ;(this.itemInfoList || []).forEach(item => {
|
|
|
|
|
- const count = Number(item.refundCount) || 0
|
|
|
|
|
- if (count > 0) {
|
|
|
|
|
- price += count * Number(item.unitPrice || 0)
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- return parseFloat(price.toFixed(2))
|
|
|
|
|
|
|
+ const parts = this.sumSelectedPriceParts()
|
|
|
|
|
+ const activityMoney = Number(parts.activity) || 0
|
|
|
|
|
+ const normalMoney = this.applyOrderDiscounts(Number(parts.normal) || 0)
|
|
|
|
|
+ const money = activityMoney + normalMoney
|
|
|
|
|
+ if (!(money > 0)) {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ const could = Number(this.couldRefundPrice) || 0
|
|
|
|
|
+ const capped = money > could ? could : money
|
|
|
|
|
+ if (!(capped > 0)) {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ return parseFloat(capped.toFixed(2))
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
@@ -275,6 +297,124 @@ export default {
|
|
|
getRemainNum(res) {
|
|
getRemainNum(res) {
|
|
|
return Number(res.num) - Number(res.refundNum || 0)
|
|
return Number(res.num) - Number(res.refundNum || 0)
|
|
|
},
|
|
},
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 商品活动标签:秒杀行 / 整单拼团。给模板展示,避免复杂表达式
|
|
|
|
|
+ * @param {object} res 订单商品或花材行
|
|
|
|
|
+ * @returns {string} 秒杀|团购|空
|
|
|
|
|
+ */
|
|
|
|
|
+ goodsActivityLabel(res) {
|
|
|
|
|
+ if (this.isGroupBuyOrder) {
|
|
|
|
|
+ return '团购'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (res && Number(res.seckillGoodsId) > 0) {
|
|
|
|
|
+ return '秒杀'
|
|
|
|
|
+ }
|
|
|
|
|
+ return ''
|
|
|
|
|
+ },
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 是否按活动价退、不摊会员折/满减:拼团整单,或花束行 seckillGoodsId>0
|
|
|
|
|
+ * @param {object} item 订单行
|
|
|
|
|
+ */
|
|
|
|
|
+ isActivityLine(item) {
|
|
|
|
|
+ if (this.isGroupBuyOrder) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ return Number(item && item.seckillGoodsId) > 0
|
|
|
|
|
+ },
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 勾选退货拆成活动价合计与普通原价合计
|
|
|
|
|
+ * 秒杀/团购按行上的活动单价;普通商品再去分摊整单优惠
|
|
|
|
|
+ */
|
|
|
|
|
+ sumSelectedPriceParts() {
|
|
|
|
|
+ let activity = 0
|
|
|
|
|
+ let normal = 0
|
|
|
|
|
+ const addList = list => {
|
|
|
|
|
+ ;(list || []).forEach(item => {
|
|
|
|
|
+ const count = Number(item.refundCount) || 0
|
|
|
|
|
+ if (!(count > 0)) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const line = count * Number(item.unitPrice || 0)
|
|
|
|
|
+ if (this.isActivityLine(item)) {
|
|
|
|
|
+ activity += line
|
|
|
|
|
+ } else {
|
|
|
|
|
+ normal += line
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ addList(this.goodsInfoList)
|
|
|
|
|
+ addList(this.itemInfoList)
|
|
|
|
|
+ return {
|
|
|
|
|
+ activity: parseFloat(activity.toFixed(2)),
|
|
|
|
|
+ normal: parseFloat(normal.toFixed(2))
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 整单里秒杀/团购商品原价合计,用来从优惠分摊基数里剔除
|
|
|
|
|
+ * 下单时会员折/满减本来就不打在这些活动价上
|
|
|
|
|
+ */
|
|
|
|
|
+ sumOrderActivityOriginal() {
|
|
|
|
|
+ if (this.isGroupBuyOrder) {
|
|
|
|
|
+ return Number(this.orderInfo.goodsPrice) || 0
|
|
|
|
|
+ }
|
|
|
|
|
+ let price = 0
|
|
|
|
|
+ ;(this.goodsInfoList || []).forEach(item => {
|
|
|
|
|
+ if (Number(item.seckillGoodsId) > 0) {
|
|
|
|
|
+ price += Number(item.num || 0) * Number(item.unitPrice || 0)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ return parseFloat(price.toFixed(2))
|
|
|
|
|
+ },
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 整单优惠分摊基数:会员折/满减按「商品+运费包装-红包」后的应付计算,
|
|
|
|
|
+ * prePrice 已扣红包,这里加回红包得到扣优惠前的应付,与下单口径一致
|
|
|
|
|
+ */
|
|
|
|
|
+ getDiscountAllocBase() {
|
|
|
|
|
+ const info = this.orderInfo || {}
|
|
|
|
|
+ const hb = Number(info.hbAmount) || 0
|
|
|
|
|
+ const pre = Number(info.prePrice) || 0
|
|
|
|
|
+ if (pre > 0) {
|
|
|
|
|
+ return parseFloat((pre + hb).toFixed(2))
|
|
|
|
|
+ }
|
|
|
|
|
+ const goods = Number(info.goodsPrice) || 0
|
|
|
|
|
+ const send = Number(info.sendCost) || 0
|
|
|
|
|
+ const pack = Number(info.packingFee) || 0
|
|
|
|
|
+ const labour = Number(info.labourCost) || 0
|
|
|
|
|
+ const service = Number(info.serviceFee) || 0
|
|
|
|
|
+ const base = goods + send + pack + labour + service
|
|
|
|
|
+ return parseFloat(base.toFixed(2))
|
|
|
|
|
+ },
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 只对普通商品勾选原价分摊会员折、满减、红包
|
|
|
|
|
+ * 秒杀已按活动价成交,红包/会员折打在非秒杀应付上,故从分摊基数剔除活动商品原价
|
|
|
|
|
+ * @param {number} original 普通商品勾选原价合计
|
|
|
|
|
+ * @returns {number} 扣除整单优惠后的应退金额
|
|
|
|
|
+ */
|
|
|
|
|
+ applyOrderDiscounts(original) {
|
|
|
|
|
+ if (!(original > 0)) {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ const info = this.orderInfo || {}
|
|
|
|
|
+ const discountAmount = Number(info.discountAmount) || 0
|
|
|
|
|
+ const meetCut = Number(info.orderReachDiscountPrice) || 0
|
|
|
|
|
+ const hbAmount = Number(info.hbAmount) || 0
|
|
|
|
|
+ const discountTotal = discountAmount + meetCut + hbAmount
|
|
|
|
|
+ const allocBase = this.getDiscountAllocBase()
|
|
|
|
|
+ const activityOriginal = this.sumOrderActivityOriginal()
|
|
|
|
|
+ let normalBase = allocBase - activityOriginal
|
|
|
|
|
+ if (!(normalBase > 0)) {
|
|
|
|
|
+ normalBase = 0
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!(discountTotal > 0) || !(normalBase > 0)) {
|
|
|
|
|
+ return parseFloat(original.toFixed(2))
|
|
|
|
|
+ }
|
|
|
|
|
+ const deduct = original * discountTotal / normalBase
|
|
|
|
|
+ const money = original - deduct
|
|
|
|
|
+ if (!(money > 0)) {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ return parseFloat(money.toFixed(2))
|
|
|
|
|
+ },
|
|
|
/**
|
|
/**
|
|
|
* 成品退货数量输入
|
|
* 成品退货数量输入
|
|
|
* 不用 v-model 绑 v-for 项,避免 key 表达式写入 data-event-opts
|
|
* 不用 v-model 绑 v-for 项,避免 key 表达式写入 data-event-opts
|
|
@@ -371,7 +511,8 @@ export default {
|
|
|
unitType: ele.unitType || 0,
|
|
unitType: ele.unitType || 0,
|
|
|
unitName: ele.unitName || '份',
|
|
unitName: ele.unitName || '份',
|
|
|
unitPrice: ele.unitPrice,
|
|
unitPrice: ele.unitPrice,
|
|
|
- property: 0
|
|
|
|
|
|
|
+ property: 0,
|
|
|
|
|
+ seckillGoodsId: Number(ele.seckillGoodsId) || 0
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
@@ -586,6 +727,14 @@ export default {
|
|
|
border-radius: 4upx;
|
|
border-radius: 4upx;
|
|
|
margin-right: 12upx;
|
|
margin-right: 12upx;
|
|
|
}
|
|
}
|
|
|
|
|
+ .activity-info {
|
|
|
|
|
+ font-size: 24upx;
|
|
|
|
|
+ color: $mainColor;
|
|
|
|
|
+ background: rgba(255, 40, 66, 0.08);
|
|
|
|
|
+ padding: 4upx 8upx;
|
|
|
|
|
+ border-radius: 4upx;
|
|
|
|
|
+ margin-right: 12upx;
|
|
|
|
|
+ }
|
|
|
.available-info {
|
|
.available-info {
|
|
|
font-size: 24upx;
|
|
font-size: 24upx;
|
|
|
color: $mainColor;
|
|
color: $mainColor;
|