Files
cmroubao/backend-api/internal/transport/webui/templates/task-detail.gohtml
T

154 lines
6.8 KiB
Go Template
Raw Normal View History

{{define "task-detail"}}
<!doctype html>
<html lang="zh-CN">
<head>
<title>{{.Task.Title}} - 采购任务管理</title>
{{template "document-head" .}}
</head>
<body>
{{template "site-header" .}}
<main id="main-content" class="page">
<a class="back-link" href="/tasks">返回任务列表</a>
{{if .Notice}}
<div class="notice" role="status" tabindex="-1" data-notice>{{.Notice}}</div>
{{end}}
<div class="title-row detail-title">
<div>
<h1>{{.Task.Title}}</h1>
<p class="subtitle">SKU:{{.Task.SKU}} · 任务编号:{{.Task.ID}}</p>
</div>
<div class="title-actions">
<span class="status {{.Task.StatusClass}}" title="状态码 {{.Task.Status}}">
{{.Task.StatusLabel}}
</span>
{{if .Task.CanCancel}}
<button class="button danger-outline" type="button" data-open-cancel>取消任务</button>
{{end}}
</div>
</div>
{{if eq .Task.Status "SUCCEEDED"}}
<section class="success-banner" aria-labelledby="success-heading">
<div aria-hidden="true" class="success-mark">✓</div>
<div>
<h2 id="success-heading">验证完成,未提交订单</h2>
<p>采购人员已完成候选确认,系统只记录验证结果。</p>
</div>
</section>
{{end}}
<div class="detail-layout">
<section class="content-section" aria-labelledby="original-heading">
<h2 id="original-heading">原始采购要求</h2>
<p class="section-note">以下内容来自管理员输入,不会被 AI 派生结果覆盖。</p>
<div class="requirement-layout">
<figure class="reference-figure">
<img class="reference-image"
src="/api/v1/assets/{{pathPart .Task.ReferenceAssetID}}/content"
alt="商品参考图">
<figcaption>已规范化的参考图片</figcaption>
</figure>
<dl class="definition-list">
<dt>商品标题</dt><dd>{{.Task.Title}}</dd>
<dt>SKU</dt><dd>{{.Task.SKU}}</dd>
<dt>描述</dt><dd>{{if .Task.Description}}{{.Task.Description}}{{else}}未填写{{end}}</dd>
<dt>数量</dt><dd>{{.Task.Quantity}}</dd>
<dt>最高总预算</dt>
<dd>{{if .Task.MaxBudget}}{{.Task.MaxBudget}} 元{{else}}未设置{{end}}</dd>
</dl>
</div>
</section>
<aside class="content-section summary-section" aria-labelledby="summary-heading">
<h2 id="summary-heading">任务摘要</h2>
<dl class="definition-list">
<dt>状态</dt><dd>{{.Task.StatusLabel}}({{.Task.Status}})</dd>
<dt>创建时间</dt>
<dd><time datetime="{{machineTime .Task.CreatedAt}}">{{displayTime .Task.CreatedAt}}</time></dd>
<dt>最后更新</dt>
<dd><time datetime="{{machineTime .Task.UpdatedAt}}">{{displayTime .Task.UpdatedAt}}</time></dd>
</dl>
</aside>
</div>
2026-07-27 12:23:05 +08:00
{{with .Task.ExecutionReport}}
<section class="content-section execution-audit" aria-labelledby="execution-audit-heading">
<h2 id="execution-audit-heading">执行审计</h2>
{{if .Outcome}}
<dl class="definition-list audit-summary">
<dt>结果类型</dt><dd>{{.Outcome.ResultType}}</dd>
<dt>人工理由</dt><dd>{{if .Outcome.OperatorReason}}{{.Outcome.OperatorReason}}{{else}}未提供{{end}}</dd>
<dt>订单提交</dt><dd>{{if .Outcome.OrderSubmitted}}是{{else}}否{{end}}</dd>
{{if .Outcome.ErrorCode}}<dt>失败信息</dt><dd>{{.Outcome.ErrorCode}}:{{.Outcome.ErrorMessage}}</dd>{{end}}
</dl>
{{end}}
{{if .Mode}}<p class="section-note">模式:{{.Mode}} · 搜索词:{{.SearchQuery}}</p>{{end}}
{{if .Provenance}}<h3>本地模型出处</h3><pre class="audit-json">{{.Provenance}}</pre>{{end}}
{{if .Candidates}}<h3>候选与评估</h3><pre class="audit-json">{{.Candidates}}</pre>{{end}}
{{if .Recommendation}}<h3>本地推荐</h3><pre class="audit-json">{{.Recommendation}}</pre>{{end}}
{{if .Evidence}}
<h3>证据截图</h3>
<div class="audit-evidence-grid">
{{range .Evidence}}<figure class="audit-evidence">
<img src="{{.ContentURL}}" alt="执行证据截图">
<figcaption>SHA-256 {{.SHA256}}({{.SizeBytes}} bytes){{if .ReceivedAfterExecutionExpiry}},授权到期后补报{{end}}</figcaption>
</figure>{{end}}
</div>
{{end}}
{{if .Events}}
<h3>执行事件</h3>
<ul class="audit-list">
{{range .Events}}<li><time datetime="{{machineTime .OccurredAt}}">{{displayTime .OccurredAt}}</time> · {{.Step}} · {{.Message}}{{if .ReceivedAfterExecutionExpiry}}(授权到期后补报){{end}}</li>{{end}}
</ul>
{{end}}
</section>
{{end}}
{{if .Task.CanCancel}}
<noscript>
<section class="noscript-cancel" aria-labelledby="noscript-cancel-heading">
{{if .Task.CancelRequiresAck}}
<h2 id="noscript-cancel-heading">请求安全停止任务</h2>
<p>设备确认安全停止前,任务仍保持当前执行状态。</p>
{{else}}
<h2 id="noscript-cancel-heading">确认取消任务</h2>
<p>取消后任务不会自动恢复。</p>
{{end}}
<form method="post" action="/tasks/{{pathPart .Task.ID}}/cancel">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<input type="hidden" name="cancel_key" value="{{.CancelKey}}">
<button class="button danger" type="submit">
{{if .Task.CancelRequiresAck}}确认请求停止{{else}}确认取消{{end}}
</button>
</form>
</section>
</noscript>
<dialog class="confirm-dialog" data-cancel-dialog aria-labelledby="cancel-title">
{{if .Task.CancelRequiresAck}}
<h2 id="cancel-title">请求安全停止任务?</h2>
<p>系统将通知采购 App 在安全检查点停止;设备确认前任务仍保持当前执行状态。</p>
{{else}}
<h2 id="cancel-title">确认取消任务?</h2>
<p>任务取消后不会自动恢复,采购执行员将不能再领取。</p>
{{end}}
<div class="dialog-actions">
<button class="button" type="button" data-keep-task>保留任务</button>
<form method="post" action="/tasks/{{pathPart .Task.ID}}/cancel" data-submit-form>
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<input type="hidden" name="cancel_key" value="{{.CancelKey}}">
<button class="button danger" type="submit" data-submit-button
data-loading-label="{{if .Task.CancelRequiresAck}}正在请求停止…{{else}}正在取消…{{end}}">
{{if .Task.CancelRequiresAck}}确认请求停止{{else}}确认取消{{end}}
</button>
</form>
</div>
</dialog>
{{end}}
</main>
</body>
</html>
{{end}}