Compare commits
No commits in common. "078e4f07d05bf6efec4d009a35cc2bbec005ee2c" and "8ae1dc51cfc4903400e68311b37bfccf82d4f15c" have entirely different histories.
078e4f07d0
...
8ae1dc51cf
|
|
@ -119,12 +119,23 @@ public class UsersPayBeforController extends BaseController
|
||||||
return toAjax(usersPayBeforService.deleteUsersPayBeforByIds(ids));
|
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查询预支付数据
|
* 根据订单ID查询预支付数据
|
||||||
*/
|
*/
|
||||||
@GetMapping("/getByOrderId/{orderId}")
|
@GetMapping("/getByOrderId/{orderId}")
|
||||||
public AjaxResult getByOrderId(@PathVariable("orderId") String orderId)
|
public AjaxResult getByOrderId(@PathVariable("orderId") String orderId)
|
||||||
{
|
{
|
||||||
|
|
||||||
GoodsOrder goodsOrder = new GoodsOrder();
|
GoodsOrder goodsOrder = new GoodsOrder();
|
||||||
goodsOrder.setMainOrderId(orderId);
|
goodsOrder.setMainOrderId(orderId);
|
||||||
List<GoodsOrder> orders = goodsOrderService.selectGoodsOrderList(goodsOrder);
|
List<GoodsOrder> orders = goodsOrderService.selectGoodsOrderList(goodsOrder);
|
||||||
|
|
@ -137,6 +148,9 @@ public class UsersPayBeforController extends BaseController
|
||||||
}else{
|
}else{
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -207,7 +221,11 @@ public class UsersPayBeforController extends BaseController
|
||||||
}
|
}
|
||||||
orderLog.setContent(jsonObject.toJSONString());
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
int flg=orderLogService.insertOrderLog(orderLog);
|
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 currentReturnMoney = originalRecord.getReturnmoney() != null ? originalRecord.getReturnmoney() : BigDecimal.ZERO;
|
||||||
BigDecimal totalRefund = currentReturnMoney.add(returnMoney);
|
BigDecimal totalRefund = currentReturnMoney.add(returnMoney);
|
||||||
|
|
@ -223,149 +241,4 @@ public class UsersPayBeforController extends BaseController
|
||||||
|
|
||||||
return toAjax(usersPayBeforService.updateUsersPayBefor(originalRecord));
|
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 统一退款
|
|
||||||
export function unifiedRefund(data) {
|
|
||||||
return request({
|
|
||||||
url: '/system/UsersPayBefor/unifiedRefund',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,422 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-dialog title="统一退款" :visible.sync="visible" width="900px" @close="handleClose">
|
|
||||||
<el-form ref="refundForm" :model="refundForm" label-width="100px">
|
|
||||||
<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"
|
|
||||||
>
|
|
||||||
<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"
|
|
||||||
>
|
|
||||||
<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"
|
|
||||||
>
|
|
||||||
<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"
|
|
||||||
>
|
|
||||||
<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"
|
|
||||||
>
|
|
||||||
<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"
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<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,16 +277,6 @@
|
||||||
style="color: #E6A23C;"
|
style="color: #E6A23C;"
|
||||||
>售后</el-button>
|
>售后</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
|
<el-button
|
||||||
|
|
||||||
|
|
@ -409,14 +399,6 @@
|
||||||
@close="handlePrePaymentClose"
|
@close="handlePrePaymentClose"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 统一退款对话框 -->
|
|
||||||
<UnifiedRefundDialog
|
|
||||||
:visible.sync="unifiedRefundDialogVisible"
|
|
||||||
:orderId="currentRefundOrder ? currentRefundOrder.orderId : ''"
|
|
||||||
:paymentData="currentRefundPaymentData"
|
|
||||||
@success="handleRefundSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -438,8 +420,7 @@ export default {
|
||||||
ShipmentDialog: () => import('./ShipmentDialog.vue'),
|
ShipmentDialog: () => import('./ShipmentDialog.vue'),
|
||||||
ExcelImportDialog: () => import('./ExcelImportDialog.vue'),
|
ExcelImportDialog: () => import('./ExcelImportDialog.vue'),
|
||||||
ImportResultDialog: () => import('./ImportResultDialog.vue'),
|
ImportResultDialog: () => import('./ImportResultDialog.vue'),
|
||||||
PrePaymentDialog: () => import('./PrePaymentDialog.vue'),
|
PrePaymentDialog: () => import('./PrePaymentDialog.vue')
|
||||||
UnifiedRefundDialog: () => import('./UnifiedRefundDialog.vue')
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -618,12 +599,7 @@ export default {
|
||||||
shipMode: 'single',
|
shipMode: 'single',
|
||||||
currentShipOrder: null,
|
currentShipOrder: null,
|
||||||
shipLoading: false,
|
shipLoading: false,
|
||||||
shipmentOrders: [],
|
shipmentOrders: []
|
||||||
|
|
||||||
// 统一退款对话框相关
|
|
||||||
unifiedRefundDialogVisible: false,
|
|
||||||
currentRefundOrder: null,
|
|
||||||
currentRefundPaymentData: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|
@ -641,9 +617,6 @@ export default {
|
||||||
this.excelImportDialogVisible = false;
|
this.excelImportDialogVisible = false;
|
||||||
this.importResultVisible = false;
|
this.importResultVisible = false;
|
||||||
this.detailDialogVisible = false;
|
this.detailDialogVisible = false;
|
||||||
this.unifiedRefundDialogVisible = false;
|
|
||||||
this.currentRefundOrder = null;
|
|
||||||
this.currentRefundPaymentData = null;
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 简化mounted钩子
|
// 简化mounted钩子
|
||||||
|
|
@ -792,9 +765,6 @@ export default {
|
||||||
this.excelImportDialogVisible = false;
|
this.excelImportDialogVisible = false;
|
||||||
this.importResultVisible = false;
|
this.importResultVisible = false;
|
||||||
this.detailDialogVisible = false;
|
this.detailDialogVisible = false;
|
||||||
this.unifiedRefundDialogVisible = false;
|
|
||||||
this.currentRefundOrder = null;
|
|
||||||
this.currentRefundPaymentData = null;
|
|
||||||
|
|
||||||
// 使用nextTick确保弹窗完全关闭后再重置数据
|
// 使用nextTick确保弹窗完全关闭后再重置数据
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|
@ -1305,35 +1275,6 @@ export default {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.prePaymentData = null;
|
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