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

创建ThirdParty模块 - 专门处理接入第三方服务的需求

✨ 新增功能:
- 创建完整的ThirdParty模块目录结构
- 实现5个核心枚举类型(SERVICE_TYPE, AUTH_TYPE, SERVICE_STATUS, LOG_LEVEL, QUOTA_TYPE)
- 创建5个数据模型(Service, Credential, Log, Quota, Monitor)
- 实现核心服务类ThirdPartyService
- 创建服务提供者ThirdPartyServiceProvider
- 设计完整的配置文件thirdparty.php

��️ 数据库:
- 创建5个数据库表(services, credentials, logs, quotas, monitors)
- 插入10个默认第三方服务配置
- 建立完整的外键关系和索引

�� 文档:
- 创建模块README.md文档
- 编写详细的设计概述文档
- 更新模块目录文档,新增ThirdParty模块说明

🔧 核心特性:
- 支持12种服务类型(SMS, EMAIL, PUSH, PAYMENT, STORAGE, MAP, AI等)
- 支持8种认证方式(API_KEY, OAUTH2, JWT, SIGNATURE等)
- 完整的配额管理和监控机制
- 安全的凭证加密存储
- 详细的API调用日志记录

与OpenAPI模块互补: OpenAPI提供API给别人,ThirdParty使用别人的API
notfff 7 месяцев назад
Родитель
Сommit
45e83f09e7

+ 38 - 22
app/Module/README.md

@@ -164,11 +164,25 @@
 - **状态**: ✅ 已完成
 - **特点**: 不实现具体游戏逻辑,提供暂存系统等统筹功能
 
-### 🔧 基础服务模块 (9个)
+### 🔧 基础服务模块 (10个)
 
 提供系统基础功能和服务:
 
-#### 15. **OpenAPI** - 对外开放API管理模块
+#### 15. **ThirdParty** - 第三方服务管理模块
+- **路径**: `app/Module/ThirdParty`
+- **功能**: 专门处理接入第三方服务的需求,提供统一的第三方服务管理、认证、监控和调用功能
+- **状态**: ✅ 已完成
+- **核心功能**:
+  - 服务配置管理(统一管理各种第三方服务的配置信息)
+  - 认证凭证管理(安全存储和管理API密钥、Token等认证信息)
+  - 服务状态监控(实时监控第三方服务的可用性和响应时间)
+  - 调用日志记录(详细记录所有第三方API调用的日志信息)
+  - 错误处理和重试(统一的错误处理机制和智能重试策略)
+  - 配额和限流管理(管理第三方服务的调用配额和频率限制)
+- **特点**: 与OpenAPI模块互补,OpenAPI是提供API给别人,ThirdParty是使用别人的API
+- **支持服务**: 短信、邮件、推送、支付、存储、地图、AI、社交、分析、CDN、验证码、翻译等12种服务类型
+
+#### 17. **OpenAPI** - 对外开放API管理模块
 - **路径**: `app/Module/OpenAPI`
 - **功能**: 专门处理对外开放API的需求,为第三方应用提供安全、稳定的API接入服务
 - **状态**: ✅ 已完成
@@ -181,7 +195,7 @@
   - 开发支持(API文档、多语言SDK、在线调试工具、错误码说明)
 - **特点**: 完整的API管理生态,支持多种认证方式,提供丰富的监控和开发工具
 
-#### 16. **Admin** - 后台基础功能扩展模块
+#### 18. **Admin** - 后台基础功能扩展模块
 - **路径**: `app/Module/Admin`
 - **功能**: 扩展后台基础功能,提供通用的后台管理组件和工具
 - **状态**: ✅ 已完成
@@ -194,7 +208,7 @@
   - 系统维护(维护操作、备份管理、性能优化)
 - **特点**: 专注后台基础功能,不处理具体业务逻辑,为其他模块提供通用组件
 
-#### 16. **System** - 系统模块
+#### 19. **System** - 系统模块
 - **路径**: `app/Module/System`
 - **功能**: 系统基础功能
 - **状态**: ✅ 已完成
@@ -205,7 +219,7 @@
   - 缓存管理
   - 工具类
 
-#### 16. **File** - 文件模块
+#### 20. **File** - 文件模块
 - **路径**: `app/Module/File`
 - **功能**: 文件和图片上传、存储和访问的基础模块
 - **状态**: ✅ 已完成
@@ -216,7 +230,7 @@
   - 临时文件处理
   - 文件模板
 
-#### 17. **Notification** - 通知模块
+#### 21. **Notification** - 通知模块
 - **路径**: `app/Module/Notification`
 - **功能**: 统一的消息通知系统
 - **状态**: ✅ 已完成
@@ -226,7 +240,7 @@
   - 通知记录
   - 批量发送
 
-#### 18. **Sms** - 短信模块
+#### 22. **Sms** - 短信模块
 - **路径**: `app/Module/Sms`
 - **功能**: 统一的短信发送系统
 - **状态**: ✅ 已完成
@@ -236,7 +250,7 @@
   - 多服务商支持
   - 发送记录
 
-#### 19. **Mail** - 邮件模块
+#### 23. **Mail** - 邮件模块
 - **路径**: `app/Module/Mail`
 - **功能**: 统一的邮件发送系统
 - **状态**: ✅ 已完成
@@ -246,7 +260,7 @@
   - 多服务商支持
   - 发送记录
 
-#### 20. **Push** - 推送模块
+#### 24. **Push** - 推送模块
 - **路径**: `app/Module/Push`
 - **功能**: 统一的手机推送系统
 - **状态**: ✅ 已完成
@@ -256,7 +270,7 @@
   - 多服务商支持
   - 设备管理
 
-#### 21. **OAuth** - OAuth认证模块
+#### 25. **OAuth** - OAuth认证模块
 - **路径**: `app/Module/OAuth`
 - **功能**: OAuth认证服务
 - **状态**: ✅ 已完成
@@ -269,31 +283,31 @@
 
 提供开发和运维工具:
 
-#### 23. **LCache** - 本地缓存模块
+#### 26. **LCache** - 本地缓存模块
 - **路径**: `app/Module/LCache`
 - **功能**: 本地缓存系统
 - **状态**: ✅ 已完成
 - **核心功能**: 缓存管理、队列缓存
 
-#### 23. **DelayQueue** - 延迟队列模块
+#### 27. **DelayQueue** - 延迟队列模块
 - **路径**: `app/Module/DelayQueue`
 - **功能**: 延迟队列(Redis)
 - **状态**: ✅ 已完成
 - **核心功能**: Redis延迟队列处理
 
-#### 24. **Test** - 测试模块
+#### 28. **Test** - 测试模块
 - **路径**: `app/Module/Test`
 - **功能**: 示例模块,展示模块化开发最佳实践
 - **状态**: ✅ 已完成
 - **特点**: 包含完整的模块结构示例
 
-#### 25. **Dev** - 开发者模块
+#### 29. **Dev** - 开发者模块
 - **路径**: `app/Module/Dev`
 - **功能**: 开发者工具
 - **状态**: ✅ 已完成
 - **核心功能**: 开发调试工具
 
-#### 26. **Ulogic** - 用户逻辑模块
+#### 30. **Ulogic** - 用户逻辑模块
 - **路径**: `app/Module/Ulogic`
 - **功能**: 常见用户逻辑处理
 - **状态**: ✅ 已完成
@@ -303,7 +317,7 @@
   - 惩罚
   - 时间处理
 
-#### 27. **Protobuf** - Protobuf模块
+#### 31. **Protobuf** - Protobuf模块
 - **路径**: `app/Module/Protobuf`
 - **功能**: Protobuf相关功能
 - **状态**: ✅ 已完成
@@ -313,12 +327,12 @@
 
 处理内容管理:
 
-#### 28. **Article** - 文章模块
+#### 32. **Article** - 文章模块
 - **路径**: `app/Module/Article`
 - **功能**: 文章管理
 - **状态**: 🔧 基础功能
 
-#### 29. **China** - 中国特殊内容模块
+#### 33. **China** - 中国特殊内容模块
 - **路径**: `app/Module/China`
 - **功能**: 中国特殊内容模块
 - **状态**: ✅ 已完成
@@ -333,10 +347,10 @@
 
 ## 模块状态分布
 
-- ✅ 已完成: 27个模块 (79%)
+- ✅ 已完成: 28个模块 (82%)
 - 🔧 基础功能: 2个模块 (6%)
 - 📋 文档阶段: 2个模块 (6%)
-- 其他: 3个模块 (9%)
+- 其他: 2个模块 (6%)
 
 ## 模块依赖关系
 
@@ -350,10 +364,11 @@ Fund + Point + Mex (资金层)
 User + Friend + Game (用户层)
