Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -2415,6 +2415,110 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/system/client-customization/settings": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "返回客户端名称、英文名称、平台名和图标路径;数据库对象尚未创建时返回默认设置。",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"system"
|
||||
],
|
||||
"summary": "获取客户端自定义设置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/store.ClientCustomizationSettings"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "更新客户端名称、英文名称、平台名和图标路径。",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"system"
|
||||
],
|
||||
"summary": "更新客户端自定义设置",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "客户端自定义设置",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/store.ClientCustomizationSettingsInput"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/store.ClientCustomizationSettings"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/system/file-storage/channels": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -5031,6 +5135,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/public/client-customization": {
|
||||
"get": {
|
||||
"description": "无需鉴权返回客户端名称、英文名称、平台名和图标路径;数据库对象尚未创建时返回默认设置。",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"system"
|
||||
],
|
||||
"summary": "获取公开客户端自定义设置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/store.ClientCustomizationSettings"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/reranks": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -10872,6 +11002,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"store.ClientCustomizationSettings": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"clientEnglishName": {
|
||||
"type": "string"
|
||||
},
|
||||
"clientName": {
|
||||
"type": "string"
|
||||
},
|
||||
"iconPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"platformName": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"store.ClientCustomizationSettingsInput": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"clientEnglishName": {
|
||||
"type": "string"
|
||||
},
|
||||
"clientName": {
|
||||
"type": "string"
|
||||
},
|
||||
"iconPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"platformName": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"store.CreateAPIKeyInput": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -1209,6 +1209,28 @@ definitions:
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
store.ClientCustomizationSettings:
|
||||
properties:
|
||||
clientEnglishName:
|
||||
type: string
|
||||
clientName:
|
||||
type: string
|
||||
iconPath:
|
||||
type: string
|
||||
platformName:
|
||||
type: string
|
||||
type: object
|
||||
store.ClientCustomizationSettingsInput:
|
||||
properties:
|
||||
clientEnglishName:
|
||||
type: string
|
||||
clientName:
|
||||
type: string
|
||||
iconPath:
|
||||
type: string
|
||||
platformName:
|
||||
type: string
|
||||
type: object
|
||||
store.CreateAPIKeyInput:
|
||||
properties:
|
||||
expiresAt:
|
||||
@@ -4061,6 +4083,72 @@ paths:
|
||||
summary: 更新 Runner 策略
|
||||
tags:
|
||||
- runtime
|
||||
/api/admin/system/client-customization/settings:
|
||||
get:
|
||||
description: 返回客户端名称、英文名称、平台名和图标路径;数据库对象尚未创建时返回默认设置。
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/store.ClientCustomizationSettings'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 获取客户端自定义设置
|
||||
tags:
|
||||
- system
|
||||
patch:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 更新客户端名称、英文名称、平台名和图标路径。
|
||||
parameters:
|
||||
- description: 客户端自定义设置
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/store.ClientCustomizationSettingsInput'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/store.ClientCustomizationSettings'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 更新客户端自定义设置
|
||||
tags:
|
||||
- system
|
||||
/api/admin/system/file-storage/channels:
|
||||
get:
|
||||
description: 返回所有未删除的文件存储通道,用于管理上传与生成资源回传策略。
|
||||
@@ -5741,6 +5829,23 @@ paths:
|
||||
summary: 列出目录供应商
|
||||
tags:
|
||||
- catalog
|
||||
/api/v1/public/client-customization:
|
||||
get:
|
||||
description: 无需鉴权返回客户端名称、英文名称、平台名和图标路径;数据库对象尚未创建时返回默认设置。
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/store.ClientCustomizationSettings'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/httpapi.ErrorEnvelope'
|
||||
summary: 获取公开客户端自定义设置
|
||||
tags:
|
||||
- system
|
||||
/api/v1/reranks:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
@@ -70,6 +70,7 @@ func NewServerWithContext(ctx context.Context, cfg config.Config, db *store.Stor
|
||||
mux.Handle("GET /api/v1/me", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.me)))
|
||||
mux.Handle("GET /api/v1/public/catalog/providers", server.auth.Require(auth.PermissionPublic, http.HandlerFunc(server.listCatalogProviders)))
|
||||
mux.Handle("GET /api/v1/public/catalog/base-models", server.auth.Require(auth.PermissionPublic, http.HandlerFunc(server.listBaseModels)))
|
||||
mux.Handle("GET /api/v1/public/client-customization", server.auth.Require(auth.PermissionPublic, http.HandlerFunc(server.getPublicClientCustomizationSettings)))
|
||||
mux.Handle("GET /api/admin/catalog/providers", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.listCatalogProviders)))
|
||||
mux.Handle("POST /api/admin/catalog/providers", server.requireAdmin(auth.PermissionManager, http.HandlerFunc(server.createCatalogProvider)))
|
||||
mux.Handle("PATCH /api/admin/catalog/providers/{providerID}", server.requireAdmin(auth.PermissionManager, http.HandlerFunc(server.updateCatalogProvider)))
|
||||
@@ -133,6 +134,8 @@ func NewServerWithContext(ctx context.Context, cfg config.Config, db *store.Stor
|
||||
mux.Handle("GET /api/admin/config/network-proxy", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.getNetworkProxyConfig)))
|
||||
mux.Handle("GET /api/admin/system/file-storage/settings", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.getFileStorageSettings)))
|
||||
mux.Handle("PATCH /api/admin/system/file-storage/settings", server.requireAdmin(auth.PermissionManager, http.HandlerFunc(server.updateFileStorageSettings)))
|
||||
mux.Handle("GET /api/admin/system/client-customization/settings", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.getClientCustomizationSettings)))
|
||||
mux.Handle("PATCH /api/admin/system/client-customization/settings", server.requireAdmin(auth.PermissionManager, http.HandlerFunc(server.updateClientCustomizationSettings)))
|
||||
mux.Handle("GET /api/admin/system/file-storage/channels", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.listFileStorageChannels)))
|
||||
mux.Handle("POST /api/admin/system/file-storage/channels", server.requireAdmin(auth.PermissionManager, http.HandlerFunc(server.createFileStorageChannel)))
|
||||
mux.Handle("PATCH /api/admin/system/file-storage/channels/{channelID}", server.requireAdmin(auth.PermissionManager, http.HandlerFunc(server.updateFileStorageChannel)))
|
||||
|
||||
@@ -83,6 +83,76 @@ func (s *Server) updateFileStorageSettings(w http.ResponseWriter, r *http.Reques
|
||||
writeJSON(w, http.StatusOK, settings)
|
||||
}
|
||||
|
||||
// getClientCustomizationSettings godoc
|
||||
// @Summary 获取客户端自定义设置
|
||||
// @Description 返回客户端名称、英文名称、平台名和图标路径;数据库对象尚未创建时返回默认设置。
|
||||
// @Tags system
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} store.ClientCustomizationSettings
|
||||
// @Failure 401 {object} ErrorEnvelope
|
||||
// @Failure 403 {object} ErrorEnvelope
|
||||
// @Failure 500 {object} ErrorEnvelope
|
||||
// @Router /api/admin/system/client-customization/settings [get]
|
||||
func (s *Server) getClientCustomizationSettings(w http.ResponseWriter, r *http.Request) {
|
||||
s.writeClientCustomizationSettings(w, r)
|
||||
}
|
||||
|
||||
// getPublicClientCustomizationSettings godoc
|
||||
// @Summary 获取公开客户端自定义设置
|
||||
// @Description 无需鉴权返回客户端名称、英文名称、平台名和图标路径;数据库对象尚未创建时返回默认设置。
|
||||
// @Tags system
|
||||
// @Produce json
|
||||
// @Success 200 {object} store.ClientCustomizationSettings
|
||||
// @Failure 500 {object} ErrorEnvelope
|
||||
// @Router /api/v1/public/client-customization [get]
|
||||
func (s *Server) getPublicClientCustomizationSettings(w http.ResponseWriter, r *http.Request) {
|
||||
s.writeClientCustomizationSettings(w, r)
|
||||
}
|
||||
|
||||
func (s *Server) writeClientCustomizationSettings(w http.ResponseWriter, r *http.Request) {
|
||||
settings, err := s.store.GetClientCustomizationSettings(r.Context())
|
||||
if err != nil {
|
||||
if store.IsUndefinedDatabaseObject(err) {
|
||||
writeJSON(w, http.StatusOK, store.DefaultClientCustomizationSettings())
|
||||
return
|
||||
}
|
||||
s.logger.Error("get client customization settings failed", "error", err)
|
||||
writeError(w, http.StatusInternalServerError, "get client customization settings failed")
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, settings)
|
||||
}
|
||||
|
||||
// updateClientCustomizationSettings godoc
|
||||
// @Summary 更新客户端自定义设置
|
||||
// @Description 更新客户端名称、英文名称、平台名和图标路径。
|
||||
// @Tags system
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param body body store.ClientCustomizationSettingsInput true "客户端自定义设置"
|
||||
// @Success 200 {object} store.ClientCustomizationSettings
|
||||
// @Failure 400 {object} ErrorEnvelope
|
||||
// @Failure 401 {object} ErrorEnvelope
|
||||
// @Failure 403 {object} ErrorEnvelope
|
||||
// @Failure 500 {object} ErrorEnvelope
|
||||
// @Router /api/admin/system/client-customization/settings [patch]
|
||||
func (s *Server) updateClientCustomizationSettings(w http.ResponseWriter, r *http.Request) {
|
||||
var input store.ClientCustomizationSettingsInput
|
||||
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid json body")
|
||||
return
|
||||
}
|
||||
settings, err := s.store.UpdateClientCustomizationSettings(r.Context(), input)
|
||||
if err != nil {
|
||||
s.logger.Error("update client customization settings failed", "error", err)
|
||||
writeError(w, http.StatusInternalServerError, "update client customization settings failed")
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, settings)
|
||||
}
|
||||
|
||||
// createFileStorageChannel godoc
|
||||
// @Summary 创建文件存储通道
|
||||
// @Description 创建文件存储通道,当前主要用于配置 server-main OpenAPI 上传通道。
|
||||
|
||||
@@ -24,6 +24,7 @@ const (
|
||||
)
|
||||
|
||||
const SystemSettingFileStorage = "file_storage"
|
||||
const SystemSettingClientCustomization = "client_customization"
|
||||
|
||||
const fileStorageChannelColumns = `
|
||||
id::text, channel_key, name, provider, COALESCE(upload_url, ''), credentials,
|
||||
@@ -72,6 +73,20 @@ type FileStorageSettingsInput struct {
|
||||
ResultUploadPolicy string `json:"resultUploadPolicy"`
|
||||
}
|
||||
|
||||
type ClientCustomizationSettings struct {
|
||||
ClientName string `json:"clientName"`
|
||||
ClientEnglishName string `json:"clientEnglishName"`
|
||||
PlatformName string `json:"platformName"`
|
||||
IconPath string `json:"iconPath"`
|
||||
}
|
||||
|
||||
type ClientCustomizationSettingsInput struct {
|
||||
ClientName *string `json:"clientName"`
|
||||
ClientEnglishName *string `json:"clientEnglishName"`
|
||||
PlatformName *string `json:"platformName"`
|
||||
IconPath *string `json:"iconPath"`
|
||||
}
|
||||
|
||||
type fileStorageChannelScanner interface {
|
||||
Scan(dest ...any) error
|
||||
}
|
||||
@@ -348,6 +363,15 @@ func DefaultFileStorageSettings() FileStorageSettings {
|
||||
return FileStorageSettings{ResultUploadPolicy: FileStorageResultUploadPolicyDefault}
|
||||
}
|
||||
|
||||
func DefaultClientCustomizationSettings() ClientCustomizationSettings {
|
||||
return ClientCustomizationSettings{
|
||||
ClientName: "EasyAI AI Gateway",
|
||||
ClientEnglishName: "EasyAI AI Gateway",
|
||||
PlatformName: "EasyAI",
|
||||
IconPath: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) GetFileStorageSettings(ctx context.Context) (FileStorageSettings, error) {
|
||||
var value []byte
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
@@ -380,13 +404,53 @@ func (s *Store) UpdateFileStorageSettings(ctx context.Context, input FileStorage
|
||||
return fileStorageSettingsFromValue(decodeObject(saved)), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetClientCustomizationSettings(ctx context.Context) (ClientCustomizationSettings, error) {
|
||||
var value []byte
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
SELECT value
|
||||
FROM system_settings
|
||||
WHERE setting_key = $1`, SystemSettingClientCustomization).Scan(&value)
|
||||
if err != nil {
|
||||
if IsNotFound(err) {
|
||||
return DefaultClientCustomizationSettings(), nil
|
||||
}
|
||||
return ClientCustomizationSettings{}, err
|
||||
}
|
||||
return clientCustomizationSettingsFromValue(decodeObject(value)), nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateClientCustomizationSettings(ctx context.Context, input ClientCustomizationSettingsInput) (ClientCustomizationSettings, error) {
|
||||
current, err := s.GetClientCustomizationSettings(ctx)
|
||||
if err != nil && !IsUndefinedDatabaseObject(err) {
|
||||
return ClientCustomizationSettings{}, err
|
||||
}
|
||||
settings := normalizeClientCustomizationSettings(input, current)
|
||||
value, _ := json.Marshal(settings)
|
||||
var saved []byte
|
||||
err = s.upsertSystemSetting(ctx, SystemSettingClientCustomization, value, &saved)
|
||||
if err != nil && IsUndefinedDatabaseObject(err) {
|
||||
if ensureErr := s.ensureSystemSettingsTable(ctx); ensureErr != nil {
|
||||
return ClientCustomizationSettings{}, ensureErr
|
||||
}
|
||||
err = s.upsertSystemSetting(ctx, SystemSettingClientCustomization, value, &saved)
|
||||
}
|
||||
if err != nil {
|
||||
return ClientCustomizationSettings{}, err
|
||||
}
|
||||
return clientCustomizationSettingsFromValue(decodeObject(saved)), nil
|
||||
}
|
||||
|
||||
func (s *Store) upsertFileStorageSettings(ctx context.Context, value []byte, saved *[]byte) error {
|
||||
return s.upsertSystemSetting(ctx, SystemSettingFileStorage, value, saved)
|
||||
}
|
||||
|
||||
func (s *Store) upsertSystemSetting(ctx context.Context, settingKey string, value []byte, saved *[]byte) error {
|
||||
return s.pool.QueryRow(ctx, `
|
||||
INSERT INTO system_settings (setting_key, value)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (setting_key)
|
||||
DO UPDATE SET value = EXCLUDED.value, updated_at = now()
|
||||
RETURNING value`, SystemSettingFileStorage, value).Scan(saved)
|
||||
RETURNING value`, settingKey, value).Scan(saved)
|
||||
}
|
||||
|
||||
func (s *Store) ensureSystemSettingsTable(ctx context.Context) error {
|
||||
@@ -409,6 +473,53 @@ func fileStorageSettingsFromValue(value map[string]any) FileStorageSettings {
|
||||
return settings
|
||||
}
|
||||
|
||||
func clientCustomizationSettingsFromValue(value map[string]any) ClientCustomizationSettings {
|
||||
settings := DefaultClientCustomizationSettings()
|
||||
if value == nil {
|
||||
return settings
|
||||
}
|
||||
if clientName := stringFromAny(value["clientName"]); clientName != "" {
|
||||
settings.ClientName = clientName
|
||||
}
|
||||
if clientEnglishName := stringFromAny(value["clientEnglishName"]); clientEnglishName != "" {
|
||||
settings.ClientEnglishName = clientEnglishName
|
||||
}
|
||||
if platformName := stringFromAny(value["platformName"]); platformName != "" {
|
||||
settings.PlatformName = platformName
|
||||
}
|
||||
settings.IconPath = stringFromAny(value["iconPath"])
|
||||
return settings
|
||||
}
|
||||
|
||||
func normalizeClientCustomizationSettings(input ClientCustomizationSettingsInput, current ClientCustomizationSettings) ClientCustomizationSettings {
|
||||
settings := current
|
||||
if settings.ClientName == "" && settings.ClientEnglishName == "" && settings.PlatformName == "" {
|
||||
settings = DefaultClientCustomizationSettings()
|
||||
}
|
||||
if input.ClientName != nil {
|
||||
settings.ClientName = strings.TrimSpace(*input.ClientName)
|
||||
}
|
||||
if input.ClientEnglishName != nil {
|
||||
settings.ClientEnglishName = strings.TrimSpace(*input.ClientEnglishName)
|
||||
}
|
||||
if input.PlatformName != nil {
|
||||
settings.PlatformName = strings.TrimSpace(*input.PlatformName)
|
||||
}
|
||||
if input.IconPath != nil {
|
||||
settings.IconPath = strings.TrimSpace(*input.IconPath)
|
||||
}
|
||||
if settings.ClientName == "" {
|
||||
settings.ClientName = DefaultClientCustomizationSettings().ClientName
|
||||
}
|
||||
if settings.ClientEnglishName == "" {
|
||||
settings.ClientEnglishName = DefaultClientCustomizationSettings().ClientEnglishName
|
||||
}
|
||||
if settings.PlatformName == "" {
|
||||
settings.PlatformName = DefaultClientCustomizationSettings().PlatformName
|
||||
}
|
||||
return settings
|
||||
}
|
||||
|
||||
func NormalizeFileStorageResultUploadPolicy(policy string) string {
|
||||
normalized := strings.ToLower(strings.TrimSpace(policy))
|
||||
normalized = strings.ReplaceAll(normalized, "-", "_")
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
INSERT INTO system_settings (setting_key, value)
|
||||
VALUES (
|
||||
'client_customization',
|
||||
'{"clientName":"EasyAI AI Gateway","clientEnglishName":"EasyAI AI Gateway","platformName":"EasyAI","iconPath":""}'::jsonb
|
||||
)
|
||||
ON CONFLICT (setting_key) DO NOTHING;
|
||||
Reference in New Issue
Block a user