'integer', 'out_id2' => 'integer', 'out_id3' => 'integer', 'currency_id' => 'integer', 'fund_id' => 'integer', 'fund_to_uid' => 'integer', 'fund_in_uid' => 'integer', 'exchange_rate' => 'decimal:4', 'fee_in_rate' => 'decimal:4', 'fee_out_rate' => 'decimal:4', 'fee_in_min' => 'decimal:4', 'fee_in_max' => 'decimal:4', 'fee_out_min' => 'decimal:4', 'fee_out_max' => 'decimal:4', 'fee_account_uid' => 'integer', 'is_enabled' => 'boolean', 'allow_transfer_in' => 'boolean', 'allow_transfer_out' => 'boolean', 'created_at' => 'datetime', 'updated_at' => 'datetime', 'deleted_at' => 'datetime', ]; /** * 软删除 */ protected $dates = ['deleted_at']; /** * 隐藏字段 */ protected $hidden = []; /** * 关联划转订单 */ public function orders() { return $this->hasMany(TransferOrder::class, 'transfer_app_id'); } /** * 获取启用状态文本 */ public function getEnabledTextAttribute(): string { return $this->is_enabled ? '启用' : '禁用'; } /** * 获取启用状态颜色 */ public function getEnabledColorAttribute(): string { return $this->is_enabled ? 'success' : 'danger'; } /** * 获取允许转入状态文本 */ public function getAllowTransferInTextAttribute(): string { return $this->allow_transfer_in ? '允许' : '禁止'; } /** * 获取允许转入状态颜色 */ public function getAllowTransferInColorAttribute(): string { return $this->allow_transfer_in ? 'success' : 'danger'; } /** * 获取允许转出状态文本 */ public function getAllowTransferOutTextAttribute(): string { return $this->allow_transfer_out ? '允许' : '禁止'; } /** * 获取允许转出状态颜色 */ public function getAllowTransferOutColorAttribute(): string { return $this->allow_transfer_out ? 'success' : 'danger'; } /** * 判断是否支持转入 * 支持转入的条件:应用启用 && 允许转入 && (配置了转入查询URL 或者 没有配置任何外部API(本地处理)) */ public function supportsTransferIn(): bool { if (!$this->is_enabled || !$this->allow_transfer_in) { return false; } return !empty($this->order_in_info_url) || (empty($this->order_callback_url) && empty($this->order_in_info_url) && empty($this->order_out_create_url) && empty($this->order_out_info_url)); } /** * 判断是否支持转出 * 支持转出的条件:应用启用 && 允许转出 && (配置了转出创建URL 或者 没有配置任何外部API(本地处理)) */ public function supportsTransferOut(): bool { if (!$this->is_enabled || !$this->allow_transfer_out) { return false; } return !empty($this->order_out_create_url) || (empty($this->order_callback_url) && empty($this->order_in_info_url) && empty($this->order_out_create_url) && empty($this->order_out_info_url)); } /** * 判断是否支持回调 */ public function supportsCallback(): bool { return !empty($this->order_callback_url); } /** * 获取手续费收取账户UID * * @return int 手续费收取账户UID,默认为1 */ public function getFeeAccountUid(): int { return $this->fee_account_uid > 0 ? $this->fee_account_uid : 1; } /** * 获取手续费收取账户信息 */ public function getFeeAccount() { $feeAccountUid = $this->getFeeAccountUid(); return \App\Module\Fund\Services\FundService::getAccountInfo($feeAccountUid); } /** * 计算转入手续费 * * @param string $amount 转入金额 * @return array ['fee_rate' => 手续费率, 'fee_amount' => 手续费金额, 'actual_amount' => 实际到账金额] * @deprecated 模型内不应该有逻辑 */ public function calculateInFee(string $amount): array { return $this->calculateFee($amount, $this->fee_in_rate, $this->fee_in_min, $this->fee_in_max); } /** * 计算转出手续费 * * @param string $amount 转出金额 * @param array $context 额外的上下文数据(包含用户ID等信息) * @return array ['fee_rate' => 手续费率, 'fee_amount' => 手续费金额, 'actual_amount' => 用户总支付金额] * @deprecated 模型内,不应该有逻辑 */ public function calculateOutFee(string $amount, array $context = []): array { // 使用FeeService来计算手续费,这样可以触发事件机制 return \App\Module\Transfer\Services\FeeService::calculateOutFee($this, $amount, $context); } /** * 计算手续费的通用方法(从金额中扣除手续费) * * @param string $amount 金额 * @param float $feeRate 手续费率 * @param float $minFee 最低手续费 * @param float $maxFee 最高手续费 * @return array */ private function calculateFee(string $amount, float $feeRate, float $minFee, float $maxFee): array { $amountDecimal = bcmul($amount, '1', 4); // 转换为4位小数 // 按比例计算手续费 $feeAmount = bcmul($amountDecimal, (string)$feeRate, 4); // 应用最低手续费限制 if (bccomp($feeAmount, (string)$minFee, 4) < 0) { $feeAmount = bcmul((string)$minFee, '1', 4); } // 应用最高手续费限制(如果设置了) if ($maxFee > 0 && bccomp($feeAmount, (string)$maxFee, 4) > 0) { $feeAmount = bcmul((string)$maxFee, '1', 4); } // 计算实际到账金额(扣除手续费后) $actualAmount = bcsub($amountDecimal, $feeAmount, 4); return [ 'fee_rate' => $feeRate, 'fee_amount' => $feeAmount, 'actual_amount' => $actualAmount, // 对于转入:用户实际收到金额 ]; } /** * 检查是否启用了手续费 * * @param string $type 类型:'in' 或 'out' * @return bool */ public function isFeeEnabled(string $type): bool { if ($type === 'in') { return $this->fee_in_rate > 0 || $this->fee_in_min > 0; } elseif ($type === 'out') { return $this->fee_out_rate > 0 || $this->fee_out_min > 0; } return false; } }