-OpenAPI + Admin + System + File + Notification + Sms + Mail + Push + OAuth (基础服务层)
+ThirdParty + OpenAPI + Admin + System + File + Notification + Sms + Mail + Push + OAuth (基础服务层)
 ```
 
 ### 重要依赖关系
+- **ThirdParty模块**: 为系统提供第三方服务接入能力,被Sms、Mail、Push等模块依赖,依赖System、User模块
 - **OpenAPI模块**: 为第三方应用提供API接入服务,依赖OAuth、User、Admin、System模块
 - **Admin模块**: 为所有模块提供后台基础功能和通用组件,依赖System、File、User模块
 - **GameItems模块**: 被Farm、Pet、Shop、Activity、Task等模块依赖
@@ -393,6 +408,7 @@ app/Module/ModuleName/
   - 农场模块: `farm_`
   - 资金模块: `fund_`
   - 积分模块: `point_`
+  - 第三方服务模块: `thirdparty_`
 - **Handler命名空间**: `App\Module\AppGame\Handler`
 - **枚举命名**: 使用PHP enum语法,避免魔法数字
 
@@ -405,6 +421,6 @@ app/Module/ModuleName/
 
 ## 最后更新
 
-本文档最后更新时间:**2025年06月13日 18:19:11 CST**
+本文档最后更新时间:**2025年06月13日 21:39:44 CST**
 
 如需了解具体模块的详细信息,请查看各模块目录下的README.md文件。

+ 247 - 0
app/Module/ThirdParty/Config/thirdparty.php

@@ -0,0 +1,247 @@
+<?php
+
+return [
+    /*
+    |--------------------------------------------------------------------------
+    | ThirdParty模块配置
+    |--------------------------------------------------------------------------
+    |
+    | 这里定义了ThirdParty模块的各种配置选项
+    |
+    */
+
+    // 模块基础配置
+    'module' => [
+        'name' => 'ThirdParty',
+        'version' => '1.0.0',
+        'description' => '第三方服务管理模块',
+        'author' => 'KKU Team',
+    ],
+
+    // 默认配置
+    'defaults' => [
+        'timeout' => 30,                    // 默认超时时间(秒)
+        'retry_times' => 3,                 // 默认重试次数
+        'retry_delay' => 1000,              // 默认重试延迟(毫秒)
+        'auth_type' => 'API_KEY',           // 默认认证类型
+        'service_status' => 'INACTIVE',     // 默认服务状态
+        'environment' => 'production',       // 默认环境
+        'health_check_interval' => 300,     // 默认健康检查间隔(秒)
+    ],
+
+    // HTTP客户端配置
+    'http' => [
+        'timeout' => 30,                    // HTTP请求超时时间
+        'connect_timeout' => 10,            // 连接超时时间
+        'verify' => true,                   // 是否验证SSL证书
+        'user_agent' => 'KKU-ThirdParty/1.0',
+        'headers' => [
+            'Accept' => 'application/json',
+            'Content-Type' => 'application/json',
+        ],
+    ],
+
+    // 重试配置
+    'retry' => [
+        'max_attempts' => 3,                // 最大重试次数
+        'delay' => 1000,                    // 重试延迟(毫秒)
+        'multiplier' => 2,                  // 延迟倍数
+        'max_delay' => 10000,               // 最大延迟(毫秒)
+        'retry_on_status' => [              // 需要重试的HTTP状态码
+            429, 500, 502, 503, 504
+        ],
+    ],
+
+    // 日志配置
+    'logging' => [
+        'enabled' => true,                  // 是否启用日志
+        'level' => 'INFO',                  // 默认日志级别
+        'max_body_size' => 10240,           // 最大请求/响应体大小(字节)
+        'sensitive_fields' => [             // 敏感字段(不记录到日志)
+            'password',
+            'secret',
+            'token',
+            'key',
+            'authorization',
+        ],
+        'retention_days' => 30,             // 日志保留天数
+    ],
+
+    // 监控配置
+    'monitoring' => [
+        'enabled' => true,                  // 是否启用监控
+        'health_check' => [
+            'enabled' => true,              // 是否启用健康检查
+            'interval' => 300,              // 检查间隔(秒)
+            'timeout' => 10,                // 检查超时时间(秒)
+            'retry_times' => 2,             // 检查重试次数
+        ],
+        'performance' => [
+            'enabled' => true,              // 是否启用性能监控
+            'slow_threshold' => 2000,       // 慢请求阈值(毫秒)
+            'alert_threshold' => 5000,      // 告警阈值(毫秒)
+        ],
+        'availability' => [
+            'enabled' => true,              // 是否启用可用性监控
+            'check_interval' => 60,         // 检查间隔(秒)
+            'failure_threshold' => 3,       // 失败阈值
+        ],
+    ],
+
+    // 配额管理配置
+    'quota' => [
+        'enabled' => true,                  // 是否启用配额管理
+        'default_limits' => [
+            'PER_MINUTE' => 100,            // 每分钟默认限制
+            'PER_HOUR' => 1000,             // 每小时默认限制
+            'PER_DAY' => 10000,             // 每天默认限制
+            'PER_MONTH' => 100000,          // 每月默认限制
+        ],
+        'alert_threshold' => 80,            // 默认告警阈值(百分比)
+        'auto_reset' => true,               // 是否自动重置配额
+    ],
+
+    // 缓存配置
+    'cache' => [
+        'enabled' => true,                  // 是否启用缓存
+        'prefix' => 'thirdparty:',          // 缓存键前缀
+        'ttl' => 3600,                      // 默认缓存时间(秒)
+        'credentials_ttl' => 1800,          // 凭证缓存时间(秒)
+        'quota_ttl' => 300,                 // 配额缓存时间(秒)
+    ],
+
+    // 安全配置
+    'security' => [
+        'encryption' => [
+            'enabled' => true,              // 是否启用加密
+            'algorithm' => 'AES-256-CBC',   // 加密算法
+        ],
+        'webhook' => [
+            'verify_signature' => true,     // 是否验证Webhook签名
+            'signature_header' => 'X-Signature',
+            'signature_algorithm' => 'sha256',
+        ],
+        'rate_limiting' => [
+            'enabled' => true,              // 是否启用频率限制
+            'max_requests_per_minute' => 60,
+        ],
+    ],
+
+    // 告警配置
+    'alerts' => [
+        'enabled' => true,                  // 是否启用告警
+        'channels' => ['mail', 'sms'],      // 告警渠道
+        'thresholds' => [
+            'quota_usage' => 80,            // 配额使用告警阈值(百分比)
+            'error_rate' => 10,             // 错误率告警阈值(百分比)
+            'response_time' => 5000,        // 响应时间告警阈值(毫秒)
+        ],
+        'cooldown' => 300,                  // 告警冷却时间(秒)
+    ],
+
+    // 服务提供商配置模板
+    'providers' => [
+        'aliyun' => [
+            'name' => '阿里云',
+            'base_url' => 'https://ecs.aliyuncs.com',
+            'auth_type' => 'API_KEY',
+            'required_credentials' => ['access_key_id', 'access_key_secret'],
+            'regions' => ['cn-hangzhou', 'cn-beijing', 'cn-shanghai'],
+        ],
+        'tencent' => [
+            'name' => '腾讯云',
+            'base_url' => 'https://cvm.tencentcloudapi.com',
+            'auth_type' => 'SIGNATURE',
+            'required_credentials' => ['secret_id', 'secret_key'],
+            'regions' => ['ap-beijing', 'ap-shanghai', 'ap-guangzhou'],
+        ],
+        'baidu' => [
+            'name' => '百度云',
+            'base_url' => 'https://bcc.bj.baidubce.com',
+            'auth_type' => 'SIGNATURE',
+            'required_credentials' => ['access_key', 'secret_key'],
+            'regions' => ['bj', 'gz', 'su'],
+        ],
+    ],
+
+    // 服务类型配置
+    'service_types' => [
+        'SMS' => [
+            'name' => '短信服务',
+            'icon' => 'fa-sms',
+            'color' => 'primary',
+            'default_timeout' => 10,
+            'default_retry' => 3,
+        ],
+        'EMAIL' => [
+            'name' => '邮件服务',
+            'icon' => 'fa-envelope',
+            'color' => 'info',
+            'default_timeout' => 30,
+            'default_retry' => 2,
+        ],
+        'PUSH' => [
+            'name' => '推送服务',
+            'icon' => 'fa-bell',
+            'color' => 'warning',
+            'default_timeout' => 15,
+            'default_retry' => 3,
+        ],
+        'PAYMENT' => [
+            'name' => '支付服务',
+            'icon' => 'fa-credit-card',
+            'color' => 'success',
+            'default_timeout' => 60,
+            'default_retry' => 1,
+        ],
+        'STORAGE' => [
+            'name' => '存储服务',
+            'icon' => 'fa-cloud',
+            'color' => 'secondary',
+            'default_timeout' => 120,
+            'default_retry' => 2,
+        ],
+    ],
+
+    // 环境配置
+    'environments' => [
+        'production' => [
+            'name' => '生产环境',
+            'color' => 'danger',
+            'requires_approval' => true,
+        ],
+        'staging' => [
+            'name' => '预发布环境',
+            'color' => 'warning',
+            'requires_approval' => false,
+        ],
+        'development' => [
+            'name' => '开发环境',
+            'color' => 'info',
+            'requires_approval' => false,
+        ],
+        'testing' => [
+            'name' => '测试环境',
+            'color' => 'secondary',
+            'requires_approval' => false,
+        ],
+    ],
+
+    // 数据清理配置
+    'cleanup' => [
+        'enabled' => true,                  // 是否启用自动清理
+        'schedule' => '0 2 * * *',          // 清理计划(Cron表达式)
+        'retention' => [
+            'logs' => 30,                   // 日志保留天数
+            'monitors' => 90,               // 监控记录保留天数
+            'inactive_credentials' => 180,   // 未使用凭证保留天数
+        ],
+    ],
+
+    // 导出配置
+    'export' => [
+        'formats' => ['csv', 'excel', 'json'],
+        'max_records' => 10000,             // 最大导出记录数
+        'chunk_size' => 1000,               // 分块大小
+    ],
+];

+ 153 - 0
app/Module/ThirdParty/Databases/GenerateSql/thirdparty_tables.sql

@@ -0,0 +1,153 @@
+-- ThirdParty模块数据库表结构
+-- 创建时间: 2025-06-13
+-- 说明: 第三方服务管理模块的数据库表
+
+-- 第三方服务配置表
+CREATE TABLE `kku_thirdparty_services` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+  `name` varchar(100) NOT NULL COMMENT '服务名称',
+  `code` varchar(50) NOT NULL COMMENT '服务代码(唯一标识)',
+  `type` varchar(20) NOT NULL COMMENT '服务类型',
+  `provider` varchar(50) NOT NULL COMMENT '服务提供商',
+  `description` text COMMENT '服务描述',
+  `base_url` varchar(255) COMMENT '基础URL',
+  `version` varchar(20) DEFAULT 'v1' COMMENT 'API版本',
+  `auth_type` varchar(20) NOT NULL COMMENT '认证类型',
+  `status` varchar(20) NOT NULL DEFAULT 'INACTIVE' COMMENT '服务状态',
+  `priority` int(11) DEFAULT 0 COMMENT '优先级(数字越小优先级越高)',
+  `timeout` int(11) DEFAULT 30 COMMENT '超时时间(秒)',
+  `retry_times` int(11) DEFAULT 3 COMMENT '重试次数',
+  `retry_delay` int(11) DEFAULT 1000 COMMENT '重试延迟(毫秒)',
+  `config` json COMMENT '服务配置信息',
+  `headers` json COMMENT '默认请求头',
+  `params` json COMMENT '默认参数',
+  `webhook_url` varchar(255) COMMENT 'Webhook回调地址',
+  `webhook_secret` varchar(100) COMMENT 'Webhook密钥',
+  `health_check_url` varchar(255) COMMENT '健康检查URL',
+  `health_check_interval` int(11) DEFAULT 300 COMMENT '健康检查间隔(秒)',
+  `last_health_check` timestamp NULL COMMENT '最后健康检查时间',
+  `health_status` varchar(20) DEFAULT 'UNKNOWN' COMMENT '健康状态',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_code` (`code`),
+  KEY `idx_type` (`type`),
+  KEY `idx_provider` (`provider`),
+  KEY `idx_status` (`status`),
+  KEY `idx_priority` (`priority`),
+  KEY `idx_created_at` (`created_at`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='第三方服务配置表';
+
+-- 认证凭证表
+CREATE TABLE `kku_thirdparty_credentials` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+  `service_id` bigint(20) unsigned NOT NULL COMMENT '服务ID',
+  `name` varchar(100) NOT NULL COMMENT '凭证名称',
+  `type` varchar(20) NOT NULL COMMENT '凭证类型',
+  `credentials` json NOT NULL COMMENT '凭证信息(加密存储)',
+  `environment` varchar(20) DEFAULT 'production' COMMENT '环境(production/staging/development)',
+  `is_active` tinyint(1) DEFAULT 1 COMMENT '是否激活',
+  `expires_at` timestamp NULL COMMENT '过期时间',
+  `last_used_at` timestamp NULL COMMENT '最后使用时间',
+  `usage_count` bigint(20) DEFAULT 0 COMMENT '使用次数',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_service_id` (`service_id`),
+  KEY `idx_type` (`type`),
+  KEY `idx_environment` (`environment`),
+  KEY `idx_is_active` (`is_active`),
+  KEY `idx_expires_at` (`expires_at`),
+  CONSTRAINT `fk_credentials_service` FOREIGN KEY (`service_id`) REFERENCES `kku_thirdparty_services` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='认证凭证表';
+
+-- 调用日志表
+CREATE TABLE `kku_thirdparty_logs` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+  `service_id` bigint(20) unsigned NOT NULL COMMENT '服务ID',
+  `credential_id` bigint(20) unsigned COMMENT '凭证ID',
+  `request_id` varchar(50) NOT NULL COMMENT '请求ID(用于追踪)',
+  `method` varchar(10) NOT NULL COMMENT '请求方法',
+  `url` varchar(500) NOT NULL COMMENT '请求URL',
+  `headers` json COMMENT '请求头',
+  `params` json COMMENT '请求参数',
+  `body` text COMMENT '请求体',
+  `response_status` int(11) COMMENT '响应状态码',
+  `response_headers` json COMMENT '响应头',
+  `response_body` text COMMENT '响应体',
+  `response_time` int(11) COMMENT '响应时间(毫秒)',
+  `error_message` text COMMENT '错误信息',
+  `level` varchar(20) DEFAULT 'INFO' COMMENT '日志级别',
+  `user_id` bigint(20) unsigned COMMENT '用户ID',
+  `ip_address` varchar(45) COMMENT 'IP地址',
+  `user_agent` varchar(500) COMMENT 'User Agent',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_service_id` (`service_id`),
+  KEY `idx_credential_id` (`credential_id`),
+  KEY `idx_request_id` (`request_id`),
+  KEY `idx_method` (`method`),
+  KEY `idx_response_status` (`response_status`),
+  KEY `idx_level` (`level`),
+  KEY `idx_user_id` (`user_id`),
+  KEY `idx_created_at` (`created_at`),
+  CONSTRAINT `fk_logs_service` FOREIGN KEY (`service_id`) REFERENCES `kku_thirdparty_services` (`id`) ON DELETE CASCADE,
+  CONSTRAINT `fk_logs_credential` FOREIGN KEY (`credential_id`) REFERENCES `kku_thirdparty_credentials` (`id`) ON DELETE SET NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='调用日志表';
+
+-- 配额管理表
+CREATE TABLE `kku_thirdparty_quotas` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+  `service_id` bigint(20) unsigned NOT NULL COMMENT '服务ID',
+  `type` varchar(20) NOT NULL COMMENT '配额类型',
+  `limit_value` bigint(20) NOT NULL COMMENT '限制值',
+  `used_value` bigint(20) DEFAULT 0 COMMENT '已使用值',
+  `reset_at` timestamp NULL COMMENT '重置时间',
+  `window_start` timestamp NULL COMMENT '时间窗口开始',
+  `window_end` timestamp NULL COMMENT '时间窗口结束',
+  `is_active` tinyint(1) DEFAULT 1 COMMENT '是否激活',
+  `alert_threshold` decimal(5,2) DEFAULT 80.00 COMMENT '告警阈值(百分比)',
+  `is_exceeded` tinyint(1) DEFAULT 0 COMMENT '是否已超限',
+  `exceeded_at` timestamp NULL COMMENT '超限时间',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_service_type` (`service_id`, `type`),
+  KEY `idx_type` (`type`),
+  KEY `idx_is_active` (`is_active`),
+  KEY `idx_is_exceeded` (`is_exceeded`),
+  KEY `idx_reset_at` (`reset_at`),
+  CONSTRAINT `fk_quotas_service` FOREIGN KEY (`service_id`) REFERENCES `kku_thirdparty_services` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='配额管理表';
+
+-- 监控记录表
+CREATE TABLE `kku_thirdparty_monitors` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+  `service_id` bigint(20) unsigned NOT NULL COMMENT '服务ID',
+  `check_type` varchar(20) NOT NULL COMMENT '检查类型(health/performance/availability)',
+  `status` varchar(20) NOT NULL COMMENT '检查状态',
+  `response_time` int(11) COMMENT '响应时间(毫秒)',
+  `status_code` int(11) COMMENT 'HTTP状态码',
+  `error_message` text COMMENT '错误信息',
+  `details` json COMMENT '详细信息',
+  `checked_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '检查时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_service_id` (`service_id`),
+  KEY `idx_check_type` (`check_type`),
+  KEY `idx_status` (`status`),
+  KEY `idx_checked_at` (`checked_at`),
+  CONSTRAINT `fk_monitors_service` FOREIGN KEY (`service_id`) REFERENCES `kku_thirdparty_services` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='监控记录表';
+
+-- 插入默认数据
+INSERT INTO `kku_thirdparty_services` (`name`, `code`, `type`, `provider`, `description`, `auth_type`, `status`) VALUES
+('阿里云短信服务', 'aliyun_sms', 'SMS', 'ALIYUN', '阿里云短信发送服务', 'API_KEY', 'INACTIVE'),
+('腾讯云短信服务', 'tencent_sms', 'SMS', 'TENCENT', '腾讯云短信发送服务', 'API_KEY', 'INACTIVE'),
+('阿里云邮件推送', 'aliyun_email', 'EMAIL', 'ALIYUN', '阿里云邮件推送服务', 'API_KEY', 'INACTIVE'),
+('极光推送', 'jpush', 'PUSH', 'JPUSH', '极光移动推送服务', 'API_KEY', 'INACTIVE'),
+('支付宝支付', 'alipay', 'PAYMENT', 'ALIPAY', '支付宝开放平台支付服务', 'SIGNATURE', 'INACTIVE'),
+('微信支付', 'wechat_pay', 'PAYMENT', 'WECHAT', '微信支付API服务', 'SIGNATURE', 'INACTIVE'),
+('阿里云OSS', 'aliyun_oss', 'STORAGE', 'ALIYUN', '阿里云对象存储服务', 'API_KEY', 'INACTIVE'),
+('高德地图', 'amap', 'MAP', 'AMAP', '高德地图API服务', 'API_KEY', 'INACTIVE'),
+('百度AI', 'baidu_ai', 'AI', 'BAIDU', '百度人工智能服务', 'API_KEY', 'INACTIVE'),
+('腾讯验证码', 'tencent_captcha', 'CAPTCHA', 'TENCENT', '腾讯天御验证码服务', 'API_KEY', 'INACTIVE');

+ 22 - 0
app/Module/ThirdParty/Databases/README.md

@@ -0,0 +1,22 @@
+# 数据库文件目录
+
+⚠️ **重要提示:此目录内容为自动生成,请勿手动修改!**
+
+本目录包含ThirdParty模块的数据库相关文件,所有文件都是通过自动化工具生成的。
+
+## 目录结构
+
+- `GenerateSql/` - 自动生成的SQL脚本文件
+  - `thirdparty_tables.sql` - 数据库表结构创建脚本
+
+## 使用说明
+
+1. 这些文件由系统自动生成和维护
+2. 如需修改数据库结构,请通过相应的配置文件或代码生成器进行
+3. 直接修改这些文件可能会在下次生成时被覆盖
+
+## 注意事项
+
+- 请勿直接编辑此目录下的任何文件
+- 如有问题请联系开发团队
+- 所有修改都应通过正规流程进行

+ 215 - 0
app/Module/ThirdParty/Docs/设计概述.md

@@ -0,0 +1,215 @@
+# ThirdParty模块设计概述
+
+## 1. 模块简介
+
+ThirdParty模块是一个专门处理接入第三方服务需求的统一管理平台。该模块提供了完整的第三方服务配置、认证、监控、日志记录和配额管理功能,旨在简化和标准化第三方服务的接入和使用流程。
+
+## 2. 设计目标
+
+### 2.1 统一管理
+- 统一管理所有第三方服务的配置信息
+- 标准化第三方服务的接入流程
+- 提供一致的API调用接口
+
+### 2.2 安全可靠
+- 安全存储和管理认证凭证
+- 支持多种认证方式
+- 完整的访问日志记录
+
+### 2.3 监控告警
+- 实时监控第三方服务状态
+- 自动健康检查机制
+- 智能告警和通知
+
+### 2.4 配额控制
+- 灵活的配额管理机制
+- 多维度限流控制
+- 自动配额重置
+
+## 3. 核心功能
+
+### 3.1 服务配置管理
+- **服务注册**: 支持注册各种类型的第三方服务
+- **配置管理**: 统一管理服务的基础配置信息
+- **状态控制**: 灵活的服务状态管理机制
+- **优先级设置**: 支持服务优先级配置
+
+### 3.2 认证凭证管理
+- **多种认证方式**: 支持API Key、OAuth2、JWT、签名认证等
+- **安全存储**: 敏感信息加密存储
+- **环境隔离**: 支持多环境凭证管理
+- **自动过期**: 凭证过期检查和提醒
+
+### 3.3 API调用管理
+- **统一接口**: 提供统一的API调用接口
+- **自动重试**: 智能重试机制
+- **错误处理**: 完善的错误处理和异常管理
+- **响应缓存**: 支持响应结果缓存
+
+### 3.4 监控和健康检查
+- **健康检查**: 定期检查第三方服务健康状态
+- **性能监控**: 监控API调用性能指标
+- **可用性监控**: 监控服务可用性状态
+- **告警机制**: 自动告警和通知
+
+### 3.5 日志记录
+- **完整日志**: 记录所有API调用的详细信息
+- **敏感信息过滤**: 自动过滤敏感信息
+- **日志级别**: 支持多种日志级别
+- **日志清理**: 自动清理过期日志
+
+### 3.6 配额管理
+- **多维度限制**: 支持分钟、小时、天、月等多种配额类型
+- **实时监控**: 实时监控配额使用情况
+- **自动重置**: 自动重置配额计数
+- **告警提醒**: 配额即将耗尽时自动告警
+
+## 4. 架构设计
+
+### 4.1 分层架构
+```
+┌─────────────────────────────────────────┐
+│              业务应用层                    │
+├─────────────────────────────────────────┤
+│              服务接口层                    │
+│  ThirdPartyService | CredentialService  │
+│  MonitorService | LogService | QuotaService │
+├─────────────────────────────────────────┤
+│              业务逻辑层                    │
+│  ServiceLogic | CredentialLogic         │
+│  MonitorLogic | LogLogic | QuotaLogic   │
+├─────────────────────────────────────────┤
+│              数据访问层                    │
+│  ServiceModel | CredentialModel         │
+│  LogModel | QuotaModel | MonitorModel   │
+├─────────────────────────────────────────┤
+│              数据存储层                    │
+│        MySQL | Redis | File System      │
+└─────────────────────────────────────────┘
+```
+
+### 4.2 核心组件
+
+#### 4.2.1 服务管理组件
+- **ServiceModel**: 第三方服务数据模型
+- **ServiceLogic**: 服务管理业务逻辑
+- **ThirdPartyService**: 服务管理对外接口
+
+#### 4.2.2 认证管理组件
+- **CredentialModel**: 认证凭证数据模型
+- **CredentialLogic**: 凭证管理业务逻辑
+- **CredentialService**: 凭证管理对外接口
+
+#### 4.2.3 监控组件
+- **MonitorModel**: 监控记录数据模型
+- **MonitorLogic**: 监控业务逻辑
+- **MonitorService**: 监控服务对外接口
+
+#### 4.2.4 日志组件
+- **LogModel**: 日志记录数据模型
+- **LogLogic**: 日志管理业务逻辑
+- **LogService**: 日志服务对外接口
+
+#### 4.2.5 配额管理组件
+- **QuotaModel**: 配额管理数据模型
+- **QuotaLogic**: 配额管理业务逻辑
+- **QuotaService**: 配额管理对外接口
+
+## 5. 数据库设计
+
+### 5.1 核心表结构
+
+#### 5.1.1 服务配置表 (kku_thirdparty_services)
+存储第三方服务的基本配置信息,包括服务名称、类型、提供商、认证方式、状态等。
+
+#### 5.1.2 认证凭证表 (kku_thirdparty_credentials)
+存储各种认证凭证信息,支持加密存储敏感信息,支持多环境配置。
+
+#### 5.1.3 调用日志表 (kku_thirdparty_logs)
+记录所有第三方API调用的详细日志,包括请求信息、响应信息、性能数据等。
+
+#### 5.1.4 配额管理表 (kku_thirdparty_quotas)
+管理第三方服务的调用配额和限制,支持多种配额类型和自动重置。
+
+#### 5.1.5 监控记录表 (kku_thirdparty_monitors)
+记录服务监控和健康检查数据,包括健康状态、性能指标、可用性数据等。
+
+### 5.2 索引设计
+- 为常用查询字段创建索引
+- 为外键关系创建索引
+- 为时间字段创建索引以支持时间范围查询
+
+## 6. 安全设计
+
+### 6.1 数据安全
+- **加密存储**: 敏感信息使用AES加密存储
+- **访问控制**: 基于角色的访问控制
+- **审计日志**: 完整的操作审计日志
+
+### 6.2 传输安全
+- **HTTPS**: 强制使用HTTPS传输
+- **签名验证**: 支持请求签名验证
+- **令牌管理**: 安全的令牌生成和管理
+
+### 6.3 权限控制
+- **细粒度权限**: 支持细粒度的权限控制
+- **环境隔离**: 不同环境的权限隔离
+- **操作审计**: 记录所有敏感操作
+
+## 7. 性能优化
+
+### 7.1 缓存策略
+- **配置缓存**: 缓存服务配置信息
+- **凭证缓存**: 缓存认证凭证信息
+- **结果缓存**: 缓存API调用结果
+
+### 7.2 连接池
+- **HTTP连接池**: 复用HTTP连接
+- **数据库连接池**: 优化数据库连接使用
+
+### 7.3 异步处理
+- **异步日志**: 异步记录日志信息
+- **异步监控**: 异步执行监控检查
+- **队列处理**: 使用队列处理耗时操作
+
+## 8. 监控和告警
+
+### 8.1 监控指标
+- **可用性**: 服务可用性监控
+- **性能**: 响应时间和吞吐量监控
+- **错误率**: API调用错误率监控
+- **配额使用**: 配额使用情况监控
+
+### 8.2 告警机制
+- **阈值告警**: 基于阈值的自动告警
+- **趋势告警**: 基于趋势分析的告警
+- **多渠道通知**: 支持邮件、短信、推送等多种通知方式
+
+## 9. 扩展性设计
+
+### 9.1 插件机制
+- **认证插件**: 支持自定义认证方式
+- **监控插件**: 支持自定义监控指标
+- **告警插件**: 支持自定义告警规则
+
+### 9.2 适配器模式
+- **服务适配器**: 为不同的第三方服务提供统一接口
+- **协议适配器**: 支持不同的通信协议
+- **格式适配器**: 支持不同的数据格式
+
+## 10. 运维支持
+
+### 10.1 健康检查
+- **自动检查**: 定期自动健康检查
+- **手动检查**: 支持手动触发健康检查
+- **检查报告**: 生成详细的健康检查报告
+
+### 10.2 数据清理
+- **自动清理**: 自动清理过期数据
+- **手动清理**: 支持手动清理操作
+- **备份恢复**: 支持数据备份和恢复
+
+### 10.3 配置管理
+- **配置热更新**: 支持配置热更新
+- **配置版本管理**: 支持配置版本管理
+- **配置回滚**: 支持配置回滚操作

+ 244 - 0
app/Module/ThirdParty/Enums/AUTH_TYPE.php

@@ -0,0 +1,244 @@
+<?php
+
+namespace App\Module\ThirdParty\Enums;
+
+/**
+ * 第三方服务认证类型枚举
+ */
+enum AUTH_TYPE: string
+{
+    case API_KEY = 'API_KEY';           // API密钥认证
+    case OAUTH2 = 'OAUTH2';             // OAuth2.0认证
+    case JWT = 'JWT';                   // JWT Token认证
+    case SIGNATURE = 'SIGNATURE';       // 签名认证
+    case BASIC = 'BASIC';               // Basic认证
+    case BEARER = 'BEARER';             // Bearer Token认证
+    case CUSTOM = 'CUSTOM';             // 自定义认证
+    case NONE = 'NONE';                 // 无需认证
+
+    /**
+     * 获取认证类型的中文描述
+     *
+     * @return string
+     */
+    public function getLabel(): string
+    {
+        return match ($this) {
+            self::API_KEY => 'API密钥认证',
+            self::OAUTH2 => 'OAuth2.0认证',
+            self::JWT => 'JWT令牌认证',
+            self::SIGNATURE => '签名认证',
+            self::BASIC => 'Basic认证',
+            self::BEARER => 'Bearer令牌认证',
+            self::CUSTOM => '自定义认证',
+            self::NONE => '无需认证',
+        };
+    }
+
+    /**
+     * 获取认证类型的详细描述
+     *
+     * @return string
+     */
+    public function getDescription(): string
+    {
+        return match ($this) {
+            self::API_KEY => '使用API密钥进行身份验证,通常在请求头或参数中传递',
+            self::OAUTH2 => '使用OAuth2.0协议进行授权认证,支持多种授权模式',
+            self::JWT => '使用JSON Web Token进行身份验证和信息传递',
+            self::SIGNATURE => '使用请求签名进行身份验证,确保请求完整性',
+            self::BASIC => '使用HTTP Basic认证,用户名密码Base64编码',
+            self::BEARER => '使用Bearer令牌进行身份验证,通常用于API访问',
+            self::CUSTOM => '使用自定义的认证方式,需要特殊处理',
+            self::NONE => '无需任何认证,通常用于公开API',
+        };
+    }
+
+    /**
+     * 获取安全级别
+     *
+     * @return string
+     */
+    public function getSecurityLevel(): string
+    {
+        return match ($this) {
+            self::API_KEY => 'MEDIUM',
+            self::OAUTH2 => 'HIGH',
+            self::JWT => 'HIGH',
+            self::SIGNATURE => 'HIGH',
+            self::BASIC => 'LOW',
+            self::BEARER => 'MEDIUM',
+            self::CUSTOM => 'UNKNOWN',
+            self::NONE => 'NONE',
+        };
+    }
+
+    /**
+     * 获取安全级别的中文描述
+     *
+     * @return string
+     */
+    public function getSecurityLevelLabel(): string
+    {
+        return match ($this->getSecurityLevel()) {
+            'HIGH' => '高',
+            'MEDIUM' => '中',
+            'LOW' => '低',
+            'NONE' => '无',
+            'UNKNOWN' => '未知',
+        };
+    }
+
+    /**
+     * 获取安全级别的颜色
+     *
+     * @return string
+     */
+    public function getSecurityLevelColor(): string
+    {
+        return match ($this->getSecurityLevel()) {
+            'HIGH' => 'success',
+            'MEDIUM' => 'warning',
+            'LOW' => 'danger',
+            'NONE' => 'secondary',
+            'UNKNOWN' => 'dark',
+        };
+    }
+
+    /**
+     * 获取认证复杂度评分(1-10)
+     *
+     * @return int
+     */
+    public function getComplexityScore(): int
+    {
+        return match ($this) {
+            self::API_KEY => 3,
+            self::OAUTH2 => 9,
+            self::JWT => 7,
+            self::SIGNATURE => 8,
+            self::BASIC => 2,
+            self::BEARER => 4,
+            self::CUSTOM => 5,
+            self::NONE => 1,
+        };
+    }
+
+    /**
+     * 获取认证所需的配置字段
+     *
+     * @return array
+     */
+    public function getRequiredFields(): array
+    {
+        return match ($this) {
+            self::API_KEY => ['api_key', 'api_secret'],
+            self::OAUTH2 => ['client_id', 'client_secret', 'redirect_uri', 'scope'],
+            self::JWT => ['secret_key', 'algorithm', 'expiry'],
+            self::SIGNATURE => ['app_key', 'app_secret', 'sign_method'],
+            self::BASIC => ['username', 'password'],
+            self::BEARER => ['access_token', 'token_type'],
+            self::CUSTOM => ['custom_config'],
+            self::NONE => [],
+        };
+    }
+
+    /**
+     * 获取Header名称
+     *
+     * @return string
+     */
+    public function getHeaderName(): string
+    {
+        return match ($this) {
+            self::API_KEY => 'X-API-Key',
+            self::OAUTH2 => 'Authorization',
+            self::JWT => 'Authorization',
+            self::SIGNATURE => 'X-Signature',
+            self::BASIC => 'Authorization',
+            self::BEARER => 'Authorization',
+            self::CUSTOM => 'X-Custom-Auth',
+            self::NONE => '',
+        };
+    }
+
+    /**
+     * 获取Header值前缀
+     *
+     * @return string
+     */
+    public function getHeaderPrefix(): string
+    {
+        return match ($this) {
+            self::API_KEY => '',
+            self::OAUTH2 => 'Bearer ',
+            self::JWT => 'Bearer ',
+            self::SIGNATURE => '',
+            self::BASIC => 'Basic ',
+            self::BEARER => 'Bearer ',
+            self::CUSTOM => '',
+            self::NONE => '',
+        };
+    }
+
+    /**
+     * 检查是否支持令牌刷新
+     *
+     * @return bool
+     */
+    public function supportsTokenRefresh(): bool
+    {
+        return in_array($this, [self::OAUTH2, self::JWT, self::BEARER]);
+    }
+
+    /**
+     * 检查是否需要定期更新凭证
+     *
+     * @return bool
+     */
+    public function needsCredentialRotation(): bool
+    {
+        return in_array($this, [self::API_KEY, self::SIGNATURE, self::CUSTOM]);
+    }
+
+    /**
+     * 获取所有认证类型的选项数组
+     *
+     * @return array
+     */
+    public static function getOptions(): array
+    {
+        $options = [];
+        foreach (self::cases() as $case) {
+            $options[$case->value] = $case->getLabel();
+        }
+        return $options;
+    }
+
+    /**
+     * 获取推荐的认证类型
+     *
+     * @return array
+     */
+    public static function getRecommended(): array
+    {
+        return [
+            self::OAUTH2,
+            self::JWT,
+            self::SIGNATURE,
+            self::API_KEY,
+        ];
+    }
+
+    /**
+     * 获取高安全级别的认证类型
+     *
+     * @return array
+     */
+    public static function getHighSecurity(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->getSecurityLevel() === 'HIGH';
+        });
+    }
+}

