Просмотр исходного кода

扩展URS转账手续费配置支持转入/转出

- 添加transfer_type字段区分转入(in)和转出(out)类型
- 更新模型、DTO、服务层和逻辑层支持转账类型参数
- 扩展后台管理界面:新增转账类型字段、筛选、表单等
- 添加转入手续费配置数据(大多免费)
- 优化缓存机制:按转账类型分别缓存
- 更新SQL文件和数据库结构文档
- 测试验证:API和后台管理功能正常工作
AI Assistant 6 месяцев назад
Родитель
Сommit
f276214e14

+ 135 - 0
AiWork/202506/190054-删除URS用户推荐关系表多余字段.md

@@ -0,0 +1,135 @@
+# 删除URS用户推荐关系表多余字段
+
+## 任务概述
+删除URS用户推荐关系表中的多余字段:user_key和referrer_user_key,这些字段已确认为无效字段,用户key信息已经在用户绑定表中保存。
+
+## 完成时间
+2025-06-19 00:45:00 - 2025-06-19 00:54:00
+
+## 问题分析
+
+### 发现的问题
+1. **多余字段**:`kku_urs_promotion_user_referrals`表中存在`user_key`和`referrer_user_key`字段
+2. **数据为空**:这两个字段在所有记录中都是NULL,没有被使用
+3. **功能重复**:用户key信息已经在`kku_urs_promotion_user_mappings`表中保存
+4. **代码未使用**:在模型的`$fillable`数组中没有包含这两个字段,服务层代码也没有使用
+
+### 字段状态验证
+```sql
+-- 检查字段使用情况
+SELECT COUNT(*) as total_count, 
+       COUNT(user_key) as user_key_count, 
+       COUNT(referrer_user_key) as referrer_user_key_count
+FROM kku_urs_promotion_user_referrals;
+
+-- 结果:total_count=3, user_key_count=0, referrer_user_key_count=0
+```
+
+## 实施方案
+
+### 1. 数据库修改
+删除字段和相关索引:
+
+```sql
+-- 删除索引
+ALTER TABLE kku_urs_promotion_user_referrals 
+DROP INDEX idx_user_key,
+DROP INDEX idx_referrer_user_key;
+
+-- 删除字段
+ALTER TABLE kku_urs_promotion_user_referrals 
+DROP COLUMN user_key,
+DROP COLUMN referrer_user_key;
+```
+
+### 2. 模型代码更新
+更新`UrsUserReferral`模型:
+- 移除字段注释定义
+- 保持`$fillable`数组不变(本来就没有包含这些字段)
+
+### 3. 后台管理修复
+修复后台管理控制器中的闭包函数参数问题:
+```php
+// 修复前
+$show->field('related_links', '相关链接')->unescape()->as(function ($value, $model) {
+
+// 修复后  
+$show->field('related_links', '相关链接')->unescape()->as(function ($value) use ($show) {
+    $model = $show->model();
+```
+
+### 4. SQL文件更新
+- 更新`urs_promotion_user_referrals.sql`,移除多余字段定义
+- 创建`remove_user_key_fields.sql`记录删除操作
+
+## 验证测试
+
+### 1. 数据库结构验证
+```sql
+DESCRIBE kku_urs_promotion_user_referrals;
+```
+确认字段已成功删除,表结构正确。
+
+### 2. 后台管理界面测试
+- ✅ 列表页面正常显示
+- ✅ 详情页面正常显示
+- ✅ 数据完整性保持
+- ✅ 相关链接功能正常
+
+### 3. 功能完整性测试
+- ✅ 推荐关系数据完整
+- ✅ 农场用户信息正常显示
+- ✅ 关联查询功能正常
+- ✅ 筛选和排序功能正常
+
+## 影响评估
+
+### 正面影响
+1. **数据库优化**:减少了无用字段,提升查询性能
+2. **代码简化**:移除了冗余的字段定义
+3. **维护性提升**:减少了混淆,提高代码可读性
+4. **存储优化**:减少了数据库存储空间占用
+
+### 风险控制
+1. **数据安全**:删除前确认字段为空,无数据丢失风险
+2. **功能完整**:用户key信息在映射表中完整保存
+3. **向后兼容**:代码中本来就没有使用这些字段
+4. **测试验证**:全面测试后台管理功能正常
+
+## 技术细节
+
+### 删除的字段
+- `user_key` VARCHAR(255) - URS用户凭证
+- `referrer_user_key` VARCHAR(255) - URS推荐人凭证
+
+### 删除的索引
+- `idx_user_key` - user_key字段索引
+- `idx_referrer_user_key` - referrer_user_key字段索引
+
+### 保留的核心字段
+- `id` - 主键ID
+- `urs_user_id` - URS用户ID
+- `urs_referrer_id` - URS推荐人ID
+- `referral_time` - 推荐时间
+- `status` - 状态
+- `created_at` - 创建时间
+- `updated_at` - 更新时间
+
+## 文件修改清单
+
+### 修改的文件
+1. `app/Module/UrsPromotion/Models/UrsUserReferral.php` - 移除字段定义
+2. `app/Module/UrsPromotion/AdminControllers/UrsUserReferralController.php` - 修复闭包参数
+3. `app/Module/UrsPromotion/Databases/GenerateSql/urs_promotion_user_referrals.sql` - 更新表结构
+
+### 新增的文件
+1. `app/Module/UrsPromotion/Databases/GenerateSql/remove_user_key_fields.sql` - 删除操作记录
+
+## 总结
+成功删除了URS用户推荐关系表中的多余字段,优化了数据库结构,提升了系统性能和代码可维护性。删除操作安全无风险,所有功能测试通过,系统运行正常。
+
+这次优化体现了数据库设计的重要性:
+- 避免冗余字段设计
+- 及时清理无用数据
+- 保持代码和数据库结构的一致性
+- 定期进行系统优化和清理

