fix(售后): 0 元单允许申请并实退 0,有可退现金时仍拦截空退款

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
吴昊天 2026-10-27 13:09:31 +08:00
parent d4fa21ea00
commit 5f342bb505
3 changed files with 29 additions and 9 deletions

View File

@ -760,8 +760,8 @@ class AfterSaleServices extends BaseService
if ($targets['has_integral']) {
$fields = $this->appendRefundIntegralField($fields);
}
// 纯积分订单(无现金可退):移除"申请退款金额"字段
if (!$targets['has_cash'] && $targets['has_integral']) {
// 无现金可退(纯积分或 0 元单):移除"申请退款金额"字段,避免必填 0 金额干扰申请
if (!$targets['has_cash']) {
$fields = $this->removeRefundPriceField($fields);
}
$config['fields'] = $fields;
@ -1249,9 +1249,14 @@ class AfterSaleServices extends BaseService
&& ((float)$maxRefundPrice <= 0 || (int)($center['use_integral_num'] ?? 0) > 0)) {
$refundIntegral = $maxRefundIntegral;
}
// 0 元单(无现金、无积分可退):未传金额时按 0 落库,仍走售后闭环(库存/状态)
if ($refundPrice <= 0 && (float)$maxRefundPrice <= 0) {
$refundPrice = 0.0;
}
// 退款金额与退还积分至少一项大于 0
if ($refundPrice <= 0 && $refundIntegral <= 0) {
// 存在可退现金或积分时,至少一项须大于 0;两侧上限均为 0 时允许 0 退款
if ($refundPrice <= 0 && $refundIntegral <= 0
&& ((float)$maxRefundPrice > 0 || $maxRefundIntegral > 0)) {
throw new \RuntimeException('退款金额或退还积分至少一项必须大于 0');
}
if ($refundPrice > (float)$maxRefundPrice) {

View File

@ -539,7 +539,14 @@ class RefundOrderServices extends BaseService
&& (int)($afterSale['receive_time'] ?? 0) <= 0) {
throw new \RuntimeException('请先确认收到退货再执行退款');
}
if (bccomp($amount, '0.00', 2) < 0 || ((int)($afterSale['refund_integral'] ?? 0) <= 0 && bccomp($amount, '0.00', 2) <= 0)) {
if (bccomp($amount, '0.00', 2) < 0) {
throw new \RuntimeException('退款金额不能为负数');
}
// 0 元售后(申请金额与退还积分均为 0)允许实退 0,走本地退款闭环;有可退现金却实退 0 仍拦截
$hasCash = bccomp($amount, '0.00', 2) > 0;
$hasIntegral = (int)($afterSale['refund_integral'] ?? 0) > 0;
if (!$hasCash && !$hasIntegral
&& bccomp((string)($afterSale['refund_price'] ?? '0.00'), '0.00', 2) > 0) {
throw new \RuntimeException('退款金额或退款积分必须大于零');
}
if (bccomp($amount, (string)($afterSale['refund_price'] ?? '0.00'), 2) > 0) {

View File

@ -348,11 +348,11 @@
<el-form-item label="可退金额">
<span class="price">¥{{ detail.refund_price || '0.00' }}</span>
</el-form-item>
<el-form-item label="退款金额" required>
<el-form-item label="退款金额" :required="Number(detail.refund_price) > 0">
<el-input-number
v-model="refundForm.amount"
:min="0.01"
:max="Number(detail.refund_price) || 0"
:min="Number(detail.refund_price) > 0 ? 0.01 : 0"
:max="Math.max(Number(detail.refund_price) || 0, 0)"
:precision="2"
style="width: 200px"
></el-input-number>
@ -676,7 +676,15 @@ function openRefund() {
* 提交退款
*/
function submitRefund() {
if (refundForm.value.amount <= 0) {
const amount = Number(refundForm.value.amount) || 0;
const maxCash = Number(detail.value.refund_price) || 0;
const refundIntegral = Number(detail.value.refund_integral) || 0;
// 有可退现金时金额须 > 0;0 元单(无现金、可无积分)允许实退 0
if (amount < 0) {
ElMessage.warning('退款金额不能为负数');
return;
}
if (amount <= 0 && refundIntegral <= 0 && maxCash > 0) {
ElMessage.warning('退款金额必须大于0');
return;
}