+ 215 - 0
app/Module/ThirdParty/Enums/LOG_LEVEL.php

@@ -0,0 +1,215 @@
+<?php
+
+namespace App\Module\ThirdParty\Enums;
+
+/**
+ * 第三方服务日志级别枚举
+ */
+enum LOG_LEVEL: string
+{
+    case DEBUG = 'DEBUG';               // 调试级别
+    case INFO = 'INFO';                 // 信息级别
+    case WARNING = 'WARNING';           // 警告级别
+    case ERROR = 'ERROR';               // 错误级别
+    case CRITICAL = 'CRITICAL';         // 严重错误级别
+
+    /**
+     * 获取日志级别的中文描述
+     *
+     * @return string
+     */
+    public function getLabel(): string
+    {
+        return match ($this) {
+            self::DEBUG => '调试',
+            self::INFO => '信息',
+            self::WARNING => '警告',
+            self::ERROR => '错误',
+            self::CRITICAL => '严重错误',
+        };
+    }
+
+    /**
+     * 获取日志级别的详细描述
+     *
+     * @return string
+     */
+    public function getDescription(): string
+    {
+        return match ($this) {
+            self::DEBUG => '调试信息,用于开发和调试阶段',
+            self::INFO => '一般信息,记录正常的操作流程',
+            self::WARNING => '警告信息,可能存在问题但不影响正常运行',
+            self::ERROR => '错误信息,操作失败但系统可以继续运行',
+            self::CRITICAL => '严重错误,系统可能无法正常运行',
+        };
+    }
+
+    /**
+     * 获取日志级别的颜色
+     *
+     * @return string
+     */
+    public function getColor(): string
+    {
+        return match ($this) {
+            self::DEBUG => 'secondary',
+            self::INFO => 'primary',
+            self::WARNING => 'warning',
+            self::ERROR => 'danger',
+            self::CRITICAL => 'dark',
+        };
+    }
+
+    /**
+     * 获取日志级别的图标
+     *
+     * @return string
+     */
+    public function getIcon(): string
+    {
+        return match ($this) {
+            self::DEBUG => 'fa-bug',
+            self::INFO => 'fa-info-circle',
+            self::WARNING => 'fa-exclamation-triangle',
+            self::ERROR => 'fa-times-circle',
+            self::CRITICAL => 'fa-skull-crossbones',
+        };
+    }
+
+    /**
+     * 获取日志级别的数值(数字越大级别越高)
+     *
+     * @return int
+     */
+    public function getLevel(): int
+    {
+        return match ($this) {
+            self::DEBUG => 1,
+            self::INFO => 2,
+            self::WARNING => 3,
+            self::ERROR => 4,
+            self::CRITICAL => 5,
+        };
+    }
+
+    /**
+     * 检查是否为错误级别
+     *
+     * @return bool
+     */
+    public function isError(): bool
+    {
+        return in_array($this, [self::ERROR, self::CRITICAL]);
+    }
+
+    /**
+     * 检查是否需要告警
+     *
+     * @return bool
+     */
+    public function needsAlert(): bool
+    {
+        return in_array($this, [self::WARNING, self::ERROR, self::CRITICAL]);
+    }
+
+    /**
+     * 检查是否需要立即处理
+     *
+     * @return bool
+     */
+    public function needsImmediateAction(): bool
+    {
+        return $this === self::CRITICAL;
+    }
+
+    /**
+     * 获取所有日志级别的选项数组
+     *
+     * @return array
+     */
+    public static function getOptions(): array
+    {
+        $options = [];
+        foreach (self::cases() as $case) {
+            $options[$case->value] = $case->getLabel();
+        }
+        return $options;
+    }
+
+    /**
+     * 按级别排序(从低到高)
+     *
+     * @return array
+     */
+    public static function getSortedByLevel(): array
+    {
+        $levels = self::cases();
+        usort($levels, function ($a, $b) {
+            return $a->getLevel() <=> $b->getLevel();
+        });
+        return $levels;
+    }
+
+    /**
+     * 获取错误级别
+     *
+     * @return array
+     */
+    public static function getErrorLevels(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->isError();
+        });
+    }
+
+    /**
+     * 获取需要告警的级别
+     *
+     * @return array
+     */
+    public static function getAlertLevels(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->needsAlert();
+        });
+    }
+
+    /**
+     * 根据数值获取日志级别
+     *
+     * @param int $level
+     * @return LOG_LEVEL|null
+     */
+    public static function fromLevel(int $level): ?LOG_LEVEL
+    {
+        foreach (self::cases() as $case) {
+            if ($case->getLevel() === $level) {
+                return $case;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 检查当前级别是否高于指定级别
+     *
+     * @param LOG_LEVEL $compareLevel
+     * @return bool
+     */
+    public function isHigherThan(LOG_LEVEL $compareLevel): bool
+    {
+        return $this->getLevel() > $compareLevel->getLevel();
+    }
+
+    /**
+     * 检查当前级别是否低于指定级别
+     *
+     * @param LOG_LEVEL $compareLevel
+     * @return bool
+     */
+    public function isLowerThan(LOG_LEVEL $compareLevel): bool
+    {
+        return $this->getLevel() < $compareLevel->getLevel();
+    }
+}

+ 295 - 0
app/Module/ThirdParty/Enums/QUOTA_TYPE.php

@@ -0,0 +1,295 @@
+<?php
+
+namespace App\Module\ThirdParty\Enums;
+
+/**
+ * 第三方服务配额类型枚举
+ */
+enum QUOTA_TYPE: string
+{
+    case PER_MINUTE = 'PER_MINUTE';     // 每分钟
+    case PER_HOUR = 'PER_HOUR';         // 每小时
+    case PER_DAY = 'PER_DAY';           // 每天
+    case PER_WEEK = 'PER_WEEK';         // 每周
+    case PER_MONTH = 'PER_MONTH';       // 每月
+    case PER_YEAR = 'PER_YEAR';         // 每年
+    case TOTAL = 'TOTAL';               // 总计
+
+    /**
+     * 获取配额类型的中文描述
+     *
+     * @return string
+     */
+    public function getLabel(): string
+    {
+        return match ($this) {
+            self::PER_MINUTE => '每分钟',
+            self::PER_HOUR => '每小时',
+            self::PER_DAY => '每天',
+            self::PER_WEEK => '每周',
+            self::PER_MONTH => '每月',
+            self::PER_YEAR => '每年',
+            self::TOTAL => '总计',
+        };
+    }
+
+    /**
+     * 获取配额类型的详细描述
+     *
+     * @return string
+     */
+    public function getDescription(): string
+    {
+        return match ($this) {
+            self::PER_MINUTE => '每分钟允许的最大调用次数',
+            self::PER_HOUR => '每小时允许的最大调用次数',
+            self::PER_DAY => '每天允许的最大调用次数',
+            self::PER_WEEK => '每周允许的最大调用次数',
+            self::PER_MONTH => '每月允许的最大调用次数',
+            self::PER_YEAR => '每年允许的最大调用次数',
+            self::TOTAL => '总的调用次数限制',
+        };
+    }
+
+    /**
+     * 获取时间窗口(秒)
+     *
+     * @return int
+     */
+    public function getWindowSeconds(): int
+    {
+        return match ($this) {
+            self::PER_MINUTE => 60,
+            self::PER_HOUR => 3600,
+            self::PER_DAY => 86400,
+            self::PER_WEEK => 604800,
+            self::PER_MONTH => 2592000, // 30天
+            self::PER_YEAR => 31536000, // 365天
+            self::TOTAL => 0, // 无时间窗口
+        };
+    }
+
+    /**
+     * 获取缓存键前缀
+     *
+     * @return string
+     */
+    public function getCachePrefix(): string
+    {
+        return match ($this) {
+            self::PER_MINUTE => 'quota_minute',
+            self::PER_HOUR => 'quota_hour',
+            self::PER_DAY => 'quota_day',
+            self::PER_WEEK => 'quota_week',
+            self::PER_MONTH => 'quota_month',
+            self::PER_YEAR => 'quota_year',
+            self::TOTAL => 'quota_total',
+        };
+    }
+
+    /**
+     * 获取时间格式
+     *
+     * @return string
+     */
+    public function getTimeFormat(): string
+    {
+        return match ($this) {
+            self::PER_MINUTE => 'Y-m-d H:i',
+            self::PER_HOUR => 'Y-m-d H',
+            self::PER_DAY => 'Y-m-d',
+            self::PER_WEEK => 'Y-W',
+            self::PER_MONTH => 'Y-m',
+            self::PER_YEAR => 'Y',
+            self::TOTAL => '',
+        };
+    }
+
+    /**
+     * 获取优先级(数字越小优先级越高)
+     *
+     * @return int
+     */
+    public function getPriority(): int
+    {
+        return match ($this) {
+            self::PER_MINUTE => 1,
+            self::PER_HOUR => 2,
+            self::PER_DAY => 3,
+            self::PER_WEEK => 4,
+            self::PER_MONTH => 5,
+            self::PER_YEAR => 6,
+            self::TOTAL => 7,
+        };
+    }
+
+    /**
+     * 获取颜色
+     *
+     * @return string
+     */
+    public function getColor(): string
+    {
+        return match ($this) {
+            self::PER_MINUTE => 'danger',
+            self::PER_HOUR => 'warning',
+            self::PER_DAY => 'primary',
+            self::PER_WEEK => 'info',
+            self::PER_MONTH => 'success',
+            self::PER_YEAR => 'secondary',
+            self::TOTAL => 'dark',
+        };
+    }
+
+    /**
+     * 获取图标
+     *
+     * @return string
+     */
+    public function getIcon(): string
+    {
+        return match ($this) {
+            self::PER_MINUTE => 'fa-stopwatch',
+            self::PER_HOUR => 'fa-clock',
+            self::PER_DAY => 'fa-calendar-day',
+            self::PER_WEEK => 'fa-calendar-week',
+            self::PER_MONTH => 'fa-calendar-alt',
+            self::PER_YEAR => 'fa-calendar',
+            self::TOTAL => 'fa-infinity',
+        };
+    }
+
+    /**
+     * 检查是否为时间窗口类型
+     *
+     * @return bool
+     */
+    public function isTimeWindow(): bool
+    {
+        return $this !== self::TOTAL;
+    }
+
+    /**
+     * 检查是否为短期限制
+     *
+     * @return bool
+     */
+    public function isShortTerm(): bool
+    {
+        return in_array($this, [self::PER_MINUTE, self::PER_HOUR]);
+    }
+
+    /**
+     * 检查是否为长期限制
+     *
+     * @return bool
+     */
+    public function isLongTerm(): bool
+    {
+        return in_array($this, [self::PER_MONTH, self::PER_YEAR, self::TOTAL]);
+    }
+
+    /**
+     * 获取当前时间窗口的开始时间
+     *
+     * @return \DateTime
+     */
+    public function getCurrentWindowStart(): \DateTime
+    {
+        $now = new \DateTime();
+        
+        return match ($this) {
+            self::PER_MINUTE => $now->setTime($now->format('H'), $now->format('i'), 0),
+            self::PER_HOUR => $now->setTime($now->format('H'), 0, 0),
+            self::PER_DAY => $now->setTime(0, 0, 0),
+            self::PER_WEEK => $now->setISODate($now->format('Y'), $now->format('W'), 1)->setTime(0, 0, 0),
+            self::PER_MONTH => $now->setDate($now->format('Y'), $now->format('m'), 1)->setTime(0, 0, 0),
+            self::PER_YEAR => $now->setDate($now->format('Y'), 1, 1)->setTime(0, 0, 0),
+            self::TOTAL => new \DateTime('1970-01-01 00:00:00'),
+        };
+    }
+
+    /**
+     * 获取当前时间窗口的结束时间
+     *
+     * @return \DateTime
+     */
+    public function getCurrentWindowEnd(): \DateTime
+    {
+        $start = $this->getCurrentWindowStart();
+        
+        return match ($this) {
+            self::PER_MINUTE => $start->add(new \DateInterval('PT1M')),
+            self::PER_HOUR => $start->add(new \DateInterval('PT1H')),
+            self::PER_DAY => $start->add(new \DateInterval('P1D')),
+            self::PER_WEEK => $start->add(new \DateInterval('P1W')),
+            self::PER_MONTH => $start->add(new \DateInterval('P1M')),
+            self::PER_YEAR => $start->add(new \DateInterval('P1Y')),
+            self::TOTAL => new \DateTime('2099-12-31 23:59:59'),
+        };
+    }
+
+    /**
+     * 获取所有配额类型的选项数组
+     *
+     * @return array
+     */
+    public static function getOptions(): array
+    {
+        $options = [];
+        foreach (self::cases() as $case) {
+            $options[$case->value] = $case->getLabel();
+        }
+        return $options;
+    }
+
+    /**
+     * 按优先级排序
+     *
+     * @return array
+     */
+    public static function getSortedByPriority(): array
+    {
+        $types = self::cases();
+        usort($types, function ($a, $b) {
+            return $a->getPriority() <=> $b->getPriority();
+        });
+        return $types;
+    }
+
+    /**
+     * 获取时间窗口类型
+     *
+     * @return array
+     */
+    public static function getTimeWindowTypes(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->isTimeWindow();
+        });
+    }
+
+    /**
+     * 获取短期限制类型
+     *
+     * @return array
+     */
+    public static function getShortTermTypes(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->isShortTerm();
+        });
+    }
+
+    /**
+     * 获取长期限制类型
+     *
+     * @return array
+     */
+    public static function getLongTermTypes(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->isLongTerm();
+        });
+    }
+}

