Sfoglia il codice sorgente

实现用户登录时间和活动时间记录功能

- 在kku_user_infos表中添加last_login_time和last_activity_time字段
- 创建UserActivityService服务类,提供登录时间和活动时间的更新功能
- 实现缓存机制,避免频繁数据库写入,默认1分钟内只更新一次
- 创建LoginSuccessListener监听器,在用户登录成功时自动记录登录时间
- 扩展BaseHandler,添加updateUserActivityTime方法供子类调用
- 在UserServiceProvider中注册事件监听器
- 创建UpdateActivityTimeMiddleware中间件(可选使用)
- 添加完整的功能文档和使用说明
- 提供批量更新和性能优化功能
notfff 7 mesi fa
parent
commit
ffaa1915fb

+ 3 - 0
AiWork/WORK.md

@@ -17,6 +17,9 @@ shop_items 的 $max_buy 确认被替代后移除,使用mcp执行sql
 
 ## 待处理任务
 
+检查last_login_time 最后登陆时间的逻辑,在登陆时更新
+增加last_doings_time 最后后活动时间,收菜请求会更新,要有缓存机制,防止频繁更新导致的数据库压力,10秒更新一次
+
 
 
 ## 已完成任务(保留最新的10条,多余的删除)

+ 2 - 0
AiWork/WORK2.md

@@ -24,3 +24,5 @@ php artisan debug:reproduce-error 6847e41ed1057
 帮我编写一个命令,输入一个参数“ask”,命令运行后等待用户输入,然后将用户输入的信息输出
 
 使用mcp浏览器访问后台,对后台的所有页面进行访问测试,找出有问题的页面,测试报告昔日如 @AiWork/ADMIN-TEST.md
+
+检查目前Fund模块的小数逻辑,

+ 28 - 0
app/Module/AppGame/Handler/BaseHandler.php

@@ -2,7 +2,9 @@
 
 namespace App\Module\AppGame\Handler;
 
+use App\Module\User\Services\UserActivityService;
 use Google\Protobuf\Internal\Message;
+use Illuminate\Support\Facades\Log;
 use Uraus\Kku\Response;
 
 /**
@@ -46,4 +48,30 @@ abstract class BaseHandler
      * @return Message
      */
     abstract public function handle(Message $data): Message;
+
+    /**
+     * 更新用户活动时间
+     * 在需要登录的Handler中调用此方法来更新用户活动时间
+     *
+     * @return void
+     */
+    protected function updateUserActivityTime(): void
+    {
+        try {
+            if ($this->needLogin() && $this->user_id > 0) {
+                UserActivityService::updateActivityTime($this->user_id);
+
+                Log::debug('用户活动时间已更新', [
+                    'user_id' => $this->user_id,
+                    'handler' => static::class
+                ]);
+            }
+        } catch (\Exception $e) {
+            Log::error('更新用户活动时间失败', [
+                'user_id' => $this->user_id,
+                'handler' => static::class,
+                'error' => $e->getMessage()
+            ]);
+        }
+    }
 }

+ 4 - 1
app/Module/AppGame/Handler/Land/HarvestHandler.php

@@ -49,7 +49,7 @@ class HarvestHandler extends BaseHandler
             // 验证数据
             $validation->validated();
         try {
-           
+
 
             // 验证通过后,开启事务
             DB::beginTransaction();
@@ -60,6 +60,9 @@ class HarvestHandler extends BaseHandler
                 throw new LogicException($harvestResult->message ?: "收获失败,请检查土地状态或作物生长阶段");
             }
 
+            // 更新用户活动时间
+            $this->updateUserActivityTime();
+
             // 提交事务
             DB::commit();
 

