diff --git a/app/admin/controller/order/WithdrawOrder.php b/app/admin/controller/order/WithdrawOrder.php index 6eee312..e469ac4 100644 --- a/app/admin/controller/order/WithdrawOrder.php +++ b/app/admin/controller/order/WithdrawOrder.php @@ -25,7 +25,7 @@ class WithdrawOrder extends Backend protected bool $modelSceneValidate = true; - protected string|array $quickSearchField = ['id', 'order_no', 'idempotency_key', 'receive_type', 'receive_account', 'remark']; + protected string|array $quickSearchField = ['id', 'order_no', 'idempotency_key', 'pay_channel', 'receive_type', 'receive_account', 'ddpay_receiver_name', 'receiver_email', 'receiver_mobile', 'remark']; protected string|array $defaultSortField = ['id' => 'desc']; @@ -264,9 +264,13 @@ class WithdrawOrder extends Backend } else { $orderNo = is_string($fresh['order_no'] ?? null) ? trim($fresh['order_no'] ?? '') : strval($fresh['order_no'] ?? ''); $receiveType = is_string($fresh['receive_type'] ?? null) ? strtolower(trim($fresh['receive_type'] ?? '')) : ''; + $payChannel = is_string($fresh['pay_channel'] ?? null) ? strtolower(trim($fresh['pay_channel'] ?? '')) : ''; + if ($payChannel === '') { + $payChannel = 'ddpay'; + } - // 当前仅接入 bank 类型出金(与移动端 withdrawCreate 校验一致) - if ($orderNo !== '' && $receiveType === 'bank') { + // 当前仅 ddpay + bank 类型自动出金(与移动端 withdrawCreate 校验一致) + if ($orderNo !== '' && $receiveType === 'bank' && $payChannel === 'ddpay') { $base = \app\common\library\finance\DDPayGateway::publicBaseUrlForCallbacks($request); if ($base === '') { $base = 'https://' . strval($request->host()); diff --git a/app/api/controller/Finance.php b/app/api/controller/Finance.php index 415b3f1..c16632e 100644 --- a/app/api/controller/Finance.php +++ b/app/api/controller/Finance.php @@ -826,18 +826,38 @@ class Finance extends MobileBase } $withdrawCoinRaw = $request->post('withdraw_coin', ''); $withdrawCoin = is_string($withdrawCoinRaw) ? trim($withdrawCoinRaw) : (is_numeric($withdrawCoinRaw) ? strval($withdrawCoinRaw) : ''); + $channelCode = strtolower($this->stringParam($request->post('channel_code'))); + if ($channelCode === '') { + $channelCode = strtolower($this->stringParam($request->post('pay_channel'))); + } $receiveAccount = trim(is_string($request->post('receive_account', '')) ? $request->post('receive_account', '') : ''); $receiveType = trim(is_string($request->post('receive_type', '')) ? $request->post('receive_type', '') : ''); $receiveType = strtolower($receiveType); // DDPAY 出金(Payout)所需扩展字段:当前仅支持 receive_type=bank $receiverName = trim(is_string($request->post('receiver_name', '')) ? $request->post('receiver_name', '') : ''); + $receiverEmail = trim(is_string($request->post('receiver_email', '')) ? $request->post('receiver_email', '') : ''); + $receiverMobile = trim(is_string($request->post('receiver_mobile', '')) ? $request->post('receiver_mobile', '') : ''); $bankCode = trim(is_string($request->post('bank_code', '')) ? $request->post('bank_code', '') : ''); $bankBranch = trim(is_string($request->post('bank_branch', '')) ? $request->post('bank_branch', '') : ''); $idempotencyKey = trim(is_string($request->post('idempotency_key', '')) ? $request->post('idempotency_key', '') : ''); - if ($withdrawCoin === '' || $receiveAccount === '' || $receiveType === '' || $idempotencyKey === '') { + if ($withdrawCoin === '' || $channelCode === '' || $receiveAccount === '' || $receiveType === '' || $idempotencyKey === '' + || $receiverEmail === '' || $receiverMobile === '') { return $this->mobileError(1001, 'Missing parameters'); } + if (!in_array($channelCode, DepositChannelLib::withdrawPayoutChannelCodes(), true)) { + return $this->mobileError(2004, 'Withdraw only supports DDPay'); + } + $effectiveChannels = $this->loadDepositChannelEffective(); + if (!DepositChannelLib::assertChannelEnabled($channelCode, $effectiveChannels)) { + return $this->mobileError(2004, 'Pay channel not available'); + } + if (mb_strlen($receiverEmail) > 255 || !filter_var($receiverEmail, FILTER_VALIDATE_EMAIL)) { + return $this->mobileError(1001, 'Invalid receiver email'); + } + if (mb_strlen($receiverMobile) > 64 || !$this->isValidReceiverMobile($receiverMobile)) { + return $this->mobileError(1001, 'Invalid receiver mobile'); + } if (mb_strlen($idempotencyKey) > 64) { return $this->mobileError(1002, 'Idempotency key is too long'); } @@ -970,11 +990,14 @@ class Finance extends MobileBase 'idempotency_key' => $idempotencyKey, 'user_id' => $userId, 'channel_id' => $channelId, + 'pay_channel' => $channelCode, 'amount' => $withdrawCoin, 'fee' => $feeCoin, 'actual_amount' => $actualArrivalCoin, 'receive_type' => $receiveType, 'receive_account' => $receiveAccount, + 'receiver_email' => $receiverEmail, + 'receiver_mobile' => $receiverMobile, 'ddpay_receiver_name' => $receiverName, 'ddpay_bank_name' => $ddpayBankName, 'ddpay_bank_branch' => $bankBranch, @@ -1044,6 +1067,9 @@ class Finance extends MobileBase 'actual_arrival_coin' => $this->amountNumber($order->actual_amount ?? '0'), 'receive_type' => is_string($order->receive_type ?? null) ? $order->receive_type : strval($order->receive_type ?? ''), 'receive_account' => is_string($order->receive_account ?? null) ? $order->receive_account : strval($order->receive_account ?? ''), + 'pay_channel' => is_string($order->pay_channel ?? null) ? $order->pay_channel : strval($order->pay_channel ?? ''), + 'receiver_email' => is_string($order->receiver_email ?? null) ? $order->receiver_email : strval($order->receiver_email ?? ''), + 'receiver_mobile' => is_string($order->receiver_mobile ?? null) ? $order->receiver_mobile : strval($order->receiver_mobile ?? ''), 'reject_reason' => $statusCode === 2 && $remark !== '' ? $remark : null, 'create_time' => $order->create_time, 'review_time' => $order->review_time, @@ -1249,8 +1275,10 @@ class Finance extends MobileBase $wc = $cfg['withdraw_copy'] ?? []; $rateMode = is_array($wc) && isset($wc['rate_mode']) && is_string($wc['rate_mode']) ? $wc['rate_mode'] : 'fixed'; - $payChannels = []; $effectiveCh = DepositChannelLib::effectiveRowsFromDb(); + $withdrawPayChannels = DepositChannelLib::channelsForWithdraw($effectiveCh, $lang); + + $payChannels = []; $regCh = DepositChannelLib::codeRegistry(); foreach ($effectiveCh as $row) { if (!is_array($row)) { @@ -1296,6 +1324,7 @@ class Finance extends MobileBase 'banks' => $depositBanks, ], 'withdraw' => [ + 'pay_channels' => $withdrawPayChannels, 'banks' => $withdrawBanks, 'min_ewallet' => $minEw, 'min_bank' => $minBk, @@ -1312,8 +1341,11 @@ class Finance extends MobileBase // 与 DDPay 出金及 withdrawCreate 一致,不由后台开关配置 'fields' => [ 'receive_type_bank_only' => true, + 'require_channel_code' => true, 'require_receiver_name' => true, 'require_receive_account' => true, + 'require_receiver_email' => true, + 'require_receiver_mobile' => true, 'require_bank_code' => true, 'require_bank_branch' => false, ], @@ -1365,6 +1397,23 @@ class Finance extends MobileBase return trim($raw); } + /** + * 收款人手机号:5–32 位,仅允许数字与常见分隔符(+ - 空格) + */ + private function isValidReceiverMobile(string $mobile): bool + { + $len = mb_strlen($mobile); + if ($len < 5 || $len > 32) { + return false; + } + if (!preg_match('/^[0-9+\-\s]+$/', $mobile)) { + return false; + } + $digits = preg_replace('/\D/', '', $mobile); + + return is_string($digits) && strlen($digits) >= 5; + } + private function loadEnabledTiers(): array { $row = GameConfig::where('config_key', DepositTierLib::CONFIG_KEY)->find(); diff --git a/app/api/lang/en.php b/app/api/lang/en.php index bc317f8..cacb29e 100644 --- a/app/api/lang/en.php +++ b/app/api/lang/en.php @@ -47,6 +47,8 @@ return [ 'Deposit tier not available' => 'The selected deposit tier is not available', 'Order not found after settle' => 'Order not found after settlement', 'Invalid withdraw amount' => 'Invalid withdraw amount', + 'Invalid receiver email' => 'Invalid receiver email', + 'Invalid receiver mobile' => 'Invalid receiver mobile', 'Withdraw exceeds available bet flow' => 'The withdraw amount exceeds the available bet-flow quota', 'Too many pending deposit orders' => 'You already have multiple pending deposit orders, please complete payment first or wait for timeout', 'Too many pending withdraw orders' => 'You already have withdraw orders under review, please wait for them to be processed', @@ -58,6 +60,7 @@ return [ 'Pay channel not available for this currency' => 'The payment channel is not available for this currency', 'DDPay deposit initiation failed' => 'DDPay deposit initiation failed', 'Deposit only supports DDPay' => 'Only DDPay deposits are supported (channel_code must be ddpay)', + 'Withdraw only supports DDPay' => 'Only DDPay withdrawals are supported (channel_code must be ddpay)', // Member center account 'Data updated successfully~' => 'Data updated successfully~', 'Password has been changed~' => 'Password has been changed~', diff --git a/app/api/lang/zh-cn.php b/app/api/lang/zh-cn.php index bfb1979..8e2c1b7 100644 --- a/app/api/lang/zh-cn.php +++ b/app/api/lang/zh-cn.php @@ -79,6 +79,8 @@ return [ 'Deposit tier not available' => '所选充值档位不可用', 'Order not found after settle' => '充值成功后未找到订单', 'Invalid withdraw amount' => '提现金额不合法', + 'Invalid receiver email' => '收款人邮箱格式不正确', + 'Invalid receiver mobile' => '收款人手机号格式不正确', 'Withdraw exceeds available bet flow' => '提现金额超出可提现额度', 'Too many pending deposit orders' => '存在多笔待支付充值订单,请先完成支付或等待超时', 'Too many pending withdraw orders' => '用户当前存在多笔提现订单,请等待审核', @@ -90,6 +92,7 @@ return [ 'Pay channel not available for this currency' => '当前币种不支持该支付渠道', 'DDPay deposit initiation failed' => 'DDPay 充值发起失败', 'Deposit only supports DDPay' => '仅支持 DDPay 充值(channel_code 须为 ddpay)', + 'Withdraw only supports DDPay' => '仅支持 DDPay 提现(channel_code 须为 ddpay)', // 会员中心 account 'Data updated successfully~' => '资料更新成功~', 'Password has been changed~' => '密码已修改~', diff --git a/app/common/library/game/DepositChannel.php b/app/common/library/game/DepositChannel.php index a1b1976..af9bf7c 100644 --- a/app/common/library/game/DepositChannel.php +++ b/app/common/library/game/DepositChannel.php @@ -402,6 +402,72 @@ final class DepositChannel return array_values(array_unique($codes)); } + /** + * 当前服务端已对接自动出金的渠道(与 withdrawCreate 校验一致) + * + * @return list + */ + public static function withdrawPayoutChannelCodes(): array + { + return ['ddpay']; + } + + /** + * @param list}> $effectiveRows + */ + public static function assertChannelEnabled(string $channelCode, array $effectiveRows): bool + { + $row = self::findMergedByCode($effectiveRows, $channelCode); + if ($row === null) { + return false; + } + + return ($row['status'] ?? 0) === 1; + } + + /** + * 提现页可选支付渠道(仅返回已启用且已对接出金的渠道) + * + * @param list}> $effectiveRows + * + * @return list + */ + public static function channelsForWithdraw(array $effectiveRows, string $lang): array + { + $registry = self::codeRegistry(); + $allowed = self::withdrawPayoutChannelCodes(); + $out = []; + foreach ($effectiveRows as $row) { + if (($row['status'] ?? 0) !== 1) { + continue; + } + $code = isset($row['code']) && is_string($row['code']) ? $row['code'] : ''; + if ($code === '' || !in_array($code, $allowed, true)) { + continue; + } + if (!isset($registry[$code])) { + continue; + } + $meta = $registry[$code]; + $sortRaw = $row['sort'] ?? 0; + $sortVal = is_numeric($sortRaw) ? intval($sortRaw) : 0; + $out[] = [ + 'code' => $code, + 'name' => self::pickLangName($meta, $lang), + 'sort' => $sortVal, + ]; + } + usort($out, static function (array $a, array $b): int { + if ($a['sort'] !== $b['sort']) { + return $a['sort'] <=> $b['sort']; + } + + return strcmp($a['code'], $b['code']); + }); + + return $out; + } + /** * @param list> $items * diff --git a/docs/36字花-移动端接口设计草案.md b/docs/36字花-移动端接口设计草案.md index e23c2ce..c972718 100644 --- a/docs/36字花-移动端接口设计草案.md +++ b/docs/36字花-移动端接口设计草案.md @@ -428,6 +428,8 @@ - `status`:int(启用状态,1=启用) - `tier_ids`:array(兼容字段;当前固定空数组,表示自动兼容全部充值档位) - `withdraw`:object + - `pay_channels`:array(提现可选支付渠道,用于 `withdrawCreate` 的 `channel_code`;仅返回后台已启用且服务端已对接出金的渠道) + - 每项:`code`(string,渠道代码,小写)、`name`(展示名)、`sort`(排序) - `banks`:array(提现银行) - `min_ewallet`:string(电子钱包最低提现) - `min_bank`:string(银行卡最低提现) @@ -437,8 +439,11 @@ - `rate_mode`:string(`fixed` / `live`) - `fields`:object(**与 DDPay / `withdrawCreate` 一致**,不由后台「支付/收款配置」开关维护;用于客户端展示必填项) - `receive_type_bank_only`:bool(当前固定 `true`,仅支持银行卡出金) + - `require_channel_code`:bool(固定 `true`,对应 `channel_code`) - `require_receiver_name`:bool(固定 `true`,对应 `receiver_name`) - `require_receive_account`:bool(固定 `true`,对应 `receive_account`) + - `require_receiver_email`:bool(固定 `true`,对应 `receiver_email`) + - `require_receiver_mobile`:bool(固定 `true`,对应 `receiver_mobile`) - `require_bank_code`:bool(固定 `true`,对应 `bank_code`) - `require_bank_branch`:bool(固定 `false`,`bank_branch` 选填,不传时服务端按 `N/A` 提交 DDPay) @@ -578,12 +583,19 @@ ### 5.7 提现申请 - **POST** `/api/finance/withdrawCreate` +说明: +- **仅支持 DDPay 出金**:`channel_code` 必须为 **`ddpay`**(兼容同义字段 `pay_channel`),且该渠道在收银台配置中为启用状态,否则返回 `code=2004`。 +- 可选渠道列表见 `depositWithdrawConfig` → `withdraw.pay_channels`。 + 请求参数: +- `channel_code`:string,必填(支付渠道代码;当前仅支持 `ddpay`;兼容字段 `pay_channel`) - `withdraw_coin`:string(含义:申请提现金额,必须 > 0) - `receive_account`:string(含义:收款账号;对接 DDPay 出金时对应官方字段 **`receiver_account`**,为收款账户号/手机号,须与银行登记一致) - `receive_type`:string(含义:收款类型;当前版本仅支持 `bank`) - `idempotency_key`:string(含义:防重复提交提现) - `receiver_name`:string(含义:收款账户持有人姓名;`receive_type=bank` 必填,对应官方 **`receiver_name`**,须与银行登记一致) +- `receiver_email`:string(含义:收款人邮箱,必填,须为合法邮箱格式,最长 255) +- `receiver_mobile`:string(含义:收款人手机号,必填,5–32 位,仅允许数字与 `+` `-` 空格,至少含 5 位数字) - `bank_code`:string(含义:银行代码;`receive_type=bank` 必填。取值来自收银台配置 `withdraw_banks[].code`;服务端会映射为 DDPay 所需的 **`bank[name]`** 银行全称发起出金) - `bank_branch`:string(含义:银行支行名称;`receive_type=bank` 可选。官方 **`bank_branch`** 为必填项,若客户端不传则服务端按 **`N/A`** 提交,与 DDPay 文档「若缺失则默认值为 `N/A`」一致) @@ -611,17 +623,18 @@ - `risk_review_required`:bool(含义:是否命中人工审核) 校验顺序(任一失败即返回对应错误码,不再创建订单): -1. 参数完整性与金额合法性(`code=1001`;金额必须为数值且 > 0) -2. **待审核订单数限制**:同一用户 `status=0`(待审核)的 `withdraw_order` 不得超过 3 笔,否则 `code=2004 Too many pending withdraw orders`,`data` 中回传: +1. 参数完整性与金额合法性(`code=1001`;含 `channel_code`、`withdraw_coin` 等必填项;金额必须为数值且 > 0) +2. **支付渠道**:`channel_code` 非 `ddpay` 返回 `code=2004 Withdraw only supports DDPay`;渠道未启用返回 `code=2004 Pay channel not available` +3. **待审核订单数限制**:同一用户 `status=0`(待审核)的 `withdraw_order` 不得超过 3 笔,否则 `code=2004 Too many pending withdraw orders`,`data` 中回传: - `max_pending`:上限值(当前为 `3`) - `pending_count`:当前待审核订单数 -3. `coin_balance >= withdraw_coin`,否则 `code=2001 Insufficient balance` -4. **单笔上限校验**:`withdraw_coin <= max_withdrawable`,否则 `code=2002 Withdraw exceeds available bet flow`,`data` 中回传: +4. `coin_balance >= withdraw_coin`,否则 `code=2001 Insufficient balance` +5. **单笔上限校验**:`withdraw_coin <= max_withdrawable`,否则 `code=2002 Withdraw exceeds available bet flow`,`data` 中回传: - `max_withdrawable`:**当前允许的单笔最大提现金额**(= `min(coin_balance, max_withdraw_by_flow)`,前端据此提示"最大可提现金额为 XXX") - `coin_balance`、`bet_flow_coin`、`total_withdraw_coin`、`ratio` - `max_withdraw_by_flow`:仅按打码量折算的上限(= `max(0, bet_flow_coin / ratio - total_withdraw_coin)`);`ratio=0` 时为 `null` -5. 以上全通过后在同一事务内: - - `withdraw_order` 写入:`amount` / `fee`(默认 0.5%) / `actual_amount = amount - fee` / `status=0`(待审核) / `channel_id` 取自用户归属渠道快照;同时写入收款字段(`receive_type/receive_account/receiver_name/bank_code/bank_branch`)。 +6. 以上全通过后在同一事务内: + - `withdraw_order` 写入:`pay_channel`(= `channel_code`)/ `amount` / `fee`(默认 0.5%) / `actual_amount = amount - fee` / `status=0`(待审核) / `channel_id` 取自用户归属渠道快照;同时写入收款字段(`receive_type/receive_account/receiver_email/receiver_mobile/receiver_name/bank_code/bank_branch`)。 - `user` 表原子更新:`coin -= withdraw_coin` 且 `total_withdraw_coin += withdraw_coin`(WHERE `coin >= withdraw_coin` 防止并发超额扣减)。 - `user_wallet_record` 写入 `biz_type=withdraw`、`direction=2`、`amount=withdraw_coin`、`ref_type=withdraw_order`、`idempotency_key=wd_apply_{order_no}`,代表"冻结"动作。 @@ -645,6 +658,11 @@ - `withdraw_coin`:string(含义:申请提现金额,与后台 `withdraw_order.amount` 对齐) - `fee_coin`:string(含义:手续费,与后台 `withdraw_order.fee` 对齐) - `actual_arrival_coin`:string(含义:实际到账金额 = 申请金额 - 手续费;后台审核调整后会同步刷新) +- `receive_type`:string(含义:收款类型) +- `receive_account`:string(含义:收款账号) +- `pay_channel`:string(含义:支付渠道代码,与 `channel_code` 一致) +- `receiver_email`:string(含义:收款人邮箱) +- `receiver_mobile`:string(含义:收款人手机号) - `reject_reason`:string/null(含义:拒绝原因,`status=rejected` 时取自 `withdraw_order.remark`,否则为 `null`) - `create_time`:int(含义:申请时间) - `review_time`:int/null(含义:审核时间戳,未审核为 `null`) diff --git a/web/src/lang/backend/en/config/financeCashierConfig.ts b/web/src/lang/backend/en/config/financeCashierConfig.ts index 1e5d964..499649c 100644 --- a/web/src/lang/backend/en/config/financeCashierConfig.ts +++ b/web/src/lang/backend/en/config/financeCashierConfig.ts @@ -39,7 +39,7 @@ export default { ddpay_spec_intro: 'Withdrawals use DDPay Payout (mobile: withdrawCreate). Deposits with channel ddpay use depositCreate. Below is a short field summary; see the DDPay doc and the mobile API draft in the repo for details.', ddpay_spec_li_withdraw: - 'Withdraw (required): withdraw_coin, receive_type=bank, receive_account, receiver_name (as registered with the bank), bank_code (must match a code from “Withdraw banks by currency” on this page), idempotency_key; bank_branch optional (server sends N/A if omitted).', + 'Withdraw (required): channel_code=ddpay, withdraw_coin, receive_type=bank, receive_account, receiver_name (as registered with the bank), receiver_email, receiver_mobile, bank_code (must match a code from “Withdraw banks by currency” on this page), idempotency_key; bank_branch optional (server sends N/A if omitted).', ddpay_spec_li_bank_table: 'English bank name maps to DDPay bank[name] and must match the official full bank names, or payout may be rejected.', ddpay_spec_li_deposit: diff --git a/web/src/lang/backend/en/order/withdrawOrder.ts b/web/src/lang/backend/en/order/withdrawOrder.ts index b6d030a..67a839d 100644 --- a/web/src/lang/backend/en/order/withdrawOrder.ts +++ b/web/src/lang/backend/en/order/withdrawOrder.ts @@ -7,8 +7,12 @@ export default { amount: 'Apply amount', fee: 'Fee', actual_amount: 'Actual amount', + pay_channel: 'Pay channel', receive_type: 'Receive type', receive_account: 'Receive account', + receiver_name: 'Cardholder name', + receiver_email: 'Receiver email', + receiver_mobile: 'Receiver mobile', idempotency_key: 'Idempotency key', status: 'Status', 'status 0': 'Pending review', diff --git a/web/src/lang/backend/zh-cn/config/financeCashierConfig.ts b/web/src/lang/backend/zh-cn/config/financeCashierConfig.ts index bf53fd1..f0a2c06 100644 --- a/web/src/lang/backend/zh-cn/config/financeCashierConfig.ts +++ b/web/src/lang/backend/zh-cn/config/financeCashierConfig.ts @@ -39,7 +39,7 @@ export default { ddpay_spec_intro: '当前提现走 DDPay 出金(Payout),移动端调用 withdrawCreate;充值渠道为 ddpay 时调用 depositCreate。下列为字段约定摘要,详细以仓库内 DDPay 文档与《36字花-移动端接口设计草案》为准。', ddpay_spec_li_withdraw: - '提现必填:withdraw_coin、receive_type=bank、receive_account(收款账号)、receiver_name(与银行登记一致)、bank_code(须与本页「提现支持银行(按币种)」中 code 一致)、idempotency_key;bank_branch 选填,不传则服务端按 N/A 提交。', + '提现必填:channel_code=ddpay(支付渠道)、withdraw_coin、receive_type=bank、receive_account(收款账号)、receiver_name(与银行登记一致)、receiver_email、receiver_mobile、bank_code(须与本页「提现支持银行(按币种)」中 code 一致)、idempotency_key;bank_branch 选填,不传则服务端按 N/A 提交。', ddpay_spec_li_bank_table: '「银行名(英文)」将映射为 DDPay 的 bank[name],请与 DDPay 官方银行全称列表一致,否则出金可能被拒。', ddpay_spec_li_deposit: diff --git a/web/src/lang/backend/zh-cn/order/withdrawOrder.ts b/web/src/lang/backend/zh-cn/order/withdrawOrder.ts index 3bd2f15..9510414 100644 --- a/web/src/lang/backend/zh-cn/order/withdrawOrder.ts +++ b/web/src/lang/backend/zh-cn/order/withdrawOrder.ts @@ -7,8 +7,12 @@ export default { amount: '申请金额', fee: '手续费', actual_amount: '实际到账', + pay_channel: '支付渠道', receive_type: '收款类型', receive_account: '收款账号', + receiver_name: '持卡人姓名', + receiver_email: '收款人邮箱', + receiver_mobile: '收款人手机号', idempotency_key: '幂等键', status: '状态', 'status 0': '待审核', diff --git a/web/src/views/backend/order/withdrawOrder/index.vue b/web/src/views/backend/order/withdrawOrder/index.vue index 94512e9..36c42f2 100644 --- a/web/src/views/backend/order/withdrawOrder/index.vue +++ b/web/src/views/backend/order/withdrawOrder/index.vue @@ -79,6 +79,14 @@ const baTable = new baTableClass( { label: t('order.withdrawOrder.amount'), prop: 'amount', align: 'center', minWidth: 110, operator: 'RANGE', formatter: formatAmount }, { label: t('order.withdrawOrder.fee'), prop: 'fee', align: 'center', minWidth: 110, operator: 'RANGE', formatter: formatAmount }, { label: t('order.withdrawOrder.actual_amount'), prop: 'actual_amount', align: 'center', minWidth: 110, operator: 'RANGE', formatter: formatAmount }, + { + label: t('order.withdrawOrder.pay_channel'), + prop: 'pay_channel', + align: 'center', + minWidth: 110, + operator: 'LIKE', + operatorPlaceholder: t('Fuzzy query'), + }, { label: t('order.withdrawOrder.receive_type'), prop: 'receive_type', @@ -96,6 +104,33 @@ const baTable = new baTableClass( operatorPlaceholder: t('Fuzzy query'), showOverflowTooltip: true, }, + { + label: t('order.withdrawOrder.receiver_name'), + prop: 'ddpay_receiver_name', + align: 'center', + minWidth: 120, + operator: 'LIKE', + operatorPlaceholder: t('Fuzzy query'), + showOverflowTooltip: true, + }, + { + label: t('order.withdrawOrder.receiver_email'), + prop: 'receiver_email', + align: 'center', + minWidth: 180, + operator: 'LIKE', + operatorPlaceholder: t('Fuzzy query'), + showOverflowTooltip: true, + }, + { + label: t('order.withdrawOrder.receiver_mobile'), + prop: 'receiver_mobile', + align: 'center', + minWidth: 140, + operator: 'LIKE', + operatorPlaceholder: t('Fuzzy query'), + showOverflowTooltip: true, + }, { label: t('order.withdrawOrder.idempotency_key'), prop: 'idempotency_key', diff --git a/web/src/views/backend/order/withdrawOrder/popupForm.vue b/web/src/views/backend/order/withdrawOrder/popupForm.vue index a23abbd..b8aef93 100644 --- a/web/src/views/backend/order/withdrawOrder/popupForm.vue +++ b/web/src/views/backend/order/withdrawOrder/popupForm.vue @@ -39,12 +39,24 @@ + + + + + + + + + + + + @@ -171,8 +183,12 @@ const form = reactive({ review_admin_text: '-', review_time_text: '-', idempotency_key: '', + pay_channel: '', receive_type: '', receive_account: '', + receiver_name: '', + receiver_email: '', + receiver_mobile: '', amount: 0, fee: 0, status: 0, @@ -220,8 +236,12 @@ const hydrate = () => { form.status = Number(row['status'] ?? 0) form.remark = String(row['remark'] ?? '') form.idempotency_key = String(row['idempotency_key'] ?? '') + form.pay_channel = String(row['pay_channel'] ?? '') form.receive_type = String(row['receive_type'] ?? '') form.receive_account = String(row['receive_account'] ?? '') + form.receiver_name = String(row['ddpay_receiver_name'] ?? '') + form.receiver_email = String(row['receiver_email'] ?? '') + form.receiver_mobile = String(row['receiver_mobile'] ?? '') form.create_time_text = formatTime(row['create_time']) form.review_time_text = formatTime(row['review_time']) form.user_text = resolveRelationText(row, 'user', row['user_id'])