+ 246 - 0
app/Module/ThirdParty/Enums/SERVICE_STATUS.php

@@ -0,0 +1,246 @@
+<?php
+
+namespace App\Module\ThirdParty\Enums;
+
+/**
+ * 第三方服务状态枚举
+ */
+enum SERVICE_STATUS: string
+{
+    case ACTIVE = 'ACTIVE';             // 激活状态
+    case INACTIVE = 'INACTIVE';         // 未激活状态
+    case DISABLED = 'DISABLED';         // 禁用状态
+    case MAINTENANCE = 'MAINTENANCE';   // 维护状态
+    case ERROR = 'ERROR';               // 错误状态
+    case TESTING = 'TESTING';           // 测试状态
+    case EXPIRED = 'EXPIRED';           // 已过期状态
+
+    /**
+     * 获取状态的中文描述
+     *
+     * @return string
+     */
+    public function getLabel(): string
+    {
+        return match ($this) {
+            self::ACTIVE => '激活',
+            self::INACTIVE => '未激活',
+            self::DISABLED => '禁用',
+            self::MAINTENANCE => '维护中',
+            self::ERROR => '错误',
+            self::TESTING => '测试中',
+            self::EXPIRED => '已过期',
+        };
+    }
+
+    /**
+     * 获取状态的详细描述
+     *
+     * @return string
+     */
+    public function getDescription(): string
+    {
+        return match ($this) {
+            self::ACTIVE => '服务正常运行,可以正常调用API',
+            self::INACTIVE => '服务未激活,暂时无法使用',
+            self::DISABLED => '服务已被禁用,不允许调用API',
+            self::MAINTENANCE => '服务正在维护中,暂时不可用',
+            self::ERROR => '服务出现错误,需要检查配置',
+            self::TESTING => '服务处于测试状态,仅限测试使用',
+            self::EXPIRED => '服务已过期,需要续费或重新配置',
+        };
+    }
+
+    /**
+     * 获取状态的颜色
+     *
+     * @return string
+     */
+    public function getColor(): string
+    {
+        return match ($this) {
+            self::ACTIVE => 'success',
+            self::INACTIVE => 'secondary',
+            self::DISABLED => 'danger',
+            self::MAINTENANCE => 'warning',
+            self::ERROR => 'danger',
+            self::TESTING => 'info',
+            self::EXPIRED => 'dark',
+        };
+    }
+
+    /**
+     * 获取状态的图标
+     *
+     * @return string
+     */
+    public function getIcon(): string
+    {
+        return match ($this) {
+            self::ACTIVE => 'fa-check-circle',
+            self::INACTIVE => 'fa-pause-circle',
+            self::DISABLED => 'fa-ban',
+            self::MAINTENANCE => 'fa-tools',
+            self::ERROR => 'fa-exclamation-triangle',
+            self::TESTING => 'fa-flask',
+            self::EXPIRED => 'fa-clock',
+        };
+    }
+
+    /**
+     * 检查状态是否可用
+     *
+     * @return bool
+     */
+    public function isAvailable(): bool
+    {
+        return in_array($this, [self::ACTIVE, self::TESTING]);
+    }
+
+    /**
+     * 检查状态是否需要关注
+     *
+     * @return bool
+     */
+    public function needsAttention(): bool
+    {
+        return in_array($this, [self::ERROR, self::EXPIRED, self::MAINTENANCE]);
+    }
+
+    /**
+     * 检查状态是否可以调用API
+     *
+     * @return bool
+     */
+    public function canCallApi(): bool
+    {
+        return $this === self::ACTIVE;
+    }
+
+    /**
+     * 检查状态是否可以测试
+     *
+     * @return bool
+     */
+    public function canTest(): bool
+    {
+        return in_array($this, [self::ACTIVE, self::TESTING]);
+    }
+
+    /**
+     * 获取优先级(数字越小优先级越高)
+     *
+     * @return int
+     */
+    public function getPriority(): int
+    {
+        return match ($this) {
+            self::ACTIVE => 1,
+            self::TESTING => 2,
+            self::INACTIVE => 3,
+            self::MAINTENANCE => 4,
+            self::DISABLED => 5,
+            self::ERROR => 6,
+            self::EXPIRED => 7,
+        };
+    }
+
+    /**
+     * 获取状态的严重程度
+     *
+     * @return string
+     */
+    public function getSeverity(): string
+    {
+        return match ($this) {
+            self::ACTIVE => 'INFO',
+            self::INACTIVE => 'WARNING',
+            self::DISABLED => 'ERROR',
+            self::MAINTENANCE => 'WARNING',
+            self::ERROR => 'CRITICAL',
+            self::TESTING => 'INFO',
+            self::EXPIRED => 'ERROR',
+        };
+    }
+
+    /**
+     * 获取可以转换到的状态
+     *
+     * @return array
+     */
+    public function getAllowedTransitions(): array
+    {
+        return match ($this) {
+            self::ACTIVE => [self::INACTIVE, self::DISABLED, self::MAINTENANCE, self::TESTING],
+            self::INACTIVE => [self::ACTIVE, self::DISABLED, self::TESTING],
+            self::DISABLED => [self::INACTIVE, self::TESTING],
+            self::MAINTENANCE => [self::ACTIVE, self::INACTIVE, self::DISABLED],
+            self::ERROR => [self::ACTIVE, self::INACTIVE, self::DISABLED, self::TESTING],
+            self::TESTING => [self::ACTIVE, self::INACTIVE, self::DISABLED],
+            self::EXPIRED => [self::INACTIVE, self::TESTING],
+        };
+    }
+
+    /**
+     * 检查是否可以转换到指定状态
+     *
+     * @param SERVICE_STATUS $targetStatus
+     * @return bool
+     */
+    public function canTransitionTo(SERVICE_STATUS $targetStatus): bool
+    {
+        return in_array($targetStatus, $this->getAllowedTransitions());
+    }
+
+    /**
+     * 获取所有状态的选项数组
+     *
+     * @return array
+     */
+    public static function getOptions(): array
+    {
+        $options = [];
+        foreach (self::cases() as $case) {
+            $options[$case->value] = $case->getLabel();
+        }
+        return $options;
+    }
+
+    /**
+     * 获取可用状态
+     *
+     * @return array
+     */
+    public static function getAvailableStatuses(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->isAvailable();
+        });
+    }
+
+    /**
+     * 获取需要关注的状态
+     *
+     * @return array
+     */
+    public static function getAttentionStatuses(): array
+    {
+        return array_filter(self::cases(), function ($case) {
+            return $case->needsAttention();
+        });
+    }
+
+    /**
+     * 按优先级排序状态
+     *
+     * @return array
+     */
+    public static function getSortedByPriority(): array
+    {
+        $statuses = self::cases();
+        usort($statuses, function ($a, $b) {
+            return $a->getPriority() <=> $b->getPriority();
+        });
+        return $statuses;
+    }
+}

+ 197 - 0
app/Module/ThirdParty/Enums/SERVICE_TYPE.php

@@ -0,0 +1,197 @@
+<?php
+
+namespace App\Module\ThirdParty\Enums;
+
+/**
+ * 第三方服务类型枚举
+ */
+enum SERVICE_TYPE: string
+{
+    case SMS = 'SMS';                   // 短信服务
+    case EMAIL = 'EMAIL';               // 邮件服务
+    case PUSH = 'PUSH';                 // 推送服务
+    case PAYMENT = 'PAYMENT';           // 支付服务
+    case STORAGE = 'STORAGE';           // 存储服务
+    case MAP = 'MAP';                   // 地图服务
+    case AI = 'AI';                     // AI服务
+    case SOCIAL = 'SOCIAL';             // 社交服务
+    case ANALYTICS = 'ANALYTICS';       // 分析服务
+    case CDN = 'CDN';                   // CDN服务
+    case CAPTCHA = 'CAPTCHA';           // 验证码服务
+    case TRANSLATION = 'TRANSLATION';   // 翻译服务
+
+    /**
+     * 获取服务类型的中文描述
+     *
+     * @return string
+     */
+    public function getLabel(): string
+    {
+        return match ($this) {
+            self::SMS => '短信服务',
+            self::EMAIL => '邮件服务',
+            self::PUSH => '推送服务',
+            self::PAYMENT => '支付服务',
+            self::STORAGE => '存储服务',
+            self::MAP => '地图服务',
+            self::AI => 'AI服务',
+            self::SOCIAL => '社交服务',
+            self::ANALYTICS => '分析服务',
+            self::CDN => 'CDN服务',
+            self::CAPTCHA => '验证码服务',
+            self::TRANSLATION => '翻译服务',
+        };
+    }
+
+    /**
+     * 获取服务类型的详细描述
+     *
+     * @return string
+     */
+    public function getDescription(): string
+    {
+        return match ($this) {
+            self::SMS => '提供短信发送、验证码等短信相关服务',
+            self::EMAIL => '提供邮件发送、邮件模板等邮件相关服务',
+            self::PUSH => '提供移动端推送、消息推送等服务',
+            self::PAYMENT => '提供支付宝、微信支付等第三方支付服务',
+            self::STORAGE => '提供云存储、文件上传等存储相关服务',
+            self::MAP => '提供地图定位、路径规划等地图相关服务',
+            self::AI => '提供语音识别、图像识别等AI相关服务',
+            self::SOCIAL => '提供社交登录、分享等社交相关服务',
+            self::ANALYTICS => '提供数据统计、用户行为分析等服务',
+            self::CDN => '提供内容分发、加速等CDN相关服务',
+            self::CAPTCHA => '提供验证码生成、验证等安全服务',
+            self::TRANSLATION => '提供文本翻译、语言检测等翻译服务',
+        };
+    }
+
+    /**
+     * 获取服务类型的图标
+     *
+     * @return string
+     */
+    public function getIcon(): string
+    {
+        return match ($this) {
+            self::SMS => 'fa-sms',
+            self::EMAIL => 'fa-envelope',
+            self::PUSH => 'fa-bell',
+            self::PAYMENT => 'fa-credit-card',
+            self::STORAGE => 'fa-cloud',
+            self::MAP => 'fa-map',
+            self::AI => 'fa-robot',
+            self::SOCIAL => 'fa-share-alt',
+            self::ANALYTICS => 'fa-chart-bar',
+            self::CDN => 'fa-network-wired',
+            self::CAPTCHA => 'fa-shield-alt',
+            self::TRANSLATION => 'fa-language',
+        };
+    }
+
+    /**
+     * 获取服务类型的颜色
+     *
+     * @return string
+     */
+    public function getColor(): string
+    {
+        return match ($this) {
+            self::SMS => 'primary',
+            self::EMAIL => 'info',
+            self::PUSH => 'warning',
+            self::PAYMENT => 'success',
+            self::STORAGE => 'secondary',
+            self::MAP => 'danger',
+            self::AI => 'dark',
+            self::SOCIAL => 'primary',
+            self::ANALYTICS => 'info',
+            self::CDN => 'warning',
+            self::CAPTCHA => 'success',
+            self::TRANSLATION => 'secondary',
+        };
+    }
+
+    /**
+     * 获取常用的服务提供商
+     *
+     * @return array
+     */
+    public function getProviders(): array
+    {
+        return match ($this) {
+            self::SMS => ['阿里云', '腾讯云', '华为云', '网易云信', '容联云通讯'],
+            self::EMAIL => ['阿里云邮件推送', 'SendGrid', 'Mailgun', 'SMTP'],
+            self::PUSH => ['极光推送', '个推', '友盟推送', '小米推送', '华为推送'],
+            self::PAYMENT => ['支付宝', '微信支付', '银联支付', 'PayPal'],
+            self::STORAGE => ['阿里云OSS', '腾讯云COS', '七牛云', 'AWS S3'],
+            self::MAP => ['高德地图', '百度地图', '腾讯地图', 'Google Maps'],
+            self::AI => ['百度AI', '阿里云AI', '腾讯云AI', 'OpenAI'],
+            self::SOCIAL => ['微信开放平台', 'QQ互联', '微博开放平台', 'GitHub'],
+            self::ANALYTICS => ['百度统计', 'Google Analytics', '友盟统计'],
+            self::CDN => ['阿里云CDN', '腾讯云CDN', '七牛云CDN'],
+            self::CAPTCHA => ['腾讯验证码', '极验验证', 'reCAPTCHA'],
+            self::TRANSLATION => ['百度翻译', '腾讯翻译', 'Google Translate'],
+        };
+    }
+
+    /**
+     * 获取所有服务类型的选项数组
+     *
+     * @return array
+     */
+    public static function getOptions(): array
+    {
+        $options = [];
+        foreach (self::cases() as $case) {
+            $options[$case->value] = $case->getLabel();
+        }
+        return $options;
+    }
+
+    /**
+     * 获取推荐的服务类型
+     *
+     * @return array
+     */
+    public static function getRecommended(): array
+    {
+        return [
+            self::SMS,
+            self::EMAIL,
+            self::PUSH,
+            self::PAYMENT,
+            self::STORAGE,
+        ];
+    }
+
+    /**
+     * 检查是否为通信类服务
+     *
+     * @return bool
+     */
+    public function isCommunication(): bool
+    {
+        return in_array($this, [self::SMS, self::EMAIL, self::PUSH]);
+    }
+
+    /**
+     * 检查是否为云服务
+     *
+     * @return bool
+     */
+    public function isCloudService(): bool
+    {
+        return in_array($this, [self::STORAGE, self::CDN, self::AI]);
+    }
+
+    /**
+     * 检查是否为第三方平台服务
+     *
+     * @return bool
+     */
+    public function isThirdPlatform(): bool
+    {
+        return in_array($this, [self::PAYMENT, self::SOCIAL, self::MAP]);
+    }
+}

+ 353 - 0
app/Module/ThirdParty/Models/ThirdPartyCredential.php