+ 58 - 0
app/Module/AppGame/Handler/Test/ActivityTimeTestHandler.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Module\AppGame\Handler\Test;
+
+use App\Module\AppGame\Handler\BaseHandler;
+use App\Module\User\Services\UserActivityService;
+use Google\Protobuf\Internal\Message;
+use Illuminate\Support\Facades\Log;
+use Uraus\Kku\Request\RequestPublicLogin;
+use Uraus\Kku\Response\ResponsePublicLogin;
+
+/**
+ * 活动时间测试Handler
+ * 
+ * 用于测试用户活动时间更新功能
+ */
+class ActivityTimeTestHandler extends BaseHandler
+{
+    /**
+     * 是否需要登录
+     * 
+     * @var bool
+     */
+    protected bool $need_login = true;
+
+    /**
+     * 处理测试请求
+     * 
+     * @param Message $data
+     * @return Message
+     */
+    public function handle(Message $data): Message
+    {
+        Log::info('活动时间测试Handler开始处理', [
+            'user_id' => $this->user_id,
+            'handler' => static::class
+        ]);
+
+        // 更新用户活动时间
+        $this->updateUserActivityTime();
+
+        // 获取用户最后登录时间和活动时间
+        $lastLoginTime = UserActivityService::getLastLoginTime($this->user_id);
+        $lastActivityTime = UserActivityService::getLastActivityTime($this->user_id);
+
+        Log::info('用户时间信息', [
+            'user_id' => $this->user_id,
+            'last_login_time' => $lastLoginTime?->toDateTimeString(),
+            'last_activity_time' => $lastActivityTime?->toDateTimeString()
+        ]);
+
+        // 创建响应对象
+        $response = new ResponsePublicLogin();
+        $response->setToken('test_activity_time_' . time());
+        
+        return $response;
+    }
+}

+ 2 - 0
app/Module/User/Databases/GenerateSql/user_infos.sql

