refactor: 合并第三方服务类型,去重字段
1. token_service 合并到 alarm_service - 去掉重复的 username/password/tenant_code - alarm_service 保留 get_token_url、put_message_url、tenant_code 三个有效字段 - token_service_main 槽位绑定类型改为接受 alarm_service 2. 第三方服务页支持按类型动态显示字段(JS控制) - 添加自定义(custom)类型,使用 JSON 文本域 - custom 类型支持槽位解析(resolvedServiceBinding) 3. 后端代码清理 - 移除 token_service 类型相关逻辑 - integration_type_label 去掉认证服务
This commit is contained in:
parent
ce18c85eba
commit
62d73f36e2
@ -101,9 +101,8 @@ type TokenServiceConfig struct {
|
||||
}
|
||||
|
||||
type AlarmServiceConfig struct {
|
||||
GetTokenURL string `json:"get_token_url"`
|
||||
PutMessageURL string `json:"put_message_url"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
TenantCode string `json:"tenant_code"`
|
||||
}
|
||||
|
||||
@ -1375,32 +1374,24 @@ func (s *ConfigPreviewService) SaveIntegrationServiceAsset(asset ConfigIntegrati
|
||||
return fmt.Errorf("object storage %s is required", key)
|
||||
}
|
||||
}
|
||||
case "token_service":
|
||||
if asset.TokenService == nil {
|
||||
return fmt.Errorf("token service config is required")
|
||||
}
|
||||
setAnyString(configMap, "get_token_url", asset.TokenService.GetTokenURL)
|
||||
setAnyString(configMap, "username", asset.TokenService.Username)
|
||||
setAnyString(configMap, "password", asset.TokenService.Password)
|
||||
setAnyString(configMap, "tenant_code", asset.TokenService.TenantCode)
|
||||
if strings.TrimSpace(stringValue(configMap["get_token_url"])) == "" {
|
||||
return fmt.Errorf("token service get_token_url is required")
|
||||
}
|
||||
case "alarm_service":
|
||||
if asset.AlarmService == nil {
|
||||
return fmt.Errorf("alarm service config is required")
|
||||
}
|
||||
setAnyString(configMap, "get_token_url", asset.AlarmService.GetTokenURL)
|
||||
setAnyString(configMap, "put_message_url", asset.AlarmService.PutMessageURL)
|
||||
setAnyString(configMap, "username", asset.AlarmService.Username)
|
||||
setAnyString(configMap, "password", asset.AlarmService.Password)
|
||||
setAnyString(configMap, "tenant_code", asset.AlarmService.TenantCode)
|
||||
if strings.TrimSpace(stringValue(configMap["put_message_url"])) == "" {
|
||||
return fmt.Errorf("alarm service put_message_url is required")
|
||||
if strings.TrimSpace(stringValue(configMap["get_token_url"])) == "" && strings.TrimSpace(stringValue(configMap["put_message_url"])) == "" {
|
||||
return fmt.Errorf("alarm service requires at least one of get_token_url or put_message_url")
|
||||
}
|
||||
case "custom":
|
||||
raw["config"] = asset.Raw
|
||||
default:
|
||||
return fmt.Errorf("unsupported third-party service type: %s", serviceType)
|
||||
}
|
||||
raw["config"] = configMap
|
||||
if serviceType != "custom" {
|
||||
raw["config"] = configMap
|
||||
}
|
||||
body, err := marshalConfigJSON(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1659,22 +1650,19 @@ func integrationServiceAssetFromRecord(record storage.IntegrationServiceRecord)
|
||||
SecretKey: firstString(sourceMap["secret_key"], stringValue(sourceMap["minio_secret_key"])),
|
||||
}
|
||||
item.AddressSummary = strings.TrimSpace(strings.Trim(strings.Join([]string{item.ObjectStorage.Endpoint, item.ObjectStorage.Bucket}, " / "), " /"))
|
||||
case "token_service":
|
||||
item.TokenService = &TokenServiceConfig{
|
||||
GetTokenURL: stringValue(sourceMap["get_token_url"]),
|
||||
Username: stringValue(sourceMap["username"]),
|
||||
Password: stringValue(sourceMap["password"]),
|
||||
TenantCode: stringValue(sourceMap["tenant_code"]),
|
||||
}
|
||||
item.AddressSummary = item.TokenService.GetTokenURL
|
||||
case "alarm_service":
|
||||
item.AlarmService = &AlarmServiceConfig{
|
||||
GetTokenURL: stringValue(sourceMap["get_token_url"]),
|
||||
PutMessageURL: stringValue(sourceMap["put_message_url"]),
|
||||
Username: stringValue(sourceMap["username"]),
|
||||
Password: stringValue(sourceMap["password"]),
|
||||
TenantCode: stringValue(sourceMap["tenant_code"]),
|
||||
}
|
||||
item.AddressSummary = item.AlarmService.PutMessageURL
|
||||
summary := strings.TrimSpace(item.AlarmService.PutMessageURL)
|
||||
if summary == "" {
|
||||
summary = item.AlarmService.GetTokenURL
|
||||
}
|
||||
item.AddressSummary = summary
|
||||
case "custom":
|
||||
item.AddressSummary = "自定义"
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
@ -1719,10 +1707,10 @@ func integrationTypeLabel(v string) string {
|
||||
switch strings.TrimSpace(v) {
|
||||
case "object_storage":
|
||||
return "对象存储"
|
||||
case "token_service":
|
||||
return "认证服务"
|
||||
case "alarm_service":
|
||||
return "告警服务"
|
||||
case "custom":
|
||||
return "自定义"
|
||||
default:
|
||||
return strings.TrimSpace(v)
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ func (s *ConfigPreviewService) resolveSceneBindings(raw map[string]any) (map[str
|
||||
expected string
|
||||
}{
|
||||
{slot: "object_storage_main", expected: "object_storage"},
|
||||
{slot: "token_service_main", expected: "token_service"},
|
||||
{slot: "token_service_main", expected: "alarm_service"},
|
||||
{slot: "alarm_service_main", expected: "alarm_service"},
|
||||
} {
|
||||
serviceRef := bindingField(serviceBindings, binding.slot, "service_ref")
|
||||
@ -405,26 +405,22 @@ func resolvedServiceBinding(asset *ConfigIntegrationServiceAsset) map[string]any
|
||||
"access_key": asset.ObjectStorage.AccessKey,
|
||||
"secret_key": asset.ObjectStorage.SecretKey,
|
||||
}
|
||||
case "token_service":
|
||||
if asset.TokenService == nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]any{
|
||||
"get_token_url": asset.TokenService.GetTokenURL,
|
||||
"username": asset.TokenService.Username,
|
||||
"password": asset.TokenService.Password,
|
||||
"tenant_code": asset.TokenService.TenantCode,
|
||||
}
|
||||
case "alarm_service":
|
||||
if asset.AlarmService == nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]any{
|
||||
"get_token_url": asset.AlarmService.GetTokenURL,
|
||||
"put_message_url": asset.AlarmService.PutMessageURL,
|
||||
"username": asset.AlarmService.Username,
|
||||
"password": asset.AlarmService.Password,
|
||||
"tenant_code": asset.AlarmService.TenantCode,
|
||||
}
|
||||
case "custom":
|
||||
if cfg, ok := asset.Raw["config"]; ok {
|
||||
if m, ok := cfg.(map[string]any); ok {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ func TestConfigPreviewServiceRenderProfileEditorWritesResolvedBindings(t *testin
|
||||
t.Fatalf("SaveVideoSource: %v", err)
|
||||
}
|
||||
saveIntegrationServiceForPreviewTest(t, repo, "minio_main", "object_storage", `{"name":"minio_main","type":"object_storage","config":{"endpoint":"http://10.0.0.49:9000","bucket":"myminio","access_key":"admin","secret_key":"password"}}`)
|
||||
saveIntegrationServiceForPreviewTest(t, repo, "token_main", "token_service", `{"name":"token_main","type":"token_service","config":{"get_token_url":"http://10.0.0.49:8080/api/getToken","tenant_code":"32"}}`)
|
||||
saveIntegrationServiceForPreviewTest(t, repo, "token_main", "alarm_service", `{"name":"token_main","type":"alarm_service","config":{"get_token_url":"http://10.0.0.49:8080/api/getToken","tenant_code":"32"}}`)
|
||||
saveIntegrationServiceForPreviewTest(t, repo, "alarm_main", "alarm_service", `{"name":"alarm_main","type":"alarm_service","config":{"put_message_url":"http://10.0.0.49:8080/api/putMessage","tenant_code":"32"}}`)
|
||||
|
||||
svc := NewConfigPreviewService(&config.Config{MediaRepoPath: root}, repo)
|
||||
@ -248,7 +248,7 @@ func TestConfigPreviewServiceRenderProfileEditorAllowsUnboundOptionalServiceSlot
|
||||
"source":"standard",
|
||||
"slots":{
|
||||
"inputs":[{"name":"video_input_main","type":"video_source","required":true,"description":"主视频输入"}],
|
||||
"services":[{"name":"token_service_main","type":"token_service","required":false,"description":"认证服务"}],
|
||||
"services":[{"name":"token_service_main","type":"alarm_service","required":false,"description":"告警服务"}],
|
||||
"outputs":[{"name":"stream_output_main","type":"stream_publish","required":true,"description":"主视频输出"}]
|
||||
},
|
||||
"template":{
|
||||
|
||||
@ -131,6 +131,7 @@ type PageData struct {
|
||||
TemplateCloneDesc string
|
||||
TemplateCreateMode string
|
||||
OverlayDraftJSON string
|
||||
IntegrationConfigDraft string
|
||||
AuditEntries []storage.AuditLogRecord
|
||||
PersistedConfig *storage.DeviceConfigStateRecord
|
||||
DBPath string
|
||||
@ -419,8 +420,6 @@ func NewUI(discovery *service.DiscoveryService, registry *service.RegistryServic
|
||||
return "视频源"
|
||||
case "object_storage":
|
||||
return "对象存储"
|
||||
case "token_service":
|
||||
return "认证服务"
|
||||
case "alarm_service":
|
||||
return "告警服务"
|
||||
case "stream_publish":
|
||||
@ -2468,6 +2467,16 @@ func (u *UI) pageAssetIntegrations(w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
data.AssetIntegrationEditing = newMode || editMode
|
||||
}
|
||||
if data.AssetIntegration != nil && data.AssetIntegration.Type == "custom" {
|
||||
if configRaw, ok := data.AssetIntegration.Raw["config"]; ok {
|
||||
if s, err := compactJSON(configRaw); err == nil {
|
||||
data.IntegrationConfigDraft = s
|
||||
}
|
||||
}
|
||||
if data.IntegrationConfigDraft == "" {
|
||||
data.IntegrationConfigDraft = "{}"
|
||||
}
|
||||
}
|
||||
u.render(w, r, "assets", data)
|
||||
}
|
||||
|
||||
@ -2478,29 +2487,34 @@ func (u *UI) actionAssetIntegrationSave(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
_ = r.ParseForm()
|
||||
enabled := strings.TrimSpace(r.FormValue("enabled")) == "1" || strings.EqualFold(strings.TrimSpace(r.FormValue("enabled")), "true") || strings.EqualFold(strings.TrimSpace(r.FormValue("enabled")), "on")
|
||||
serviceType := strings.TrimSpace(r.FormValue("type"))
|
||||
asset := service.ConfigIntegrationServiceAsset{
|
||||
Name: strings.TrimSpace(r.FormValue("name")),
|
||||
Type: strings.TrimSpace(r.FormValue("type")),
|
||||
Type: serviceType,
|
||||
Description: strings.TrimSpace(r.FormValue("description")),
|
||||
Enabled: enabled,
|
||||
ObjectStorage: &service.ObjectStorageConfig{
|
||||
Endpoint: strings.TrimSpace(r.FormValue("endpoint")),
|
||||
Bucket: strings.TrimSpace(r.FormValue("bucket")),
|
||||
AccessKey: strings.TrimSpace(r.FormValue("access_key")),
|
||||
SecretKey: strings.TrimSpace(r.FormValue("secret_key")),
|
||||
},
|
||||
TokenService: &service.TokenServiceConfig{
|
||||
GetTokenURL: strings.TrimSpace(r.FormValue("get_token_url")),
|
||||
Username: strings.TrimSpace(r.FormValue("username")),
|
||||
Password: strings.TrimSpace(r.FormValue("password")),
|
||||
TenantCode: strings.TrimSpace(r.FormValue("tenant_code")),
|
||||
},
|
||||
AlarmService: &service.AlarmServiceConfig{
|
||||
PutMessageURL: strings.TrimSpace(r.FormValue("put_message_url")),
|
||||
Username: strings.TrimSpace(r.FormValue("alarm_username")),
|
||||
Password: strings.TrimSpace(r.FormValue("alarm_password")),
|
||||
TenantCode: strings.TrimSpace(r.FormValue("alarm_tenant_code")),
|
||||
},
|
||||
ObjectStorage: &service.ObjectStorageConfig{},
|
||||
AlarmService: &service.AlarmServiceConfig{},
|
||||
}
|
||||
if serviceType == "custom" {
|
||||
configRaw := strings.TrimSpace(r.FormValue("config_json"))
|
||||
if configRaw == "" {
|
||||
configRaw = "{}"
|
||||
}
|
||||
var raw map[string]any
|
||||
if err := json.Unmarshal([]byte(configRaw), &raw); err != nil {
|
||||
http.Redirect(w, r, "/ui/assets/integrations?error="+urlQueryEscape("自定义配置 JSON 格式不正确:"+err.Error())+"&name="+url.PathEscape(asset.Name), http.StatusFound)
|
||||
return
|
||||
}
|
||||
asset.Raw = raw
|
||||
} else {
|
||||
asset.ObjectStorage.Endpoint = strings.TrimSpace(r.FormValue("endpoint"))
|
||||
asset.ObjectStorage.Bucket = strings.TrimSpace(r.FormValue("bucket"))
|
||||
asset.ObjectStorage.AccessKey = strings.TrimSpace(r.FormValue("access_key"))
|
||||
asset.ObjectStorage.SecretKey = strings.TrimSpace(r.FormValue("secret_key"))
|
||||
asset.AlarmService.GetTokenURL = strings.TrimSpace(r.FormValue("get_token_url"))
|
||||
asset.AlarmService.PutMessageURL = strings.TrimSpace(r.FormValue("put_message_url"))
|
||||
asset.AlarmService.TenantCode = strings.TrimSpace(r.FormValue("tenant_code"))
|
||||
}
|
||||
if err := u.preview.SaveIntegrationServiceAsset(asset); err != nil {
|
||||
http.Redirect(w, r, "/ui/assets/integrations?error="+urlQueryEscape(err.Error())+"&name="+url.PathEscape(asset.Name), http.StatusFound)
|
||||
|
||||
@ -98,35 +98,40 @@
|
||||
<label><span>服务名称<span class="required-mark">*</span></span><input name="name" value="{{.AssetIntegration.Name}}" autofocus /></label>
|
||||
<label>
|
||||
<span>服务类型<span class="required-mark">*</span></span>
|
||||
<select name="type">
|
||||
<select name="type" onchange="toggleIntegrationFields(this.value)">
|
||||
<option value="object_storage" {{if eq .AssetIntegration.Type "object_storage"}}selected{{end}}>对象存储</option>
|
||||
<option value="token_service" {{if eq .AssetIntegration.Type "token_service"}}selected{{end}}>认证服务</option>
|
||||
<option value="alarm_service" {{if eq .AssetIntegration.Type "alarm_service"}}selected{{end}}>告警服务</option>
|
||||
<option value="custom" {{if eq .AssetIntegration.Type "custom"}}selected{{end}}>自定义</option>
|
||||
</select>
|
||||
</label>
|
||||
<label><span>描述</span><input name="description" value="{{.AssetIntegration.Description}}" /></label>
|
||||
<label><span>启用</span><select name="enabled"><option value="1" {{if .AssetIntegration.Enabled}}selected{{end}}>启用</option><option value="0" {{if not .AssetIntegration.Enabled}}selected{{end}}>停用</option></select></label>
|
||||
</div>
|
||||
|
||||
<div class="field-grid">
|
||||
<label><span>对象存储地址</span><input class="mono" name="endpoint" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.Endpoint}}{{end}}" /></label>
|
||||
<label><span>Bucket</span><input class="mono" name="bucket" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.Bucket}}{{end}}" /></label>
|
||||
<label><span>Access Key</span><input class="mono" name="access_key" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.AccessKey}}{{end}}" /></label>
|
||||
<label><span>Secret Key</span><input class="mono" name="secret_key" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.SecretKey}}{{end}}" /></label>
|
||||
<div class="field-group" data-type="object_storage">
|
||||
<h3>对象存储配置</h3>
|
||||
<div class="field-grid">
|
||||
<label><span>对象存储地址</span><input class="mono" name="endpoint" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.Endpoint}}{{end}}" /></label>
|
||||
<label><span>Bucket</span><input class="mono" name="bucket" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.Bucket}}{{end}}" /></label>
|
||||
<label><span>Access Key</span><input class="mono" name="access_key" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.AccessKey}}{{end}}" /></label>
|
||||
<label><span>Secret Key</span><input class="mono" name="secret_key" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.SecretKey}}{{end}}" /></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-grid">
|
||||
<label><span>Token 获取地址</span><input class="mono" name="get_token_url" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.GetTokenURL}}{{end}}" /></label>
|
||||
<label><span>认证用户名</span><input name="username" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.Username}}{{end}}" /></label>
|
||||
<label><span>认证密码</span><input name="password" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.Password}}{{end}}" /></label>
|
||||
<label><span>认证租户编码</span><input class="mono" name="tenant_code" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.TenantCode}}{{end}}" /></label>
|
||||
<div class="field-group" data-type="alarm_service">
|
||||
<h3>告警服务配置</h3>
|
||||
<div class="field-grid">
|
||||
<label><span>Token 获取地址</span><input class="mono" name="get_token_url" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.GetTokenURL}}{{end}}" /></label>
|
||||
<label><span>消息上报地址</span><input class="mono" name="put_message_url" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.PutMessageURL}}{{end}}" /></label>
|
||||
<label><span>租户编码</span><input class="mono" name="tenant_code" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.TenantCode}}{{end}}" /></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-grid">
|
||||
<label><span>消息上报地址</span><input class="mono" name="put_message_url" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.PutMessageURL}}{{end}}" /></label>
|
||||
<label><span>告警用户名</span><input name="alarm_username" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.Username}}{{end}}" /></label>
|
||||
<label><span>告警密码</span><input name="alarm_password" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.Password}}{{end}}" /></label>
|
||||
<label><span>告警租户编码</span><input class="mono" name="alarm_tenant_code" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.TenantCode}}{{end}}" /></label>
|
||||
<div class="field-group" data-type="custom">
|
||||
<h3>自定义配置</h3>
|
||||
<div class="field-grid">
|
||||
<label class="full"><span>配置 JSON<span class="required-mark">*</span></span><textarea class="code-input" name="config_json" rows="10">{{.IntegrationConfigDraft}}</textarea></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
@ -139,21 +144,38 @@
|
||||
<div class="detail-item"><span>服务类型</span><strong>{{.AssetIntegration.TypeLabel}}</strong></div>
|
||||
<div class="detail-item"><span>描述</span><strong>{{if .AssetIntegration.Description}}{{.AssetIntegration.Description}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>启用状态</span><strong>{{if .AssetIntegration.Enabled}}启用{{else}}停用{{end}}</strong></div>
|
||||
{{if eq .AssetIntegration.Type "object_storage"}}
|
||||
<div class="detail-item"><span>对象存储地址</span><strong class="mono">{{if and .AssetIntegration.ObjectStorage .AssetIntegration.ObjectStorage.Endpoint}}{{.AssetIntegration.ObjectStorage.Endpoint}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>Bucket</span><strong class="mono">{{if and .AssetIntegration.ObjectStorage .AssetIntegration.ObjectStorage.Bucket}}{{.AssetIntegration.ObjectStorage.Bucket}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>Access Key</span><strong class="mono">{{if and .AssetIntegration.ObjectStorage .AssetIntegration.ObjectStorage.AccessKey}}{{.AssetIntegration.ObjectStorage.AccessKey}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>Secret Key</span><strong class="mono">{{if and .AssetIntegration.ObjectStorage .AssetIntegration.ObjectStorage.SecretKey}}{{.AssetIntegration.ObjectStorage.SecretKey}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>Token 获取地址</span><strong class="mono">{{if and .AssetIntegration.TokenService .AssetIntegration.TokenService.GetTokenURL}}{{.AssetIntegration.TokenService.GetTokenURL}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>认证用户名</span><strong>{{if and .AssetIntegration.TokenService .AssetIntegration.TokenService.Username}}{{.AssetIntegration.TokenService.Username}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>认证租户编码</span><strong class="mono">{{if and .AssetIntegration.TokenService .AssetIntegration.TokenService.TenantCode}}{{.AssetIntegration.TokenService.TenantCode}}{{else}}-{{end}}</strong></div>
|
||||
{{end}}
|
||||
{{if eq .AssetIntegration.Type "alarm_service"}}
|
||||
<div class="detail-item"><span>Token 获取地址</span><strong class="mono">{{if and .AssetIntegration.AlarmService .AssetIntegration.AlarmService.GetTokenURL}}{{.AssetIntegration.AlarmService.GetTokenURL}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>消息上报地址</span><strong class="mono">{{if and .AssetIntegration.AlarmService .AssetIntegration.AlarmService.PutMessageURL}}{{.AssetIntegration.AlarmService.PutMessageURL}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>告警用户名</span><strong>{{if and .AssetIntegration.AlarmService .AssetIntegration.AlarmService.Username}}{{.AssetIntegration.AlarmService.Username}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>告警租户编码</span><strong class="mono">{{if and .AssetIntegration.AlarmService .AssetIntegration.AlarmService.TenantCode}}{{.AssetIntegration.AlarmService.TenantCode}}{{else}}-{{end}}</strong></div>
|
||||
<div class="detail-item"><span>租户编码</span><strong class="mono">{{if and .AssetIntegration.AlarmService .AssetIntegration.AlarmService.TenantCode}}{{.AssetIntegration.AlarmService.TenantCode}}{{else}}-{{end}}</strong></div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{{if and (not .AssetIntegrationEditing) (eq .AssetIntegration.Type "custom")}}
|
||||
<details class="card collapsible">
|
||||
<summary class="title-with-icon">{{icon "tech"}}<span>原始 JSON</span></summary>
|
||||
<pre>{{json .AssetIntegration.Raw}}</pre>
|
||||
</details>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<script>
|
||||
function toggleIntegrationFields(type) {
|
||||
document.querySelectorAll('[data-type]').forEach(function(el) {
|
||||
el.style.display = el.getAttribute('data-type') === type ? '' : 'none';
|
||||
});
|
||||
}
|
||||
toggleIntegrationFields('{{.AssetIntegration.Type}}');
|
||||
</script>
|
||||
{{else if eq .AssetTab "video-sources"}}
|
||||
<div class="card">
|
||||
<div class="section-title">
|
||||
|
||||
@ -2327,11 +2327,11 @@ func TestUI_AssetIntegrationsPageShowsStructuredServices(t *testing.T) {
|
||||
defer store.Close()
|
||||
repo := storage.NewAssetsRepo(store.DB())
|
||||
mustSaveIntegrationService(t, repo, "minio_main", "object_storage", `{"name":"minio_main","type":"object_storage","description":"主对象存储","config":{"endpoint":"http://10.0.0.49:9000","bucket":"myminio","access_key":"admin","secret_key":"password"}}`)
|
||||
mustSaveIntegrationService(t, repo, "token_main", "token_service", `{"name":"token_main","type":"token_service","description":"认证","config":{"get_token_url":"http://10.0.0.49:8080/api/getToken","tenant_code":"32"}}`)
|
||||
mustSaveIntegrationService(t, repo, "alarm_main", "alarm_service", `{"name":"alarm_main","type":"alarm_service","description":"告警","config":{"get_token_url":"http://10.0.0.49:8080/api/getToken","put_message_url":"http://10.0.0.49:8080/api/putMessage","tenant_code":"32"}}`)
|
||||
ui.preview = service.NewConfigPreviewService(&config.Config{MediaRepoPath: root}, repo)
|
||||
mustImportAssetsForUI(t, ui.preview)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ui/assets/integrations", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/ui/assets/integrations?name=alarm_main", nil)
|
||||
rr := httptest.NewRecorder()
|
||||
ui.pageAssetIntegrations(rr, req)
|
||||
|
||||
@ -2343,15 +2343,15 @@ func TestUI_AssetIntegrationsPageShowsStructuredServices(t *testing.T) {
|
||||
"编辑",
|
||||
"删除",
|
||||
"minio_main",
|
||||
"token_main",
|
||||
"alarm_main",
|
||||
"对象存储",
|
||||
"认证服务",
|
||||
"告警服务",
|
||||
"http://10.0.0.49:9000 / myminio",
|
||||
"1",
|
||||
"查看模式",
|
||||
`<strong class="mono">minio_main</strong>`,
|
||||
`<strong class="mono">alarm_main</strong>`,
|
||||
`data-nav-row`,
|
||||
`data-nav-href="/ui/assets/integrations?name=minio_main"`,
|
||||
`data-nav-href="/ui/assets/integrations?name=alarm_main"`,
|
||||
`class="selected"`,
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user