feat: 接口管理代理密钥

This commit is contained in:
tbphp
2025-07-24 16:34:51 +08:00
parent cdfc0b07aa
commit 746c9f3108
5 changed files with 40 additions and 3 deletions

View File

@@ -211,6 +211,7 @@ func (s *Server) CreateGroup(c *gin.Context) {
ValidationEndpoint: validationEndpoint,
ParamOverrides: req.ParamOverrides,
Config: cleanedConfig,
ProxyKeys: strings.TrimSpace(req.ProxyKeys),
}
if err := s.DB.Create(&group).Error; err != nil {
@@ -253,6 +254,7 @@ type GroupUpdateRequest struct {
ValidationEndpoint *string `json:"validation_endpoint,omitempty"`
ParamOverrides map[string]any `json:"param_overrides"`
Config map[string]any `json:"config"`
ProxyKeys *string `json:"proxy_keys,omitempty"`
}
// UpdateGroup handles updating an existing group.
@@ -351,6 +353,10 @@ func (s *Server) UpdateGroup(c *gin.Context) {
group.Config = cleanedConfig
}
if req.ProxyKeys != nil {
group.ProxyKeys = strings.TrimSpace(*req.ProxyKeys)
}
// Save the updated group object
if err := tx.Save(&group).Error; err != nil {
response.Error(c, app_errors.ParseDBError(err))
@@ -382,6 +388,7 @@ type GroupResponse struct {
ValidationEndpoint string `json:"validation_endpoint"`
ParamOverrides datatypes.JSONMap `json:"param_overrides"`
Config datatypes.JSONMap `json:"config"`
ProxyKeys string `json:"proxy_keys"`
LastValidatedAt *time.Time `json:"last_validated_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
@@ -412,6 +419,7 @@ func (s *Server) newGroupResponse(group *models.Group) *GroupResponse {
ValidationEndpoint: group.ValidationEndpoint,
ParamOverrides: group.ParamOverrides,
Config: group.Config,
ProxyKeys: group.ProxyKeys,
LastValidatedAt: group.LastValidatedAt,
CreatedAt: group.CreatedAt,
UpdatedAt: group.UpdatedAt,

View File

@@ -21,7 +21,7 @@ type SystemSettings struct {
AppUrl string `json:"app_url" default:"http://localhost:3001" name:"项目地址" category:"基础参数" desc:"项目的基础 URL用于拼接分组终端节点地址。系统配置优先于环境变量 APP_URL。"`
RequestLogRetentionDays int `json:"request_log_retention_days" default:"7" name:"日志保留时长(天)" category:"基础参数" desc:"请求日志在数据库中的保留天数0为不清理日志。" validate:"min=0"`
RequestLogWriteIntervalMinutes int `json:"request_log_write_interval_minutes" default:"1" name:"日志延迟写入周期(分钟)" category:"基础参数" desc:"请求日志从缓存写入数据库的周期分钟0为实时写入数据。" validate:"min=0"`
ProxyKeys string `json:"proxy_keys" name:"全局代理密钥" category:"基础参数" desc:"全局代理密钥,用于访问所有代理端点。多个密钥请用逗号分隔。"`
ProxyKeys string `json:"proxy_keys" name:"全局代理密钥" category:"基础参数" desc:"全局代理密钥,用于访问所有分组的代理端点。多个密钥请用逗号分隔。"`
// 请求设置
RequestTimeout int `json:"request_timeout" default:"600" name:"请求超时(秒)" category:"请求设置" desc:"转发请求的完整生命周期超时(秒)等。" validate:"min=1"`

View File

@@ -59,6 +59,7 @@ interface GroupFormData {
param_overrides: string;
config: Record<string, number>;
configItems: ConfigItem[];
proxy_keys: string;
}
// 表单数据
@@ -79,6 +80,7 @@ const formData = reactive<GroupFormData>({
param_overrides: "",
config: {},
configItems: [] as ConfigItem[],
proxy_keys: "",
});
const channelTypeOptions = ref<{ label: string; value: string }[]>([]);
@@ -269,6 +271,7 @@ function resetForm() {
param_overrides: "",
config: {},
configItems: [],
proxy_keys: "",
});
// 重置用户修改状态追踪
@@ -304,6 +307,7 @@ function loadGroupData() {
param_overrides: JSON.stringify(props.group.param_overrides || {}, null, 2),
config: {},
configItems,
proxy_keys: props.group.proxy_keys || "",
});
}
@@ -408,6 +412,7 @@ async function handleSubmit() {
validation_endpoint: formData.validation_endpoint,
param_overrides: paramOverrides,
config,
proxy_keys: formData.proxy_keys,
};
let res: Group;
@@ -592,6 +597,25 @@ async function handleSubmit() {
<div v-else class="form-item-half" />
</div>
<!-- 代理密钥 -->
<n-form-item label="代理密钥" path="proxy_keys">
<template #label>
<div class="form-label-with-tooltip">
代理密钥
<n-tooltip trigger="hover" placement="top">
<template #trigger>
<n-icon :component="HelpCircleOutline" class="help-icon" />
</template>
分组专用代理密钥用于访问此分组的代理端点多个密钥请用逗号分隔
</n-tooltip>
</div>
</template>
<n-input
v-model:value="formData.proxy_keys"
placeholder="多个密钥请用英文逗号 , 分隔"
/>
</n-form-item>
<!-- 描述独占一行 -->
<n-form-item label="描述" path="description">
<template #label>

View File

@@ -43,6 +43,7 @@ export interface Group {
api_keys?: APIKey[];
endpoint?: string;
param_overrides: Record<string, unknown>;
proxy_keys: string;
created_at?: string;
updated_at?: string;
}

View File

@@ -72,8 +72,12 @@ async function handleSubmit() {
hoverable
bordered
>
<n-grid :x-gap="24" :y-gap="24" responsive="screen" cols="1 s:2 m:2 l:3 xl:4">
<n-grid-item v-for="item in category.settings" :key="item.key">
<n-grid :x-gap="24" :y-gap="0" responsive="screen" cols="1 s:2 m:2 l:3 xl:4">
<n-grid-item
v-for="item in category.settings"
:key="item.key"
:span="item.key === 'proxy_keys' ? 4 : 1"
>
<n-form-item
:path="item.key"
:rule="{ required: true, message: `请输入 ${item.name}` }"