mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-08 12:32:47 +08:00
feat(post): 新增手机图片排版与AI智能排版功能
- 新增手机图片排版功能,支持小红书/抖音尺寸输出 - 新增AI智能排版顾问,支持内容分析与优化推荐 - 新增AI供应商管理,支持多渠道配置与同步 - 新增文章输出管理页面,支持图片预览与批量下载 - 新增字体文件与排版样式配置
This commit is contained in:
186
app/common/tools/ai/AiChannelManager.php
Normal file
186
app/common/tools/ai/AiChannelManager.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user