diff --git a/api/insurance/admin/ppt_admin_service.py b/api/insurance/admin/ppt_admin_service.py
index c738f8b..28f3b48 100644
--- a/api/insurance/admin/ppt_admin_service.py
+++ b/api/insurance/admin/ppt_admin_service.py
@@ -507,8 +507,10 @@ class PptAdminService:
"gemini": "Google",
"qwen": "通义千问",
"glm": "智谱",
+ "cogview": "智谱",
"MiniMax": "MiniMax",
"moonshot": "月之暗面",
+ "doubao": "豆包",
}
def _infer_brand(self, model_name: str) -> str:
diff --git a/api/insurance/poster/image_generator.py b/api/insurance/poster/image_generator.py
index f855a16..02ea120 100644
--- a/api/insurance/poster/image_generator.py
+++ b/api/insurance/poster/image_generator.py
@@ -1,4 +1,4 @@
-"""海报图片生成器 — 调用 GPT image API + Pillow 降级方案。"""
+"""海报图片生成器 — 支持多供应商生图模型(OpenAI / 豆包 / 智谱等)。"""
import os
import base64
import logging
@@ -14,17 +14,43 @@ SIZE_MAP = {
}
+def _load_image_config() -> dict:
+ """从数据库读取海报图片模型配置。"""
+ try:
+ from insurance.db.compat import db
+ from insurance.models.system_setting import SystemSetting
+ keys = ["poster_image_provider", "poster_image_model",
+ "poster_image_api_key", "poster_image_base_url"]
+ settings = {s.key: s.value for s in SystemSetting.query.filter(SystemSetting.key.in_(keys)).all()}
+ return settings
+ except Exception:
+ return {}
+
+
class PosterImageGenerator:
- """海报图片生成器,调用 GPT image 模型。"""
+ """海报图片生成器,支持 OpenAI 兼容接口的多供应商生图模型。"""
def __init__(self):
- self.client = None
+ self._client = None
+ self._config = None
+
+ def _get_config(self) -> dict:
+ if self._config is None:
+ self._config = _load_image_config()
+ return self._config
def _get_client(self):
- if self.client is None:
+ if self._client is None:
import openai
- self.client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
- return self.client
+ cfg = self._get_config()
+ api_key = cfg.get("poster_image_api_key") or os.getenv("OPENAI_API_KEY", "")
+ base_url = cfg.get("poster_image_base_url") or os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")
+ self._client = openai.OpenAI(api_key=api_key, base_url=base_url)
+ return self._client
+
+ def _get_model(self) -> str:
+ cfg = self._get_config()
+ return cfg.get("poster_image_model") or "gpt-image-1"
def build_prompt(self, template: dict = None, product: dict = None,
company: dict = None, copy: dict = None, size: str = "1024x1792") -> str:
@@ -81,16 +107,17 @@ class PosterImageGenerator:
return "\n".join(parts)
def generate(self, prompt: str, size: str = "1024x1792", reference_image: str = None) -> bytes:
- """调用 GPT image 模型生成海报图片。
+ """调用配置的生图模型生成海报图片。
返回:
PNG 图片的 bytes
"""
api_size = SIZE_MAP.get(size, "1024x1792")
client = self._get_client()
+ model = self._get_model()
kwargs = {
- "model": "gpt-image-1",
+ "model": model,
"prompt": prompt,
"n": 1,
"size": api_size,
@@ -106,7 +133,7 @@ class PosterImageGenerator:
try:
with open(reference_image, "rb") as img_file:
response = client.images.edit(
- model="gpt-image-1",
+ model=model,
image=img_file,
prompt=prompt,
n=1,
diff --git a/frontend/src/pages/admin/PptSettingsAdmin.vue b/frontend/src/pages/admin/PptSettingsAdmin.vue
index 7c27299..a5bf278 100644
--- a/frontend/src/pages/admin/PptSettingsAdmin.vue
+++ b/frontend/src/pages/admin/PptSettingsAdmin.vue
@@ -86,12 +86,25 @@
海报图片模型
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
@@ -129,8 +142,10 @@ const form = reactive({
poster_llm_model: '',
poster_llm_api_key: '',
poster_llm_base_url: '',
+ poster_image_provider: 'openai',
poster_image_model: 'gpt-image-1',
poster_image_api_key: '',
+ poster_image_base_url: 'https://api.openai.com/v1',
dify_workspace_api_key: '',
})
@@ -141,6 +156,20 @@ const DEFAULT_MODELS: Record = {
openai: 'gpt-4o',
}
+const IMAGE_PROVIDER_PRESETS: Record = {
+ openai: { model: 'gpt-image-1', baseUrl: 'https://api.openai.com/v1' },
+ doubao: { model: 'doubao-seedream-3-0-t2i-250415', baseUrl: 'https://ark.cn-beijing.volces.com/api/v3' },
+ zhipu: { model: 'cogview-4-250304', baseUrl: 'https://open.bigmodel.cn/api/paas/v4' },
+}
+
+function onImageProviderChange(val: string) {
+ const preset = IMAGE_PROVIDER_PRESETS[val]
+ if (preset) {
+ form.poster_image_model = preset.model
+ form.poster_image_base_url = preset.baseUrl
+ }
+}
+
function onPptProviderChange(val: string) {
if (val !== 'custom' && !form.ppt_llm_model) {
form.ppt_llm_model = DEFAULT_MODELS[val] || ''