329 lines
16 KiB
HTML
329 lines
16 KiB
HTML
{{define "asset_tabs"}}
|
|
<div class="card-tabs asset-tab-wrap">
|
|
<ul class="nav nav-tabs asset-tabs" role="tablist" aria-label="配置管理页面">
|
|
<li class="nav-item" role="presentation">
|
|
<a href="/ui/assets" class="nav-link{{if eq .AssetTab "overview"}} active{{end}}" role="tab" {{if eq .AssetTab "overview"}}aria-selected="true"{{else}}aria-selected="false"{{end}}>总览</a>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<a href="/ui/assets/video-sources" class="nav-link{{if eq .AssetTab "video-sources"}} active{{end}}" role="tab" {{if eq .AssetTab "video-sources"}}aria-selected="true"{{else}}aria-selected="false"{{end}}>视频源</a>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<a href="/ui/assets/templates" class="nav-link{{if eq .AssetTab "templates"}} active{{end}}" role="tab" {{if eq .AssetTab "templates"}}aria-selected="true"{{else}}aria-selected="false"{{end}}>识别模板</a>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<a href="/ui/assets/integrations" class="nav-link{{if eq .AssetTab "integrations"}} active{{end}}" role="tab" {{if eq .AssetTab "integrations"}}aria-selected="true"{{else}}aria-selected="false"{{end}}>第三方服务</a>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<a href="/ui/assets/overlays" class="nav-link{{if eq .AssetTab "overlays"}} active{{end}}" role="tab" {{if eq .AssetTab "overlays"}}aria-selected="true"{{else}}aria-selected="false"{{end}}>调试参数</a>
|
|
</li>
|
|
</ul>
|
|
<div class="tab-content">
|
|
<div class="card tab-pane active show asset-tab-card">
|
|
<div class="card-body asset-panel-body">
|
|
{{end}}
|
|
|
|
{{define "asset_tabs_end"}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "assets"}}
|
|
{{template "asset_tabs" .}}
|
|
|
|
{{if eq .AssetTab "integrations"}}
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "service"}}<span>第三方服务列表</span></h2>
|
|
</div>
|
|
<div class="actions compact">
|
|
<a class="btn secondary" href="/ui/assets/integrations?new=1">{{icon "apply"}}<span>新增服务</span></a>
|
|
{{if .AssetIntegration.Name}}
|
|
<a class="btn secondary" href="/ui/assets/integrations?name={{.AssetIntegration.Name}}&edit=1">{{icon "edit"}}<span>编辑</span></a>
|
|
<form method="post" action="/ui/assets/integrations/{{.AssetIntegration.Name}}/delete">
|
|
<button class="btn secondary" type="submit">删除</button>
|
|
</form>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>服务名称</th>
|
|
<th>服务类型</th>
|
|
<th>描述</th>
|
|
<th>地址摘要</th>
|
|
<th>状态</th>
|
|
<th>引用数量</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .AssetIntegrations}}
|
|
<tr>
|
|
<td><a class="mono" href="/ui/assets/integrations?name={{.Name}}">{{.Name}}</a></td>
|
|
<td>{{.TypeLabel}}</td>
|
|
<td>{{if .Description}}{{.Description}}{{else}}-{{end}}</td>
|
|
<td class="mono">{{if .AddressSummary}}{{.AddressSummary}}{{else}}-{{end}}</td>
|
|
<td>{{if .Enabled}}启用{{else}}停用{{end}}</td>
|
|
<td>{{.RefCount}}</td>
|
|
</tr>
|
|
{{else}}
|
|
<tr><td colspan="6"><div class="empty-state compact"><div class="empty-title">还没有第三方服务</div></div></td></tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{if .AssetIntegration}}
|
|
<form method="post" action="/ui/assets/integrations">
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "service"}}<span>{{if .AssetIntegrationEditing}}第三方服务编辑{{else}}第三方服务详情{{end}}</span></h2>
|
|
</div>
|
|
</div>
|
|
<div class="field-grid">
|
|
<label><span>服务名称</span><input name="name" value="{{.AssetIntegration.Name}}" {{if .AssetIntegrationEditing}}autofocus{{else}}readonly{{end}} /></label>
|
|
<label>
|
|
<span>服务类型</span>
|
|
<select name="type" {{if not .AssetIntegrationEditing}}disabled{{end}}>
|
|
<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>
|
|
</select>
|
|
</label>
|
|
<label><span>描述</span><input name="description" value="{{.AssetIntegration.Description}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>启用</span><select name="enabled" {{if not .AssetIntegrationEditing}}disabled{{end}}><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}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>Bucket</span><input class="mono" name="bucket" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.Bucket}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>Access Key</span><input class="mono" name="access_key" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.AccessKey}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>Secret Key</span><input class="mono" name="secret_key" value="{{if .AssetIntegration.ObjectStorage}}{{.AssetIntegration.ObjectStorage.SecretKey}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
</div>
|
|
|
|
<div class="field-grid">
|
|
<label><span>Token 获取地址</span><input class="mono" name="get_token_url" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.GetTokenURL}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>认证用户名</span><input name="username" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.Username}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>认证密码</span><input name="password" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.Password}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>认证租户编码</span><input class="mono" name="tenant_code" value="{{if .AssetIntegration.TokenService}}{{.AssetIntegration.TokenService.TenantCode}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
</div>
|
|
|
|
<div class="field-grid">
|
|
<label><span>消息上报地址</span><input class="mono" name="put_message_url" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.PutMessageURL}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>告警用户名</span><input name="alarm_username" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.Username}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>告警密码</span><input name="alarm_password" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.Password}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
<label><span>告警租户编码</span><input class="mono" name="alarm_tenant_code" value="{{if .AssetIntegration.AlarmService}}{{.AssetIntegration.AlarmService.TenantCode}}{{end}}" {{if not .AssetIntegrationEditing}}readonly{{end}} /></label>
|
|
</div>
|
|
|
|
{{if .AssetIntegrationEditing}}
|
|
<div class="actions">
|
|
<button type="submit">{{icon "apply"}}<span>保存</span></button>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</form>
|
|
{{end}}
|
|
{{else if eq .AssetTab "video-sources"}}
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "device"}}<span>视频源列表</span></h2>
|
|
</div>
|
|
<div class="actions compact">
|
|
<a class="btn secondary" href="/ui/assets/video-sources?new=1">{{icon "apply"}}<span>新增视频源</span></a>
|
|
{{if .AssetVideoSource.Name}}
|
|
<a class="btn secondary" href="/ui/assets/video-sources?name={{.AssetVideoSource.Name}}&edit=1">{{icon "edit"}}<span>编辑</span></a>
|
|
<form method="post" action="/ui/assets/video-sources/{{.AssetVideoSource.Name}}/delete">
|
|
<button class="btn secondary" type="submit">删除</button>
|
|
</form>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>视频源名称</th>
|
|
<th>类型</th>
|
|
<th>区域</th>
|
|
<th>输入地址</th>
|
|
<th>分辨率</th>
|
|
<th>帧率</th>
|
|
<th>引用数量</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .AssetVideoSources}}
|
|
<tr>
|
|
<td><a class="mono" href="/ui/assets/video-sources?name={{.Name}}">{{.Name}}</a></td>
|
|
<td>{{.SourceTypeLabel}}</td>
|
|
<td>{{if .Area}}{{.Area}}{{else}}-{{end}}</td>
|
|
<td class="mono">{{if .Config.URL}}{{.Config.URL}}{{else}}-{{end}}</td>
|
|
<td>{{if .Config.Resolution}}{{.Config.Resolution}}{{else}}-{{end}}</td>
|
|
<td class="mono">{{if .Config.FPS}}{{.Config.FPS}}{{else}}-{{end}}</td>
|
|
<td>{{.RefCount}}</td>
|
|
</tr>
|
|
{{else}}
|
|
<tr><td colspan="7"><div class="empty-state compact"><div class="empty-title">还没有视频源</div></div></td></tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{if .AssetVideoSource}}
|
|
<form method="post" action="/ui/assets/video-sources">
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "device"}}<span>{{if .AssetVideoSourceEditing}}视频源编辑{{else}}视频源详情{{end}}</span></h2>
|
|
</div>
|
|
</div>
|
|
<div class="field-grid">
|
|
<label><span>视频源名称</span><input name="name" value="{{.AssetVideoSource.Name}}" {{if .AssetVideoSourceEditing}}autofocus{{else}}readonly{{end}} /></label>
|
|
<label>
|
|
<span>类型</span>
|
|
<select name="source_type" {{if not .AssetVideoSourceEditing}}disabled{{end}}>
|
|
<option value="rtsp" {{if eq .AssetVideoSource.SourceType "rtsp"}}selected{{end}}>RTSP</option>
|
|
<option value="rtmp" {{if eq .AssetVideoSource.SourceType "rtmp"}}selected{{end}}>RTMP</option>
|
|
<option value="file" {{if eq .AssetVideoSource.SourceType "file"}}selected{{end}}>文件</option>
|
|
<option value="usb_camera" {{if eq .AssetVideoSource.SourceType "usb_camera"}}selected{{end}}>USB 摄像头</option>
|
|
</select>
|
|
</label>
|
|
<label><span>区域</span><input name="area" value="{{.AssetVideoSource.Area}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>描述</span><input name="description" value="{{.AssetVideoSource.Description}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
</div>
|
|
<div class="field-grid">
|
|
<label class="full"><span>输入地址</span><input class="mono" name="url" value="{{.AssetVideoSource.Config.URL}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>标准分辨率</span><input name="resolution" value="{{.AssetVideoSource.Config.Resolution}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>像素尺寸</span><input class="mono" name="frame_size" value="{{.AssetVideoSource.Config.FrameSize}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>帧率</span><input class="mono" name="fps" value="{{.AssetVideoSource.Config.FPS}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>视频格式</span><input name="video_format" value="{{.AssetVideoSource.Config.VideoFormat}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>焦距</span><input name="focal_length" value="{{.AssetVideoSource.Config.FocalLength}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>安装高度</span><input name="mount_height" value="{{.AssetVideoSource.Config.MountHeight}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
<label><span>安装角度</span><input name="mount_angle" value="{{.AssetVideoSource.Config.MountAngle}}" {{if not .AssetVideoSourceEditing}}readonly{{end}} /></label>
|
|
</div>
|
|
{{if .AssetVideoSourceEditing}}
|
|
<div class="actions">
|
|
<button type="submit">{{icon "apply"}}<span>保存</span></button>
|
|
<a class="btn secondary" href="/ui/assets/video-sources?name={{.AssetVideoSource.Name}}">{{icon "close"}}<span>取消</span></a>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</form>
|
|
{{end}}
|
|
{{else}}
|
|
<div class="stats">
|
|
<div class="stat accent-teal">
|
|
<div class="k metric-label">{{icon "template"}}<span>识别模板</span></div>
|
|
<div class="v">{{len .AssetTemplates}}</div>
|
|
<div class="hint">{{if .ConfigSources.Root}}{{.ConfigSources.Root}}{{else}}标准模板与配置均存储在本地数据库{{end}}</div>
|
|
</div>
|
|
<div class="stat accent-green">
|
|
<div class="k metric-label">{{icon "device"}}<span>视频源</span></div>
|
|
<div class="v">{{len .AssetVideoSources}}</div>
|
|
<div class="hint">可复用输入流配置</div>
|
|
</div>
|
|
<div class="stat accent-slate">
|
|
<div class="k metric-label">{{icon "overlay"}}<span>调试参数</span></div>
|
|
<div class="v">{{len .AssetOverlays}}</div>
|
|
<div class="hint">调试与敏感度变化</div>
|
|
</div>
|
|
<div class="stat accent-amber">
|
|
<div class="k metric-label">{{icon "service"}}<span>第三方服务</span></div>
|
|
<div class="v">{{len .AssetIntegrations}}</div>
|
|
<div class="hint">告警、对象存储和认证服务</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="quad-grid">
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "template"}}<span>识别模板</span></h2>
|
|
</div>
|
|
</div>
|
|
<div class="asset-list">
|
|
{{range .AssetTemplates}}
|
|
<a class="asset-row asset-link" href="/ui/assets/templates/{{.Name}}">
|
|
<span class="mono">{{.Name}}</span>
|
|
<span class="muted small">{{.NodeCount}}节点 / {{.EdgeCount}}连线</span>
|
|
</a>
|
|
{{else}}
|
|
<div class="empty-state compact">
|
|
<div class="empty-title">还没有模板</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "device"}}<span>视频源</span></h2>
|
|
</div>
|
|
</div>
|
|
<div class="asset-list">
|
|
{{range .AssetVideoSources}}
|
|
<a class="asset-row asset-link" href="/ui/assets/video-sources?name={{.Name}}">
|
|
<span class="mono">{{.Name}}</span>
|
|
<span class="muted small">{{if .Area}}{{.Area}} / {{end}}{{if .Config.Resolution}}{{.Config.Resolution}}{{else}}未设置分辨率{{end}}</span>
|
|
</a>
|
|
{{else}}
|
|
<div class="empty-state compact">
|
|
<div class="empty-title">还没有视频源</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "service"}}<span>第三方服务</span></h2>
|
|
</div>
|
|
</div>
|
|
<div class="asset-list">
|
|
{{range .AssetIntegrations}}
|
|
<a class="asset-row asset-link" href="/ui/assets/integrations">
|
|
<span>{{.Name}}</span>
|
|
<span class="muted small">{{if .AddressSummary}}{{.AddressSummary}}{{else}}{{.TypeLabel}}{{end}}</span>
|
|
</a>
|
|
{{else}}
|
|
<div class="empty-state compact">
|
|
<div class="empty-title">还没有第三方服务</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "overlay"}}<span>调试参数</span></h2>
|
|
</div>
|
|
</div>
|
|
<div class="asset-list">
|
|
{{range .AssetOverlays}}
|
|
<a class="asset-row asset-link" href="/ui/assets/overlays/{{.Name}}">
|
|
<span>{{.Name}}</span>
|
|
<span class="muted small">{{.OverrideTargetNum}} 个目标</span>
|
|
</a>
|
|
{{else}}
|
|
<div class="empty-state compact">
|
|
<div class="empty-title">还没有调试参数</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
{{end}}
|
|
|
|
{{if .Error}}<div class="error">{{.Error}}</div>{{end}}
|
|
{{template "asset_tabs_end" .}}
|
|
{{end}}
|