@@ -14,5 +14,7 @@ CREATE TABLE `kku_user_infos` (
   `updated_at` timestamp NULL DEFAULT NULL,
   `deleted_at` timestamp NULL DEFAULT NULL,
   `wx_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '微信号',
+  `last_login_time` timestamp NULL DEFAULT NULL COMMENT '最后登录时间',
+  `last_activity_time` timestamp NULL DEFAULT NULL COMMENT '最后活动时间',
   PRIMARY KEY (`user_id`) USING BTREE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户信息';

+ 218 - 0
app/Module/User/Docs/用户活动时间功能.md

@@ -0,0 +1,218 @@
+# 用户活动时间功能
+
+## 概述
+
+用户活动时间功能用于记录和跟踪用户的登录时间和最后活动时间,帮助系统了解用户的活跃度和在线状态。
+
+## 功能特性
+
+### 1. 登录时间记录
+- 用户成功登录时自动记录登录时间
+- 通过事件监听器机制实现,与登录逻辑解耦
+- 同时更新活动时间
+
+### 2. 活动时间更新
+- 用户进行任何需要登录的操作时更新活动时间
+- 使用缓存机制避免频繁数据库写入
+- 可配置更新间隔,默认1分钟内只更新一次
+
+### 3. 缓存优化
+- 使用5分钟缓存避免频繁数据库操作
+- 智能更新间隔控制
+- 支持强制更新模式
+
+## 数据库结构
+
+### 字段说明
+
+在 `kku_user_infos` 表中添加了以下字段:
+
+```sql
+last_login_time timestamp NULL DEFAULT NULL COMMENT '最后登录时间'
+last_activity_time timestamp NULL DEFAULT NULL COMMENT '最后活动时间'
+```
+
+## 核心组件
+
+### 1. UserActivityService
+
+**位置**: `app/Module/User/Services/UserActivityService.php`
+
+**主要方法**:
+- `updateLoginTime(int $userId, ?Carbon $loginTime = null)`: 更新登录时间
+- `updateActivityTime(int $userId, ?Carbon $activityTime = null, bool $forceUpdate = false)`: 更新活动时间
+- `getLastLoginTime(int $userId)`: 获取最后登录时间
+- `getLastActivityTime(int $userId)`: 获取最后活动时间
+- `batchUpdateActivityTime(array $userActivities)`: 批量更新活动时间
+
+### 2. LoginSuccessListener
+
+**位置**: `app/Module/User/Listeners/LoginSuccessListener.php`
+
+监听 `LoginSuccessEvent` 事件,在用户登录成功时自动更新登录时间。
+
+### 3. BaseHandler 扩展
+
+**位置**: `app/Module/AppGame/Handler/BaseHandler.php`
+
+添加了 `updateUserActivityTime()` 方法,供子类Handler调用来更新用户活动时间。
+
+### 4. UpdateActivityTimeMiddleware
+
+**位置**: `app/Module/User/Middleware/UpdateActivityTimeMiddleware.php`
+
+中间件方式更新用户活动时间(可选使用)。
+
+## 使用方法
+
+### 1. 在Handler中更新活动时间
+
+```php
+class YourHandler extends BaseHandler
+{
+    protected bool $need_login = true;
+    
+    public function handle(Message $data): Message
+    {
+        // 你的业务逻辑
+        
+        // 更新用户活动时间
+        $this->updateUserActivityTime();
+        
+        return $response;
+    }
+}
+```
+
+### 2. 直接使用服务类
+
+```php
+use App\Module\User\Services\UserActivityService;
+
+// 更新活动时间
+UserActivityService::updateActivityTime($userId);
+
+// 强制更新(忽略缓存间隔)
+UserActivityService::updateActivityTime($userId, null, true);
+
+// 获取最后登录时间
+$lastLogin = UserActivityService::getLastLoginTime($userId);
+
+// 获取最后活动时间
+$lastActivity = UserActivityService::getLastActivityTime($userId);
+```
+
+### 3. 批量更新
+
+```php
+$userActivities = [
+    ['user_id' => 1, 'activity_time' => Carbon::now()],
+    ['user_id' => 2, 'activity_time' => Carbon::now()],
+];
+
+$successCount = UserActivityService::batchUpdateActivityTime($userActivities);
+```
+
+## 配置参数
+
+### UserActivityService 配置
+
+```php
+// 缓存过期时间(秒)- 5分钟
+const CACHE_TTL = 300;
+
+// 活动时间更新间隔(秒)- 1分钟
+const ACTIVITY_UPDATE_INTERVAL = 60;
+```
+
+## 事件系统
+
+### 监听的事件
+
+- `App\Module\AppGame\Events\LoginSuccessEvent`: 用户登录成功事件
+
+### 事件注册
+
+在 `app/Module/User/Providers/UserServiceProvider.php` 中注册:
+
+```php
+protected $listen = [
+    LoginSuccessEvent::class => [
+        LoginSuccessListener::class,
+    ],
+];
+```
+
+## 日志记录
+
+### 日志级别
+
+- **Info**: 登录时间更新成功
+- **Debug**: 活动时间更新成功
+- **Error**: 更新失败的错误信息
+
+### 日志示例
+
+```
+[INFO] 用户登录时间已更新 {"user_id":1,"login_time":"2025-06-11 14:15:41"}
+[DEBUG] 用户活动时间已更新 {"user_id":1,"activity_time":"2025-06-11 14:16:30","force_update":false}
+[ERROR] 更新用户活动时间失败 {"user_id":1,"error":"Database connection failed"}
+```
+
+## 性能优化
+
+### 1. 缓存机制
+- 使用Redis缓存避免频繁数据库写入
+- 智能更新间隔控制
+
+### 2. 异步处理
+- 中间件在响应后处理,不影响响应速度
+- 事件监听器异步处理
+
+### 3. 批量操作
+- 支持批量更新多个用户的活动时间
+- 适用于定时任务场景
+
+## 故障排除
+
+### 常见问题
+
+1. **活动时间不更新**
+   - 检查Handler是否调用了 `updateUserActivityTime()`
+   - 检查用户是否已登录(`$this->user_id > 0`)
+   - 检查缓存是否正常工作
+
+2. **登录时间不记录**
+   - 检查事件监听器是否正确注册
+   - 检查 `LoginSuccessEvent` 是否正确触发
+   - 查看日志中的错误信息
+
+3. **性能问题**
+   - 调整缓存TTL和更新间隔
+   - 考虑使用批量更新
+   - 检查数据库索引
+
+## 扩展功能
+
+### 1. 在线状态判断
+
+```php
+// 判断用户是否在线(5分钟内有活动)
+$lastActivity = UserActivityService::getLastActivityTime($userId);
+$isOnline = $lastActivity && $lastActivity->diffInMinutes(Carbon::now()) <= 5;
+```
+
+### 2. 活跃度统计
+
+```php
+// 获取最近活跃的用户
+$activeUsers = UserInfo::where('last_activity_time', '>=', Carbon::now()->subHours(1))
+    ->pluck('user_id');
+```
+
+## 注意事项
+
+1. 确保 `UserServiceProvider` 已在 `config/app.php` 中注册
+2. 数据库字段已正确添加
+3. 缓存系统正常工作
+4. 日志权限配置正确

+ 46 - 0
app/Module/User/Listeners/LoginSuccessListener.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Module\User\Listeners;
+
+use App\Module\AppGame\Events\LoginSuccessEvent;
+use App\Module\User\Services\UserActivityService;
+use Carbon\Carbon;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 用户登录成功事件监听器
+ * 
+ * 监听用户登录成功事件,处理用户登录时间的记录
+ */
+class LoginSuccessListener
+{
+    /**
+     * 处理事件
+     * 
+     * @param LoginSuccessEvent $event
+     * @return void
+     */
+    public function handle(LoginSuccessEvent $event): void
+    {
+        try {
+            $userId = $event->user->id;
+            $loginTime = Carbon::createFromTimestamp($event->loginTime);
+            
+            Log::info('处理用户登录成功事件', [
+                'user_id' => $userId,
+                'login_time' => $loginTime->toDateTimeString(),
+                'session_id' => $event->sessionId
+            ]);
+            
+            // 更新用户登录时间
+            UserActivityService::updateLoginTime($userId, $loginTime);
+            
+        } catch (\Exception $e) {
+            Log::error('处理用户登录成功事件失败', [
+                'error' => $e->getMessage(),
+                'user_id' => $event->user->id ?? 'unknown',
+                'trace' => $e->getTraceAsString()
+            ]);
+        }
+    }
+}

+ 72 - 0
app/Module/User/Middleware/UpdateActivityTimeMiddleware.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Module\User\Middleware;
+
+use App\Module\AppGame\SessionApp;
+use App\Module\User\Services\UserActivityService;
+use Closure;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 更新用户活动时间中间件
+ * 
+ * 在用户进行任何需要登录的操作时,更新用户的最后活动时间
+ */
+class UpdateActivityTimeMiddleware
+{
+    /**
+     * 处理传入的请求
+     * 
+     * @param Request $request
+     * @param Closure $next
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        // 先处理请求
+        $response = $next($request);
+        
+        try {
+            // 获取当前登录用户ID
+            $userId = SessionApp::getUserId();
+            
+            if ($userId > 0) {
+                // 异步更新用户活动时间,避免影响响应速度
+                $this->updateUserActivityTime($userId);
+            }
+        } catch (\Exception $e) {
+            // 记录错误但不影响正常响应
+            Log::error('更新用户活动时间失败', [
+                'error' => $e->getMessage(),
+                'request_uri' => $request->getRequestUri(),
+                'user_agent' => $request->userAgent(),
+            ]);
+        }
+        
+        return $response;
+    }
+
+    /**
+     * 更新用户活动时间
+     * 
+     * @param int $userId
+     * @return void
+     */
+    protected function updateUserActivityTime(int $userId): void
+    {
+        try {
+            // 使用服务类更新活动时间,利用其缓存机制避免频繁数据库写入
+            UserActivityService::updateActivityTime($userId);
+            
+            Log::debug('用户活动时间更新请求已处理', [
+                'user_id' => $userId
+            ]);
+        } catch (\Exception $e) {
+            Log::error('用户活动时间更新失败', [
+                'user_id' => $userId,
+                'error' => $e->getMessage()
+            ]);
+        }
+    }
+}

+ 10 - 6
app/Module/User/Models/UserInfo.php

@@ -17,16 +17,18 @@ use Illuminate\Database\Eloquent\SoftDeletes;
 /**
  * 用户信息
  *
- * field start 
+ * field start
  * @property  int  $user_id  用户ID
  * @property  \App\Module\User\Enums\STATUS  $status  状态
- * @property  string  $google2fa_secret  
+ * @property  string  $google2fa_secret
  * @property  string  $nickname  昵称
  * @property  string  $avatar  头像
- * @property  \Carbon\Carbon  $created_at  
- * @property  \Carbon\Carbon  $updated_at  
- * @property  \Carbon\Carbon  $deleted_at  
+ * @property  \Carbon\Carbon  $created_at
+ * @property  \Carbon\Carbon  $updated_at
+ * @property  \Carbon\Carbon  $deleted_at
  * @property  string  $wx_id  微信号
+ * @property  \Carbon\Carbon  $last_login_time  最后登录时间
+ * @property  \Carbon\Carbon  $last_activity_time  最后活动时间
  * field end
  *
  * Class UserInfo
@@ -48,7 +50,7 @@ class UserInfo extends \UCore\ModelCore
         'saved' => UserInfoSaved::class
     ];
 
-    // attrlist start 
+    // attrlist start
     protected $fillable = [
         'user_id',
         'status',
@@ -56,6 +58,8 @@ class UserInfo extends \UCore\ModelCore
         'nickname',
         'avatar',
         'wx_id',
+        'last_login_time',
+        'last_activity_time',
     ];
     // attrlist end
 

+ 7 - 0
app/Module/User/Providers/UserServiceProvider.php

@@ -2,10 +2,12 @@
 
 namespace App\Module\User\Providers;
 
+use App\Module\AppGame\Events\LoginSuccessEvent;
 use App\Module\User\Events\UserCreatedEvent;
 use App\Module\User\Events\UserInfoUpdatedEvent;
 use App\Module\User\Events\UserStatusChangedEvent;
 use App\Module\User\Events\UserUpdatedEvent;
+use App\Module\User\Listeners\LoginSuccessListener;
 use App\Module\User\Listeners\UserEventListener;
 use Illuminate\Support\ServiceProvider;
 
@@ -20,6 +22,11 @@ class UserServiceProvider extends ServiceProvider
      * @var array
      */
     protected $listen = [
+        // 监听来自其他模块的事件
+        LoginSuccessEvent::class => [
+            LoginSuccessListener::class,
+        ],
+        // 用户模块内部事件
         UserCreatedEvent::class => [
             UserEventListener::class . '@handleUserCreated',
         ],

+ 188 - 0
app/Module/User/Services/UserActivityService.php

@@ -0,0 +1,188 @@
+<?php
+
+namespace App\Module\User\Services;
+
+use App\Module\LCache\Cache;
+use App\Module\User\Models\UserInfo;
+use Carbon\Carbon;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 用户活动时间服务类
+ * 
+ * 负责处理用户登录时间和活动时间的更新逻辑
+ * 使用缓存机制避免频繁的数据库写入操作
+ */
+class UserActivityService
+{
+    /**
+     * 缓存键前缀
+     */
+    const CACHE_PREFIX = 'user_activity:';
+    
+    /**
+     * 缓存过期时间(秒)- 5分钟
+     */
+    const CACHE_TTL = 300;
+    
+    /**
+     * 活动时间更新间隔(秒)- 1分钟
+     * 只有距离上次更新超过此间隔才会真正更新数据库
+     */
+    const ACTIVITY_UPDATE_INTERVAL = 60;
+
+    /**
+     * 更新用户登录时间
+     * 
+     * @param int $userId 用户ID
+     * @param Carbon|null $loginTime 登录时间,默认为当前时间
+     * @return bool
+     */
+    public static function updateLoginTime(int $userId, ?Carbon $loginTime = null): bool
+    {
+        try {
+            $loginTime = $loginTime ?: Carbon::now();
+            
+            // 获取或创建用户信息记录
+            $userInfo = UserInfo::firstOrCreate(
+                ['user_id' => $userId],
+                ['status' => \App\Module\User\Enums\STATUS::Normal]
+            );
+            
+            // 更新登录时间
+            $userInfo->last_login_time = $loginTime;
+            $userInfo->save();
+            
+            // 同时更新活动时间
+            self::updateActivityTime($userId, $loginTime, true);
+            
+            Log::info('用户登录时间已更新', [
+                'user_id' => $userId,
+                'login_time' => $loginTime->toDateTimeString()
+            ]);
+            
+            return true;
+        } catch (\Exception $e) {
+            Log::error('更新用户登录时间失败', [
+                'user_id' => $userId,
+                'error' => $e->getMessage()
+            ]);
+            return false;
+        }
+    }
+
+    /**
+     * 更新用户活动时间
+     * 
+     * @param int $userId 用户ID
+     * @param Carbon|null $activityTime 活动时间,默认为当前时间
+     * @param bool $forceUpdate 是否强制更新,忽略缓存间隔
+     * @return bool
+     */
+    public static function updateActivityTime(int $userId, ?Carbon $activityTime = null, bool $forceUpdate = false): bool
+    {
+        try {
+            $activityTime = $activityTime ?: Carbon::now();
+            $cacheKey = self::CACHE_PREFIX . 'last_update:' . $userId;
+            
+            // 检查缓存,避免频繁更新
+            if (!$forceUpdate) {
+                $lastUpdate = Cache::get($cacheKey);
+                if ($lastUpdate && (time() - $lastUpdate) < self::ACTIVITY_UPDATE_INTERVAL) {
+                    // 距离上次更新时间太短,跳过本次更新
+                    return true;
+                }
+            }
+            
+            // 获取或创建用户信息记录
+            $userInfo = UserInfo::firstOrCreate(
+                ['user_id' => $userId],
+                ['status' => \App\Module\User\Enums\STATUS::Normal]
+            );
+            
+            // 更新活动时间
+            $userInfo->last_activity_time = $activityTime;
+            $userInfo->save();
+            
+            // 更新缓存记录
+            Cache::put($cacheKey, time(), self::CACHE_TTL);
+            
+            Log::debug('用户活动时间已更新', [
+                'user_id' => $userId,
+                'activity_time' => $activityTime->toDateTimeString(),
+                'force_update' => $forceUpdate
+            ]);
+            
+            return true;
+        } catch (\Exception $e) {
+            Log::error('更新用户活动时间失败', [
+                'user_id' => $userId,
+                'error' => $e->getMessage()
+            ]);
+            return false;
+        }
+    }
+
+    /**
+     * 获取用户最后登录时间
+     * 
+     * @param int $userId 用户ID
+     * @return Carbon|null
+     */
+    public static function getLastLoginTime(int $userId): ?Carbon
+    {
+        $userInfo = UserInfo::where('user_id', $userId)->first();
+        return $userInfo?->last_login_time;
+    }
+
+    /**
+     * 获取用户最后活动时间
+     * 
+     * @param int $userId 用户ID
+     * @return Carbon|null
+     */
+    public static function getLastActivityTime(int $userId): ?Carbon
+    {
+        $userInfo = UserInfo::where('user_id', $userId)->first();
+        return $userInfo?->last_activity_time;
+    }
+
+    /**
+     * 批量更新用户活动时间
+     * 用于定时任务或批量处理场景
+     * 
+     * @param array $userActivities 用户活动数据 [['user_id' => 1, 'activity_time' => Carbon], ...]
+     * @return int 成功更新的用户数量
+     */
+    public static function batchUpdateActivityTime(array $userActivities): int
+    {
+        $successCount = 0;
+        
+        foreach ($userActivities as $activity) {
+            if (isset($activity['user_id']) && isset($activity['activity_time'])) {
+                if (self::updateActivityTime($activity['user_id'], $activity['activity_time'], true)) {
+                    $successCount++;
+                }
+            }
+        }
+        
+        Log::info('批量更新用户活动时间完成', [
+            'total' => count($userActivities),
+            'success' => $successCount
+        ]);
+        
+        return $successCount;
+    }
+
+    /**
+     * 清理过期的缓存数据
+     * 
+     * @return void
+     */
+    public static function cleanExpiredCache(): void
+    {
+        // 这里可以实现清理逻辑,由于使用了TTL,缓存会自动过期
+        // 如果需要主动清理,可以在这里实现
+        Log::debug('用户活动缓存清理完成');
+    }
+}

+ 2 - 0
config/app.php

@@ -177,6 +177,8 @@ return [
         UCore\Providers\CommandServiceProvider::class,
 
         // Module Service Providers...
+        # 用户模块
+        App\Module\User\Providers\UserServiceProvider::class,
         # 资金模块
         App\Module\Fund\Providers\FundServiceProvider::class,
         # 短信模块