2026-08-14 09:49:11 +08:00
{{define "ai/list"}}
{{template "header" .}}
< div class = "toolbar ai-config-toolbar" >
< form class = "inline grow" method = "post" action = "/settings/ai/save" >
< input type = "hidden" name = "csrf_token" value = "{{.CSRFToken}}" >
< label for = "ai-name" > 服务商</ label >
< input id = "ai-name" name = "name" maxlength = "191" required placeholder = "例如:主模型" >
< label for = "ai-base-url" > Base URL</ label >
2026-08-14 11:15:50 +08:00
< input id = "ai-base-url" name = "base_url" type = "url" required placeholder = "http://api.example.com/v1" >
2026-08-14 09:49:11 +08:00
< label for = "ai-model" > 模型</ label >
< input id = "ai-model" name = "model" maxlength = "191" required placeholder = "模型名称" >
< label for = "ai-timeout" > 超时</ label >
< input id = "ai-timeout" class = "input-short" name = "timeout_seconds" type = "number" min = "1" max = "120" value = "30" required aria-describedby = "ai-create-help" >
< label for = "ai-concurrency" > 并发</ label >
< input id = "ai-concurrency" class = "input-short" name = "max_concurrency" type = "number" min = "1" max = "16" value = "2" required >
< label for = "ai-threshold" > 置信度%</ label >
< input id = "ai-threshold" class = "input-short" name = "confidence_threshold" type = "number" min = "0" max = "100" step = "0.01" value = "85" required >
< button class = "primary" type = "submit" > 新增</ button >
< small id = "ai-create-help" class = "visually-hidden" > 超时单位为秒;新增后还需要保存 API Key、测试连接并启用。</ small >
</ form >
</ div >
{{if .Message}}< p class = "hint" role = "status" > {{.Message}}</ p > {{end}}
{{if .Error}}< p class = "missing" role = "alert" > {{.Error}}</ p > {{end}}
{{if .SecretStoreError}}< p class = "missing" role = "alert" > 密钥存储不可用:{{.SecretStoreError}}</ p > {{end}}
2026-08-14 11:15:50 +08:00
< p class = "hint" > Base URL 支持 HTTP 和 HTTPS; HTTP 会明文传输 API Key 和匹配请求,请只在可信网络使用。API Key 只写入部署指定的独立 600 权限密钥文件,页面永不回显明文;修改普通配置或密钥后必须重新测试才能启用。</ p >
2026-08-14 09:49:11 +08:00
< div class = "table-wrap" >
< table class = "ai-config-table" >
< thead >< tr >< th > 服务商</ th >< th > 接口与模型</ th >< th > 运行参数</ th >< th > API Key</ th >< th > 连接测试</ th >< th > 状态与操作</ th ></ tr ></ thead >
< tbody >
{{range .Rows}}
< tr >
< td >< label class = "visually-hidden" for = "ai-name-{{.ProviderID}}" > 服务商名称</ label >< input id = "ai-name-{{.ProviderID}}" name = "name" value = "{{.Name}}" maxlength = "191" required form = "ai-edit-{{.ProviderID}}" ></ td >
< td class = "ai-config-endpoint" >
< label for = "ai-url-{{.ProviderID}}" > Base URL</ label >< input id = "ai-url-{{.ProviderID}}" name = "base_url" type = "url" value = "{{.BaseURL}}" required form = "ai-edit-{{.ProviderID}}" >
< label for = "ai-model-{{.ProviderID}}" > 模型</ label >< input id = "ai-model-{{.ProviderID}}" name = "model" value = "{{.Model}}" maxlength = "191" required form = "ai-edit-{{.ProviderID}}" >
</ td >
< td class = "ai-config-params" >
< label for = "ai-timeout-{{.ProviderID}}" > 超时秒</ label >< input id = "ai-timeout-{{.ProviderID}}" name = "timeout_seconds" type = "number" min = "1" max = "120" value = "{{.TimeoutSeconds}}" required form = "ai-edit-{{.ProviderID}}" >
< label for = "ai-concurrency-{{.ProviderID}}" > 最大并发</ label >< input id = "ai-concurrency-{{.ProviderID}}" name = "max_concurrency" type = "number" min = "1" max = "16" value = "{{.MaxConcurrency}}" required form = "ai-edit-{{.ProviderID}}" >
< label for = "ai-threshold-{{.ProviderID}}" > 置信度%</ label >< input id = "ai-threshold-{{.ProviderID}}" name = "confidence_threshold" type = "number" min = "0" max = "100" step = "0.01" value = "{{.ConfidencePercent}}" required form = "ai-edit-{{.ProviderID}}" >
</ td >
< td >
< p > {{if .SecretConfigured}}已配置:{{.SecretSuffix}}{{else}}未配置{{end}}</ p >
< form class = "form-stack" method = "post" action = "/settings/ai/secret" >
< input type = "hidden" name = "csrf_token" value = "{{$.CSRFToken}}" >< input type = "hidden" name = "provider_id" value = "{{.ProviderID}}" >
< label for = "ai-key-{{.ProviderID}}" > 替换 API Key</ label >< input id = "ai-key-{{.ProviderID}}" name = "api_key" type = "password" minlength = "8" required autocomplete = "new-password" >
< button type = "submit" > 保存密钥</ button >
</ form >
{{if .SecretConfigured}}< form class = "inline" method = "post" action = "/settings/ai/secret/clear" data-confirm-submit = "确定清除“{{.Name}}”的 API Key 吗?该服务商会立即停用。" >
< input type = "hidden" name = "csrf_token" value = "{{$.CSRFToken}}" >< input type = "hidden" name = "provider_id" value = "{{.ProviderID}}" >< button class = "danger" type = "submit" > 清除</ button >
</ form > {{end}}
</ td >
< td >< strong > {{.TestStatusLabel}}</ strong > {{if .LastTestMessage}}< p > {{.LastTestMessage}}</ p > {{end}}{{if .LastTestedAt}}< small > {{.LastTestedAt}}</ small > {{end}}
< form class = "inline" method = "post" action = "/settings/ai/test" >< input type = "hidden" name = "csrf_token" value = "{{$.CSRFToken}}" >< input type = "hidden" name = "provider_id" value = "{{.ProviderID}}" >< button type = "submit" > 测试连接</ button ></ form >
</ td >
< td >< p >< strong > {{.StatusLabel}}</ strong ></ p >
< form id = "ai-edit-{{.ProviderID}}" class = "inline" method = "post" action = "/settings/ai/save" >< input type = "hidden" name = "csrf_token" value = "{{$.CSRFToken}}" >< input type = "hidden" name = "provider_id" value = "{{.ProviderID}}" >< button type = "submit" > 保存配置</ button ></ form >
{{if .Enabled}}< form class = "inline" method = "post" action = "/settings/ai/disable" >< input type = "hidden" name = "csrf_token" value = "{{$.CSRFToken}}" >< input type = "hidden" name = "provider_id" value = "{{.ProviderID}}" >< button type = "submit" > 停用</ button ></ form >
{{else}}< form class = "inline" method = "post" action = "/settings/ai/enable" >< input type = "hidden" name = "csrf_token" value = "{{$.CSRFToken}}" >< input type = "hidden" name = "provider_id" value = "{{.ProviderID}}" >< button class = "primary" type = "submit" > 启用</ button ></ form > {{end}}
</ td >
</ tr >
{{else}}
< tr class = "empty" >< td colspan = "6" > 还没有 AI 服务商。先新增非敏感配置,再保存密钥并测试连接。</ td ></ tr >
{{end}}
</ tbody >
</ table >
</ div >
< div class = "statusbar" >< span class = "grow" ></ span >< span > 共 {{len .Rows}} 个服务商</ span ></ div >
{{template "footer" .}}
{{end}}