Files
ulthon_information/app/common/tools/ai/AiChannelManager.php
augushong 83a2bd48a2 feat(post): 新增手机图片排版与AI智能排版功能
- 新增手机图片排版功能,支持小红书/抖音尺寸输出
- 新增AI智能排版顾问,支持内容分析与优化推荐
- 新增AI供应商管理,支持多渠道配置与同步
- 新增文章输出管理页面,支持图片预览与批量下载
- 新增字体文件与排版样式配置
2026-05-01 12:23:17 +08:00

187 lines
5.2 KiB
PHP

<?php
namespace app\common\tools\ai;
use app\common\tools\ai\provider\OpenAiCompatibleAdapter;
/**
* AI 渠道管理器.
*
* 管理多个AI供应商的配置、连接和调用.
*/
class AiChannelManager
{
/**
* @var array 已注册的供应商适配器实例
*/
protected $providers = [];
/**
* 获取默认供应商的适配器实例.
*
* @return AiProviderInterface|null
*/
public function getDefaultProvider(): ?AiProviderInterface
{
$defaultId = get_system_config('ai_default_provider', '');
if (empty($defaultId)) {
return null;
}
return $this->getProvider($defaultId);
}
/**
* 获取指定供应商的适配器实例.
*
* @param string $providerId 供应商标识
*
* @return AiProviderInterface|null
*/
public function getProvider(string $providerId): ?AiProviderInterface
{
if (isset($this->providers[$providerId])) {
return $this->providers[$providerId];
}
$apiKey = get_system_config("ai_provider_{$providerId}_key", '');
if (empty($apiKey)) {
return null;
}
$provider = new OpenAiCompatibleAdapter($providerId);
$this->providers[$providerId] = $provider;
return $provider;
}
/**
* 获取所有已配置(有API Key)的供应商列表.
*
* @return array
*/
public function getAvailableProviders(): array
{
$sync = new ModelsDevSync();
$allProviders = $sync->getProviders();
$available = [];
foreach ($allProviders as $id => $provider) {
$apiKey = get_system_config("ai_provider_{$id}_key", '');
if (!empty($apiKey)) {
$provider['configured'] = true;
$provider['base_url'] = get_system_config("ai_provider_{$id}_base_url", $provider['api_base_url'] ?? '');
$available[$id] = $provider;
}
}
// 检查不在models.dev中但已手动配置的供应商
$allConfig = get_system_config();
if (is_array($allConfig)) {
foreach ($allConfig as $key => $value) {
if (preg_match('/^ai_provider_([a-z0-9_]+)_key$/', $key, $matches)) {
$customId = $matches[1];
if (!empty($value) && !isset($available[$customId])) {
$available[$customId] = [
'id' => $customId,
'name' => ucfirst(str_replace('_', ' ', $customId)),
'configured' => true,
'base_url' => get_system_config("ai_provider_{$customId}_base_url", ''),
];
}
}
}
}
return $available;
}
/**
* 保存供应商配置.
*
* @param array $data 配置数据,格式:
* [
* 'provider_id' => 'zhipu',
* 'key' => 'api_key_value',
* 'base_url' => 'https://open.bigmodel.cn/api/paas/v4',
* ]
*
* @return bool
*/
public function saveChannelConfig(array $data): bool
{
$providerId = $data['provider_id'] ?? '';
if (empty($providerId)) {
return false;
}
$configs = [
"ai_provider_{$providerId}_key" => $data['key'] ?? '',
"ai_provider_{$providerId}_base_url" => $data['base_url'] ?? '',
];
if (isset($data['is_default']) && $data['is_default']) {
$configs['ai_default_provider'] = $providerId;
}
if (isset($data['default_model'])) {
$configs['ai_default_model'] = $data['default_model'];
}
return $this->saveConfigs($configs);
}
/**
* 删除供应商配置.
*
* @param string $providerId 供应商标识
*
* @return bool
*/
public function deleteChannelConfig(string $providerId): bool
{
$configs = [
"ai_provider_{$providerId}_key" => '',
"ai_provider_{$providerId}_base_url" => '',
];
// 如果删除的是默认供应商,清除默认设置
$defaultProvider = get_system_config('ai_default_provider', '');
if ($defaultProvider === $providerId) {
$configs['ai_default_provider'] = '';
}
return $this->saveConfigs($configs);
}
/**
* 批量保存配置到SystemConfig.
*
* @param array $configs 键值对配置
*
* @return bool
*/
protected function saveConfigs(array $configs): bool
{
$list = \app\model\SystemConfig::column('value', 'name');
foreach ($configs as $key => $value) {
if (isset($list[$key])) {
\app\model\SystemConfig::where('name', $key)->update(['value' => $value]);
} else {
$model = new \app\model\SystemConfig();
$model->name = $key;
$model->value = $value;
$model->save();
}
$list[$key] = $value;
}
\think\facade\Cache::set('system_config', $list);
return true;
}
}