mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-28 13:31:04 +00:00
fix(售后维修): 维修完成可填寄回物流并完结恢复订单,退款终态统一 refunded
已退款 Tab 兼容历史 completed;售后状态 Tab 避免空字符串被 EP 序号化。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
89a8ea13d8
commit
02c11e3e19
@ -233,7 +233,7 @@ class AfterSaleController extends AuthController
|
||||
|
||||
/**
|
||||
* 维修完成
|
||||
* 维修完成后商家寄回商品,进入补发流程
|
||||
* 可附带寄回物流;完成后售后完结,订单恢复为申请前状态
|
||||
* @param int $id 售后单主键
|
||||
* @return mixed
|
||||
*/
|
||||
@ -242,12 +242,17 @@ class AfterSaleController extends AuthController
|
||||
if ($id <= 0) {
|
||||
return app('json')->fail('参数错误');
|
||||
}
|
||||
[$repairRemark] = $this->request->postMore([
|
||||
[$repairRemark, $deliveryType, $deliveryNo] = $this->request->postMore([
|
||||
['repair_remark', ''],
|
||||
['delivery_type', ''],
|
||||
['delivery_no', ''],
|
||||
], true);
|
||||
try {
|
||||
$this->services->repairComplete($id, $repairRemark);
|
||||
return app('json')->success('维修完成');
|
||||
$this->services->repairComplete($id, (string)$repairRemark, [
|
||||
'delivery_type' => (string)$deliveryType,
|
||||
'delivery_no' => (string)$deliveryNo,
|
||||
]);
|
||||
return app('json')->success('维修完成,订单已恢复原状态');
|
||||
} catch (\RuntimeException $e) {
|
||||
return app('json')->fail($e->getMessage());
|
||||
}
|
||||
|
||||
@ -266,9 +266,13 @@ class AfterSaleDao extends BaseDao
|
||||
$processingStatuses = ['pending_audit', 'audit_passed', 'refunding', 'pending_return', 'receiving', 'resending', 'repairing', 'repair_complete'];
|
||||
$query->whereIn('status', $processingStatuses);
|
||||
} elseif ($mode === 'refunded') {
|
||||
// 已退款完成:退款/退货退款类型且已完结
|
||||
$query->whereIn('status', ['refunded', 'completed'])
|
||||
->whereIn('type', ['refund_only', 'return_refund']);
|
||||
// 已退款:退款落账终态;兼容历史误写入 completed 的退款型售后
|
||||
$query->where(function ($q) {
|
||||
$q->where('status', 'refunded')->whereOr(function ($q2) {
|
||||
$q2->where('status', 'completed')
|
||||
->whereIn('type', ['refund_only', 'return_refund']);
|
||||
});
|
||||
});
|
||||
}
|
||||
// all 模式:不追加状态条件,返回所有有售后记录的订单号
|
||||
|
||||
|
||||
@ -1624,30 +1624,59 @@ class AfterSaleServices extends BaseService
|
||||
|
||||
/**
|
||||
* 维修完成
|
||||
* 记录维修结果与可选寄回物流后,直接完结售后并恢复中台订单到申请前状态。
|
||||
* 兼容已停在 repair_complete、尚未完结的历史单。
|
||||
*
|
||||
* @param int $afterSaleId
|
||||
* @param string $repairRemark
|
||||
* @param array $deliveryData 可选寄回物流 delivery_type/delivery_no
|
||||
* @return void
|
||||
*/
|
||||
public function repairComplete(int $afterSaleId, string $repairRemark = ''): void
|
||||
public function repairComplete(int $afterSaleId, string $repairRemark = '', array $deliveryData = []): void
|
||||
{
|
||||
$afterSale = $this->dao->get($afterSaleId);
|
||||
if (empty($afterSale)) {
|
||||
throw new \RuntimeException('售后单不存在');
|
||||
}
|
||||
if ($afterSale['status'] !== 'repairing') {
|
||||
if (!in_array($afterSale['status'], ['repairing', 'repair_complete'], true)) {
|
||||
throw new \RuntimeException('当前状态不可维修完成');
|
||||
}
|
||||
|
||||
$this->dao->update($afterSaleId, [
|
||||
'status' => 'repair_complete',
|
||||
'repair_remark' => $repairRemark,
|
||||
'repair_complete_time'=> time(),
|
||||
]);
|
||||
if (($afterSale['type'] ?? '') !== 'repair') {
|
||||
throw new \RuntimeException('非维修类型售后不可执行维修完成');
|
||||
}
|
||||
|
||||
$lifecycle = $this->getLifecycleHandler($afterSale['product_type']);
|
||||
if ($lifecycle) {
|
||||
$update = [];
|
||||
if ($afterSale['status'] === 'repairing') {
|
||||
$update['status'] = 'repair_complete';
|
||||
$update['repair_complete_time'] = time();
|
||||
}
|
||||
if ($repairRemark !== '') {
|
||||
$update['repair_remark'] = $repairRemark;
|
||||
}
|
||||
$deliveryType = trim((string)($deliveryData['delivery_type'] ?? ''));
|
||||
$deliveryNo = trim((string)($deliveryData['delivery_no'] ?? ''));
|
||||
if ($deliveryType !== '' || $deliveryNo !== '') {
|
||||
$update['resend_delivery_type'] = $deliveryType;
|
||||
$update['resend_delivery_no'] = $deliveryNo;
|
||||
$update['resend_time'] = time();
|
||||
}
|
||||
if ($update) {
|
||||
$this->dao->update($afterSaleId, $update);
|
||||
}
|
||||
|
||||
if ($afterSale['status'] === 'repairing' && $lifecycle) {
|
||||
$lifecycle->afterRepair($afterSale['after_sale_no'], 'repair_complete');
|
||||
}
|
||||
if (($deliveryType !== '' || $deliveryNo !== '') && $lifecycle) {
|
||||
$lifecycle->afterResend($afterSale['after_sale_no'], [
|
||||
'delivery_type' => $deliveryType,
|
||||
'delivery_no' => $deliveryNo,
|
||||
]);
|
||||
}
|
||||
|
||||
// 维修流程终结:完结售后单并恢复订单原状态(不再等待用户二次确认收货)
|
||||
$this->complete($afterSaleId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1945,26 +1974,31 @@ class AfterSaleServices extends BaseService
|
||||
*/
|
||||
public function getListForAdmin(array $where, int $page, int $limit): array
|
||||
{
|
||||
$map = [];
|
||||
// 售后单号模糊查询
|
||||
// 关联键走模型搜索器(status/type 等);模糊/区间条件用三元数组
|
||||
$map = ['is_del' => 0];
|
||||
if (!empty($where['after_sale_no'])) {
|
||||
$map[] = ['after_sale_no', 'like', '%' . $where['after_sale_no'] . '%'];
|
||||
$map[] = ['after_sale_no', 'like', '%' . trim((string)$where['after_sale_no']) . '%'];
|
||||
}
|
||||
// 订单号模糊查询
|
||||
if (!empty($where['order_no'])) {
|
||||
$map[] = ['order_no', 'like', '%' . $where['order_no'] . '%'];
|
||||
$map[] = ['order_no', 'like', '%' . trim((string)$where['order_no']) . '%'];
|
||||
}
|
||||
// 精确筛选
|
||||
foreach (['status', 'type', 'product_type', 'order_category'] as $field) {
|
||||
if (!empty($where[$field])) {
|
||||
$map[] = [$field, '=', $where[$field]];
|
||||
// 状态:单值精确;逗号串/数组走 whereIn(兼容流程分组)
|
||||
$status = $where['status'] ?? '';
|
||||
if ($status !== '' && $status !== null) {
|
||||
if (is_string($status) && str_contains($status, ',')) {
|
||||
$map['status'] = array_values(array_filter(array_map('trim', explode(',', $status))));
|
||||
} else {
|
||||
$map['status'] = $status;
|
||||
}
|
||||
}
|
||||
foreach (['type', 'product_type', 'order_category'] as $field) {
|
||||
if (!empty($where[$field])) {
|
||||
$map[$field] = $where[$field];
|
||||
}
|
||||
}
|
||||
// 时间范围
|
||||
if (!empty($where['start_time']) && !empty($where['end_time'])) {
|
||||
$map[] = ['add_time', 'between', [(int)$where['start_time'], (int)$where['end_time']]];
|
||||
}
|
||||
$map[] = ['is_del', '=', 0];
|
||||
|
||||
$list = $this->dao->getList($map, $page, $limit);
|
||||
// 附加文案
|
||||
@ -2383,8 +2417,13 @@ class AfterSaleServices extends BaseService
|
||||
$query->where('status', 'audit_rejected');
|
||||
break;
|
||||
case 'refunded':
|
||||
// 已退款:refunded 为退款落账瞬时态、completed 为终态,双取兜底历史数据
|
||||
$query->whereIn('status', ['refunded', 'completed']);
|
||||
// 已退款:退款型终态;兼容历史误写入 completed 的退款单
|
||||
$query->where(function ($q) {
|
||||
$q->where('status', 'refunded')->whereOr(function ($q2) {
|
||||
$q2->where('status', 'completed')
|
||||
->whereIn('type', ['refund_only', 'return_refund']);
|
||||
});
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
@ -2482,8 +2521,13 @@ class AfterSaleServices extends BaseService
|
||||
case 3: // 退货待收货
|
||||
$query->where('status', 'receiving');
|
||||
break;
|
||||
case 4: // 已退款
|
||||
$query->whereIn('status', ['refunded', 'completed']);
|
||||
case 4: // 已退款(含历史误标 completed 的退款型)
|
||||
$query->where(function ($q) {
|
||||
$q->where('status', 'refunded')->whereOr(function ($q2) {
|
||||
$q2->where('status', 'completed')
|
||||
->whereIn('type', ['refund_only', 'return_refund']);
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2509,7 +2553,11 @@ class AfterSaleServices extends BaseService
|
||||
3 => ['name' => '拒绝退款', 'num' => (clone $base)->where('status', 'audit_rejected')->count()],
|
||||
4 => ['name' => '商品待退货', 'num' => (clone $base)->where('status', 'pending_return')->count()],
|
||||
5 => ['name' => '退货待收货', 'num' => (clone $base)->where('status', 'receiving')->count()],
|
||||
6 => ['name' => '已退款', 'num' => (clone $base)->whereIn('status', ['refunded', 'completed'])->count()],
|
||||
6 => ['name' => '已退款', 'num' => (clone $base)->where(function ($q) {
|
||||
$q->where('status', 'refunded')->whereOr(function ($q2) {
|
||||
$q2->where('status', 'completed')->whereIn('type', ['refund_only', 'return_refund']);
|
||||
});
|
||||
})->count()],
|
||||
];
|
||||
return ['list' => $list, 'count' => $count, 'num' => $num];
|
||||
}
|
||||
@ -2523,8 +2571,11 @@ class AfterSaleServices extends BaseService
|
||||
protected function tidyKefuListItem(array $item, array $orderMap): array
|
||||
{
|
||||
$status = $item['status'] ?? '';
|
||||
$type = $item['type'] ?? '';
|
||||
// 旧数字 refund_status:1=处理中 2=已退款 3=已拒绝
|
||||
if (in_array($status, ['refunded', 'completed'])) {
|
||||
// completed 仅对退款型计为已退款;换货/补发/维修的 completed 仍属处理完结而非退款
|
||||
if ($status === 'refunded'
|
||||
|| ($status === 'completed' && in_array($type, ['refund_only', 'return_refund'], true))) {
|
||||
$refundStatus = 2;
|
||||
} elseif ($status === 'audit_rejected' || $status === 'canceled') {
|
||||
$refundStatus = 3;
|
||||
@ -2629,11 +2680,11 @@ class AfterSaleServices extends BaseService
|
||||
$query->whereBetween('add_time', [strtotime($start), strtotime($end) + 86399]);
|
||||
}
|
||||
if (($where['refund_status'] ?? 0) == 1) {
|
||||
// 进行中:未完结且未取消/驳回
|
||||
$query->whereNotIn('status', ['completed', 'canceled', 'audit_rejected']);
|
||||
// 进行中:未完结且未取消/驳回(含已退款终态)
|
||||
$query->whereNotIn('status', ['completed', 'refunded', 'canceled', 'audit_rejected']);
|
||||
} elseif (($where['refund_status'] ?? 0) == 2) {
|
||||
// 已完成
|
||||
$query->where('status', 'completed');
|
||||
// 已完结:已完成 + 已退款
|
||||
$query->whereIn('status', ['completed', 'refunded']);
|
||||
}
|
||||
$count = (clone $query)->count();
|
||||
$list = $query->field('id, after_sale_no, order_no, uid, type, status, refund_price, actual_refund_price, refund_integral, reason, reject_reason, remark, refund_num, add_time, refund_time')
|
||||
|
||||
@ -181,8 +181,9 @@ class RefundEffectServices extends BaseService implements RefundEffectContextInt
|
||||
$refundTradeNo = $manualTradeNo !== ''
|
||||
? $manualTradeNo
|
||||
: (string)($locked['channel_refund_id'] ?: $locked['refund_no']);
|
||||
// 退款型售后终态为 refunded(已退款 tab);换货/补发/维修走 complete() 才是 completed
|
||||
$this->afterSaleDao->update((int)$afterSale['id'], [
|
||||
'status' => 'completed',
|
||||
'status' => 'refunded',
|
||||
'actual_refund_price' => (string)$locked['amount'],
|
||||
'refund_type' => (string)$locked['refund_method'],
|
||||
'refund_trade_no' => $refundTradeNo,
|
||||
|
||||
@ -14,6 +14,7 @@ use crmeb\trade\order\aftersale\BaseAfterSaleHandler;
|
||||
use app\dao\order\AfterSaleDao;
|
||||
use modules\product\normal\dao\NormalOrderDao;
|
||||
use modules\product\normal\dao\NormalProductDao;
|
||||
use modules\product\normal\service\OrderServices as NormalOrderServices;
|
||||
use app\services\order\OrderCenterServices;
|
||||
|
||||
/**
|
||||
@ -271,4 +272,118 @@ class NormalAfterSaleHandler extends BaseAfterSaleHandler
|
||||
'refund_status' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 补发/维修寄回后
|
||||
* 扩展表进入待收货,并同步中台发货信息
|
||||
* @param string $afterSaleNo
|
||||
* @param array $deliveryData
|
||||
* @return void
|
||||
*/
|
||||
public function afterResend(string $afterSaleNo, array $deliveryData): void
|
||||
{
|
||||
$orderNo = $this->getOrderNo($afterSaleNo);
|
||||
if ($orderNo === '') {
|
||||
return;
|
||||
}
|
||||
$deliveryName = trim((string)($deliveryData['delivery_type'] ?? $deliveryData['delivery_name'] ?? ''));
|
||||
$deliveryId = trim((string)($deliveryData['delivery_no'] ?? $deliveryData['delivery_id'] ?? ''));
|
||||
if ($deliveryName === '' && $deliveryId === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var NormalOrderServices $orderServices */
|
||||
$orderServices = app(NormalOrderServices::class);
|
||||
$orderServices->updateDeliveryInfo(
|
||||
$orderNo,
|
||||
$deliveryName !== '' ? $deliveryName : '快递',
|
||||
$deliveryId,
|
||||
'express'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 非退款型售后完结后
|
||||
* 必须清掉扩展表 refund_status=1,否则适配器仍会推导为「售后中」
|
||||
* 维修/换货/补发若已寄回,确保扩展状态为待收货
|
||||
* @param string $afterSaleNo
|
||||
* @return void
|
||||
*/
|
||||
public function afterComplete(string $afterSaleNo): void
|
||||
{
|
||||
$orderNo = $this->getOrderNo($afterSaleNo);
|
||||
if ($orderNo === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$afterSale = $this->getAfterSaleRecord($afterSaleNo);
|
||||
$type = (string)($afterSale['type'] ?? '');
|
||||
$deliveryName = trim((string)($afterSale['resend_delivery_type'] ?? ''));
|
||||
$deliveryId = trim((string)($afterSale['resend_delivery_no'] ?? ''));
|
||||
$needPendingReceive = in_array($type, ['repair', 'exchange', 'resend'], true)
|
||||
&& ($deliveryName !== '' || $deliveryId !== '');
|
||||
|
||||
$sourceUpdate = ['refund_status' => 0];
|
||||
if ($needPendingReceive) {
|
||||
$sourceUpdate['status'] = NormalOrderAdapter::EXT_STATUS_PENDING_RECEIVE;
|
||||
$sourceUpdate['delivery_type'] = 'express';
|
||||
if ($deliveryName !== '') {
|
||||
$sourceUpdate['delivery_name'] = $deliveryName;
|
||||
}
|
||||
if ($deliveryId !== '') {
|
||||
$sourceUpdate['delivery_id'] = $deliveryId;
|
||||
}
|
||||
}
|
||||
$this->orderDao->update(['order_no' => $orderNo], $sourceUpdate);
|
||||
|
||||
$centerOrder = $this->centerServices->getOne(['order_no' => $orderNo], 'status_code,extra_info,delivery_time');
|
||||
$centerUpdate = ['refund_status' => 0];
|
||||
if (($centerOrder['status_code'] ?? '') === 'after_sale') {
|
||||
$centerUpdate['status_code'] = \app\model\order\OrderCenter::STATUS_PROCESSING;
|
||||
}
|
||||
if ($needPendingReceive) {
|
||||
$extraInfo = $centerOrder['extra_info'] ?? [];
|
||||
if (is_string($extraInfo)) {
|
||||
$extraInfo = json_decode($extraInfo, true) ?: [];
|
||||
}
|
||||
$extraInfo['delivery'] = [
|
||||
'delivery_type' => 'express',
|
||||
'delivery_name' => $deliveryName !== '' ? $deliveryName : (string)($extraInfo['delivery']['delivery_name'] ?? ''),
|
||||
'delivery_id' => $deliveryId !== '' ? $deliveryId : (string)($extraInfo['delivery']['delivery_id'] ?? ''),
|
||||
'delivery_uid' => (int)($extraInfo['delivery']['delivery_uid'] ?? 0),
|
||||
];
|
||||
$extraInfo['business_status'] = [
|
||||
'code' => NormalOrderAdapter::EXT_STATUS_PENDING_RECEIVE,
|
||||
'text' => '待收货',
|
||||
'detail' => '维修/补发商品运输中',
|
||||
'extend' => new \stdClass(),
|
||||
];
|
||||
$centerUpdate['extra_info'] = json_encode($extraInfo, JSON_UNESCAPED_UNICODE);
|
||||
if (empty($centerOrder['delivery_time'])) {
|
||||
$centerUpdate['delivery_time'] = time();
|
||||
}
|
||||
// restoreOrderStatus 可能已把中台写成 processing;寄回场景显式保持 processing
|
||||
$centerUpdate['status_code'] = \app\model\order\OrderCenter::STATUS_PROCESSING;
|
||||
}
|
||||
$this->centerServices->updateRecord($orderNo, $centerUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $afterSaleNo
|
||||
* @return array
|
||||
*/
|
||||
protected function getAfterSaleRecord(string $afterSaleNo): array
|
||||
{
|
||||
try {
|
||||
/** @var AfterSaleDao $afterSaleDao */
|
||||
$afterSaleDao = app(AfterSaleDao::class);
|
||||
$record = $afterSaleDao->getByNo($afterSaleNo);
|
||||
if (empty($record)) {
|
||||
return [];
|
||||
}
|
||||
return is_object($record) ? $record->toArray() : (array)$record;
|
||||
} catch (\Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,9 +278,9 @@
|
||||
v-auth="['admin-order-afterSale-start_repair']"
|
||||
>开始维修</el-button
|
||||
>
|
||||
<!-- 维修中:维修完成 -->
|
||||
<!-- 维修中 / 已维修完成未完结:维修完成(完结售后并恢复订单原状态) -->
|
||||
<el-button
|
||||
v-if="detail.status === 'repairing'"
|
||||
v-if="detail.status === 'repairing' || detail.status === 'repair_complete'"
|
||||
type="success"
|
||||
v-db-click
|
||||
@click="openRepairComplete"
|
||||
@ -399,7 +399,12 @@
|
||||
</el-dialog>
|
||||
|
||||
<!-- 维修完成弹窗 -->
|
||||
<el-dialog v-model="repairModal" title="维修完成" width="500px" @close="repairForm = { repair_remark: '' }">
|
||||
<el-dialog
|
||||
v-model="repairModal"
|
||||
title="维修完成"
|
||||
width="500px"
|
||||
@close="repairForm = { repair_remark: '', delivery_type: '', delivery_no: '' }"
|
||||
>
|
||||
<el-form :model="repairForm" label-width="100px">
|
||||
<el-form-item label="维修备注">
|
||||
<el-input
|
||||
@ -409,7 +414,13 @@
|
||||
placeholder="维修过程记录(选填)"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<div class="repair-tip">维修完成后将进入补发流程,请填写补发物流寄回用户。</div>
|
||||
<el-form-item label="寄回快递">
|
||||
<el-input v-model="repairForm.delivery_type" placeholder="快递公司(选填)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="寄回单号">
|
||||
<el-input v-model="repairForm.delivery_no" placeholder="快递单号(选填)"></el-input>
|
||||
</el-form-item>
|
||||
<div class="repair-tip">填写寄回物流并确认后,售后完结,订单将变为「待收货」。</div>
|
||||
</el-form>
|
||||
<template #footer
|
||||
><div>
|
||||
@ -463,7 +474,7 @@ const resendModal = ref(false);
|
||||
const resendForm = ref({ delivery_type: '', delivery_no: '' });
|
||||
// 维修完成弹窗
|
||||
const repairModal = ref(false);
|
||||
const repairForm = ref({ repair_remark: '' });
|
||||
const repairForm = ref({ repair_remark: '', delivery_type: '', delivery_no: '' });
|
||||
// 产品类型文案映射(与列表页保持一致)
|
||||
const productTypeOptions = [
|
||||
{ key: 'normal', label: '实物商品' },
|
||||
@ -566,14 +577,13 @@ const canStartRepair = computed(() => {
|
||||
* 是否可补发商品
|
||||
* - 补发类型:audit_passed 状态可补发
|
||||
* - 换货类型:receiving 状态且已确认收货后可补发
|
||||
* - 维修类型:repair_complete 状态可补发
|
||||
* - 维修类型:维修完成时一并处理寄回,不再单独补发
|
||||
*/
|
||||
const canResend = computed(() => {
|
||||
if (!detail.value) return false;
|
||||
const { status, type } = detail.value;
|
||||
if (type === 'resend' && status === 'audit_passed') return true;
|
||||
if (type === 'exchange' && status === 'receiving' && isReceived.value) return true;
|
||||
if (type === 'repair' && status === 'repair_complete') return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
@ -732,7 +742,7 @@ function handleStartRepair() {
|
||||
* 打开维修完成弹窗
|
||||
*/
|
||||
function openRepairComplete() {
|
||||
repairForm.value = { repair_remark: '' };
|
||||
repairForm.value = { repair_remark: '', delivery_type: '', delivery_no: '' };
|
||||
repairModal.value = true;
|
||||
}
|
||||
|
||||
|
||||
@ -3,18 +3,6 @@
|
||||
<el-card :bordered="false" shadow="never" :body-style="{ padding: 0 }">
|
||||
<div class="padding-add">
|
||||
<el-form :model="searchForm" label-width="80px" label-position="right" inline @submit.prevent>
|
||||
<el-form-item label="售后状态:">
|
||||
<el-select
|
||||
v-model="searchForm.status"
|
||||
clearable
|
||||
@change="getList(1)"
|
||||
placeholder="全部"
|
||||
class="form_content_width"
|
||||
>
|
||||
<el-option label="全部" value="" />
|
||||
<el-option v-for="item in statusOptions" :key="item.key" :value="item.key" :label="item.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="售后类型:">
|
||||
<el-select
|
||||
v-model="searchForm.type"
|
||||
@ -85,7 +73,7 @@
|
||||
</el-card>
|
||||
<el-card :bordered="false" shadow="never" class="mt16" :body-style="{ padding: '0 0 20px' }">
|
||||
<el-tabs v-model="statusTab" @tab-change="handleStatusTabClick">
|
||||
<el-tab-pane label="全部" name=""></el-tab-pane>
|
||||
<el-tab-pane label="全部" name="all"></el-tab-pane>
|
||||
<el-tab-pane v-for="item in statusOptions" :key="item.key" :label="item.label" :name="item.key"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="table-content">
|
||||
@ -224,7 +212,6 @@ const router = useRouter();
|
||||
const routePre = setting.routePre;
|
||||
|
||||
const searchForm = ref({
|
||||
status: '',
|
||||
type: '',
|
||||
product_type: '',
|
||||
order_category: '',
|
||||
@ -238,7 +225,8 @@ const list = ref([]);
|
||||
const total = ref(0);
|
||||
const page = ref({ page: 1, limit: 15 });
|
||||
const loading = ref(false);
|
||||
const statusTab = ref('');
|
||||
/** 状态 Tab:all=全部,其余为售后状态码(勿用空字符串,EP 会回退为序号名) */
|
||||
const statusTab = ref('all');
|
||||
const remarkModal = ref(false);
|
||||
const remarkForm = ref({ id: 0, remark: '' });
|
||||
const auditModal = ref(false);
|
||||
@ -255,6 +243,7 @@ const statusOptions = [
|
||||
{ key: 'pending_return', label: '待退货' },
|
||||
{ key: 'receiving', label: '待收货' },
|
||||
{ key: 'repairing', label: '维修中' },
|
||||
{ key: 'repair_complete', label: '维修完成' },
|
||||
{ key: 'resending', label: '补发中' },
|
||||
{ key: 'completed', label: '已完成' },
|
||||
];
|
||||
@ -283,9 +272,8 @@ const categoryOptions = [
|
||||
function getList(res) {
|
||||
page.value.page = res === 1 ? 1 : page.value.page;
|
||||
loading.value = true;
|
||||
// 状态 Tab 优先于筛选下拉
|
||||
const status = statusTab.value || searchForm.value.status;
|
||||
// 单号搜索映射到对应字段
|
||||
// 状态仅来自 Tab:all 表示不筛选,避免与空字符串/筛选下拉互相抢优先级
|
||||
const status = statusTab.value === 'all' ? '' : statusTab.value;
|
||||
const params = {
|
||||
status,
|
||||
type: searchForm.value.type,
|
||||
@ -345,7 +333,6 @@ function onchangeTime(e) {
|
||||
*/
|
||||
function handleReset() {
|
||||
searchForm.value = {
|
||||
status: '',
|
||||
type: '',
|
||||
product_type: '',
|
||||
order_category: '',
|
||||
@ -355,14 +342,16 @@ function handleReset() {
|
||||
end_time: '',
|
||||
};
|
||||
timeVal.value = [];
|
||||
statusTab.value = '';
|
||||
statusTab.value = 'all';
|
||||
getList(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态 Tab 切换
|
||||
* 状态 Tab 切换(以事件入参为准,避免 v-model 时序导致读到旧值)
|
||||
* @param {string} name Tab name
|
||||
*/
|
||||
function handleStatusTabClick() {
|
||||
function handleStatusTabClick(name) {
|
||||
statusTab.value = name || 'all';
|
||||
getList(1);
|
||||
}
|
||||
|
||||
@ -433,10 +422,10 @@ function saveRemark() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 终态不可备注(已完成/已取消/审核拒绝)
|
||||
* 终态不可备注(已退款/已完成/已取消/审核拒绝)
|
||||
*/
|
||||
function canRemark(status) {
|
||||
return !['completed', 'canceled', 'audit_rejected'].includes(status);
|
||||
return !['refunded', 'completed', 'canceled', 'audit_rejected'].includes(status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user