diff --git a/apps/portal/migrations/0001_initial.py b/apps/portal/migrations/0001_initial.py index c7692574893..4269916ad39 100644 --- a/apps/portal/migrations/0001_initial.py +++ b/apps/portal/migrations/0001_initial.py @@ -44,10 +44,6 @@ class Migration(migrations.Migration): ("name", models.CharField(default="智能体门户", max_length=64, verbose_name="门户名称")), ("description", models.TextField(blank=True, max_length=256, null=True, verbose_name="门户描述")), ("logo", models.CharField(blank=True, max_length=512, null=True, verbose_name="门户Logo地址")), - ( - "tab_logo", - models.CharField(blank=True, max_length=512, null=True, verbose_name="浏览器Tab Logo地址"), - ), ("enable_public_access", models.BooleanField(default=True, verbose_name="是否开启公开访问")), ("enable_api", models.BooleanField(default=True, verbose_name="是否开启API服务")), ("enable_knowledge_base_api", models.BooleanField(default=True, verbose_name="是否开启知识库API")), diff --git a/apps/portal/models/portal.py b/apps/portal/models/portal.py index 659ebcfb4e7..e7d42ecd538 100644 --- a/apps/portal/models/portal.py +++ b/apps/portal/models/portal.py @@ -19,8 +19,6 @@ class Portal(AppModelMixin): logo = models.CharField(max_length=512, null=True, blank=True, verbose_name="门户Logo地址") - tab_logo = models.CharField(max_length=512, null=True, blank=True, verbose_name="浏览器Tab Logo地址") - enable_public_access = models.BooleanField(default=True, verbose_name="是否开启公开访问") # API服务配置 enable_api = models.BooleanField(default=True, verbose_name="是否开启API服务") diff --git a/apps/portal/serializers/portal.py b/apps/portal/serializers/portal.py index 9d1dac165c9..d5797024b35 100644 --- a/apps/portal/serializers/portal.py +++ b/apps/portal/serializers/portal.py @@ -45,9 +45,6 @@ class PortalSerializer(serializers.Serializer): logo = serializers.CharField( required=False, allow_null=True, allow_blank=True, label=_("portal logo"), help_text=_("portal logo") ) - tab_logo = serializers.CharField( - required=False, allow_null=True, allow_blank=True, label=_("tab logo"), help_text=_("tab logo") - ) enable_public_access = serializers.BooleanField( required=False, label=_("enable public access"), help_text=_("enable public access") ) @@ -65,9 +62,7 @@ class Meta: model = Portal fields = "__all__" - def one(self, with_valid=True): - if with_valid: - self.is_valid(raise_exception=True) + def one(self): portal = Portal.objects.first() if portal is None: raise AppApiException(500, _("Portal configuration does not exist")) @@ -101,11 +96,11 @@ def edit(self, instance, with_valid=True): portal = Portal.objects.first() if portal is None: raise AppApiException(500, _("Portal configuration does not exist")) - file_fields = ["logo", "tab_logo", "id", "create_time", "update_time"] + file_fields = ["logo", "id", "create_time", "update_time"] for field, value in instance.items(): if hasattr(portal, field) and field not in file_fields: setattr(portal, field, value) - for field_name in ["logo", "tab_logo"]: + for field_name in ["logo"]: if field_name in instance: self._handle_file_field(portal, field_name, instance.get(field_name)) portal.save() diff --git a/apps/portal/views/portal.py b/apps/portal/views/portal.py index 0e7b71a0db1..a1fe30365a7 100644 --- a/apps/portal/views/portal.py +++ b/apps/portal/views/portal.py @@ -56,7 +56,7 @@ def get(self, request: Request): @log(menu="Portal", operate="Save portal configuration") @has_permissions(PermissionConstants.PORTAL_EDIT, RoleConstants.ADMIN) def put(self, request: Request): - return result.success(PortalSerializer().edit(request.data)) + return result.success(PortalSerializer(data=request.data).edit(request.data)) class PortalLoginView(APIView): diff --git a/ui/src/api/API_README.md b/ui/src/api/API_README.md index 625f882a544..e5069812ed6 100644 --- a/ui/src/api/API_README.md +++ b/ui/src/api/API_README.md @@ -60,9 +60,12 @@ src/api/ ## 业务接口组织 -`admin/system/portal.ts` 通过 Admin `/portal` 读取和局部保存门户配置,公共类型维护在 -`types/portal.ts`。JSON 用于访问开关和认证配置,门户名称与 Logo 使用 FormData;保存返回完整配置。 -认证配置保留未编辑字段,跨域 `cors_config` 暂按不透明对象保留,待后端定义其字段与执行协议。 +`admin/system/chat-management/portal-setting.ts` 通过 Admin `/portal` 读取和局部保存门户配置, +公共类型维护在 `types/portal.ts`。JSON 用于访问开关和认证、跨域配置,门户名称与 Logo 使用 +FormData;保存返回完整配置,页面以该返回值作为唯一数据来源。 +认证配置保留未编辑字段,仅提交后端读取的 `login_value`、`max_attempts`、`failed_attempts`、 +`lock_time`;跨域配置写入 `cross_domain_list`(对齐后端 `ApplicationApiKey.cross_domain_list`), +并保留 `cors_config` 中的其他字段。 - 业务 API 先按 Admin 入口下的 `auth`、`workspace`、`system` 等一级业务域归类。Workspace 和 System 内部可继续按明确的功能域建立子目录,例如 `workspace/application/`、 diff --git a/ui/src/api/types/portal.ts b/ui/src/api/types/portal.ts index 112e0d7ab02..9f5ca0e48ff 100644 --- a/ui/src/api/types/portal.ts +++ b/ui/src/api/types/portal.ts @@ -2,25 +2,28 @@ import type { Dict } from './common' export interface PortalAuthConfig extends Dict { login_value?: string[] - default_value?: string max_attempts?: number failed_attempts?: number lock_time?: number } +export interface PortalCorsConfig extends Dict { + /** 允许跨域访问的地址列表,对齐后端 cross_domain_list 字段。 */ + cross_domain_list?: string[] +} + export interface PortalSetting { id: string name: string description: string | null logo: string | null - tab_logo: string | null enable_public_access: boolean enable_api: boolean enable_knowledge_base_api: boolean enable_auth: boolean auth_config: PortalAuthConfig enable_cors: boolean - cors_config: Dict + cors_config: PortalCorsConfig } export type PortalSettingPayload = Partial> diff --git a/ui/src/views/system/chat-management/portal-setting/PortalSettingView.vue b/ui/src/views/system/chat-management/portal-setting/PortalSettingView.vue index 42e04750dfe..e8df9685e59 100644 --- a/ui/src/views/system/chat-management/portal-setting/PortalSettingView.vue +++ b/ui/src/views/system/chat-management/portal-setting/PortalSettingView.vue @@ -1,15 +1,15 @@