206 lines
10 KiB
HTML
206 lines
10 KiB
HTML
{{define "plans"}}
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "profile"}}<span>场景配置列表</span></h2>
|
|
</div>
|
|
</div>
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>场景配置</th>
|
|
<th>描述</th>
|
|
<th>视频通道</th>
|
|
<th>队列</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .AssetProfiles}}
|
|
<tr>
|
|
<td><a class="mono" href="/ui/plans?name={{.Name}}">{{.Name}}</a></td>
|
|
<td>{{if .Description}}{{.Description}}{{else}}-{{end}}</td>
|
|
<td>{{len .Instances}}</td>
|
|
<td class="mono">{{if .QueueStrategy}}{{.QueueStrategy}} / {{.QueueSize}}{{else}}-{{end}}</td>
|
|
</tr>
|
|
{{else}}
|
|
<tr><td colspan="4"><div class="empty-state compact"><div class="empty-title">还没有场景配置</div></div></td></tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{{if .AssetProfileEditor}}
|
|
<form method="post" action="/ui/plans/{{.AssetProfileEditor.Name}}">
|
|
<input type="hidden" id="active-instance-input" name="active_instance" value="{{.ActiveInstanceIndex}}" />
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "profile"}}<span>场景配置</span></h2>
|
|
</div>
|
|
<div class="actions compact">
|
|
<button type="submit">{{icon "apply"}}<span>保存场景配置</span></button>
|
|
<a class="btn secondary" href="/ui/plans?name={{.AssetProfileEditor.Name}}">{{icon "close"}}<span>取消</span></a>
|
|
<button
|
|
type="button"
|
|
class="btn secondary js-export-json"
|
|
data-export-url="/ui/plans/{{.AssetProfileEditor.Name}}/export"
|
|
data-default-filename="{{.AssetProfileEditor.Name}}.json"
|
|
>{{icon "apply"}}<span>另存为 JSON</span></button>
|
|
</div>
|
|
</div>
|
|
<div class="field-grid">
|
|
<label><span>场景名称<span class="required-mark">*</span></span><input name="profile_name" value="{{.AssetProfileEditor.Name}}" /></label>
|
|
<label><span>业务名称</span><input name="business_name" value="{{.AssetProfileEditor.BusinessName}}" /></label>
|
|
<label><span>站点名</span><input name="site_name" value="{{.AssetProfileEditor.SiteName}}" /></label>
|
|
<label><span>描述</span><input name="description" value="{{.AssetProfileEditor.Description}}" /></label>
|
|
<label><span>队列大小</span><input class="mono" name="queue_size" value="{{.AssetProfileEditor.Queue.Size}}" /></label>
|
|
<label><span>队列策略</span><input name="queue_strategy" value="{{.AssetProfileEditor.Queue.Strategy}}" /></label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "device"}}<span>视频通道</span></h2>
|
|
</div>
|
|
<div class="actions compact">
|
|
<span class="pill">{{len .AssetProfileEditor.Instances}} 路</span>
|
|
<button class="btn secondary" type="submit" name="add_instance" value="1">{{icon "apply"}}<span>新增通道</span></button>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>通道</th>
|
|
<th>模板</th>
|
|
<th>输入绑定</th>
|
|
<th>服务绑定</th>
|
|
<th>输出绑定</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range $i, $inst := .AssetProfileEditor.Instances}}
|
|
{{$template := index $.AssetTemplateMap $inst.Template}}
|
|
<tr data-instance-row="{{$i}}" {{if eq $.ActiveInstanceIndex $i}}class="selected"{{else if $inst.Delete}}class="muted-row"{{end}}>
|
|
<td class="mono">{{$inst.Name}}</td>
|
|
<td>{{if $inst.Delete}}<span class="pill warn">待删除</span>{{else}}<span class="mono">{{$inst.Template}}</span>{{end}}</td>
|
|
<td>
|
|
{{if $inst.Delete}}-{{else}}
|
|
{{if $template.Slots.Inputs}}
|
|
{{range $slot := $template.Slots.Inputs}}
|
|
<div class="stacked-meta">
|
|
<span>{{$slot.Description}}</span>
|
|
<span class="mono">{{if inputBindingRef $inst.InputBindings $slot.Name}}{{inputBindingRef $inst.InputBindings $slot.Name}}{{else}}-{{end}}</span>
|
|
</div>
|
|
{{end}}
|
|
{{else}}-{{end}}
|
|
{{end}}
|
|
</td>
|
|
<td>
|
|
{{if $inst.Delete}}-{{else}}
|
|
{{if $template.Slots.Services}}
|
|
{{range $slot := $template.Slots.Services}}
|
|
<div class="stacked-meta">
|
|
<span>{{$slot.Description}}</span>
|
|
<span class="mono">{{if serviceBindingRef $inst.ServiceBindings $slot.Name}}{{serviceBindingRef $inst.ServiceBindings $slot.Name}}{{else}}-{{end}}</span>
|
|
</div>
|
|
{{end}}
|
|
{{else}}-{{end}}
|
|
{{end}}
|
|
</td>
|
|
<td>
|
|
{{if $inst.Delete}}-{{else}}
|
|
{{if $template.Slots.Outputs}}
|
|
{{range $slot := $template.Slots.Outputs}}
|
|
<div class="stacked-meta">
|
|
<span>{{$slot.Description}}</span>
|
|
<span class="mono">
|
|
{{if outputBindingValue $inst.OutputBindings $slot.Name "publish_hls_path"}}
|
|
{{outputBindingValue $inst.OutputBindings $slot.Name "publish_hls_path"}}
|
|
{{else if outputBindingValue $inst.OutputBindings $slot.Name "publish_rtsp_path"}}
|
|
{{outputBindingValue $inst.OutputBindings $slot.Name "publish_rtsp_port"}} {{outputBindingValue $inst.OutputBindings $slot.Name "publish_rtsp_path"}}
|
|
{{else}}-{{end}}
|
|
</span>
|
|
</div>
|
|
{{end}}
|
|
{{else}}-{{end}}
|
|
{{end}}
|
|
</td>
|
|
<td>
|
|
<div class="actions compact">
|
|
<button type="button" class="btn ghost js-open-instance-editor" data-instance-index="{{$i}}" data-target="profile-instance-{{$i}}">编辑</button>
|
|
<button class="btn secondary" type="submit" name="remove_instance" value="{{$i}}">删除</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{{if .AssetProfileEditor.Instances}}
|
|
<div class="card">
|
|
<div class="section-title">
|
|
<div>
|
|
<h2 class="title-with-icon">{{icon "device"}}<span>通道详情</span></h2>
|
|
<div class="form-hint">当前通道的修改会在点击“保存场景配置”后统一生效。</div>
|
|
</div>
|
|
</div>
|
|
{{range $i, $inst := .AssetProfileEditor.Instances}}
|
|
{{$template := index $.AssetTemplateMap $inst.Template}}
|
|
<section id="profile-instance-{{$i}}" class="profile-instance-editor" data-instance-editor="{{$i}}" {{if ne $.ActiveInstanceIndex $i}}hidden{{end}}>
|
|
<div class="field-grid profile-instance-grid">
|
|
<input type="hidden" name="instances[{{$i}}].template" value="{{$inst.Template}}" />
|
|
<label><span>通道名<span class="required-mark">*</span></span><input name="instances[{{$i}}].name" value="{{$inst.Name}}" /></label>
|
|
<label><span>通道显示名</span><input name="instances[{{$i}}].display_name" value="{{$inst.DisplayName}}" /></label>
|
|
<label><span>模板</span><input class="mono" value="{{$inst.Template}}" readonly /></label>
|
|
{{range $slot := $template.Slots.Inputs}}
|
|
<label>
|
|
<span>{{$slot.Description}}{{if $slot.Required}}<span class="required-mark">*</span>{{end}}</span>
|
|
<select name="instances[{{$i}}].input_bindings.{{$slot.Name}}.video_source_ref">
|
|
<option value="">未选择</option>
|
|
{{range $.AssetVideoSources}}
|
|
<option value="{{.Name}}" {{if eq (inputBindingRef $inst.InputBindings $slot.Name) .Name}}selected{{end}}>{{.Name}}{{if .Area}} - {{.Area}}{{end}}</option>
|
|
{{end}}
|
|
</select>
|
|
</label>
|
|
{{end}}
|
|
{{range $slot := $template.Slots.Services}}
|
|
<label>
|
|
<span>{{$slot.Description}}{{if $slot.Required}}<span class="required-mark">*</span>{{end}}</span>
|
|
<select name="instances[{{$i}}].service_bindings.{{$slot.Name}}.service_ref">
|
|
<option value="">未选择</option>
|
|
{{range $.AssetIntegrations}}{{if eq .Type $slot.Type}}
|
|
<option value="{{.Name}}" {{if eq (serviceBindingRef $inst.ServiceBindings $slot.Name) .Name}}selected{{end}}>{{.Name}}{{if .Description}} - {{.Description}}{{end}}</option>
|
|
{{end}}{{end}}
|
|
</select>
|
|
</label>
|
|
{{end}}
|
|
{{range $slot := $template.Slots.Outputs}}
|
|
<label><span>{{$slot.Description}} HLS 路径</span><input class="mono" name="instances[{{$i}}].output_bindings.{{$slot.Name}}.publish_hls_path" value="{{outputBindingValue $inst.OutputBindings $slot.Name "publish_hls_path"}}" /></label>
|
|
<label><span>{{$slot.Description}} RTSP 路径</span><input class="mono" name="instances[{{$i}}].output_bindings.{{$slot.Name}}.publish_rtsp_path" value="{{outputBindingValue $inst.OutputBindings $slot.Name "publish_rtsp_path"}}" /></label>
|
|
<label><span>{{$slot.Description}} RTSP 端口</span><input class="mono" name="instances[{{$i}}].output_bindings.{{$slot.Name}}.publish_rtsp_port" value="{{outputBindingValue $inst.OutputBindings $slot.Name "publish_rtsp_port"}}" /></label>
|
|
<label><span>{{$slot.Description}} 通道号</span><input name="instances[{{$i}}].output_bindings.{{$slot.Name}}.channel_no" value="{{outputBindingValue $inst.OutputBindings $slot.Name "channel_no"}}" /></label>
|
|
{{end}}
|
|
<details style="grid-column:1/-1;margin-top:0.25rem">
|
|
<summary style="cursor:pointer;font-size:0.875rem;font-weight:500;color:var(--text-secondary)">高级设置 JSON</summary>
|
|
<textarea name="instances[{{$i}}].advanced_params" rows="5" class="code-input" style="margin-top:0.5rem;width:100%;box-sizing:border-box">{{if $inst.AdvancedParams}}{{json $inst.AdvancedParams}}{{end}}</textarea>
|
|
</details>
|
|
</div>
|
|
</section>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
</form>
|
|
|
|
<details class="card collapsible">
|
|
<summary class="title-with-icon">{{icon "tech"}}<span>原始 JSON</span></summary>
|
|
<pre>{{json .AssetProfileEditor.Raw}}</pre>
|
|
</details>
|
|
{{end}}
|
|
{{if .Error}}<div class="error">{{.Error}}</div>{{end}}
|
|
{{end}}
|