+ 33 - 6
app/Module/UrsPromotion/AdminControllers/UrsTransferFeeConfigController.php

@@ -30,11 +30,19 @@ class UrsTransferFeeConfigController extends AdminController
     {
         return Grid::make(new UrsTransferFeeConfigRepository(), function (Grid $grid) {
             $grid->column('id', 'ID')->sortable();
-            
+
+            $grid->column('transfer_type', '转账类型')->display(function ($value) {
+                $typeMap = ['in' => '转入', 'out' => '转出'];
+                return $typeMap[$value] ?? $value;
+            })->label([
+                'in' => 'success',
+                'out' => 'primary',
+            ])->sortable();
+
             $grid->column('house_level', '房屋等级')->display(function ($value) {
                 return $value == 0 ? '所有等级' : $value . '级';
             })->sortable();
-            
+
             $grid->column('talent_level', '达人等级')->display(function ($value) {
                 return $value == 0 ? '所有等级' : $value . '级';
             })->sortable();
@@ -61,6 +69,11 @@ class UrsTransferFeeConfigController extends AdminController
             // 筛选器
             $grid->filter(function (Filter $filter) {
 
+                $filter->equal('transfer_type', '转账类型')->select([
+                    'out' => '转出',
+                    'in' => '转入',
+                ]);
+
                 $filter->equal('house_level', '房屋等级')->select([
                     0 => '所有等级',
                     1 => '1级', 2 => '2级', 3 => '3级', 4 => '4级', 5 => '5级', 6 => '6级',
@@ -99,7 +112,12 @@ class UrsTransferFeeConfigController extends AdminController
         return Show::make($id, new UrsTransferFeeConfigRepository(), function (Show $show) {
 
             $show->field('id', 'ID');
-            
+
+            $show->field('transfer_type', '转账类型')->as(function ($value) {
+                $typeMap = ['in' => '转入', 'out' => '转出'];
+                return $typeMap[$value] ?? $value;
+            });
+
             $show->field('house_level', '房屋等级')->as(function ($value) {
                 return $value == 0 ? '所有等级' : $value . '级';
             });
@@ -129,19 +147,23 @@ class UrsTransferFeeConfigController extends AdminController
             // 显示匹配条件描述
             $show->field('match_condition', '匹配条件')->as(function () {
                 $conditions = [];
-                
+
+                // 转账类型
+                $typeMap = ['in' => '转入', 'out' => '转出'];
+                $conditions[] = $typeMap[$this->transfer_type] ?? $this->transfer_type;
+
                 if ($this->house_level > 0) {
                     $conditions[] = "房屋等级{$this->house_level}级";
                 } else {
                     $conditions[] = "所有房屋等级";
                 }
-                
+
                 if ($this->talent_level > 0) {
                     $conditions[] = "达人等级{$this->talent_level}级";
                 } else {
                     $conditions[] = "所有达人等级";
                 }
-                
+
                 return implode(' + ', $conditions);
             });
         });
@@ -158,6 +180,11 @@ class UrsTransferFeeConfigController extends AdminController
 
             $form->display('id', 'ID');
 
+            $form->select('transfer_type', '转账类型')->options([
+                'out' => '转出',
+                'in' => '转入',
+            ])->default('out')->required()->help('选择转账类型:转出或转入');
+
             $form->select('house_level', '房屋等级')->options([
                 0 => '所有等级',
                 1 => '1级', 2 => '2级', 3 => '3级', 4 => '4级', 5 => '5级', 6 => '6级',

+ 35 - 0
app/Module/UrsPromotion/Databases/GenerateSql/extend_transfer_fee_config_for_transfer_in.sql

@@ -0,0 +1,35 @@
+-- 扩展URS转账手续费配置支持转入/转出
+-- 执行时间: 2025-06-19 01:05:00
+-- 说明: 为URS转账手续费配置表添加transfer_type字段,支持转入和转出两种类型的手续费配置
+
+-- 1. 添加transfer_type字段
+ALTER TABLE `kku_urs_promotion_transfer_fee_configs` 
+ADD COLUMN `transfer_type` ENUM('in', 'out') NOT NULL DEFAULT 'out' COMMENT '转账类型:in转入,out转出' AFTER `talent_level`;
+
+-- 2. 添加包含transfer_type的复合索引
+ALTER TABLE `kku_urs_promotion_transfer_fee_configs` 
+ADD INDEX `idx_type_house_talent_status` (`transfer_type`, `house_level`, `talent_level`, `status`);
+
+-- 3. 更新现有记录为转出类型(已经是默认值,此步骤可选)
+UPDATE `kku_urs_promotion_transfer_fee_configs` 
+SET `transfer_type` = 'out' 
+WHERE `transfer_type` = 'out';
+
+-- 4. 为转入操作添加默认配置
+INSERT INTO `kku_urs_promotion_transfer_fee_configs` (`transfer_type`, `house_level`, `talent_level`, `fee_rate`, `description`, `priority`, `status`) VALUES
+-- 转入默认配置(通常转入手续费较低或免费)
+('in', 0, 0, 0.0000, '默认转入手续费率0%(免费)', 1, 1),
+
+-- 转入房屋等级优惠(可以设置一些特殊情况的转入费用)
+('in', 1, 0, 0.0100, '新手房屋1级转入手续费1%', 10, 0),
+('in', 7, 0, 0.0000, '房屋7级及以上转入免费', 20, 1),
+
+-- 转入达人等级优惠
+('in', 0, 1, 0.0000, '初级达人转入免费', 15, 1),
+('in', 0, 2, 0.0000, '中级达人转入免费', 25, 1),
+('in', 0, 3, 0.0000, '高级达人转入免费', 35, 1),
+('in', 0, 4, 0.0000, '资深达人转入免费', 45, 1),
+('in', 0, 5, 0.0000, '顶级达人转入免费', 55, 1);
+
+-- 验证数据
+-- SELECT transfer_type, COUNT(*) as count FROM kku_urs_promotion_transfer_fee_configs GROUP BY transfer_type;

+ 11 - 28
app/Module/UrsPromotion/Databases/GenerateSql/urs_promotion_transfer_fee_configs.sql

@@ -1,39 +1,22 @@
--- URS推广模块转出手续费配置表
--- 用于根据用户的房屋等级和达人等级配置不同的转出手续费率
+-- ******************************************************************
+-- 表 kku_urs_promotion_transfer_fee_configs 的创建SQL
+-- 对应的Model: App\Module\UrsPromotion\Models\UrsTransferFeeConfig
+-- 警告: 此文件由系统自动生成,禁止修改!
+-- ******************************************************************
 
 CREATE TABLE `kku_urs_promotion_transfer_fee_configs` (
   `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
   `house_level` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '房屋等级(0表示所有等级)',
   `talent_level` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '达人等级(0表示所有等级)',
+  `transfer_type` enum('in','out') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'out' COMMENT '转账类型:in转入,out转出',
   `fee_rate` decimal(6,4) NOT NULL DEFAULT '0.0000' COMMENT '手续费率(0-1之间的小数)',
-  `description` varchar(255) NOT NULL DEFAULT '' COMMENT '配置描述',
+  `description` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '配置描述',
   `priority` int unsigned NOT NULL DEFAULT '0' COMMENT '优先级(数值越大优先级越高)',
   `status` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '状态:1启用,0禁用',
   `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
   `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`) USING BTREE,
-  KEY `idx_house_talent_level` (`house_level`, `talent_level`) USING BTREE,
-  KEY `idx_status_priority` (`status`, `priority`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='URS推广模块转出手续费配置表';
-
--- 插入默认配置数据
-INSERT INTO `kku_urs_promotion_transfer_fee_configs` (`house_level`, `talent_level`, `fee_rate`, `description`, `priority`, `status`) VALUES
--- 默认配置(所有用户)
-(0, 0, 0.0500, '默认转出手续费率5%', 1, 1),
-
--- 房屋等级优惠
-(7, 0, 0.0400, '房屋7级及以上用户优惠费率4%', 10, 1),
-(10, 0, 0.0300, '房屋10级及以上用户优惠费率3%', 20, 1),
-(12, 0, 0.0200, '房屋12级用户优惠费率2%', 30, 1),
-
--- 达人等级优惠
-(0, 1, 0.0450, '初级达人优惠费率4.5%', 15, 1),
-(0, 2, 0.0400, '中级达人优惠费率4%', 25, 1),
-(0, 3, 0.0350, '高级达人优惠费率3.5%', 35, 1),
-(0, 4, 0.0300, '资深达人优惠费率3%', 45, 1),
-(0, 5, 0.0200, '顶级达人优惠费率2%', 55, 1),
-
--- 房屋等级+达人等级组合优惠
-(10, 3, 0.0250, '房屋10级+高级达人组合优惠费率2.5%', 60, 1),
-(12, 4, 0.0150, '房屋12级+资深达人组合优惠费率1.5%', 70, 1),
-(12, 5, 0.0100, '房屋12级+顶级达人组合优惠费率1%', 80, 1);
+  KEY `idx_house_talent_level` (`house_level`,`talent_level`) USING BTREE,
+  KEY `idx_status_priority` (`status`,`priority`) USING BTREE,
+  KEY `idx_type_house_talent_status` (`transfer_type`,`house_level`,`talent_level`,`status`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='URS推广模块转账手续费配置表';

+ 16 - 3
app/Module/UrsPromotion/Dtos/UrsTransferFeeConfigDto.php

@@ -27,6 +27,11 @@ class UrsTransferFeeConfigDto extends BaseDto
      */
     public int $talentLevel;
 
+    /**
+     * @var string 转账类型
+     */
+    public string $transferType;
+
     /**
      * @var float 手续费率
      */
@@ -69,6 +74,7 @@ class UrsTransferFeeConfigDto extends BaseDto
         $dto->id = $model->id;
         $dto->houseLevel = $model->house_level;
         $dto->talentLevel = $model->talent_level;
+        $dto->transferType = $model->transfer_type;
         $dto->feeRate = (float)$model->fee_rate;
         $dto->description = $model->description;
         $dto->priority = $model->priority;
@@ -97,19 +103,26 @@ class UrsTransferFeeConfigDto extends BaseDto
     public function getMatchConditionDescription(): string
     {
         $conditions = [];
-        
+
+        // 转账类型
+        $typeMap = [
+            'in' => '转入',
+            'out' => '转出',
+        ];
+        $conditions[] = $typeMap[$this->transferType] ?? '未知';
+
         if ($this->houseLevel > 0) {
             $conditions[] = "房屋等级{$this->houseLevel}级";
         } else {
             $conditions[] = "所有房屋等级";
         }
-        
+
         if ($this->talentLevel > 0) {
             $conditions[] = "达人等级{$this->talentLevel}级";
         } else {
             $conditions[] = "所有达人等级";
         }
-        
+
         return implode(' + ', $conditions);
     }
 

+ 33 - 13
app/Module/UrsPromotion/Logics/UrsTransferFeeLogic.php

@@ -31,13 +31,14 @@ class UrsTransferFeeLogic
      * 根据用户ID获取最优手续费率
      *
      * @param int $userId 农场用户ID
+     * @param string $transferType 转账类型:'in'转入,'out'转出
      * @return float 手续费率
      */
-    public function getBestFeeRateForUser(int $userId): float
+    public function getBestFeeRateForUser(int $userId, string $transferType = 'out'): float
     {
         try {
             // 尝试从缓存获取
-            $cacheKey = self::CACHE_PREFIX . "user_fee_rate:{$userId}";
+            $cacheKey = self::CACHE_PREFIX . "user_fee_rate:{$userId}:{$transferType}";
             $cachedRate = Cache::get($cacheKey);
             if ($cachedRate !== null) {
                 return (float)$cachedRate;
@@ -45,18 +46,19 @@ class UrsTransferFeeLogic
 
             // 获取用户的房屋等级
             $houseLevel = $this->getUserHouseLevel($userId);
-            
+
             // 获取用户的达人等级
             $talentLevel = $this->getUserTalentLevel($userId);
 
             // 获取最优手续费率
-            $feeRate = $this->calculateBestFeeRate($houseLevel, $talentLevel);
+            $feeRate = $this->calculateBestFeeRate($houseLevel, $talentLevel, $transferType);
 
             // 缓存结果
             Cache::put($cacheKey, $feeRate, self::CACHE_TTL);
 
-            Log::info('URS转手续费率计算完成', [
+            Log::info('URS转手续费率计算完成', [
                 'user_id' => $userId,
+                'transfer_type' => $transferType,
                 'house_level' => $houseLevel,
                 'talent_level' => $talentLevel,
                 'fee_rate' => $feeRate
@@ -72,7 +74,7 @@ class UrsTransferFeeLogic
             ]);
 
             // 返回默认费率
-            return $this->getDefaultFeeRate();
+            return $this->getDefaultFeeRate($transferType);
         }
     }
 
@@ -81,12 +83,14 @@ class UrsTransferFeeLogic
      *
      * @param int $houseLevel 房屋等级
      * @param int $talentLevel 达人等级
+     * @param string $transferType 转账类型:'in'转入,'out'转出
      * @return float 手续费率
      */
-    public function calculateBestFeeRate(int $houseLevel, int $talentLevel): float
+    public function calculateBestFeeRate(int $houseLevel, int $talentLevel, string $transferType = 'out'): float
     {
         // 获取所有匹配的配置,按优先级排序
         $configs = UrsTransferFeeConfig::where('status', UrsTransferFeeConfig::STATUS_ENABLED)
+            ->where('transfer_type', $transferType)
             ->where(function ($query) use ($houseLevel) {
                 $query->where('house_level', 0)
                       ->orWhere('house_level', $houseLevel);
@@ -123,7 +127,7 @@ class UrsTransferFeeLogic
         }
 
         // 如果没有找到匹配的配置,返回默认费率
-        return $this->getDefaultFeeRate();
+        return $this->getDefaultFeeRate($transferType);
     }
 
     /**
@@ -205,18 +209,25 @@ class UrsTransferFeeLogic
     /**
      * 获取默认手续费率
      *
+     * @param string $transferType 转账类型
      * @return float 默认手续费率
      */
-    private function getDefaultFeeRate(): float
+    private function getDefaultFeeRate(string $transferType = 'out'): float
     {
         // 获取默认配置(房屋等级0,达人等级0)
         $defaultConfig = UrsTransferFeeConfig::where('status', UrsTransferFeeConfig::STATUS_ENABLED)
+            ->where('transfer_type', $transferType)
             ->where('house_level', 0)
             ->where('talent_level', 0)
             ->orderBy('priority', 'desc')
             ->first();
 
-        return $defaultConfig ? (float)$defaultConfig->fee_rate : 0.05; // 默认5%
+        if ($defaultConfig) {
+            return (float)$defaultConfig->fee_rate;
+        }
+
+        // 如果没有配置,返回硬编码默认值
+        return $transferType === 'in' ? 0.0 : 0.05; // 转入免费,转出5%
     }
 
     /**
@@ -240,12 +251,21 @@ class UrsTransferFeeLogic
      * 清除用户手续费率缓存
      *
      * @param int $userId 农场用户ID
+     * @param string|null $transferType 转账类型,null表示清除所有类型
      * @return void
      */
-    public function clearUserFeeRateCache(int $userId): void
+    public function clearUserFeeRateCache(int $userId, ?string $transferType = null): void
     {
-        $cacheKey = self::CACHE_PREFIX . "user_fee_rate:{$userId}";
-        Cache::forget($cacheKey);
+        if ($transferType) {
+            $cacheKey = self::CACHE_PREFIX . "user_fee_rate:{$userId}:{$transferType}";
+            Cache::forget($cacheKey);
+        } else {
+            // 清除所有转账类型的缓存
+            $cacheKeyIn = self::CACHE_PREFIX . "user_fee_rate:{$userId}:in";
+            $cacheKeyOut = self::CACHE_PREFIX . "user_fee_rate:{$userId}:out";
+            Cache::forget($cacheKeyIn);
+            Cache::forget($cacheKeyOut);
+        }
     }
 
     /**

+ 66 - 6
app/Module/UrsPromotion/Models/UrsTransferFeeConfig.php

@@ -5,8 +5,18 @@ namespace App\Module\UrsPromotion\Models;
 use UCore\ModelCore;
 
 /**
- * URS转手续费配置模型
+ * URS转手续费配置模型
  * field start 
+ * @property  int  $id  主键ID
+ * @property  int  $house_level  房屋等级(0表示所有等级)
+ * @property  int  $talent_level  达人等级(0表示所有等级)
+ * @property  string  $transfer_type  转账类型:in转入,out转出
+ * @property  float  $fee_rate  手续费率(0-1之间的小数)
+ * @property  string  $description  配置描述
+ * @property  int  $priority  优先级(数值越大优先级越高)
+ * @property  int  $status  状态:1启用,0禁用
+ * @property  \Carbon\Carbon  $created_at  创建时间
+ * @property  \Carbon\Carbon  $updated_at  更新时间
  * field end
  *
  */
@@ -23,6 +33,7 @@ class UrsTransferFeeConfig extends ModelCore
     protected $fillable = [
         'house_level',
         'talent_level',
+        'transfer_type',
         'fee_rate',
         'description',
         'priority',
@@ -35,6 +46,7 @@ class UrsTransferFeeConfig extends ModelCore
     protected $casts = [
         'house_level' => 'integer',
         'talent_level' => 'integer',
+        'transfer_type' => 'string',
         'fee_rate' => 'decimal:4',
         'priority' => 'integer',
         'status' => 'integer',
@@ -48,6 +60,20 @@ class UrsTransferFeeConfig extends ModelCore
     const STATUS_DISABLED = 0; // 禁用
     const STATUS_ENABLED = 1;  // 启用
 
+    /**
+     * 转账类型常量
+     */
+    const TYPE_IN = 'in';   // 转入
+    const TYPE_OUT = 'out'; // 转出
+
+    /**
+     * 转账类型映射
+     */
+    public static $typeMap = [
+        self::TYPE_IN => '转入',
+        self::TYPE_OUT => '转出',
+    ];
+
     /**
      * 检查配置是否启用
      */
@@ -56,6 +82,30 @@ class UrsTransferFeeConfig extends ModelCore
         return $this->status === self::STATUS_ENABLED;
     }
 
+    /**
+     * 检查是否为转入类型
+     */
+    public function isTransferIn(): bool
+    {
+        return $this->transfer_type === self::TYPE_IN;
+    }
+
+    /**
+     * 检查是否为转出类型
+     */
+    public function isTransferOut(): bool
+    {
+        return $this->transfer_type === self::TYPE_OUT;
+    }
+
+    /**
+     * 获取转账类型文本
+     */
+    public function getTransferTypeText(): string
+    {
+        return self::$typeMap[$this->transfer_type] ?? '未知';
+    }
+
     /**
      * 检查是否匹配指定的房屋等级
      *
@@ -83,11 +133,18 @@ class UrsTransferFeeConfig extends ModelCore
      *
      * @param int $houseLevel 房屋等级
      * @param int $talentLevel 达人等级
+     * @param string|null $transferType 转账类型
      * @return bool
      */
-    public function matches(int $houseLevel, int $talentLevel): bool
+    public function matches(int $houseLevel, int $talentLevel, ?string $transferType = null): bool
     {
-        return $this->matchesHouseLevel($houseLevel) && $this->matchesTalentLevel($talentLevel);
+        $matchesLevels = $this->matchesHouseLevel($houseLevel) && $this->matchesTalentLevel($talentLevel);
+
+        if ($transferType !== null) {
+            return $matchesLevels && $this->transfer_type === $transferType;
+        }
+
+        return $matchesLevels;
     }
 
     /**
@@ -108,19 +165,22 @@ class UrsTransferFeeConfig extends ModelCore
     public function getMatchConditionDescription(): string
     {
         $conditions = [];
-        
+
+        // 转账类型
+        $conditions[] = $this->getTransferTypeText();
+
         if ($this->house_level > 0) {
             $conditions[] = "房屋等级{$this->house_level}级";
         } else {
             $conditions[] = "所有房屋等级";
         }
-        
+
         if ($this->talent_level > 0) {
             $conditions[] = "达人等级{$this->talent_level}级";
         } else {
             $conditions[] = "所有达人等级";
         }
-        
+
         return implode(' + ', $conditions);
     }
 }

+ 16 - 12
app/Module/UrsPromotion/Services/UrsTransferFeeService.php

@@ -7,9 +7,9 @@ use App\Module\UrsPromotion\Dtos\UrsTransferFeeConfigDto;
 use Illuminate\Support\Facades\Log;
 
 /**
- * URS转手续费服务
+ * URS转手续费服务
  *
- * 对外提供URS推广模块的转出手续费相关服务接口
+ * 对外提供URS推广模块的转入/转出手续费相关服务接口
  */
 class UrsTransferFeeService
 {
@@ -17,23 +17,25 @@ class UrsTransferFeeService
      * 根据用户ID获取最优手续费率
      *
      * @param int $userId 农场用户ID
+     * @param string $transferType 转账类型:'in'转入,'out'转出
      * @return float 手续费率
      */
-    public static function getBestFeeRateForUser(int $userId): float
+    public static function getBestFeeRateForUser(int $userId, string $transferType = 'out'): float
     {
         try {
             $logic = new UrsTransferFeeLogic();
-            return $logic->getBestFeeRateForUser($userId);
+            return $logic->getBestFeeRateForUser($userId, $transferType);
 
         } catch (\Exception $e) {
-            Log::error('URS转手续费率获取失败', [
+            Log::error('URS转手续费率获取失败', [
                 'user_id' => $userId,
+                'transfer_type' => $transferType,
                 'error' => $e->getMessage(),
                 'trace' => $e->getTraceAsString()
             ]);
 
-            // 返回默认费率
-            return 0.05; // 5%
+            // 返回默认费率(转入通常免费,转出5%)
+            return $transferType === 'in' ? 0.0 : 0.05;
         }
     }
 
@@ -42,24 +44,26 @@ class UrsTransferFeeService
      *
      * @param int $houseLevel 房屋等级
      * @param int $talentLevel 达人等级
+     * @param string $transferType 转账类型:'in'转入,'out'转出
      * @return float 手续费率
      */
-    public static function calculateBestFeeRate(int $houseLevel, int $talentLevel): float
+    public static function calculateBestFeeRate(int $houseLevel, int $talentLevel, string $transferType = 'out'): float
     {
         try {
             $logic = new UrsTransferFeeLogic();
-            return $logic->calculateBestFeeRate($houseLevel, $talentLevel);
+            return $logic->calculateBestFeeRate($houseLevel, $talentLevel, $transferType);
 
         } catch (\Exception $e) {
-            Log::error('URS转手续费率计算失败', [
+            Log::error('URS转手续费率计算失败', [
                 'house_level' => $houseLevel,
                 'talent_level' => $talentLevel,
+                'transfer_type' => $transferType,
                 'error' => $e->getMessage(),
                 'trace' => $e->getTraceAsString()
             ]);
 
-            // 返回默认费率
-            return 0.05; // 5%
+            // 返回默认费率(转入通常免费,转出5%)
+            return $transferType === 'in' ? 0.0 : 0.05;
         }
     }