mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-01 14:52:48 +08:00
- 新增手机图片排版功能,支持小红书/抖音尺寸输出 - 新增AI智能排版顾问,支持内容分析与优化推荐 - 新增AI供应商管理,支持多渠道配置与同步 - 新增文章输出管理页面,支持图片预览与批量下载 - 新增字体文件与排版样式配置
187 lines
5.2 KiB
PHP
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;
|
|
}
|
|
}
|