Pārlūkot izejas kodu

feat(finance): 实现会员提现功能

- 新增提现申请接口,支持微信提现方式
- 添加提现金额校验逻辑,包括最小、最大金额限制
- 实现提现手续费计算及扣除逻辑- 集成微信转账服务,创建转账记录
- 新增插件配置类,管理提现相关参数
- 扩展微信转账账单表结构,增加手续费字段
- 完善数据库迁移脚本,支持新字段存储- 更新插件ID命名规范,使用下划线分隔
- 添加提现配置项到系统设置页面
- 实现账单编号自动生成规则
runphp 4 mēneši atpakaļ
vecāks
revīzija
9c24b8d6e2

+ 1 - 0
database/migrations/20251031083213_wechatpay_transfer_bill.php

@@ -35,6 +35,7 @@ final class WechatpayTransferBill extends AbstractMigration
                 'comment' => '单据状态 APPLYING:申请中;ACCEPTED:转账已受理;PROCESSING:转账锁定资金中;WAIT_USER_CONFIRM:待收款用户确认;TRANSFERING:转账中;SUCCESS:转账成功;FAIL:转账失败;CANCELING:转账撤销中;CANCELLED:转账撤销完成'
             ])
             ->addColumn('transfer_amount', 'integer', ['signed' => false, 'comment' => '转账金额 转账金额单位为"分"'])
+            ->addColumn('fee', 'integer', ['signed' => false, 'comment' => '手续费 转账手续费,单位为"分"'])
             ->addColumn('transfer_remark', 'string', ['limit' => 32, 'comment' => '转账备注 单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符'])
             ->addColumn('fail_reason', 'string', ['limit' => 255, 'null' => true, 'comment' => '失败原因 订单已失败或者已退资金时,会返回订单失败原因'])
             ->addColumn('openid', 'string', ['limit' => 64, 'null' => true, 'comment' => '收款用户OpenID 用户在商户appid下的唯一标识'])

+ 1 - 0
src/Entity/WechatpayTransferBillEntity.php

@@ -4,6 +4,7 @@ namespace SixShop\WechatPay\Entity;
 
 
 use SixShop\Core\Entity\BaseEntity;
+use SixShop\WechatPay\Enum\TransferBillStatusEnum;
 use think\Paginator;
 
 /**

+ 8 - 0
src/Model/WechatpayTransferBillModel.php

@@ -2,6 +2,7 @@
 declare(strict_types=1);
 namespace SixShop\WechatPay\Model;
 
+use SixShop\Payment\Enum\NumberBizEnum;
 use think\db\Query;
 use think\Model;
 use SixShop\WechatPay\Enum\TransferBillStatusEnum;
@@ -15,6 +16,8 @@ class WechatpayTransferBillModel extends Model
             'type' => [
                 'state' => TransferBillStatusEnum::class,
             ],
+            'insert' => ['out_bill_no'],
+            'readonly' => ['user_id', 'mch_id', 'out_bill_no', 'appid', 'transfer_amount', 'fee', 'openid', 'user_name'],
         ];
     }
 
@@ -32,4 +35,9 @@ class WechatpayTransferBillModel extends Model
             $query->where('out_bill_no', $value);
         }
     }
+
+    protected function setOutBillNoAttr($value, $data): string
+    {
+        return generate_number(NumberBizEnum::WITHDRAWAL);
+    }
 }

+ 29 - 0
src/Service/WechatpayTransferBillService.php

@@ -0,0 +1,29 @@
+<?php
+declare(strict_types=1);
+namespace SixShop\WechatPay\Service;
+
+use SixShop\Wechat\Facade\WechatUser;
+use SixShop\WechatPay\Config;
+use SixShop\WechatPay\Enum\TransferBillStatusEnum;
+use SixShop\WechatPay\Model\WechatpayTransferBillModel;
+
+class WechatpayTransferBillService
+{
+    public function __construct(private Config $config)
+    {
+    }
+
+    public function apply(int $userID, float $transferAmount, string $userName, float $fee): int
+    {
+        return WechatpayTransferBillModel::create([
+            'user_id' => $userID,
+            'mch_id' => $this->config->mchid,
+            'appid' => $this->config->appid,
+            'transfer_amount' => bcmul((string)$transferAmount, '100', 0),
+            'fee' => bcmul((string)$fee, '100', 0),
+            'openid' => WechatUser::openid($userID),
+            'user_name' => $userName,
+            'state' => TransferBillStatusEnum::APPLYING,
+        ])->id;
+    }
+}