202507251746
This commit is contained in:
parent
8ae1dc51cf
commit
0a34deda55
|
|
@ -34,7 +34,7 @@ import com.ruoyi.common.core.page.TableDataInfo;
|
|||
|
||||
/**
|
||||
* 预支付Controller
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-07-11
|
||||
*/
|
||||
|
|
@ -119,23 +119,12 @@ public class UsersPayBeforController extends BaseController
|
|||
return toAjax(usersPayBeforService.deleteUsersPayBeforByIds(ids));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 根据订单ID查询预支付数据
|
||||
// */
|
||||
// @GetMapping("/getByOrderId/{orderId}")
|
||||
// public AjaxResult getByOrderId(@PathVariable("orderId") String orderId)
|
||||
// {
|
||||
// UsersPayBefor usersPayBefor = usersPayBeforService.selectUsersPayBeforByOrderId(orderId);
|
||||
// return success(usersPayBefor);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 根据订单ID查询预支付数据
|
||||
*/
|
||||
@GetMapping("/getByOrderId/{orderId}")
|
||||
public AjaxResult getByOrderId(@PathVariable("orderId") String orderId)
|
||||
{
|
||||
|
||||
GoodsOrder goodsOrder = new GoodsOrder();
|
||||
goodsOrder.setMainOrderId(orderId);
|
||||
List<GoodsOrder> orders = goodsOrderService.selectGoodsOrderList(goodsOrder);
|
||||
|
|
@ -148,9 +137,6 @@ public class UsersPayBeforController extends BaseController
|
|||
}else{
|
||||
return success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -221,16 +207,12 @@ public class UsersPayBeforController extends BaseController
|
|||
}
|
||||
orderLog.setContent(jsonObject.toJSONString());
|
||||
int flg=orderLogService.insertOrderLog(orderLog);
|
||||
// if (flg>0){
|
||||
//
|
||||
// }
|
||||
// OrderUtil orderUtil = new OrderUtil();
|
||||
// OrderUtil.refund(order, usersPayBefor);
|
||||
|
||||
// 验证退款金额不能超过支付金额
|
||||
BigDecimal currentReturnMoney = originalRecord.getReturnmoney() != null ? originalRecord.getReturnmoney() : BigDecimal.ZERO;
|
||||
BigDecimal totalRefund = currentReturnMoney.add(returnMoney);
|
||||
BigDecimal paymentAmount = originalRecord.getAllmoney() != null ? originalRecord.getAllmoney() : BigDecimal.ZERO;
|
||||
|
||||
|
||||
if (totalRefund.compareTo(paymentAmount) > 0) {
|
||||
return error("退款金额不能超过支付金额");
|
||||
}
|
||||
|
|
@ -238,7 +220,152 @@ public class UsersPayBeforController extends BaseController
|
|||
originalRecord.setStatus(3L);
|
||||
// 更新退款金额
|
||||
originalRecord.setReturnmoney(totalRefund);
|
||||
|
||||
|
||||
return toAjax(usersPayBeforService.updateUsersPayBefor(originalRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一退款方法 - 支持多次退款和部分退款
|
||||
*/
|
||||
@Log(title = "统一退款", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/unifiedRefund")
|
||||
public AjaxResult unifiedRefund(@RequestBody Map<String, Object> params)
|
||||
{
|
||||
try {
|
||||
String orderId = params.get("orderId") == null ? null : params.get("orderId").toString();
|
||||
BigDecimal wechatRefund = params.get("wechatRefund") == null ? BigDecimal.ZERO : new BigDecimal(params.get("wechatRefund").toString());
|
||||
BigDecimal balanceRefund = params.get("balanceRefund") == null ? BigDecimal.ZERO : new BigDecimal(params.get("balanceRefund").toString());
|
||||
BigDecimal shoppingGoldRefund = params.get("shoppingGoldRefund") == null ? BigDecimal.ZERO : new BigDecimal(params.get("shoppingGoldRefund").toString());
|
||||
BigDecimal serviceGoldRefund = params.get("serviceGoldRefund") == null ? BigDecimal.ZERO : new BigDecimal(params.get("serviceGoldRefund").toString());
|
||||
BigDecimal memberDiscountRefund = params.get("memberDiscountRefund") == null ? BigDecimal.ZERO : new BigDecimal(params.get("memberDiscountRefund").toString());
|
||||
BigDecimal couponRefund = params.get("couponRefund") == null ? BigDecimal.ZERO : new BigDecimal(params.get("couponRefund").toString());
|
||||
String refundRemark = params.get("refundRemark") == null ? "" : params.get("refundRemark").toString();
|
||||
|
||||
if (orderId == null || orderId.trim().isEmpty()) {
|
||||
return error("订单ID不能为空");
|
||||
}
|
||||
|
||||
BigDecimal totalRefund = wechatRefund.add(balanceRefund).add(shoppingGoldRefund)
|
||||
.add(serviceGoldRefund).add(memberDiscountRefund).add(couponRefund);
|
||||
|
||||
if (totalRefund.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return error("退款金额必须大于0");
|
||||
}
|
||||
|
||||
Order order = orderService.selectOrderByOrderId(orderId);
|
||||
if (order == null) {
|
||||
return error("订单不存在");
|
||||
}
|
||||
|
||||
List<UsersPayBefor> payRecords = usersPayBeforService.selectPayDetailsByOrderId(orderId);
|
||||
if (payRecords == null || payRecords.isEmpty()) {
|
||||
return error("未找到支付记录");
|
||||
}
|
||||
|
||||
// 计算已退款金额
|
||||
BigDecimal totalRefunded = BigDecimal.ZERO;
|
||||
for (UsersPayBefor record : payRecords) {
|
||||
if (record.getReturnmoney() != null) {
|
||||
totalRefunded = totalRefunded.add(record.getReturnmoney());
|
||||
}
|
||||
}
|
||||
|
||||
// 计算总支付金额
|
||||
BigDecimal totalPaid = BigDecimal.ZERO;
|
||||
for (UsersPayBefor record : payRecords) {
|
||||
if (record.getAllmoney() != null) {
|
||||
totalPaid = totalPaid.add(record.getAllmoney());
|
||||
}
|
||||
}
|
||||
|
||||
// 验证退款金额不能超过剩余可退款金额
|
||||
BigDecimal remainingRefundable = totalPaid.subtract(totalRefunded);
|
||||
if (totalRefund.compareTo(remainingRefundable) > 0) {
|
||||
return error("退款金额不能超过剩余可退款金额,剩余可退款:¥" + remainingRefundable);
|
||||
}
|
||||
|
||||
// 记录退款日志
|
||||
OrderLog orderLog = new OrderLog();
|
||||
orderLog.setOrderId(orderId);
|
||||
orderLog.setOid(order.getId());
|
||||
orderLog.setTitle("统一退款");
|
||||
orderLog.setType(new BigDecimal(11));
|
||||
|
||||
// 构建退款详情
|
||||
JSONObject refundDetails = new JSONObject();
|
||||
StringBuilder refundDesc = new StringBuilder("统一退款:");
|
||||
|
||||
if (wechatRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
refundDesc.append("微信支付退款¥").append(wechatRefund).append(",");
|
||||
}
|
||||
if (balanceRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
refundDesc.append("余额退款¥").append(balanceRefund).append(",");
|
||||
}
|
||||
if (shoppingGoldRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
refundDesc.append("购物金退款¥").append(shoppingGoldRefund).append(",");
|
||||
}
|
||||
if (serviceGoldRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
refundDesc.append("服务金退款¥").append(serviceGoldRefund).append(",");
|
||||
}
|
||||
if (memberDiscountRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
refundDesc.append("会员优惠退款¥").append(memberDiscountRefund).append(",");
|
||||
}
|
||||
if (couponRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
refundDesc.append("优惠券抵扣退款¥").append(couponRefund).append(",");
|
||||
}
|
||||
|
||||
if (refundDesc.charAt(refundDesc.length() - 1) == ',') {
|
||||
refundDesc.setLength(refundDesc.length() - 1);
|
||||
}
|
||||
|
||||
refundDesc.append(",本次退款金额:¥").append(totalRefund);
|
||||
refundDesc.append(",累计已退款:¥").append(totalRefunded.add(totalRefund));
|
||||
refundDesc.append(",剩余可退款:¥").append(remainingRefundable.subtract(totalRefund));
|
||||
|
||||
refundDetails.put("name", refundDesc.toString());
|
||||
refundDetails.put("wechatRefund", wechatRefund);
|
||||
refundDetails.put("balanceRefund", balanceRefund);
|
||||
refundDetails.put("shoppingGoldRefund", shoppingGoldRefund);
|
||||
refundDetails.put("serviceGoldRefund", serviceGoldRefund);
|
||||
refundDetails.put("memberDiscountRefund", memberDiscountRefund);
|
||||
refundDetails.put("couponRefund", couponRefund);
|
||||
refundDetails.put("totalRefund", totalRefund);
|
||||
refundDetails.put("totalRefunded", totalRefunded.add(totalRefund));
|
||||
refundDetails.put("remainingRefundable", remainingRefundable.subtract(totalRefund));
|
||||
refundDetails.put("refundRemark", refundRemark);
|
||||
refundDetails.put("refundTime", new java.util.Date());
|
||||
|
||||
orderLog.setContent(refundDetails.toJSONString());
|
||||
orderLogService.insertOrderLog(orderLog);
|
||||
|
||||
// 更新支付记录状态和退款金额
|
||||
for (UsersPayBefor record : payRecords) {
|
||||
BigDecimal currentRefunded = record.getReturnmoney() != null ? record.getReturnmoney() : BigDecimal.ZERO;
|
||||
BigDecimal newTotalRefunded = currentRefunded.add(totalRefund);
|
||||
|
||||
// 如果累计退款金额等于或超过支付金额,设置为已退款状态
|
||||
if (newTotalRefunded.compareTo(record.getAllmoney()) >= 0) {
|
||||
record.setStatus(3L); // 完全退款
|
||||
} else {
|
||||
record.setStatus(2L); // 部分退款
|
||||
}
|
||||
|
||||
record.setReturnmoney(newTotalRefunded);
|
||||
usersPayBeforService.updateUsersPayBefor(record);
|
||||
}
|
||||
|
||||
// 这里可以添加实际的退款逻辑
|
||||
// 1. 微信支付退款 - 调用微信退款API
|
||||
// 2. 余额退款 - 更新用户余额
|
||||
// 3. 购物金退款 - 更新购物金余额
|
||||
// 4. 服务金退款 - 更新服务金余额
|
||||
// 5. 会员优惠退款 - 更新会员积分或优惠
|
||||
// 6. 优惠券退款 - 恢复优惠券使用状态
|
||||
// return success("退款成功", refundDetails);
|
||||
return success("退款成功");
|
||||
|
||||
} catch (Exception e) {
|
||||
return error("退款失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 统一退款
|
||||
export function unifiedRefund(data) {
|
||||
return request({
|
||||
url: '/system/UsersPayBefor/unifiedRefund',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,426 @@
|
|||
<template>
|
||||
<el-dialog title="统一退款" :visible.sync="visible" width="900px" @close="handleClose">
|
||||
<div class="refund-container">
|
||||
<!-- 支付信息展示 -->
|
||||
<div class="payment-info" v-if="paymentData">
|
||||
<h4>支付信息</h4>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<label>微信支付:</label>
|
||||
<span class="amount">¥{{ paymentData.wechatAmount || '0.00' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<label>余额支付:</label>
|
||||
<span class="amount">¥{{ paymentData.balanceAmount || '0.00' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<label>购物金:</label>
|
||||
<span class="amount">¥{{ paymentData.shoppingGoldAmount || '0.00' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<label>服务金:</label>
|
||||
<span class="amount">¥{{ paymentData.serviceGoldAmount || '0.00' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<label>会员优惠:</label>
|
||||
<span class="amount">¥{{ paymentData.memberDiscountAmount || '0.00' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<label>优惠券抵扣:</label>
|
||||
<span class="amount">¥{{ paymentData.couponAmount || '0.00' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="total-amount">
|
||||
<label>总支付金额:</label>
|
||||
<span class="amount total">¥{{ totalPaymentAmount }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 退款历史信息 -->
|
||||
<div class="refund-history" v-if="refundHistory && refundHistory.length > 0">
|
||||
<h5>退款历史</h5>
|
||||
<div class="history-item" v-for="(item, index) in refundHistory" :key="index">
|
||||
<span class="history-time">{{ formatTime(item.refundTime) }}</span>
|
||||
<span class="history-amount">¥{{ item.totalRefund }}</span>
|
||||
<span class="history-desc">{{ item.name }}</span>
|
||||
</div>
|
||||
<div class="history-summary">
|
||||
<span>累计已退款:¥{{ totalRefundedAmount }}</span>
|
||||
<span class="remaining">剩余可退款:¥{{ remainingRefundableAmount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 退款金额输入 -->
|
||||
<div class="refund-input">
|
||||
<h4>本次退款金额</h4>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="微信退款:">
|
||||
<el-input
|
||||
v-model="refundForm.wechatRefund"
|
||||
type="number"
|
||||
placeholder="0.00"
|
||||
min="0"
|
||||
step="0.01"
|
||||
@input="calculateTotalRefund"
|
||||
:max="paymentData.wechatAmount || 0"
|
||||
>
|
||||
<template slot="prepend">¥</template>
|
||||
</el-input>
|
||||
<div class="input-tip">最大可退:¥{{ paymentData.wechatAmount || '0.00' }}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="余额退款:">
|
||||
<el-input
|
||||
v-model="refundForm.balanceRefund"
|
||||
type="number"
|
||||
placeholder="0.00"
|
||||
min="0"
|
||||
step="0.01"
|
||||
@input="calculateTotalRefund"
|
||||
:max="paymentData.balanceAmount || 0"
|
||||
>
|
||||
<template slot="prepend">¥</template>
|
||||
</el-input>
|
||||
<div class="input-tip">最大可退:¥{{ paymentData.balanceAmount || '0.00' }}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="购物金退款:">
|
||||
<el-input
|
||||
v-model="refundForm.shoppingGoldRefund"
|
||||
type="number"
|
||||
placeholder="0.00"
|
||||
min="0"
|
||||
step="0.01"
|
||||
@input="calculateTotalRefund"
|
||||
:max="paymentData.shoppingGoldAmount || 0"
|
||||
>
|
||||
<template slot="prepend">¥</template>
|
||||
</el-input>
|
||||
<div class="input-tip">最大可退:¥{{ paymentData.shoppingGoldAmount || '0.00' }}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="服务金退款:">
|
||||
<el-input
|
||||
v-model="refundForm.serviceGoldRefund"
|
||||
type="number"
|
||||
placeholder="0.00"
|
||||
min="0"
|
||||
step="0.01"
|
||||
@input="calculateTotalRefund"
|
||||
:max="paymentData.serviceGoldAmount || 0"
|
||||
>
|
||||
<template slot="prepend">¥</template>
|
||||
</el-input>
|
||||
<div class="input-tip">最大可退:¥{{ paymentData.serviceGoldAmount || '0.00' }}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="会员优惠退款:">
|
||||
<el-input
|
||||
v-model="refundForm.memberDiscountRefund"
|
||||
type="number"
|
||||
placeholder="0.00"
|
||||
min="0"
|
||||
step="0.01"
|
||||
@input="calculateTotalRefund"
|
||||
:max="paymentData.memberDiscountAmount || 0"
|
||||
>
|
||||
<template slot="prepend">¥</template>
|
||||
</el-input>
|
||||
<div class="input-tip">最大可退:¥{{ paymentData.memberDiscountAmount || '0.00' }}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="优惠券退款:">
|
||||
<el-input
|
||||
v-model="refundForm.couponRefund"
|
||||
type="number"
|
||||
placeholder="0.00"
|
||||
min="0"
|
||||
step="0.01"
|
||||
@input="calculateTotalRefund"
|
||||
:max="paymentData.couponAmount || 0"
|
||||
>
|
||||
<template slot="prepend">¥</template>
|
||||
</el-input>
|
||||
<div class="input-tip">最大可退:¥{{ paymentData.couponAmount || '0.00' }}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 总退款金额显示 -->
|
||||
<div class="total-refund">
|
||||
<label>本次退款金额:</label>
|
||||
<span class="amount refund">¥{{ totalRefundAmount }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 退款验证提示 -->
|
||||
<div class="refund-validation" v-if="totalRefundAmount > 0">
|
||||
<el-alert
|
||||
:title="validationMessage"
|
||||
:type="validationType"
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 退款备注 -->
|
||||
<div class="refund-remark">
|
||||
<el-form-item label="退款备注:">
|
||||
<el-input
|
||||
v-model="refundForm.refundRemark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入退款备注信息"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm" :loading="loading" :disabled="!canRefund">确认退款</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { unifiedRefund } from "@/api/system/UsersPayBefor"
|
||||
|
||||
export default {
|
||||
name: "UnifiedRefundDialog",
|
||||
props: {
|
||||
visible: { type: Boolean, default: false },
|
||||
orderId: { type: String, default: "" },
|
||||
paymentData: { type: Object, default: () => ({}) }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
refundForm: {
|
||||
wechatRefund: "",
|
||||
balanceRefund: "",
|
||||
shoppingGoldRefund: "",
|
||||
serviceGoldRefund: "",
|
||||
memberDiscountRefund: "",
|
||||
couponRefund: "",
|
||||
refundRemark: ""
|
||||
},
|
||||
totalRefundAmount: "0.00",
|
||||
refundHistory: [], // 退款历史
|
||||
totalRefundedAmount: "0.00", // 累计已退款
|
||||
remainingRefundableAmount: "0.00" // 剩余可退款
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalPaymentAmount() {
|
||||
if (!this.paymentData) return "0.00";
|
||||
const total = (this.paymentData.wechatAmount || 0) + (this.paymentData.balanceAmount || 0) +
|
||||
(this.paymentData.shoppingGoldAmount || 0) + (this.paymentData.serviceGoldAmount || 0) +
|
||||
(this.paymentData.memberDiscountAmount || 0) + (this.paymentData.couponAmount || 0);
|
||||
return total.toFixed(2);
|
||||
},
|
||||
|
||||
canRefund() {
|
||||
return parseFloat(this.totalRefundAmount) > 0 && parseFloat(this.totalRefundAmount) <= parseFloat(this.remainingRefundableAmount);
|
||||
},
|
||||
|
||||
validationMessage() {
|
||||
const totalRefund = parseFloat(this.totalRefundAmount);
|
||||
const remaining = parseFloat(this.remainingRefundableAmount);
|
||||
|
||||
if (totalRefund > remaining) {
|
||||
return `退款金额超过剩余可退款金额,最多可退:¥${this.remainingRefundableAmount}`;
|
||||
} else if (totalRefund > 0) {
|
||||
return `退款后将剩余可退款:¥${(remaining - totalRefund).toFixed(2)}`;
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
validationType() {
|
||||
const totalRefund = parseFloat(this.totalRefundAmount);
|
||||
const remaining = parseFloat(this.remainingRefundableAmount);
|
||||
return totalRefund > remaining ? "error" : "success";
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(newVal) {
|
||||
if (newVal) {
|
||||
this.initForm();
|
||||
this.loadRefundHistory();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initForm() {
|
||||
// 初始化表单,设置最大退款金额
|
||||
this.refundForm.wechatRefund = "";
|
||||
this.refundForm.balanceRefund = "";
|
||||
this.refundForm.shoppingGoldRefund = "";
|
||||
this.refundForm.serviceGoldRefund = "";
|
||||
this.refundForm.memberDiscountRefund = "";
|
||||
this.refundForm.couponRefund = "";
|
||||
this.refundForm.refundRemark = "";
|
||||
this.calculateTotalRefund();
|
||||
},
|
||||
|
||||
async loadRefundHistory() {
|
||||
try {
|
||||
// 这里可以调用API获取退款历史
|
||||
// const response = await getRefundHistory(this.orderId);
|
||||
// this.refundHistory = response.data || [];
|
||||
|
||||
// 模拟数据,实际应该从API获取
|
||||
this.refundHistory = [];
|
||||
this.totalRefundedAmount = "0.00";
|
||||
this.remainingRefundableAmount = this.totalPaymentAmount;
|
||||
} catch (error) {
|
||||
console.error('获取退款历史失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
calculateTotalRefund() {
|
||||
const total = (parseFloat(this.refundForm.wechatRefund) || 0) + (parseFloat(this.refundForm.balanceRefund) || 0) +
|
||||
(parseFloat(this.refundForm.shoppingGoldRefund) || 0) + (parseFloat(this.refundForm.serviceGoldRefund) || 0) +
|
||||
(parseFloat(this.refundForm.memberDiscountRefund) || 0) + (parseFloat(this.refundForm.couponRefund) || 0);
|
||||
this.totalRefundAmount = total.toFixed(2);
|
||||
},
|
||||
|
||||
validateRefundAmount() {
|
||||
const totalRefund = parseFloat(this.totalRefundAmount);
|
||||
const remaining = parseFloat(this.remainingRefundableAmount);
|
||||
|
||||
if (totalRefund <= 0) {
|
||||
this.$message.error("退款金额必须大于0");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (totalRefund > remaining) {
|
||||
this.$message.error(`退款金额不能超过剩余可退款金额,最多可退:¥${this.remainingRefundableAmount}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
async handleConfirm() {
|
||||
if (!this.validateRefundAmount()) return;
|
||||
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
const params = {
|
||||
orderId: this.orderId,
|
||||
wechatRefund: this.refundForm.wechatRefund || "0",
|
||||
balanceRefund: this.refundForm.balanceRefund || "0",
|
||||
shoppingGoldRefund: this.refundForm.shoppingGoldRefund || "0",
|
||||
serviceGoldRefund: this.refundForm.serviceGoldRefund || "0",
|
||||
memberDiscountRefund: this.refundForm.memberDiscountRefund || "0",
|
||||
couponRefund: this.refundForm.couponRefund || "0",
|
||||
refundRemark: this.refundForm.refundRemark
|
||||
};
|
||||
|
||||
const response = await unifiedRefund(params);
|
||||
|
||||
if (response.code === 200) {
|
||||
this.$message.success("退款成功");
|
||||
this.$emit("success", response.data);
|
||||
this.handleClose();
|
||||
} else {
|
||||
this.$message.error(response.msg || "退款失败");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("退款失败:", error);
|
||||
this.$message.error("退款失败,请重试");
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
handleClose() {
|
||||
this.$emit("update:visible", false);
|
||||
this.resetForm();
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
this.refundForm = {
|
||||
wechatRefund: "",
|
||||
balanceRefund: "",
|
||||
shoppingGoldRefund: "",
|
||||
serviceGoldRefund: "",
|
||||
memberDiscountRefund: "",
|
||||
couponRefund: "",
|
||||
refundRemark: ""
|
||||
};
|
||||
this.totalRefundAmount = "0.00";
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
formatTime(timeStr) {
|
||||
if (!timeStr) return '';
|
||||
const date = new Date(timeStr);
|
||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.refund-container { padding: 20px 0; }
|
||||
.payment-info { background-color: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px; border: 1px solid #e9ecef; }
|
||||
.payment-info h4 { margin: 0 0 15px 0; color: #303133; font-size: 16px; font-weight: 600; }
|
||||
.info-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; padding: 8px 0; }
|
||||
.info-item label { font-weight: 500; color: #606266; min-width: 80px; }
|
||||
.amount { font-weight: 600; color: #E6A23C; }
|
||||
.amount.total { font-size: 18px; color: #409EFF; }
|
||||
.total-amount { text-align: center; margin-top: 15px; padding-top: 15px; border-top: 1px solid #e9ecef; }
|
||||
.total-amount label { font-weight: 600; color: #303133; margin-right: 10px; }
|
||||
|
||||
/* 退款历史样式 */
|
||||
.refund-history { margin-top: 20px; padding-top: 20px; border-top: 1px solid #e9ecef; }
|
||||
.refund-history h5 { margin: 0 0 15px 0; color: #303133; font-size: 14px; font-weight: 600; }
|
||||
.history-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 5px 0; font-size: 12px; }
|
||||
.history-time { color: #909399; min-width: 120px; }
|
||||
.history-amount { color: #F56C6C; font-weight: 600; min-width: 80px; text-align: right; }
|
||||
.history-desc { color: #606266; flex: 1; margin-left: 10px; }
|
||||
.history-summary { display: flex; justify-content: space-between; margin-top: 10px; padding-top: 10px; border-top: 1px solid #e9ecef; font-weight: 600; }
|
||||
.remaining { color: #409EFF; }
|
||||
|
||||
.refund-input { background-color: #fff; padding: 20px; border-radius: 8px; border: 1px solid #e9ecef; margin-bottom: 20px; }
|
||||
.refund-input h4 { margin: 0 0 15px 0; color: #303133; font-size: 16px; font-weight: 600; }
|
||||
.total-refund { text-align: center; margin-top: 20px; padding-top: 20px; border-top: 1px solid #e9ecef; }
|
||||
.total-refund label { font-weight: 600; color: #303133; margin-right: 10px; }
|
||||
.amount.refund { font-size: 20px; color: #F56C6C; font-weight: bold; }
|
||||
|
||||
.input-tip { font-size: 11px; color: #909399; margin-top: 2px; }
|
||||
|
||||
.refund-validation { margin-top: 15px; }
|
||||
|
||||
.refund-remark { background-color: #fff; padding: 20px; border-radius: 8px; border: 1px solid #e9ecef; }
|
||||
.dialog-footer { text-align: right; }
|
||||
.el-form-item { margin-bottom: 15px; }
|
||||
.el-input-group__prepend { background-color: #f5f7fa; color: #909399; font-weight: 500; }
|
||||
</style>
|
||||
|
|
@ -277,6 +277,16 @@
|
|||
style="color: #E6A23C;"
|
||||
>售后</el-button>
|
||||
|
||||
<!-- 统一退款按钮 -->
|
||||
<el-button
|
||||
v-if="scope.row.status >= 15"
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-money"
|
||||
@click="handleUnifiedRefund(scope.row)"
|
||||
style="color: #67C23A;"
|
||||
>统一退款</el-button>
|
||||
|
||||
<!-- 如果是主行,显示查看详情按钮 -->
|
||||
<el-button
|
||||
|
||||
|
|
@ -398,6 +408,14 @@
|
|||
:prePaymentData="prePaymentData"
|
||||
@close="handlePrePaymentClose"
|
||||
/>
|
||||
|
||||
<!-- 统一退款对话框 -->
|
||||
<UnifiedRefundDialog
|
||||
:visible.sync="unifiedRefundDialogVisible"
|
||||
:orderId="currentRefundOrder ? currentRefundOrder.orderId : ''"
|
||||
:paymentData="currentRefundPaymentData"
|
||||
@success="handleRefundSuccess"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
|
@ -420,7 +438,8 @@ export default {
|
|||
ShipmentDialog: () => import('./ShipmentDialog.vue'),
|
||||
ExcelImportDialog: () => import('./ExcelImportDialog.vue'),
|
||||
ImportResultDialog: () => import('./ImportResultDialog.vue'),
|
||||
PrePaymentDialog: () => import('./PrePaymentDialog.vue')
|
||||
PrePaymentDialog: () => import('./PrePaymentDialog.vue'),
|
||||
UnifiedRefundDialog: () => import('./UnifiedRefundDialog.vue')
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -599,7 +618,12 @@ export default {
|
|||
shipMode: 'single',
|
||||
currentShipOrder: null,
|
||||
shipLoading: false,
|
||||
shipmentOrders: []
|
||||
shipmentOrders: [],
|
||||
|
||||
// 统一退款对话框相关
|
||||
unifiedRefundDialogVisible: false,
|
||||
currentRefundOrder: null,
|
||||
currentRefundPaymentData: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
@ -617,6 +641,9 @@ export default {
|
|||
this.excelImportDialogVisible = false;
|
||||
this.importResultVisible = false;
|
||||
this.detailDialogVisible = false;
|
||||
this.unifiedRefundDialogVisible = false;
|
||||
this.currentRefundOrder = null;
|
||||
this.currentRefundPaymentData = null;
|
||||
},
|
||||
mounted() {
|
||||
// 简化mounted钩子
|
||||
|
|
@ -765,6 +792,9 @@ export default {
|
|||
this.excelImportDialogVisible = false;
|
||||
this.importResultVisible = false;
|
||||
this.detailDialogVisible = false;
|
||||
this.unifiedRefundDialogVisible = false;
|
||||
this.currentRefundOrder = null;
|
||||
this.currentRefundPaymentData = null;
|
||||
|
||||
// 使用nextTick确保弹窗完全关闭后再重置数据
|
||||
this.$nextTick(() => {
|
||||
|
|
@ -1275,6 +1305,35 @@ export default {
|
|||
this.$nextTick(() => {
|
||||
this.prePaymentData = null;
|
||||
});
|
||||
},
|
||||
|
||||
/** 统一退款对话框关闭 */
|
||||
handleUnifiedRefundClose() {
|
||||
this.unifiedRefundDialogVisible = false;
|
||||
this.currentRefundOrder = null;
|
||||
this.currentRefundPaymentData = null;
|
||||
},
|
||||
|
||||
/** 处理统一退款成功 */
|
||||
handleRefundSuccess() {
|
||||
this.unifiedRefundDialogVisible = false;
|
||||
this.currentRefundOrder = null;
|
||||
this.currentRefundPaymentData = null;
|
||||
this.getList(); // 刷新列表
|
||||
},
|
||||
|
||||
/** 统一退款按钮操作 */
|
||||
handleUnifiedRefund(row) {
|
||||
this.currentRefundOrder = row;
|
||||
this.currentRefundPaymentData = {
|
||||
wechatAmount: row.payPrice || 0,
|
||||
balanceAmount: 0,
|
||||
shoppingGoldAmount: 0,
|
||||
serviceGoldAmount: 0,
|
||||
memberDiscountAmount: 0,
|
||||
couponAmount: 0
|
||||
};
|
||||
this.unifiedRefundDialogVisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue