```
feat(split): 添加分账手动指定接收方功能 - 实现SplitManualService服务类,支持手动覆盖分账明细 - 新增SplitManual和SplitManualLog数据模型 - 修改SplitCalculator优先使用手动覆盖数据进行分账计算 - 添加分账记录手动指定接收方的数据库表结构 - 集成手动分账到汇付分账流程中,支持失败重试机制 - 添加商品详情内容更新SQL脚本用于汇付审核 ```
这个提交包含在:
@@ -6,6 +6,7 @@ use app\admin\controller\shopro\Base;
|
||||
use addons\shopro\library\split\Config as SplitConfig;
|
||||
use addons\shopro\library\split\SplitCalculator;
|
||||
use addons\shopro\library\split\SplitExecutor;
|
||||
use addons\shopro\library\split\SplitManualService;
|
||||
use addons\shopro\library\split\ProfitSharingService;
|
||||
use app\admin\model\shopro\order\Order as ShopOrder;
|
||||
use app\admin\model\shopro\user\User as ShopUser;
|
||||
@@ -183,12 +184,18 @@ class Order extends Base
|
||||
$data['fail_reason_full'] = $this->enrichFailReasonWithDiagnose($data['fail_reason_full'], $status, $diag);
|
||||
$data['fail_reason'] = $this->summarizeFailReason($data['fail_reason_full'], $diag, $status);
|
||||
|
||||
$data['split_source'] = $diag['final_source'];
|
||||
$data['split_source_text'] = $this->formatSplitSourceText($diag);
|
||||
$data['calc_source'] = $diag['final_source'];
|
||||
$data['calc_source_text'] = $this->formatSplitSourceText($diag);
|
||||
$data['split_diagnose'] = $diag['issues'];
|
||||
$data['commission_total'] = $diag['commission_total'];
|
||||
$data['rule_total'] = $diag['rule_total'];
|
||||
|
||||
$orderSplitSource = $data['split_source'] ?? 'auto';
|
||||
$data['split_source'] = $orderSplitSource;
|
||||
$data['split_source_text'] = $orderSplitSource === 'manual' ? '手动指定' : $data['calc_source_text'];
|
||||
$data['has_manual_override'] = (new SplitManualService())->hasOverride($orderId);
|
||||
$data['can_edit_manual'] = ($status === 4 && $channel === 'huifu');
|
||||
|
||||
unset($data['order'], $data['receivers']);
|
||||
$rows[] = $data;
|
||||
}
|
||||
@@ -468,6 +475,143 @@ class Order extends Base
|
||||
return $map[$type] ?? ($type ?: '接收方');
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载指定接收方弹窗数据
|
||||
*/
|
||||
public function manualReceivers()
|
||||
{
|
||||
$splitOrderId = intval($this->request->get('split_order_id', 0));
|
||||
if ($splitOrderId <= 0) {
|
||||
$this->error('参数错误');
|
||||
}
|
||||
try {
|
||||
$context = (new SplitManualService())->getManualContext($splitOrderId);
|
||||
} catch (\Throwable $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$this->success('操作成功', null, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存手动覆盖(不重试)
|
||||
*/
|
||||
public function saveManual()
|
||||
{
|
||||
$splitOrderId = intval($this->request->post('split_order_id', 0));
|
||||
$items = $this->request->post('items/a', []);
|
||||
$remark = trim((string) $this->request->post('remark', ''));
|
||||
|
||||
$row = $this->model->get($splitOrderId);
|
||||
if (!$row) {
|
||||
$this->error('分账记录不存在');
|
||||
}
|
||||
try {
|
||||
(new SplitManualService())->save(
|
||||
intval($row['order_id']),
|
||||
$items,
|
||||
intval($this->auth->id),
|
||||
(string) ($this->auth->nickname ?? $this->auth->username ?? ''),
|
||||
$remark
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存手动覆盖并重新分账
|
||||
*/
|
||||
public function saveManualAndRetry()
|
||||
{
|
||||
$splitOrderId = intval($this->request->post('split_order_id', 0));
|
||||
$items = $this->request->post('items/a', []);
|
||||
$remark = trim((string) $this->request->post('remark', ''));
|
||||
|
||||
$row = $this->model->get($splitOrderId);
|
||||
if (!$row) {
|
||||
$this->error('分账记录不存在');
|
||||
}
|
||||
$orderId = intval($row['order_id']);
|
||||
$adminId = intval($this->auth->id);
|
||||
$adminName = (string) ($this->auth->nickname ?? $this->auth->username ?? '');
|
||||
|
||||
$service = new SplitManualService();
|
||||
try {
|
||||
$service->save($orderId, $items, $adminId, $adminName, $remark);
|
||||
$service->markPendingRetryLog($orderId, $adminId, $adminName, $remark);
|
||||
} catch (\Throwable $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
if (class_exists('\\addons\\shopro_huifu\\library\\HuifuSplitService')) {
|
||||
$result = (new \addons\shopro_huifu\library\HuifuSplitService())->executeByOrderId($orderId);
|
||||
} else {
|
||||
$result = (new SplitExecutor())->retry($splitOrderId);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$service->finishPendingRetryLog($orderId, false, $e->getMessage());
|
||||
$this->error('重试失败:' . $e->getMessage());
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$this->success('保存并重试成功');
|
||||
}
|
||||
$hint = $this->formatSplitWxResultHint($orderId, 'huifu');
|
||||
$this->error('保存成功但分账失败' . ($hint ?: ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除手动覆盖
|
||||
*/
|
||||
public function clearManual()
|
||||
{
|
||||
$splitOrderId = intval($this->request->post('split_order_id', 0));
|
||||
$remark = trim((string) $this->request->post('remark', ''));
|
||||
|
||||
$row = $this->model->get($splitOrderId);
|
||||
if (!$row) {
|
||||
$this->error('分账记录不存在');
|
||||
}
|
||||
try {
|
||||
(new SplitManualService())->clear(
|
||||
intval($row['order_id']),
|
||||
intval($this->auth->id),
|
||||
(string) ($this->auth->nickname ?? $this->auth->username ?? ''),
|
||||
$remark
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$this->success('已清除手动指定');
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更历史
|
||||
*/
|
||||
public function manualHistory()
|
||||
{
|
||||
$orderId = intval($this->request->get('order_id', 0));
|
||||
if ($orderId <= 0) {
|
||||
$splitOrderId = intval($this->request->get('split_order_id', 0));
|
||||
if ($splitOrderId > 0) {
|
||||
$row = $this->model->get($splitOrderId);
|
||||
$orderId = $row ? intval($row['order_id']) : 0;
|
||||
}
|
||||
}
|
||||
if ($orderId <= 0) {
|
||||
$this->error('参数错误');
|
||||
}
|
||||
|
||||
$offset = intval($this->request->get('offset', 0));
|
||||
$limit = intval($this->request->get('limit', 20));
|
||||
$limit = max(1, min(100, $limit));
|
||||
|
||||
$result = (new SplitManualService())->getHistory($orderId, $offset, $limit);
|
||||
$this->success('操作成功', null, $result);
|
||||
}
|
||||
|
||||
public function retry($ids = null)
|
||||
{
|
||||
$id = $ids ?: $this->request->post('id');
|
||||
|
||||
在新工单中引用
屏蔽一个用户