@@ -0,0 +1,353 @@
+<?php
+
+namespace App\Module\ThirdParty\Models;
+
+use UCore\ModelCore;
+use App\Module\ThirdParty\Enums\AUTH_TYPE;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Support\Facades\Crypt;
+
+/**
+ * 第三方服务认证凭证模型
+ * 
+ * @property int $id 主键ID
+ * @property int $service_id 服务ID
+ * @property string $name 凭证名称
+ * @property string $type 凭证类型
+ * @property array $credentials 凭证信息
+ * @property string $environment 环境
+ * @property bool $is_active 是否激活
+ * @property \Carbon\Carbon|null $expires_at 过期时间
+ * @property \Carbon\Carbon|null $last_used_at 最后使用时间
+ * @property int $usage_count 使用次数
+ * @property \Carbon\Carbon $created_at 创建时间
+ * @property \Carbon\Carbon $updated_at 更新时间
+ */
+class ThirdPartyCredential extends ModelCore
+{
+    /**
+     * 数据表名
+     *
+     * @var string
+     */
+    protected $table = 'thirdparty_credentials';
+
+    // field start
+    /**
+     * 可批量赋值的属性
+     *
+     * @var array
+     */
+    // attrlist start
+    protected $fillable = [
+        'service_id',
+        'name',
+        'type',
+        'credentials',
+        'environment',
+        'is_active',
+        'expires_at',
+        'last_used_at',
+        'usage_count',
+    ];
+    // attrlist end
+    // field end
+
+    /**
+     * 属性类型转换
+     *
+     * @var array
+     */
+    protected $casts = [
+        'service_id' => 'integer',
+        'credentials' => 'array',
+        'is_active' => 'boolean',
+        'expires_at' => 'datetime',
+        'last_used_at' => 'datetime',
+        'usage_count' => 'integer',
+        'created_at' => 'datetime',
+        'updated_at' => 'datetime',
+    ];
+
+    /**
+     * 隐藏的属性
+     *
+     * @var array
+     */
+    protected $hidden = [
+        'credentials',
+    ];
+
+    /**
+     * 获取认证类型枚举
+     *
+     * @return AUTH_TYPE
+     */
+    public function getAuthTypeEnum(): AUTH_TYPE
+    {
+        return AUTH_TYPE::from($this->type);
+    }
+
+    /**
+     * 获取认证类型标签
+     *
+     * @return string
+     */
+    public function getTypeLabel(): string
+    {
+        return $this->getAuthTypeEnum()->getLabel();
+    }
+
+    /**
+     * 检查凭证是否已过期
+     *
+     * @return bool
+     */
+    public function isExpired(): bool
+    {
+        if (!$this->expires_at) {
+            return false;
+        }
+        
+        return now()->gt($this->expires_at);
+    }
+
+    /**
+     * 检查凭证是否即将过期
+     *
+     * @param int $days 提前天数
+     * @return bool
+     */
+    public function isExpiringSoon(int $days = 7): bool
+    {
+        if (!$this->expires_at) {
+            return false;
+        }
+        
+        return now()->addDays($days)->gte($this->expires_at);
+    }
+
+    /**
+     * 检查凭证是否可用
+     *
+     * @return bool
+     */
+    public function isUsable(): bool
+    {
+        return $this->is_active && !$this->isExpired();
+    }
+
+    /**
+     * 获取解密后的凭证信息
+     *
+     * @return array
+     */
+    public function getDecryptedCredentials(): array
+    {
+        if (!$this->credentials) {
+            return [];
+        }
+        
+        $decrypted = [];
+        foreach ($this->credentials as $key => $value) {
+            try {
+                // 尝试解密,如果失败则返回原值
+                $decrypted[$key] = is_string($value) ? Crypt::decryptString($value) : $value;
+            } catch (\Exception $e) {
+                $decrypted[$key] = $value;
+            }
+        }
+        
+        return $decrypted;
+    }
+
+    /**
+     * 设置加密的凭证信息
+     *
+     * @param array $credentials
+     * @return void
+     */
+    public function setEncryptedCredentials(array $credentials): void
+    {
+        $encrypted = [];
+        foreach ($credentials as $key => $value) {
+            // 只加密字符串类型的敏感信息
+            if (is_string($value) && $this->isSensitiveField($key)) {
+                $encrypted[$key] = Crypt::encryptString($value);
+            } else {
+                $encrypted[$key] = $value;
+            }
+        }
+        
+        $this->credentials = $encrypted;
+    }
+
+    /**
+     * 检查字段是否为敏感信息
+     *
+     * @param string $field
+     * @return bool
+     */
+    protected function isSensitiveField(string $field): bool
+    {
+        $sensitiveFields = [
+            'api_key',
+            'api_secret',
+            'access_token',
+            'refresh_token',
+            'client_secret',
+            'private_key',
+            'password',
+            'secret',
+            'app_secret',
+            'webhook_secret',
+        ];
+        
+        return in_array(strtolower($field), $sensitiveFields);
+    }
+
+    /**
+     * 获取特定的凭证值
+     *
+     * @param string $key
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getCredential(string $key, $default = null)
+    {
+        $credentials = $this->getDecryptedCredentials();
+        return $credentials[$key] ?? $default;
+    }
+
+    /**
+     * 更新使用统计
+     *
+     * @return bool
+     */
+    public function updateUsageStats(): bool
+    {
+        return $this->update([
+            'last_used_at' => now(),
+            'usage_count' => $this->usage_count + 1,
+        ]);
+    }
+
+    /**
+     * 生成认证头
+     *
+     * @return array
+     */
+    public function generateAuthHeaders(): array
+    {
+        $authType = $this->getAuthTypeEnum();
+        $credentials = $this->getDecryptedCredentials();
+        $headers = [];
+        
+        switch ($authType) {
+            case AUTH_TYPE::API_KEY:
+                $headers[$authType->getHeaderName()] = $credentials['api_key'] ?? '';
+                break;
+                
+            case AUTH_TYPE::BEARER:
+                $headers[$authType->getHeaderName()] = $authType->getHeaderPrefix() . ($credentials['access_token'] ?? '');
+                break;
+                
+            case AUTH_TYPE::BASIC:
+                $username = $credentials['username'] ?? '';
+                $password = $credentials['password'] ?? '';
+                $headers[$authType->getHeaderName()] = $authType->getHeaderPrefix() . base64_encode($username . ':' . $password);
+                break;
+                
+            case AUTH_TYPE::JWT:
+                $headers[$authType->getHeaderName()] = $authType->getHeaderPrefix() . ($credentials['jwt_token'] ?? '');
+                break;
+                
+            case AUTH_TYPE::SIGNATURE:
+                // 签名认证需要根据具体的签名算法生成
+                $headers['X-Signature'] = $this->generateSignature($credentials);
+                break;
+                
+            case AUTH_TYPE::CUSTOM:
+                // 自定义认证方式
+                $headers = $credentials['custom_headers'] ?? [];
+                break;
+        }
+        
+        return $headers;
+    }
+
+    /**
+     * 生成签名
+     *
+     * @param array $credentials
+     * @return string
+     */
+    protected function generateSignature(array $credentials): string
+    {
+        // 这里需要根据具体的第三方服务的签名算法实现
+        // 这是一个示例实现
+        $appKey = $credentials['app_key'] ?? '';
+        $appSecret = $credentials['app_secret'] ?? '';
+        $timestamp = time();
+        $nonce = uniqid();
+        
+        $signString = $appKey . $timestamp . $nonce . $appSecret;
+        
+        return hash('sha256', $signString);
+    }
+
+    /**
+     * 关联第三方服务
+     *
+     * @return BelongsTo
+     */
+    public function service(): BelongsTo
+    {
+        return $this->belongsTo(ThirdPartyService::class, 'service_id');
+    }
+
+    /**
+     * 验证凭证配置是否完整
+     *
+     * @return array ['valid' => bool, 'missing_fields' => array]
+     */
+    public function validateCredentials(): array
+    {
+        $authType = $this->getAuthTypeEnum();
+        $requiredFields = $authType->getRequiredFields();
+        $credentials = $this->getDecryptedCredentials();
+        
+        $missingFields = [];
+        foreach ($requiredFields as $field) {
+            if (empty($credentials[$field])) {
+                $missingFields[] = $field;
+            }
+        }
+        
+        return [
+            'valid' => empty($missingFields),
+            'missing_fields' => $missingFields,
+        ];
+    }
+
+    /**
+     * 创建新的凭证
+     *
+     * @param array $data
+     * @return static
+     */
+    public static function createCredential(array $data): static
+    {
+        $credential = new static();
+        $credential->fill($data);
+        
+        // 加密敏感信息
+        if (isset($data['credentials'])) {
+            $credential->setEncryptedCredentials($data['credentials']);
+        }
+        
+        $credential->save();
+        
+        return $credential;
+    }
+}

+ 397 - 0
app/Module/ThirdParty/Models/ThirdPartyLog.php

