Compare commits

..

2 Commits

Author SHA1 Message Date
ArvinLovegood
6ca0d0df32 feat(settings):添加模型api服务专属HTTP代理配置功能
- 在AIConfig模型中新增httpProxy和httpProxyEnabled字段
- 更新OpenAi结构体以支持代理配置
- 修改OpenAI API调用逻辑使用实例级别的代理设置
- 在前端设置页面添加代理开关和地址输入框
- 扩展数据库AIConfig表结构以存储代理配置
- 增加代理配置的增删改查功能支持
- 调整默认maxTokens值从1024到4096
2026-01-19 09:55:33 +08:00
ArvinLovegood
fea9b06a27 feat(settings):添加模型api服务专属HTTP代理配置功能
- 在AIConfig模型中新增httpProxy和httpProxyEnabled字段
- 更新OpenAi结构体以支持代理配置
- 修改OpenAI API调用逻辑使用实例级别的代理设置
- 在前端设置页面添加代理开关和地址输入框
- 扩展数据库AIConfig表结构以存储代理配置
- 增加代理配置的增删改查功能支持
- 调整默认maxTokens值从1024到4096
2026-01-19 09:47:42 +08:00
5 changed files with 50 additions and 28 deletions

View File

@@ -43,6 +43,8 @@ type OpenAi struct {
CrawlTimeOut int64 `json:"crawl_time_out"`
KDays int64 `json:"kDays"`
BrowserPath string `json:"browser_path"`
HttpProxy string `json:"httpProxy"`
HttpProxyEnabled bool `json:"httpProxyEnabled"`
}
func (o OpenAi) String() string {
@@ -78,6 +80,8 @@ func NewDeepSeekOpenAi(ctx context.Context, aiConfigId int) *OpenAi {
MaxTokens: aiConfig.MaxTokens,
Temperature: aiConfig.Temperature,
TimeOut: aiConfig.TimeOut,
HttpProxy: aiConfig.HttpProxy,
HttpProxyEnabled: aiConfig.HttpProxyEnabled,
Prompt: settingConfig.Prompt,
QuestionTemplate: settingConfig.QuestionTemplate,
CrawlTimeOut: settingConfig.CrawlTimeOut,
@@ -977,9 +981,8 @@ func AskAi(o *OpenAi, err error, messages []map[string]interface{}, ch chan map[
thinking = "enabled"
}
client.SetTimeout(time.Duration(o.TimeOut) * time.Second)
config := GetSettingConfig()
if config.HttpProxyEnabled && config.HttpProxy != "" {
client.SetProxy(config.HttpProxy)
if o.HttpProxyEnabled && o.HttpProxy != "" {
client.SetProxy(o.HttpProxy)
}
bodyMap := map[string]interface{}{
"model": o.Model,
@@ -1138,9 +1141,8 @@ func AskAiWithTools(o *OpenAi, err error, messages []map[string]interface{}, ch
thinking = "enabled"
}
client.SetTimeout(time.Duration(o.TimeOut) * time.Second)
config := GetSettingConfig()
if config.HttpProxyEnabled && config.HttpProxy != "" {
client.SetProxy(config.HttpProxy)
if o.HttpProxyEnabled && o.HttpProxy != "" {
client.SetProxy(o.HttpProxy)
}
bodyMap := map[string]interface{}{
"model": o.Model,

View File

@@ -45,16 +45,18 @@ func (receiver Settings) TableName() string {
}
type AIConfig struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
Name string `json:"name"`
BaseUrl string `json:"baseUrl"`
ApiKey string `json:"apiKey" `
ModelName string `json:"modelName"`
MaxTokens int `json:"maxTokens"`
Temperature float64 `json:"temperature"`
TimeOut int `json:"timeOut"`
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
Name string `json:"name"`
BaseUrl string `json:"baseUrl"`
ApiKey string `json:"apiKey" `
ModelName string `json:"modelName"`
MaxTokens int `json:"maxTokens"`
Temperature float64 `json:"temperature"`
TimeOut int `json:"timeOut"`
HttpProxy string `json:"httpProxy"`
HttpProxyEnabled bool `json:"httpProxyEnabled"`
}
func (AIConfig) TableName() string {
@@ -163,13 +165,15 @@ func updateAiConfigs(aiConfigs []*AIConfig) error {
} else {
notDeleteIds = append(notDeleteIds, item.ID)
e = db.Dao.Model(&AIConfig{}).Where("id=?", item.ID).Updates(map[string]interface{}{
"name": item.Name,
"base_url": item.BaseUrl,
"api_key": item.ApiKey,
"model_name": item.ModelName,
"max_tokens": item.MaxTokens,
"temperature": item.Temperature,
"time_out": item.TimeOut,
"name": item.Name,
"base_url": item.BaseUrl,
"api_key": item.ApiKey,
"model_name": item.ModelName,
"max_tokens": item.MaxTokens,
"temperature": item.Temperature,
"time_out": item.TimeOut,
"http_proxy": item.HttpProxy,
"http_proxy_enabled": item.HttpProxyEnabled,
}).Error
if e != nil {
return

View File

@@ -121,10 +121,10 @@ EventsOn("updateVersion",async (msg) => {
<n-space vertical >
<n-image width="100" :src="icon" />
<h1>
<n-badge v-if="!vipLevel" :value="versionInfo" :offset="[50,10]" type="success">
<n-badge v-if="!vipLevel" :value="versionInfo" :offset="[80,10]" type="success">
<n-gradient-text type="info" :size="50" >go-stock</n-gradient-text>
</n-badge>
<n-badge v-if="vipLevel" :value="versionInfo" :offset="[50,10]" type="success">
<n-badge v-if="vipLevel" :value="versionInfo" :offset="[70,10]" type="success">
<n-gradient-text :type="expired?'error':'warning'" :size="50" >go-stock</n-gradient-text><n-tag :bordered="false" size="small" type="warning">VIP{{vipLevel}}</n-tag>
</n-badge>
</h1>

View File

@@ -34,6 +34,8 @@ const formValue = ref({
questionTemplate: "{{stockName}}分析和总结",
crawlTimeOut: 30,
kDays: 30,
httpProxy:"",
httpProxyEnabled:false,
},
enableDanmu: false,
browserPath: '',
@@ -57,8 +59,10 @@ function addAiConfig() {
apiKey: '',
modelName: 'deepseek-chat',
temperature: 0.1,
maxTokens: 1024,
maxTokens: 4096,
timeOut: 60,
httpProxy:"",
httpProxyEnabled:false,
}));
}
@@ -92,6 +96,8 @@ onMounted(() => {
questionTemplate: res.questionTemplate ? res.questionTemplate : '{{stockName}}分析和总结',
crawlTimeOut: res.crawlTimeOut,
kDays: res.kDays,
httpProxy:"",
httpProxyEnabled:false,
}
@@ -390,12 +396,12 @@ function deletePrompt(ID) {
label="日K线数据(天)" path="openAI.kDays">
<n-input-number min="30" step="1" max="60" v-model:value="formValue.openAI.kDays"/>
</n-form-item-gi>
<n-form-item-gi :span="2" label="http代理" path="httpProxyEnabled">
<n-form-item-gi :span="2" label="爬虫http代理" path="httpProxyEnabled">
<n-switch v-model:value="formValue.httpProxyEnabled"/>
</n-form-item-gi>
<n-form-item-gi :span="10" v-if="formValue.httpProxyEnabled" title="http代理地址"
label="http代理地址" path="httpProxy">
<n-input type="text" placeholder="http代理地址" v-model:value="formValue.httpProxy" clearable/>
<n-input type="text" placeholder="爬虫http代理地址" v-model:value="formValue.httpProxy" clearable/>
</n-form-item-gi>
@@ -452,6 +458,12 @@ function deletePrompt(ID) {
<n-form-item-gi :span="5" label="Timeout(秒)" :path="`openAI.aiConfigs[${index}].timeOut`">
<n-input-number min="60" step="1" placeholder="超时(秒)" v-model:value="aiConfig.timeOut"/>
</n-form-item-gi>
<n-form-item-gi :span="12" label="http代理" :path="`openAI.aiConfigs[${index}].httpProxyEnabled`">
<n-switch v-model:value="aiConfig.httpProxyEnabled"/>
</n-form-item-gi>
<n-form-item-gi :span="12" v-if="aiConfig.httpProxyEnabled" title="http代理地址" :path="`openAI.aiConfigs[${index}].httpProxy`">
<n-input type="text" placeholder="http代理地址" v-model:value="aiConfig.httpProxy" clearable/>
</n-form-item-gi>
</n-grid>
</n-card>
<n-button type="primary" dashed @click="addAiConfig" style="width: 100%;">+ 添加AI配置</n-button>

View File

@@ -13,6 +13,8 @@ export namespace data {
maxTokens: number;
temperature: number;
timeOut: number;
httpProxy: string;
httpProxyEnabled: boolean;
static createFrom(source: any = {}) {
return new AIConfig(source);
@@ -30,6 +32,8 @@ export namespace data {
this.maxTokens = source["maxTokens"];
this.temperature = source["temperature"];
this.timeOut = source["timeOut"];
this.httpProxy = source["httpProxy"];
this.httpProxyEnabled = source["httpProxyEnabled"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {