完善接口和后台页面

This commit is contained in:
2026-04-18 15:19:36 +08:00
parent a4878a9bbd
commit e3f26ba1f7
45 changed files with 3071 additions and 232 deletions

View File

@@ -9,6 +9,13 @@ use Webman\Http\Request as WebmanRequest;
/**
* 充值订单
*
* 订单的"由 0 转 1成功入账"统一走 app\common\library\finance\DepositSettlement。
* 当前充值接口为 mock 支付网关,点击即成功;后台不再保留人工审核按钮,
* 如需人工补单,请通过后续专门的"补单/冲正"工具完成,而不是在这个 CRUD 里直接改 status。
*
* 编辑入口现在只用于"查看详情"GET 返回订单 + 关联的 user/channel 信息,
* 阻止 POST 任何改字段的动作(保证金额、状态只能由结算服务变更)。
*/
class DepositOrder extends Backend
{
@@ -18,7 +25,7 @@ class DepositOrder extends Backend
protected bool $modelSceneValidate = true;
protected string|array $quickSearchField = ['id', 'order_no', 'pay_channel', 'remark'];
protected string|array $quickSearchField = ['id', 'order_no', 'pay_channel', 'remark', 'deposit_tier_id', 'idempotency_key'];
protected string|array $defaultSortField = ['id' => 'desc'];
@@ -65,6 +72,69 @@ class DepositOrder extends Backend
]);
}
/**
* GET 时返回关联信息,便于前端详情弹窗直接渲染 user.username / channel.name
* POST 一律拒绝,保证充值订单的金额/状态只能由结算服务变更。
*/
protected function _edit(): Response
{
$pk = $this->model->getPk();
$id = $this->request ? ($this->request->post($pk) ?? $this->request->get($pk)) : null;
if ($id === null || $id === '') {
return $this->error(__('Parameter error'));
}
if ($this->request && $this->request->method() === 'POST') {
return $this->error('充值订单为自动入账,禁止直接修改,如需补单请走专用工具');
}
$row = $this->loadWithRelations(intval(strval($id)));
if (!$row) {
return $this->error(__('Record not found'));
}
if (!$this->checkChannelScoped($row)) {
return $this->error(__('You have no permission'));
}
return $this->success('', ['row' => $row]);
}
private function loadWithRelations(int $id): ?array
{
$row = $this->model
->withJoin($this->withJoinTable, $this->withJoinType)
->with($this->withJoinTable)
->visible([
'user' => ['username', 'phone'],
'channel' => ['name'],
])
->where($this->model->getTable() . '.id', $id)
->find();
if (!$row) {
return null;
}
return $row->toArray();
}
private function checkChannelScoped(array $row): bool
{
if (!$this->auth || $this->auth->isSuperAdmin()) {
return true;
}
$channelIds = $this->getScopedChannelIdsForFilter();
if ($channelIds === []) {
return false;
}
$raw = $row['channel_id'] ?? null;
if ($raw === null || $raw === '') {
return false;
}
if (!is_numeric(strval($raw))) {
return false;
}
return in_array(intval(strval($raw)), $channelIds, true);
}
/**
* @return int[]
*/