@@ -0,0 +1,397 @@
+<?php
+
+namespace App\Module\ThirdParty\Models;
+
+use UCore\ModelCore;
+use App\Module\ThirdParty\Enums\LOG_LEVEL;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+/**
+ * 第三方服务调用日志模型
+ * 
+ * @property int $id 主键ID
+ * @property int $service_id 服务ID
+ * @property int|null $credential_id 凭证ID
+ * @property string $request_id 请求ID
+ * @property string $method 请求方法
+ * @property string $url 请求URL
+ * @property array|null $headers 请求头
+ * @property array|null $params 请求参数
+ * @property string|null $body 请求体
+ * @property int|null $response_status 响应状态码
+ * @property array|null $response_headers 响应头
+ * @property string|null $response_body 响应体
+ * @property int|null $response_time 响应时间
+ * @property string|null $error_message 错误信息
+ * @property string $level 日志级别
+ * @property int|null $user_id 用户ID
+ * @property string|null $ip_address IP地址
+ * @property string|null $user_agent User Agent
+ * @property \Carbon\Carbon $created_at 创建时间
+ */
+class ThirdPartyLog extends ModelCore
+{
+    /**
+     * 数据表名
+     *
+     * @var string
+     */
+    protected $table = 'thirdparty_logs';
+
+    /**
+     * 禁用updated_at字段
+     *
+     * @var bool
+     */
+    public $timestamps = false;
+
+    // field start
+    /**
+     * 可批量赋值的属性
+     *
+     * @var array
+     */
+    // attrlist start
+    protected $fillable = [
+        'service_id',
+        'credential_id',
+        'request_id',
+        'method',
+        'url',
+        'headers',
+        'params',
+        'body',
+        'response_status',
+        'response_headers',
+        'response_body',
+        'response_time',
+        'error_message',
+        'level',
+        'user_id',
+        'ip_address',
+        'user_agent',
+        'created_at',
+    ];
+    // attrlist end
+    // field end
+
+    /**
+     * 属性类型转换
+     *
+     * @var array
+     */
+    protected $casts = [
+        'service_id' => 'integer',
+        'credential_id' => 'integer',
+        'headers' => 'array',
+        'params' => 'array',
+        'response_status' => 'integer',
+        'response_headers' => 'array',
+        'response_time' => 'integer',
+        'user_id' => 'integer',
+        'created_at' => 'datetime',
+    ];
+
+    /**
+     * 获取日志级别枚举
+     *
+     * @return LOG_LEVEL
+     */
+    public function getLogLevelEnum(): LOG_LEVEL
+    {
+        return LOG_LEVEL::from($this->level);
+    }
+
+    /**
+     * 获取日志级别标签
+     *
+     * @return string
+     */
+    public function getLevelLabel(): string
+    {
+        return $this->getLogLevelEnum()->getLabel();
+    }
+
+    /**
+     * 检查是否为成功请求
+     *
+     * @return bool
+     */
+    public function isSuccessful(): bool
+    {
+        return $this->response_status >= 200 && $this->response_status < 300;
+    }
+
+    /**
+     * 检查是否为错误请求
+     *
+     * @return bool
+     */
+    public function isError(): bool
+    {
+        return $this->getLogLevelEnum()->isError() || $this->response_status >= 400;
+    }
+
+    /**
+     * 检查是否需要告警
+     *
+     * @return bool
+     */
+    public function needsAlert(): bool
+    {
+        return $this->getLogLevelEnum()->needsAlert();
+    }
+
+    /**
+     * 获取响应时间(秒)
+     *
+     * @return float
+     */
+    public function getResponseTimeInSeconds(): float
+    {
+        return $this->response_time ? $this->response_time / 1000 : 0;
+    }
+
+    /**
+     * 获取格式化的响应时间
+     *
+     * @return string
+     */
+    public function getFormattedResponseTime(): string
+    {
+        if (!$this->response_time) {
+            return '-';
+        }
+        
+        if ($this->response_time < 1000) {
+            return $this->response_time . 'ms';
+        }
+        
+        return number_format($this->getResponseTimeInSeconds(), 2) . 's';
+    }
+
+    /**
+     * 获取状态码描述
+     *
+     * @return string
+     */
+    public function getStatusDescription(): string
+    {
+        if (!$this->response_status) {
+            return '无响应';
+        }
+        
+        $statusTexts = [
+            200 => 'OK',
+            201 => 'Created',
+            204 => 'No Content',
+            400 => 'Bad Request',
+            401 => 'Unauthorized',
+            403 => 'Forbidden',
+            404 => 'Not Found',
+            429 => 'Too Many Requests',
+            500 => 'Internal Server Error',
+            502 => 'Bad Gateway',
+            503 => 'Service Unavailable',
+            504 => 'Gateway Timeout',
+        ];
+        
+        return $statusTexts[$this->response_status] ?? 'Unknown';
+    }
+
+    /**
+     * 获取状态码颜色
+     *
+     * @return string
+     */
+    public function getStatusColor(): string
+    {
+        if (!$this->response_status) {
+            return 'secondary';
+        }
+        
+        if ($this->response_status >= 200 && $this->response_status < 300) {
+            return 'success';
+        }
+        
+        if ($this->response_status >= 300 && $this->response_status < 400) {
+            return 'info';
+        }
+        
+        if ($this->response_status >= 400 && $this->response_status < 500) {
+            return 'warning';
+        }
+        
+        return 'danger';
+    }
+
+    /**
+     * 获取简化的请求体
+     *
+     * @param int $maxLength
+     * @return string
+     */
+    public function getTruncatedBody(int $maxLength = 200): string
+    {
+        if (!$this->body) {
+            return '';
+        }
+        
+        if (strlen($this->body) <= $maxLength) {
+            return $this->body;
+        }
+        
+        return substr($this->body, 0, $maxLength) . '...';
+    }
+
+    /**
+     * 获取简化的响应体
+     *
+     * @param int $maxLength
+     * @return string
+     */
+    public function getTruncatedResponseBody(int $maxLength = 200): string
+    {
+        if (!$this->response_body) {
+            return '';
+        }
+        
+        if (strlen($this->response_body) <= $maxLength) {
+            return $this->response_body;
+        }
+        
+        return substr($this->response_body, 0, $maxLength) . '...';
+    }
+
+    /**
+     * 获取请求的基本信息
+     *
+     * @return array
+     */
+    public function getRequestSummary(): array
+    {
+        return [
+            'method' => $this->method,
+            'url' => $this->url,
+            'status' => $this->response_status,
+            'response_time' => $this->getFormattedResponseTime(),
+            'level' => $this->getLevelLabel(),
+            'created_at' => $this->created_at->format('Y-m-d H:i:s'),
+        ];
+    }
+
+    /**
+     * 关联第三方服务
+     *
+     * @return BelongsTo
+     */
+    public function service(): BelongsTo
+    {
+        return $this->belongsTo(ThirdPartyService::class, 'service_id');
+    }
+
+    /**
+     * 关联认证凭证
+     *
+     * @return BelongsTo
+     */
+    public function credential(): BelongsTo
+    {
+        return $this->belongsTo(ThirdPartyCredential::class, 'credential_id');
+    }
+
+    /**
+     * 生成唯一的请求ID
+     *
+     * @return string
+     */
+    public static function generateRequestId(): string
+    {
+        return uniqid('req_', true);
+    }
+
+    /**
+     * 创建日志记录
+     *
+     * @param array $data
+     * @return static
+     */
+    public static function createLog(array $data): static
+    {
+        // 自动设置创建时间
+        if (!isset($data['created_at'])) {
+            $data['created_at'] = now();
+        }
+        
+        // 自动生成请求ID
+        if (!isset($data['request_id'])) {
+            $data['request_id'] = static::generateRequestId();
+        }
+        
+        // 自动设置日志级别
+        if (!isset($data['level'])) {
+            if (isset($data['response_status'])) {
+                if ($data['response_status'] >= 400) {
+                    $data['level'] = LOG_LEVEL::ERROR->value;
+                } elseif ($data['response_status'] >= 300) {
+                    $data['level'] = LOG_LEVEL::WARNING->value;
+                } else {
+                    $data['level'] = LOG_LEVEL::INFO->value;
+                }
+            } else {
+                $data['level'] = LOG_LEVEL::INFO->value;
+            }
+        }
+        
+        return static::create($data);
+    }
+
+    /**
+     * 按日期范围查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param string $startDate
+     * @param string $endDate
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeDateRange($query, string $startDate, string $endDate)
+    {
+        return $query->whereBetween('created_at', [$startDate, $endDate]);
+    }
+
+    /**
+     * 按服务查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param int $serviceId
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeByService($query, int $serviceId)
+    {
+        return $query->where('service_id', $serviceId);
+    }
+
+    /**
+     * 按日志级别查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param string $level
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeByLevel($query, string $level)
+    {
+        return $query->where('level', $level);
+    }
+
+    /**
+     * 查询错误日志
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeErrors($query)
+    {
+        return $query->whereIn('level', [LOG_LEVEL::ERROR->value, LOG_LEVEL::CRITICAL->value])
+            ->orWhere('response_status', '>=', 400);
+    }
+}

+ 437 - 0
app/Module/ThirdParty/Models/ThirdPartyMonitor.php

@@ -0,0 +1,437 @@
+<?php
+
+namespace App\Module\ThirdParty\Models;
+
+use UCore\ModelCore;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+/**
+ * 第三方服务监控记录模型
+ * 
+ * @property int $id 主键ID
+ * @property int $service_id 服务ID
+ * @property string $check_type 检查类型
+ * @property string $status 检查状态
+ * @property int|null $response_time 响应时间
+ * @property int|null $status_code HTTP状态码
+ * @property string|null $error_message 错误信息
+ * @property array|null $details 详细信息
+ * @property \Carbon\Carbon $checked_at 检查时间
+ */
+class ThirdPartyMonitor extends ModelCore
+{
+    /**
+     * 数据表名
+     *
+     * @var string
+     */
+    protected $table = 'thirdparty_monitors';
+
+    /**
+     * 禁用updated_at字段
+     *
+     * @var bool
+     */
+    public $timestamps = false;
+
+    // field start
+    /**
+     * 可批量赋值的属性
+     *
+     * @var array
+     */
+    // attrlist start
+    protected $fillable = [
+        'service_id',
+        'check_type',
+        'status',
+        'response_time',
+        'status_code',
+        'error_message',
+        'details',
+        'checked_at',
+    ];
+    // attrlist end
+    // field end
+
+    /**
+     * 属性类型转换
+     *
+     * @var array
+     */
+    protected $casts = [
+        'service_id' => 'integer',
+        'response_time' => 'integer',
+        'status_code' => 'integer',
+        'details' => 'array',
+        'checked_at' => 'datetime',
+    ];
+
+    /**
+     * 检查类型常量
+     */
+    const CHECK_TYPE_HEALTH = 'health';
+    const CHECK_TYPE_PERFORMANCE = 'performance';
+    const CHECK_TYPE_AVAILABILITY = 'availability';
+
+    /**
+     * 检查状态常量
+     */
+    const STATUS_SUCCESS = 'success';
+    const STATUS_WARNING = 'warning';
+    const STATUS_ERROR = 'error';
+    const STATUS_TIMEOUT = 'timeout';
+    const STATUS_UNKNOWN = 'unknown';
+
+    /**
+     * 获取检查类型标签
+     *
+     * @return string
+     */
+    public function getCheckTypeLabel(): string
+    {
+        return match ($this->check_type) {
+            self::CHECK_TYPE_HEALTH => '健康检查',
+            self::CHECK_TYPE_PERFORMANCE => '性能检查',
+            self::CHECK_TYPE_AVAILABILITY => '可用性检查',
+            default => '未知类型',
+        };
+    }
+
+    /**
+     * 获取状态标签
+     *
+     * @return string
+     */
+    public function getStatusLabel(): string
+    {
+        return match ($this->status) {
+            self::STATUS_SUCCESS => '成功',
+            self::STATUS_WARNING => '警告',
+            self::STATUS_ERROR => '错误',
+            self::STATUS_TIMEOUT => '超时',
+            self::STATUS_UNKNOWN => '未知',
+            default => '未知状态',
+        };
+    }
+
+    /**
+     * 获取状态颜色
+     *
+     * @return string
+     */
+    public function getStatusColor(): string
+    {
+        return match ($this->status) {
+            self::STATUS_SUCCESS => 'success',
+            self::STATUS_WARNING => 'warning',
+            self::STATUS_ERROR => 'danger',
+            self::STATUS_TIMEOUT => 'danger',
+            self::STATUS_UNKNOWN => 'secondary',
+            default => 'secondary',
+        };
+    }
+
+    /**
+     * 获取状态图标
+     *
+     * @return string
+     */
+    public function getStatusIcon(): string
+    {
+        return match ($this->status) {
+            self::STATUS_SUCCESS => 'fa-check-circle',
+            self::STATUS_WARNING => 'fa-exclamation-triangle',
+            self::STATUS_ERROR => 'fa-times-circle',
+            self::STATUS_TIMEOUT => 'fa-clock',
+            self::STATUS_UNKNOWN => 'fa-question-circle',
+            default => 'fa-question-circle',
+        };
+    }
+
+    /**
+     * 检查是否成功
+     *
+     * @return bool
+     */
+    public function isSuccessful(): bool
+    {
+        return $this->status === self::STATUS_SUCCESS;
+    }
+
+    /**
+     * 检查是否有问题
+     *
+     * @return bool
+     */
+    public function hasIssue(): bool
+    {
+        return in_array($this->status, [self::STATUS_WARNING, self::STATUS_ERROR, self::STATUS_TIMEOUT]);
+    }
+
+    /**
+     * 检查是否为严重问题
+     *
+     * @return bool
+     */
+    public function isCritical(): bool
+    {
+        return in_array($this->status, [self::STATUS_ERROR, self::STATUS_TIMEOUT]);
+    }
+
+    /**
+     * 获取响应时间(秒)
+     *
+     * @return float
+     */
+    public function getResponseTimeInSeconds(): float
+    {
+        return $this->response_time ? $this->response_time / 1000 : 0;
+    }
+
+    /**
+     * 获取格式化的响应时间
+     *
+     * @return string
+     */
+    public function getFormattedResponseTime(): string
+    {
+        if (!$this->response_time) {
+            return '-';
+        }
+        
+        if ($this->response_time < 1000) {
+            return $this->response_time . 'ms';
+        }
+        
+        return number_format($this->getResponseTimeInSeconds(), 2) . 's';
+    }
+
+    /**
+     * 获取性能评级
+     *
+     * @return string
+     */
+    public function getPerformanceGrade(): string
+    {
+        if (!$this->response_time) {
+            return 'N/A';
+        }
+        
+        if ($this->response_time <= 200) {
+            return 'A';
+        } elseif ($this->response_time <= 500) {
+            return 'B';
+        } elseif ($this->response_time <= 1000) {
+            return 'C';
+        } elseif ($this->response_time <= 2000) {
+            return 'D';
+        } else {
+            return 'F';
+        }
+    }
+
+    /**
+     * 获取性能评级颜色
+     *
+     * @return string
+     */
+    public function getPerformanceGradeColor(): string
+    {
+        return match ($this->getPerformanceGrade()) {
+            'A' => 'success',
+            'B' => 'info',
+            'C' => 'warning',
+            'D' => 'danger',
+            'F' => 'dark',
+            default => 'secondary',
+        };
+    }
+
+    /**
+     * 获取详细信息中的特定值
+     *
+     * @param string $key
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getDetail(string $key, $default = null)
+    {
+        return $this->details[$key] ?? $default;
+    }
+
+    /**
+     * 获取监控摘要
+     *
+     * @return array
+     */
+    public function getSummary(): array
+    {
+        return [
+            'check_type' => $this->getCheckTypeLabel(),
+            'status' => $this->getStatusLabel(),
+            'response_time' => $this->getFormattedResponseTime(),
+            'performance_grade' => $this->getPerformanceGrade(),
+            'checked_at' => $this->checked_at->format('Y-m-d H:i:s'),
+        ];
+    }
+
+    /**
+     * 关联第三方服务
+     *
+     * @return BelongsTo
+     */
+    public function service(): BelongsTo
+    {
+        return $this->belongsTo(ThirdPartyService::class, 'service_id');
+    }
+
+    /**
+     * 创建监控记录
+     *
+     * @param array $data
+     * @return static
+     */
+    public static function createMonitor(array $data): static
+    {
+        // 自动设置检查时间
+        if (!isset($data['checked_at'])) {
+            $data['checked_at'] = now();
+        }
+        
+        // 根据响应时间和状态码自动判断状态
+        if (!isset($data['status'])) {
+            if (isset($data['status_code'])) {
+                if ($data['status_code'] >= 200 && $data['status_code'] < 300) {
+                    $data['status'] = self::STATUS_SUCCESS;
+                } elseif ($data['status_code'] >= 300 && $data['status_code'] < 400) {
+                    $data['status'] = self::STATUS_WARNING;
+                } else {
+                    $data['status'] = self::STATUS_ERROR;
+                }
+            } elseif (isset($data['response_time'])) {
+                if ($data['response_time'] > 10000) { // 超过10秒认为超时
+                    $data['status'] = self::STATUS_TIMEOUT;
+                } else {
+                    $data['status'] = self::STATUS_SUCCESS;
+                }
+            } else {
+                $data['status'] = self::STATUS_UNKNOWN;
+            }
+        }
+        
+        return static::create($data);
+    }
+
+    /**
+     * 按服务查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param int $serviceId
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeByService($query, int $serviceId)
+    {
+        return $query->where('service_id', $serviceId);
+    }
+
+    /**
+     * 按检查类型查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param string $checkType
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeByCheckType($query, string $checkType)
+    {
+        return $query->where('check_type', $checkType);
+    }
+
+    /**
+     * 按状态查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param string $status
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeByStatus($query, string $status)
+    {
+        return $query->where('status', $status);
+    }
+
+    /**
+     * 查询成功的记录
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeSuccessful($query)
+    {
+        return $query->where('status', self::STATUS_SUCCESS);
+    }
+
+    /**
+     * 查询有问题的记录
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeWithIssues($query)
+    {
+        return $query->whereIn('status', [self::STATUS_WARNING, self::STATUS_ERROR, self::STATUS_TIMEOUT]);
+    }
+
+    /**
+     * 查询严重问题的记录
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeCritical($query)
+    {
+        return $query->whereIn('status', [self::STATUS_ERROR, self::STATUS_TIMEOUT]);
+    }
+
+    /**
+     * 按时间范围查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param string $startDate
+     * @param string $endDate
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeDateRange($query, string $startDate, string $endDate)
+    {
+        return $query->whereBetween('checked_at', [$startDate, $endDate]);
+    }
+
+    /**
+     * 获取所有检查类型
+     *
+     * @return array
+     */
+    public static function getCheckTypes(): array
+    {
+        return [
+            self::CHECK_TYPE_HEALTH => '健康检查',
+            self::CHECK_TYPE_PERFORMANCE => '性能检查',
+            self::CHECK_TYPE_AVAILABILITY => '可用性检查',
+        ];
+    }
+
+    /**
+     * 获取所有状态
+     *
+     * @return array
+     */
+    public static function getStatuses(): array
+    {
+        return [
+            self::STATUS_SUCCESS => '成功',
+            self::STATUS_WARNING => '警告',
+            self::STATUS_ERROR => '错误',
+            self::STATUS_TIMEOUT => '超时',
+            self::STATUS_UNKNOWN => '未知',
+        ];
+    }
+}

+ 383 - 0
app/Module/ThirdParty/Models/ThirdPartyQuota.php

@@ -0,0 +1,383 @@
+<?php
+
+namespace App\Module\ThirdParty\Models;
+
+use UCore\ModelCore;
+use App\Module\ThirdParty\Enums\QUOTA_TYPE;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+/**
+ * 第三方服务配额管理模型
+ * 
+ * @property int $id 主键ID
+ * @property int $service_id 服务ID
+ * @property string $type 配额类型
+ * @property int $limit_value 限制值
+ * @property int $used_value 已使用值
+ * @property \Carbon\Carbon|null $reset_at 重置时间
+ * @property \Carbon\Carbon|null $window_start 时间窗口开始
+ * @property \Carbon\Carbon|null $window_end 时间窗口结束
+ * @property bool $is_active 是否激活
+ * @property float $alert_threshold 告警阈值
+ * @property bool $is_exceeded 是否已超限
+ * @property \Carbon\Carbon|null $exceeded_at 超限时间
+ * @property \Carbon\Carbon $created_at 创建时间
+ * @property \Carbon\Carbon $updated_at 更新时间
+ */
+class ThirdPartyQuota extends ModelCore
+{
+    /**
+     * 数据表名
+     *
+     * @var string
+     */
+    protected $table = 'thirdparty_quotas';
+
+    // field start
+    /**
+     * 可批量赋值的属性
+     *
+     * @var array
+     */
+    // attrlist start
+    protected $fillable = [
+        'service_id',
+        'type',
+        'limit_value',
+        'used_value',
+        'reset_at',
+        'window_start',
+        'window_end',
+        'is_active',
+        'alert_threshold',
+        'is_exceeded',
+        'exceeded_at',
+    ];
+    // attrlist end
+    // field end
+
+    /**
+     * 属性类型转换
+     *
+     * @var array
+     */
+    protected $casts = [
+        'service_id' => 'integer',
+        'limit_value' => 'integer',
+        'used_value' => 'integer',
+        'reset_at' => 'datetime',
+        'window_start' => 'datetime',
+        'window_end' => 'datetime',
+        'is_active' => 'boolean',
+        'alert_threshold' => 'decimal:2',
+        'is_exceeded' => 'boolean',
+        'exceeded_at' => 'datetime',
+        'created_at' => 'datetime',
+        'updated_at' => 'datetime',
+    ];
+
+    /**
+     * 获取配额类型枚举
+     *
+     * @return QUOTA_TYPE
+     */
+    public function getQuotaTypeEnum(): QUOTA_TYPE
+    {
+        return QUOTA_TYPE::from($this->type);
+    }
+
+    /**
+     * 获取配额类型标签
+     *
+     * @return string
+     */
+    public function getTypeLabel(): string
+    {
+        return $this->getQuotaTypeEnum()->getLabel();
+    }
+
+    /**
+     * 获取使用百分比
+     *
+     * @return float
+     */
+    public function getUsagePercentage(): float
+    {
+        if ($this->limit_value <= 0) {
+            return 0;
+        }
+        
+        return min(100, ($this->used_value / $this->limit_value) * 100);
+    }
+
+    /**
+     * 获取剩余配额
+     *
+     * @return int
+     */
+    public function getRemainingQuota(): int
+    {
+        return max(0, $this->limit_value - $this->used_value);
+    }
+
+    /**
+     * 检查是否已超限
+     *
+     * @return bool
+     */
+    public function isExceeded(): bool
+    {
+        return $this->is_exceeded || $this->used_value >= $this->limit_value;
+    }
+
+    /**
+     * 检查是否接近告警阈值
+     *
+     * @return bool
+     */
+    public function isNearThreshold(): bool
+    {
+        return $this->getUsagePercentage() >= $this->alert_threshold;
+    }
+
+    /**
+     * 检查是否需要重置
+     *
+     * @return bool
+     */
+    public function needsReset(): bool
+    {
+        $quotaType = $this->getQuotaTypeEnum();
+        
+        // 总计类型不需要重置
+        if ($quotaType === QUOTA_TYPE::TOTAL) {
+            return false;
+        }
+        
+        // 检查是否超过了当前时间窗口
+        if ($this->window_end && now()->gt($this->window_end)) {
+            return true;
+        }
+        
+        // 检查重置时间
+        if ($this->reset_at && now()->gte($this->reset_at)) {
+            return true;
+        }
+        
+        return false;
+    }
+
+    /**
+     * 重置配额
+     *
+     * @return bool
+     */
+    public function resetQuota(): bool
+    {
+        $quotaType = $this->getQuotaTypeEnum();
+        
+        // 计算新的时间窗口
+        $windowStart = $quotaType->getCurrentWindowStart();
+        $windowEnd = $quotaType->getCurrentWindowEnd();
+        
+        // 计算下次重置时间
+        $resetAt = $quotaType === QUOTA_TYPE::TOTAL ? null : $windowEnd;
+        
+        return $this->update([
+            'used_value' => 0,
+            'window_start' => $windowStart,
+            'window_end' => $windowEnd,
+            'reset_at' => $resetAt,
+            'is_exceeded' => false,
+            'exceeded_at' => null,
+        ]);
+    }
+
+    /**
+     * 增加使用量
+     *
+     * @param int $amount
+     * @return bool
+     */
+    public function incrementUsage(int $amount = 1): bool
+    {
+        // 检查是否需要重置
+        if ($this->needsReset()) {
+            $this->resetQuota();
+            $this->refresh();
+        }
+        
+        $newUsedValue = $this->used_value + $amount;
+        $updateData = ['used_value' => $newUsedValue];
+        
+        // 检查是否超限
+        if ($newUsedValue >= $this->limit_value && !$this->is_exceeded) {
+            $updateData['is_exceeded'] = true;
+            $updateData['exceeded_at'] = now();
+        }
+        
+        return $this->update($updateData);
+    }
+
+    /**
+     * 检查是否可以使用指定数量的配额
+     *
+     * @param int $amount
+     * @return bool
+     */
+    public function canUse(int $amount = 1): bool
+    {
+        if (!$this->is_active) {
+            return false;
+        }
+        
+        // 检查是否需要重置
+        if ($this->needsReset()) {
+            return $amount <= $this->limit_value;
+        }
+        
+        return ($this->used_value + $amount) <= $this->limit_value;
+    }
+
+    /**
+     * 获取配额状态
+     *
+     * @return string
+     */
+    public function getStatus(): string
+    {
+        if (!$this->is_active) {
+            return 'inactive';
+        }
+        
+        if ($this->isExceeded()) {
+            return 'exceeded';
+        }
+        
+        if ($this->isNearThreshold()) {
+            return 'warning';
+        }
+        
+        return 'normal';
+    }
+
+    /**
+     * 获取配额状态颜色
+     *
+     * @return string
+     */
+    public function getStatusColor(): string
+    {
+        return match ($this->getStatus()) {
+            'exceeded' => 'danger',
+            'warning' => 'warning',
+            'normal' => 'success',
+            'inactive' => 'secondary',
+        };
+    }
+
+    /**
+     * 获取配额状态标签
+     *
+     * @return string
+     */
+    public function getStatusLabel(): string
+    {
+        return match ($this->getStatus()) {
+            'exceeded' => '已超限',
+            'warning' => '接近限制',
+            'normal' => '正常',
+            'inactive' => '未激活',
+        };
+    }
+
+    /**
+     * 获取格式化的配额信息
+     *
+     * @return string
+     */
+    public function getFormattedQuota(): string
+    {
+        return number_format($this->used_value) . ' / ' . number_format($this->limit_value);
+    }
+
+    /**
+     * 关联第三方服务
+     *
+     * @return BelongsTo
+     */
+    public function service(): BelongsTo
+    {
+        return $this->belongsTo(ThirdPartyService::class, 'service_id');
+    }
+
+    /**
+     * 创建配额记录
+     *
+     * @param array $data
+     * @return static
+     */
+    public static function createQuota(array $data): static
+    {
+        $quotaType = QUOTA_TYPE::from($data['type']);
+        
+        // 设置时间窗口
+        if ($quotaType->isTimeWindow()) {
+            $data['window_start'] = $quotaType->getCurrentWindowStart();
+            $data['window_end'] = $quotaType->getCurrentWindowEnd();
+            $data['reset_at'] = $data['window_end'];
+        }
+        
+        // 设置默认值
+        $data['used_value'] = $data['used_value'] ?? 0;
+        $data['is_active'] = $data['is_active'] ?? true;
+        $data['alert_threshold'] = $data['alert_threshold'] ?? 80.0;
+        
+        return static::create($data);
+    }
+
+    /**
+     * 按服务查询
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param int $serviceId
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeByService($query, int $serviceId)
+    {
+        return $query->where('service_id', $serviceId);
+    }
+
+    /**
+     * 查询激活的配额
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeActive($query)
+    {
+        return $query->where('is_active', true);
+    }
+
+    /**
+     * 查询已超限的配额
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeExceeded($query)
+    {
+        return $query->where('is_exceeded', true);
+    }
+
+    /**
+     * 查询接近阈值的配额
+     *
+     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function scopeNearThreshold($query)
+    {
+        return $query->whereRaw('(used_value / limit_value * 100) >= alert_threshold');
+    }
+}

+ 352 - 0
app/Module/ThirdParty/Models/ThirdPartyService.php

@@ -0,0 +1,352 @@
+<?php
+
+namespace App\Module\ThirdParty\Models;
+
+use UCore\ModelCore;
+use App\Module\ThirdParty\Enums\SERVICE_TYPE;
+use App\Module\ThirdParty\Enums\AUTH_TYPE;
+use App\Module\ThirdParty\Enums\SERVICE_STATUS;
+use Illuminate\Database\Eloquent\Relations\HasMany;
+
+/**
+ * 第三方服务模型
+ * 
+ * @property int $id 主键ID
+ * @property string $name 服务名称
+ * @property string $code 服务代码
+ * @property string $type 服务类型
+ * @property string $provider 服务提供商
+ * @property string|null $description 服务描述
+ * @property string|null $base_url 基础URL
+ * @property string $version API版本
+ * @property string $auth_type 认证类型
+ * @property string $status 服务状态
+ * @property int $priority 优先级
+ * @property int $timeout 超时时间
+ * @property int $retry_times 重试次数
+ * @property int $retry_delay 重试延迟
+ * @property array|null $config 服务配置信息
+ * @property array|null $headers 默认请求头
+ * @property array|null $params 默认参数
+ * @property string|null $webhook_url Webhook回调地址
+ * @property string|null $webhook_secret Webhook密钥
+ * @property string|null $health_check_url 健康检查URL
+ * @property int $health_check_interval 健康检查间隔
+ * @property \Carbon\Carbon|null $last_health_check 最后健康检查时间
+ * @property string $health_status 健康状态
+ * @property \Carbon\Carbon $created_at 创建时间
+ * @property \Carbon\Carbon $updated_at 更新时间
+ */
+class ThirdPartyService extends ModelCore
+{
+    /**
+     * 数据表名
+     *
+     * @var string
+     */
+    protected $table = 'thirdparty_services';
+
+    // field start
+    /**
+     * 可批量赋值的属性
+     *
+     * @var array
+     */
+    // attrlist start
+    protected $fillable = [
+        'name',
+        'code',
+        'type',
+        'provider',
+        'description',
+        'base_url',
+        'version',
+        'auth_type',
+        'status',
+        'priority',
+        'timeout',
+        'retry_times',
+        'retry_delay',
+        'config',
+        'headers',
+        'params',
+        'webhook_url',
+        'webhook_secret',
+        'health_check_url',
+        'health_check_interval',
+        'last_health_check',
+        'health_status',
+    ];
+    // attrlist end
+    // field end
+
+    /**
+     * 属性类型转换
+     *
+     * @var array
+     */
+    protected $casts = [
+        'config' => 'array',
+        'headers' => 'array',
+        'params' => 'array',
+        'priority' => 'integer',
+        'timeout' => 'integer',
+        'retry_times' => 'integer',
+        'retry_delay' => 'integer',
+        'health_check_interval' => 'integer',
+        'last_health_check' => 'datetime',
+        'created_at' => 'datetime',
+        'updated_at' => 'datetime',
+    ];
+
+    /**
+     * 获取服务类型枚举
+     *
+     * @return SERVICE_TYPE
+     */
+    public function getServiceTypeEnum(): SERVICE_TYPE
+    {
+        return SERVICE_TYPE::from($this->type);
+    }
+
+    /**
+     * 获取认证类型枚举
+     *
+     * @return AUTH_TYPE
+     */
+    public function getAuthTypeEnum(): AUTH_TYPE
+    {
+        return AUTH_TYPE::from($this->auth_type);
+    }
+
+    /**
+     * 获取服务状态枚举
+     *
+     * @return SERVICE_STATUS
+     */
+    public function getServiceStatusEnum(): SERVICE_STATUS
+    {
+        return SERVICE_STATUS::from($this->status);
+    }
+
+    /**
+     * 获取服务类型标签
+     *
+     * @return string
+     */
+    public function getTypeLabel(): string
+    {
+        return $this->getServiceTypeEnum()->getLabel();
+    }
+
+    /**
+     * 获取认证类型标签
+     *
+     * @return string
+     */
+    public function getAuthTypeLabel(): string
+    {
+        return $this->getAuthTypeEnum()->getLabel();
+    }
+
+    /**
+     * 获取状态标签
+     *
+     * @return string
+     */
+    public function getStatusLabel(): string
+    {
+        return $this->getServiceStatusEnum()->getLabel();
+    }
+
+    /**
+     * 检查服务是否可用
+     *
+     * @return bool
+     */
+    public function isAvailable(): bool
+    {
+        return $this->getServiceStatusEnum()->isAvailable();
+    }
+
+    /**
+     * 检查服务是否可以调用API
+     *
+     * @return bool
+     */
+    public function canCallApi(): bool
+    {
+        return $this->getServiceStatusEnum()->canCallApi();
+    }
+
+    /**
+     * 检查服务是否需要关注
+     *
+     * @return bool
+     */
+    public function needsAttention(): bool
+    {
+        return $this->getServiceStatusEnum()->needsAttention();
+    }
+
+    /**
+     * 获取完整的API URL
+     *
+     * @param string $endpoint
+     * @return string
+     */
+    public function getApiUrl(string $endpoint = ''): string
+    {
+        $baseUrl = rtrim($this->base_url, '/');
+        $endpoint = ltrim($endpoint, '/');
+        
+        if (empty($endpoint)) {
+            return $baseUrl;
+        }
+        
+        return $baseUrl . '/' . $endpoint;
+    }
+
+    /**
+     * 获取默认请求头
+     *
+     * @return array
+     */
+    public function getDefaultHeaders(): array
+    {
+        $headers = $this->headers ?? [];
+        
+        // 添加认证相关的默认头
+        $authType = $this->getAuthTypeEnum();
+        if ($authType->getHeaderName()) {
+            $headers['Content-Type'] = 'application/json';
+            $headers['Accept'] = 'application/json';
+        }
+        
+        return $headers;
+    }
+
+    /**
+     * 获取默认参数
+     *
+     * @return array
+     */
+    public function getDefaultParams(): array
+    {
+        return $this->params ?? [];
+    }
+
+    /**
+     * 关联认证凭证
+     *
+     * @return HasMany
+     */
+    public function credentials(): HasMany
+    {
+        return $this->hasMany(ThirdPartyCredential::class, 'service_id');
+    }
+
+    /**
+     * 关联调用日志
+     *
+     * @return HasMany
+     */
+    public function logs(): HasMany
+    {
+        return $this->hasMany(ThirdPartyLog::class, 'service_id');
+    }
+
+    /**
+     * 关联配额管理
+     *
+     * @return HasMany
+     */
+    public function quotas(): HasMany
+    {
+        return $this->hasMany(ThirdPartyQuota::class, 'service_id');
+    }
+
+    /**
+     * 关联监控记录
+     *
+     * @return HasMany
+     */
+    public function monitors(): HasMany
+    {
+        return $this->hasMany(ThirdPartyMonitor::class, 'service_id');
+    }
+
+    /**
+     * 获取激活的凭证
+     *
+     * @param string $environment
+     * @return ThirdPartyCredential|null
+     */
+    public function getActiveCredential(string $environment = 'production'): ?ThirdPartyCredential
+    {
+        return $this->credentials()
+            ->where('is_active', true)
+            ->where('environment', $environment)
+            ->where(function ($query) {
+                $query->whereNull('expires_at')
+                    ->orWhere('expires_at', '>', now());
+            })
+            ->first();
+    }
+
+    /**
+     * 更新健康状态
+     *
+     * @param string $status
+     * @return bool
+     */
+    public function updateHealthStatus(string $status): bool
+    {
+        return $this->update([
+            'health_status' => $status,
+            'last_health_check' => now(),
+        ]);
+    }
+
+    /**
+     * 检查是否需要健康检查
+     *
+     * @return bool
+     */
+    public function needsHealthCheck(): bool
+    {
+        if (!$this->health_check_url) {
+            return false;
+        }
+        
+        if (!$this->last_health_check) {
+            return true;
+        }
+        
+        $nextCheck = $this->last_health_check->addSeconds($this->health_check_interval);
+        return now()->gte($nextCheck);
+    }
+
+    /**
+     * 生成唯一的服务代码
+     *
+     * @param string $name
+     * @param string $provider
+     * @return string
+     */
+    public static function generateCode(string $name, string $provider): string
+    {
+        $code = strtolower($provider . '_' . str_replace(' ', '_', $name));
+        $code = preg_replace('/[^a-z0-9_]/', '', $code);
+        
+        // 确保代码唯一
+        $counter = 1;
+        $originalCode = $code;
+        while (static::where('code', $code)->exists()) {
+            $code = $originalCode . '_' . $counter;
+            $counter++;
+        }
+        
+        return $code;
+    }
+}

+ 207 - 0
app/Module/ThirdParty/Providers/ThirdPartyServiceProvider.php

@@ -0,0 +1,207 @@
+<?php
+
+namespace App\Module\ThirdParty\Providers;
+
+use Illuminate\Support\ServiceProvider;
+use Illuminate\Support\Facades\Route;
+
+/**
+ * ThirdParty模块服务提供者
+ *
+ * 专注于第三方服务管理功能,提供统一的第三方服务接入和管理
+ */
+class ThirdPartyServiceProvider extends ServiceProvider
+{
+    /**
+     * 注册服务
+     *
+     * @return void
+     */
+    public function register()
+    {
+        // 注册配置文件
+        $this->mergeConfigFrom(
+            __DIR__ . '/../Config/thirdparty.php',
+            'thirdparty'
+        );
+
+        // 注册服务
+        $this->registerServices();
+    }
+
+    /**
+     * 启动服务
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        // 注册路由
+        $this->registerRoutes();
+
+        // 注册命令
+        $this->registerCommands();
+
+        // 注册事件监听器
+        $this->registerEventListeners();
+
+        // 发布资源
+        $this->publishResources();
+    }
+
+    /**
+     * 注册服务
+     *
+     * @return void
+     */
+    protected function registerServices()
+    {
+        // 注册第三方服务核心服务
+        $this->app->singleton('thirdparty.service', function () {
+            return new \App\Module\ThirdParty\Services\ThirdPartyService();
+        });
+
+        // 注册凭证管理服务
+        $this->app->singleton('thirdparty.credential', function () {
+            return new \App\Module\ThirdParty\Services\CredentialService();
+        });
+
+        // 注册监控服务
+        $this->app->singleton('thirdparty.monitor', function () {
+            return new \App\Module\ThirdParty\Services\MonitorService();
+        });
+
+        // 注册日志服务
+        $this->app->singleton('thirdparty.log', function () {
+            return new \App\Module\ThirdParty\Services\LogService();
+        });
+
+        // 注册配额管理服务
+        $this->app->singleton('thirdparty.quota', function () {
+            return new \App\Module\ThirdParty\Services\QuotaService();
+        });
+    }
+
+    /**
+     * 注册路由
+     *
+     * @return void
+     */
+    protected function registerRoutes()
+    {
+        // 注册后台管理路由
+        if (file_exists($adminRoutes = __DIR__ . '/../Routes/admin.php')) {
+            Route::middleware(['web', 'admin'])
+                ->prefix(config('admin.route.prefix', 'admin'))
+                ->group($adminRoutes);
+        }
+
+        // 注册API路由(如果需要)
+        if (file_exists($apiRoutes = __DIR__ . '/../Routes/api.php')) {
+            Route::middleware(['api'])
+                ->prefix('api/thirdparty')
+                ->group($apiRoutes);
+        }
+    }
+
+    /**
+     * 注册命令
+     *
+     * @return void
+     */
+    protected function registerCommands()
+    {
+        if ($this->app->runningInConsole()) {
+            $this->commands([
+                \App\Module\ThirdParty\Commands\HealthCheckCommand::class,
+                \App\Module\ThirdParty\Commands\QuotaResetCommand::class,
+                \App\Module\ThirdParty\Commands\CleanupLogsCommand::class,
+                \App\Module\ThirdParty\Commands\SyncServicesCommand::class,
+                \App\Module\ThirdParty\Commands\TestServiceCommand::class,
+            ]);
+        }
+    }
+
+    /**
+     * 注册事件监听器
+     *
+     * @return void
+     */
+    protected function registerEventListeners()
+    {
+        // 注册事件监听器
+        $events = [
+            \App\Module\ThirdParty\Events\ServiceCreatedEvent::class => [
+                \App\Module\ThirdParty\Listeners\ServiceCreatedListener::class,
+            ],
+            \App\Module\ThirdParty\Events\ServiceStatusChangedEvent::class => [
+                \App\Module\ThirdParty\Listeners\ServiceStatusChangedListener::class,
+            ],
+            \App\Module\ThirdParty\Events\QuotaExceededEvent::class => [
+                \App\Module\ThirdParty\Listeners\QuotaExceededListener::class,
+            ],
+            \App\Module\ThirdParty\Events\HealthCheckFailedEvent::class => [
+                \App\Module\ThirdParty\Listeners\HealthCheckFailedListener::class,
+            ],
+            \App\Module\ThirdParty\Events\ApiCallFailedEvent::class => [
+                \App\Module\ThirdParty\Listeners\ApiCallFailedListener::class,
+            ],
+        ];
+
+        foreach ($events as $event => $listeners) {
+            foreach ($listeners as $listener) {
+                \Illuminate\Support\Facades\Event::listen($event, $listener);
+            }
+        }
+    }
+
+    /**
+     * 发布资源
+     *
+     * @return void
+     */
+    protected function publishResources()
+    {
+        if ($this->app->runningInConsole()) {
+            // 发布配置文件
+            $this->publishes([
+                __DIR__ . '/../Config/thirdparty.php' => config_path('thirdparty.php'),
+            ], 'thirdparty-config');
+
+            // 发布数据库迁移文件
+            $this->publishes([
+                __DIR__ . '/../Databases/GenerateSql/thirdparty_tables.sql' => database_path('sql/thirdparty_tables.sql'),
+            ], 'thirdparty-migrations');
+
+            // 发布视图文件(如果有)
+            if (is_dir(__DIR__ . '/../Resources/views')) {
+                $this->publishes([
+                    __DIR__ . '/../Resources/views' => resource_path('views/vendor/thirdparty'),
+                ], 'thirdparty-views');
+            }
+
+            // 发布前端资源(如果有)
+            if (is_dir(__DIR__ . '/../Resources/assets')) {
+                $this->publishes([
+                    __DIR__ . '/../Resources/assets' => public_path('vendor/thirdparty'),
+                ], 'thirdparty-assets');
+            }
+        }
+    }
+
+    /**
+     * 获取提供的服务
+     *
+     * @return array
+     */
+    public function provides()
+    {
+        return [
+            'thirdparty.service',
+            'thirdparty.credential',
+            'thirdparty.monitor',
+            'thirdparty.log',
+            'thirdparty.quota',
+        ];
+    }
+}

+ 206 - 0
app/Module/ThirdParty/README.md

@@ -0,0 +1,206 @@
+# ThirdParty模块
+
+ThirdParty模块专门处理接入第三方服务的需求,提供统一的第三方服务管理、认证、监控和调用功能。
+
+## 🚀 功能特性
+
+### 核心功能
+- **服务配置管理**: 统一管理各种第三方服务的配置信息
+- **认证凭证管理**: 安全存储和管理API密钥、Token等认证信息
+- **服务状态监控**: 实时监控第三方服务的可用性和响应时间
+- **调用日志记录**: 详细记录所有第三方API调用的日志信息
+- **错误处理和重试**: 统一的错误处理机制和智能重试策略
+- **配额和限流管理**: 管理第三方服务的调用配额和频率限制
+
+### 管理功能
+- **后台管理**: 完整的后台管理界面
+- **实时监控**: 第三方服务调用实时监控和告警
+- **数据统计**: 调用统计和性能分析
+- **批量操作**: 支持批量管理服务配置
+- **健康检查**: 定期检查第三方服务健康状态
+
+## 📦 支持的服务类型
+
+### 通信服务
+- **短信服务**: 阿里云短信、腾讯云短信、华为云短信等
+- **邮件服务**: SMTP、阿里云邮件推送、SendGrid等
+- **推送服务**: 极光推送、个推、友盟推送等
+
+### 支付服务
+- **支付宝**: 支付宝开放平台API
+- **微信支付**: 微信支付API
+- **银联支付**: 银联在线支付API
+
+### 云存储服务
+- **阿里云OSS**: 对象存储服务
+- **腾讯云COS**: 云对象存储
+- **七牛云**: 对象存储服务
+
+### 地图服务
+- **高德地图**: 地图API服务
+- **百度地图**: 地图API服务
+- **腾讯地图**: 地图API服务
+
+### AI服务
+- **百度AI**: 语音识别、图像识别等
+- **阿里云AI**: 智能语音、视觉智能等
+- **腾讯云AI**: 人工智能服务
+
+## 🏗️ 架构设计
+
+### 模块架构
+```
+ThirdParty模块
+├── 服务配置层 (Service Configuration)
+├── 认证管理层 (Authentication Management)
+├── 调用执行层 (API Execution)
+├── 监控记录层 (Monitoring & Logging)
+└── 配额控制层 (Quota Management)
+```
+
+### 数据流向
+```
+业务模块 → ThirdPartyService → 认证验证 → API调用 → 结果处理 → 日志记录
+```
+
+## 📋 数据库设计
+
+### 第三方服务表 (kku_thirdparty_services)
+存储第三方服务的基本配置信息
+
+### 认证凭证表 (kku_thirdparty_credentials)
+安全存储各种认证凭证信息
+
+### 调用日志表 (kku_thirdparty_logs)
+记录所有第三方API调用的详细日志
+
+### 配额管理表 (kku_thirdparty_quotas)
+管理第三方服务的调用配额和限制
+
+### 监控记录表 (kku_thirdparty_monitors)
+记录服务监控和健康检查数据
+
+## 🔧 使用示例
+
+### 1. 服务注册
+```php
+use App\Module\ThirdParty\Services\ThirdPartyService;
+
+$thirdPartyService = new ThirdPartyService();
+$service = $thirdPartyService->registerService([
+    'name' => '阿里云短信服务',
+    'type' => 'SMS',
+    'provider' => 'ALIYUN',
+    'base_url' => 'https://dysmsapi.aliyuncs.com',
+    'config' => [
+        'access_key_id' => 'your_access_key',
+        'access_key_secret' => 'your_secret',
+        'sign_name' => '您的签名'
+    ]
+]);
+```
+
+### 2. API调用
+```php
+use App\Module\ThirdParty\Services\ThirdPartyService;
+
+$thirdPartyService = new ThirdPartyService();
+$result = $thirdPartyService->callApi('aliyun_sms', 'send_sms', [
+    'phone_numbers' => '13800138000',
+    'template_code' => 'SMS_123456',
+    'template_param' => ['code' => '123456']
+]);
+```
+
+### 3. 监控检查
+```php
+use App\Module\ThirdParty\Services\MonitorService;
+
+$monitorService = new MonitorService();
+$status = $monitorService->checkServiceHealth('aliyun_sms');
+```
+
+## 🔒 安全特性
+
+### 凭证安全
+- 敏感信息加密存储
+- 支持密钥轮换
+- 访问权限控制
+- 审计日志记录
+
+### 调用安全
+- 请求签名验证
+- SSL/TLS加密传输
+- 频率限制保护
+- 异常行为监控
+
+## 📊 监控统计
+
+### 实时监控
+- API调用成功率
+- 响应时间统计
+- 错误率分析
+- 配额使用情况
+
+### 告警机制
+- 服务不可用告警
+- 响应时间超时告警
+- 错误率过高告警
+- 配额即将耗尽告警
+
+## 🚀 扩展性
+
+### 新服务接入
+模块提供标准化的接入流程,支持快速接入新的第三方服务
+
+### 自定义适配器
+支持为特殊需求的第三方服务开发自定义适配器
+
+### 插件机制
+提供插件机制,支持扩展功能和自定义处理逻辑
+
+## 📝 开发规范
+
+### 命名规范
+- 服务类以Service结尾
+- 逻辑类以Logic结尾
+- 验证器以Validator结尾
+- 枚举使用大写下划线命名
+
+### 代码规范
+- 遵循PSR-4自动加载标准
+- 使用PHP 8.0+语法特性
+- 完善的中文注释和文档
+- 严格的类型声明
+
+## 🔄 与其他模块的关系
+
+### 依赖模块
+- **System模块**: 系统配置和日志服务
+- **User模块**: 用户认证和权限管理
+- **Admin模块**: 后台管理功能
+
+### 服务模块
+- **Sms模块**: 通过ThirdParty模块调用第三方短信服务
+- **Mail模块**: 通过ThirdParty模块调用第三方邮件服务
+- **Push模块**: 通过ThirdParty模块调用第三方推送服务
+
+## 📈 后续扩展计划
+
+### 功能扩展
+- 支持更多第三方服务类型
+- 增强监控和告警功能
+- 添加自动故障转移机制
+- 实现服务负载均衡
+
+### 性能优化
+- 实现连接池管理
+- 添加缓存机制
+- 优化并发调用
+- 实现异步处理
+
+### 安全增强
+- 增强凭证管理
+- 添加访问审计
+- 实现风险评估
+- 加强异常检测

+ 438 - 0
app/Module/ThirdParty/Services/ThirdPartyService.php

@@ -0,0 +1,438 @@
+<?php
+
+namespace App\Module\ThirdParty\Services;
+
+use App\Module\ThirdParty\Models\ThirdPartyService as ServiceModel;
+use App\Module\ThirdParty\Models\ThirdPartyCredential;
+use App\Module\ThirdParty\Models\ThirdPartyLog;
+use App\Module\ThirdParty\Models\ThirdPartyQuota;
+use App\Module\ThirdParty\Enums\SERVICE_STATUS;
+use App\Module\ThirdParty\Enums\LOG_LEVEL;
+use Illuminate\Support\Facades\Http;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Http\Client\Response;
+
+/**
+ * 第三方服务核心服务类
+ */
+class ThirdPartyService
+{
+    /**
+     * 注册新的第三方服务
+     *
+     * @param array $data
+     * @return ServiceModel
+     */
+    public static function registerService(array $data): ServiceModel
+    {
+        // 生成服务代码
+        if (empty($data['code'])) {
+            $data['code'] = ServiceModel::generateCode($data['name'], $data['provider']);
+        }
+        
+        // 设置默认值
+        $data = array_merge([
+            'version' => 'v1',
+            'status' => config('thirdparty.defaults.service_status', 'INACTIVE'),
+            'auth_type' => config('thirdparty.defaults.auth_type', 'API_KEY'),
+            'timeout' => config('thirdparty.defaults.timeout', 30),
+            'retry_times' => config('thirdparty.defaults.retry_times', 3),
+            'retry_delay' => config('thirdparty.defaults.retry_delay', 1000),
+            'health_check_interval' => config('thirdparty.defaults.health_check_interval', 300),
+            'priority' => 0,
+        ], $data);
+        
+        return ServiceModel::create($data);
+    }
+
+    /**
+     * 调用第三方API
+     *
+     * @param string $serviceCode 服务代码
+     * @param string $endpoint API端点
+     * @param array $data 请求数据
+     * @param string $method HTTP方法
+     * @param array $options 额外选项
+     * @return array
+     * @throws \Exception
+     */
+    public static function callApi(
+        string $serviceCode,
+        string $endpoint,
+        array $data = [],
+        string $method = 'POST',
+        array $options = []
+    ): array {
+        $service = static::getServiceByCode($serviceCode);
+        
+        if (!$service) {
+            throw new \Exception("服务 {$serviceCode} 不存在");
+        }
+        
+        if (!$service->canCallApi()) {
+            throw new \Exception("服务 {$serviceCode} 当前不可用,状态:{$service->getStatusLabel()}");
+        }
+        
+        // 检查配额
+        if (!static::checkQuota($service)) {
+            throw new \Exception("服务 {$serviceCode} 配额已用完");
+        }
+        
+        // 获取凭证
+        $credential = $service->getActiveCredential($options['environment'] ?? 'production');
+        if (!$credential) {
+            throw new \Exception("服务 {$serviceCode} 没有可用的认证凭证");
+        }
+        
+        $requestId = ThirdPartyLog::generateRequestId();
+        $startTime = microtime(true);
+        
+        try {
+            // 构建请求
+            $url = $service->getApiUrl($endpoint);
+            $headers = array_merge($service->getDefaultHeaders(), $credential->generateAuthHeaders());
+            $params = array_merge($service->getDefaultParams(), $data);
+            
+            // 发送请求
+            $response = static::sendRequest($service, $url, $method, $params, $headers, $options);
+            
+            $responseTime = (int)((microtime(true) - $startTime) * 1000);
+            
+            // 记录日志
+            static::logApiCall($service, $credential, $requestId, $method, $url, $headers, $params, $response, $responseTime);
+            
+            // 更新配额
+            static::updateQuota($service);
+            
+            // 更新凭证使用统计
+            $credential->updateUsageStats();
+            
+            return [
+                'success' => true,
+                'data' => $response->json(),
+                'status_code' => $response->status(),
+                'response_time' => $responseTime,
+                'request_id' => $requestId,
+            ];
+            
+        } catch (\Exception $e) {
+            $responseTime = (int)((microtime(true) - $startTime) * 1000);
+            
+            // 记录错误日志
+            static::logApiError($service, $credential, $requestId, $method, $url, $headers, $params, $e, $responseTime);
+            
+            throw $e;
+        }
+    }
+
+    /**
+     * 获取服务列表
+     *
+     * @param array $filters
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public static function getServices(array $filters = [])
+    {
+        $query = ServiceModel::query();
+        
+        if (isset($filters['type'])) {
+            $query->where('type', $filters['type']);
+        }
+        
+        if (isset($filters['status'])) {
+            $query->where('status', $filters['status']);
+        }
+        
+        if (isset($filters['provider'])) {
+            $query->where('provider', $filters['provider']);
+        }
+        
+        return $query->orderBy('priority')->orderBy('name')->get();
+    }
+
+    /**
+     * 根据代码获取服务
+     *
+     * @param string $code
+     * @return ServiceModel|null
+     */
+    public static function getServiceByCode(string $code): ?ServiceModel
+    {
+        $cacheKey = "thirdparty:service:{$code}";
+        
+        return Cache::remember($cacheKey, config('thirdparty.cache.ttl', 3600), function () use ($code) {
+            return ServiceModel::where('code', $code)->first();
+        });
+    }
+
+    /**
+     * 更新服务状态
+     *
+     * @param string $serviceCode
+     * @param string $status
+     * @return bool
+     */
+    public static function updateServiceStatus(string $serviceCode, string $status): bool
+    {
+        $service = static::getServiceByCode($serviceCode);
+        
+        if (!$service) {
+            return false;
+        }
+        
+        $currentStatus = $service->getServiceStatusEnum();
+        $newStatus = SERVICE_STATUS::from($status);
+        
+        // 检查状态转换是否允许
+        if (!$currentStatus->canTransitionTo($newStatus)) {
+            throw new \Exception("不能从状态 {$currentStatus->getLabel()} 转换到 {$newStatus->getLabel()}");
+        }
+        
+        $result = $service->update(['status' => $status]);
+        
+        // 清除缓存
+        Cache::forget("thirdparty:service:{$serviceCode}");
+        
+        return $result;
+    }
+
+    /**
+     * 检查服务配额
+     *
+     * @param ServiceModel $service
+     * @param int $amount
+     * @return bool
+     */
+    protected static function checkQuota(ServiceModel $service, int $amount = 1): bool
+    {
+        if (!config('thirdparty.quota.enabled', true)) {
+            return true;
+        }
+        
+        $quotas = $service->quotas()->active()->get();
+        
+        foreach ($quotas as $quota) {
+            if (!$quota->canUse($amount)) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+
+    /**
+     * 更新服务配额
+     *
+     * @param ServiceModel $service
+     * @param int $amount
+     * @return void
+     */
+    protected static function updateQuota(ServiceModel $service, int $amount = 1): void
+    {
+        if (!config('thirdparty.quota.enabled', true)) {
+            return;
+        }
+        
+        $quotas = $service->quotas()->active()->get();
+        
+        foreach ($quotas as $quota) {
+            $quota->incrementUsage($amount);
+        }
+    }
+
+    /**
+     * 发送HTTP请求
+     *
+     * @param ServiceModel $service
+     * @param string $url
+     * @param string $method
+     * @param array $data
+     * @param array $headers
+     * @param array $options
+     * @return Response
+     */
+    protected static function sendRequest(
+        ServiceModel $service,
+        string $url,
+        string $method,
+        array $data,
+        array $headers,
+        array $options
+    ): Response {
+        $httpOptions = [
+            'timeout' => $options['timeout'] ?? $service->timeout,
+            'headers' => $headers,
+        ];
+        
+        // 配置重试
+        $retryTimes = $options['retry_times'] ?? $service->retry_times;
+        $retryDelay = $options['retry_delay'] ?? $service->retry_delay;
+        
+        $http = Http::withOptions($httpOptions);
+        
+        if ($retryTimes > 0) {
+            $http = $http->retry($retryTimes, $retryDelay, function ($exception, $request) {
+                // 只在特定错误时重试
+                if ($exception instanceof \Illuminate\Http\Client\ConnectionException) {
+                    return true;
+                }
+                
+                if ($exception instanceof \Illuminate\Http\Client\RequestException) {
+                    $status = $exception->response->status();
+                    return in_array($status, config('thirdparty.retry.retry_on_status', [429, 500, 502, 503, 504]));
+                }
+                
+                return false;
+            });
+        }
+        
+        // 发送请求
+        return match (strtoupper($method)) {
+            'GET' => $http->get($url, $data),
+            'POST' => $http->post($url, $data),
+            'PUT' => $http->put($url, $data),
+            'PATCH' => $http->patch($url, $data),
+            'DELETE' => $http->delete($url, $data),
+            default => throw new \Exception("不支持的HTTP方法: {$method}"),
+        };
+    }
+
+    /**
+     * 记录API调用日志
+     *
+     * @param ServiceModel $service
+     * @param ThirdPartyCredential $credential
+     * @param string $requestId
+     * @param string $method
+     * @param string $url
+     * @param array $headers
+     * @param array $params
+     * @param Response $response
+     * @param int $responseTime
+     * @return void
+     */
+    protected static function logApiCall(
+        ServiceModel $service,
+        ThirdPartyCredential $credential,
+        string $requestId,
+        string $method,
+        string $url,
+        array $headers,
+        array $params,
+        Response $response,
+        int $responseTime
+    ): void {
+        if (!config('thirdparty.logging.enabled', true)) {
+            return;
+        }
+        
+        // 过滤敏感信息
+        $filteredHeaders = static::filterSensitiveData($headers);
+        $filteredParams = static::filterSensitiveData($params);
+        
+        ThirdPartyLog::createLog([
+            'service_id' => $service->id,
+            'credential_id' => $credential->id,
+            'request_id' => $requestId,
+            'method' => $method,
+            'url' => $url,
+            'headers' => $filteredHeaders,
+            'params' => $filteredParams,
+            'body' => json_encode($filteredParams),
+            'response_status' => $response->status(),
+            'response_headers' => $response->headers(),
+            'response_body' => static::truncateResponseBody($response->body()),
+            'response_time' => $responseTime,
+            'level' => $response->successful() ? LOG_LEVEL::INFO->value : LOG_LEVEL::ERROR->value,
+            'user_id' => auth()->id(),
+            'ip_address' => request()->ip(),
+            'user_agent' => request()->userAgent(),
+        ]);
+    }
+
+    /**
+     * 记录API错误日志
+     *
+     * @param ServiceModel $service
+     * @param ThirdPartyCredential $credential
+     * @param string $requestId
+     * @param string $method
+     * @param string $url
+     * @param array $headers
+     * @param array $params
+     * @param \Exception $exception
+     * @param int $responseTime
+     * @return void
+     */
+    protected static function logApiError(
+        ServiceModel $service,
+        ThirdPartyCredential $credential,
+        string $requestId,
+        string $method,
+        string $url,
+        array $headers,
+        array $params,
+        \Exception $exception,
+        int $responseTime
+    ): void {
+        if (!config('thirdparty.logging.enabled', true)) {
+            return;
+        }
+        
+        $filteredHeaders = static::filterSensitiveData($headers);
+        $filteredParams = static::filterSensitiveData($params);
+        
+        ThirdPartyLog::createLog([
+            'service_id' => $service->id,
+            'credential_id' => $credential->id,
+            'request_id' => $requestId,
+            'method' => $method,
+            'url' => $url,
+            'headers' => $filteredHeaders,
+            'params' => $filteredParams,
+            'body' => json_encode($filteredParams),
+            'response_time' => $responseTime,
+            'error_message' => $exception->getMessage(),
+            'level' => LOG_LEVEL::ERROR->value,
+            'user_id' => auth()->id(),
+            'ip_address' => request()->ip(),
+            'user_agent' => request()->userAgent(),
+        ]);
+    }
+
+    /**
+     * 过滤敏感数据
+     *
+     * @param array $data
+     * @return array
+     */
+    protected static function filterSensitiveData(array $data): array
+    {
+        $sensitiveFields = config('thirdparty.logging.sensitive_fields', []);
+        
+        foreach ($sensitiveFields as $field) {
+            if (isset($data[$field])) {
+                $data[$field] = '***';
+            }
+        }
+        
+        return $data;
+    }
+
+    /**
+     * 截断响应体
+     *
+     * @param string $body
+     * @return string
+     */
+    protected static function truncateResponseBody(string $body): string
+    {
+        $maxSize = config('thirdparty.logging.max_body_size', 10240);
+        
+        if (strlen($body) > $maxSize) {
+            return substr($body, 0, $maxSize) . '... [truncated]';
+        }
+        
+        return $body;
+    }
+}