修改菜单名称和顺序

This commit is contained in:
tian 2026-07-20 11:36:58 +08:00
parent 08ec88c45e
commit a0c6df78b6
3 changed files with 54 additions and 28 deletions

View File

@ -1001,7 +1001,7 @@ func (u *UI) pageDashboard(w http.ResponseWriter, r *http.Request) {
func (u *UI) pageConsole(w http.ResponseWriter, r *http.Request) {
u.ensureDevicesLoaded()
data := PageData{Title: "管控台"}
data := PageData{Title: "运行看板"}
data.Message = strings.TrimSpace(r.URL.Query().Get("msg"))
devices := u.registry.GetDevices()
data.Devices = devices
@ -1584,7 +1584,7 @@ func (u *UI) actionDiscoverySearch(w http.ResponseWriter, r *http.Request) {
online++
}
}
data := PageData{Title: "设备", Devices: devices, Found: found, FoundCount: len(found), DeviceCount: len(devices), OnlineCount: online, OfflineCount: len(devices) - online}
data := PageData{Title: "设备管理", Devices: devices, Found: found, FoundCount: len(found), DeviceCount: len(devices), OnlineCount: online, OfflineCount: len(devices) - online}
if err != nil {
data.Error = err.Error()
}
@ -2820,7 +2820,7 @@ func (u *UI) pageAssetTemplateGraph(w http.ResponseWriter, r *http.Request) {
data.Error = strings.TrimSpace(r.URL.Query().Get("error"))
}
if u.preview == nil {
data.Error = "配置中心服务未初始化"
data.Error = "资产管理服务未初始化"
u.render(w, r, "asset_templates", data)
return
}
@ -3135,7 +3135,7 @@ func (u *UI) actionPlanSaveWithName(w http.ResponseWriter, r *http.Request, name
)
if strings.TrimSpace(name) == "" {
data = u.assetPageData("")
data.Title = "场景管理"
data.Title = "场景模板"
_ = r.ParseForm()
editor = service.ConfigProfileEditor{
Name: strings.TrimSpace(r.FormValue("profile_name")),
@ -3162,7 +3162,7 @@ func (u *UI) actionPlanSaveWithName(w http.ResponseWriter, r *http.Request, name
}
if err := u.preview.SaveProfileEditor(editor); err != nil {
data.Error = err.Error()
data.Title = "场景管理"
data.Title = "场景模板"
data.AssetProfileEditing = true
u.render(w, r, "scene_templates", data)
return
@ -3446,7 +3446,7 @@ func (u *UI) actionDeviceAssignmentDelete(w http.ResponseWriter, r *http.Request
func (u *UI) pageAssetVideoSources(w http.ResponseWriter, r *http.Request) {
data := u.assetPageData("video-sources")
data.Title = "配置中心"
data.Title = "资产管理"
data.Message = strings.TrimSpace(r.URL.Query().Get("msg"))
if data.Error == "" {
data.Error = strings.TrimSpace(r.URL.Query().Get("error"))
@ -3501,7 +3501,7 @@ func (u *UI) actionAssetVideoSourceSave(w http.ResponseWriter, r *http.Request)
}
if err := u.preview.SaveVideoSourceAsset(asset); err != nil {
data := u.assetPageData("video-sources")
data.Title = "配置中心"
data.Title = "资产管理"
data.Error = err.Error()
data.AssetVideoSource = &asset
data.AssetVideoSource.SourceTypeLabel = serviceVideoSourceTypeLabel(asset.SourceType)
@ -3626,7 +3626,7 @@ func (u *UI) actionVideoSourceCSVImport(w http.ResponseWriter, r *http.Request)
func (u *UI) pageAssetIntegrations(w http.ResponseWriter, r *http.Request) {
data := u.assetPageData("integrations")
data.Title = "配置中心"
data.Title = "资产管理"
data.Message = strings.TrimSpace(r.URL.Query().Get("msg"))
if data.Error == "" {
data.Error = strings.TrimSpace(r.URL.Query().Get("error"))
@ -3814,7 +3814,7 @@ func (u *UI) actionAssetOverlaySave(w http.ResponseWriter, r *http.Request) {
raw := map[string]any{}
if err := json.Unmarshal([]byte(rawText), &raw); err != nil {
data := u.assetPageData("overlays")
data.Title = "配置中心"
data.Title = "资产管理"
data.Error = "调试参数 JSON 格式不正确:" + err.Error()
data.AssetOverlayEditing = true
data.AssetOverlay = &service.ConfigOverlayAsset{Name: name, Description: description, Raw: raw}
@ -3825,7 +3825,7 @@ func (u *UI) actionAssetOverlaySave(w http.ResponseWriter, r *http.Request) {
asset := service.ConfigOverlayAsset{Name: name, Description: description, Raw: raw}
if err := u.preview.SaveOverlayAsset(asset, raw); err != nil {
data := u.assetPageData("overlays")
data.Title = "配置中心"
data.Title = "资产管理"
data.Error = err.Error()
data.AssetOverlayEditing = true
data.AssetOverlay = &asset
@ -3898,11 +3898,11 @@ func (u *UI) actionAssetOverlayDelete(w http.ResponseWriter, r *http.Request) {
func (u *UI) assetPageData(tab string) PageData {
data := PageData{
Title: "配置中心",
Title: "资产管理",
AssetTab: tab,
}
if u.preview == nil {
data.Error = "配置中心服务未初始化"
data.Error = "资产管理服务未初始化"
return data
}
sources, err := u.preview.ListSources()
@ -4907,7 +4907,7 @@ func (u *UI) deviceOverviewPageData(r *http.Request, selectedIDs []string, errMs
}
selectedIDs = filterSelectedDeviceIDs(devices, selectedIDs)
data := PageData{
Title: "设备",
Title: "设备管理",
Devices: devices,
DeviceRows: rows,
DeviceCount: len(devices),

View File

@ -129,12 +129,21 @@ code,.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.side-nav .nav-group summary{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--radius);color:var(--sidebar-text);font-size:13px;font-weight:500;list-style:none;cursor:pointer;user-select:none}
.side-nav .nav-group summary:hover{background:var(--sidebar-hover)}
.side-nav .nav-group summary::-webkit-details-marker{display:none}
.side-nav .nav-group summary::after{content:"";margin-left:auto;width:7px;height:7px;border-right:1.5px solid var(--sidebar-muted);border-bottom:1.5px solid var(--sidebar-muted);transform:rotate(45deg);transition:transform .16s ease,border-color .16s ease}
.side-nav .nav-group[open] summary::after{transform:rotate(225deg);border-color:var(--sidebar-text)}
.side-nav .nav-group > summary::after{content:"";margin-left:auto;width:7px;height:7px;border-right:1.5px solid var(--sidebar-muted);border-bottom:1.5px solid var(--sidebar-muted);transform:rotate(45deg);transition:transform .16s ease,border-color .16s ease}
.side-nav .nav-group[open] > summary::after{transform:rotate(225deg);border-color:var(--sidebar-text)}
.side-nav .nav-group[open] summary{background:var(--sidebar-hover)}
.side-nav .nav-group-items{display:flex;flex-direction:column;gap:4px;margin-top:4px}
.side-nav .nav-subitem{padding:8px 10px 8px 34px;font-size:12px;font-weight:500;color:var(--sidebar-muted)}
.side-nav .nav-subitem:hover{background:var(--sidebar-hover);color:var(--sidebar-text)}
.side-nav .nav-subgroup{margin:0}
.side-nav .nav-subgroup summary{display:flex;align-items:center;gap:10px;padding:8px 10px 8px 34px;color:var(--sidebar-muted);font-size:12px;font-weight:500;list-style:none;cursor:pointer;user-select:none}
.side-nav .nav-subgroup summary:hover{background:var(--sidebar-hover);color:var(--sidebar-text)}
.side-nav .nav-subgroup summary::-webkit-details-marker{display:none}
.side-nav .nav-subgroup summary::after{content:"";margin-left:auto;width:7px;height:7px;border-right:1.5px solid var(--sidebar-muted);border-bottom:1.5px solid var(--sidebar-muted);transform:rotate(45deg);transition:transform .16s ease}
.side-nav .nav-subgroup[open] summary::after{transform:rotate(225deg)}
.side-nav .nav-subgroup[open] summary{color:var(--sidebar-text)}
.side-nav .nav-subgroup-items{display:flex;flex-direction:column;gap:2px;margin-top:2px}
.side-nav .nav-subgroup .nav-subitem{padding-left:48px}
.side-nav .nav-subicon{width:22px;height:20px;font-size:9px}
.side-nav .nav-subicon .ui-icon{width:12px;height:12px}
.nav-icon{width:28px;height:24px;border-radius:3px;border:1px solid rgba(255,255,255,.12);display:grid;place-items:center;font-size:10px;color:var(--primary)}

View File

@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{{.Title}}</title>
<link rel="stylesheet" href="/ui/assets/vendor/tabler.min.css" />
<link rel="stylesheet" href="/ui/assets/style.css?v=20260508-ia07" />
<link rel="stylesheet" href="/ui/assets/graph_editor.css?v=20260429-ia01" />
<link rel="stylesheet" href="/ui/assets/style.css?v=ia12" />
<link rel="stylesheet" href="/ui/assets/graph_editor.css?v=20260720-ia01" />
</head>
<body data-theme="blue-dark">
<div class="app-shell">
@ -19,13 +19,13 @@
</div>
</div>
<nav class="side-nav" aria-label="主导航">
<a href="/ui/dashboard"><span class="nav-icon">{{icon "overview"}}</span><span>总览</span></a>
<a href="/ui/console"><span class="nav-icon">{{icon "apply"}}</span><span>管控台</span></a>
<a href="/ui/wizard"><span class="nav-icon">{{icon "control"}}</span><span>部署向导</span></a>
<a href="/ui/dashboard"><span class="nav-icon">{{icon "overview"}}</span><span>首页</span></a>
<a href="/ui/alarms"><span class="nav-icon">{{icon "bell"}}</span><span>告警中心</span></a>
<a href="/ui/devices"><span class="nav-icon">{{icon "devices"}}</span><span>设备</span></a>
<a href="/ui/monitor"><span class="nav-icon">{{icon "devices"}}</span><span>视频监控</span></a>
<a href="/ui/monitor"><span class="nav-icon">{{icon "preview"}}</span><span>视频监控</span></a>
<a href="/ui/devices"><span class="nav-icon">{{icon "devices"}}</span><span>设备管理</span></a>
<a href="/ui/console"><span class="nav-icon">{{icon "apply"}}</span><span>运行看板</span></a>
<a href="/ui/face-gallery"><span class="nav-icon">{{icon "profile"}}</span><span>人脸库</span></a>
<a href="/ui/wizard"><span class="nav-icon">{{icon "control"}}</span><span>部署向导</span></a>
<details class="nav-group" id="system-nav-group">
<summary>
<span class="nav-icon">{{icon "system"}}</span>
@ -35,12 +35,19 @@
<a class="nav-subitem" href="/ui/system"><span class="nav-icon nav-subicon">{{icon "heartbeat"}}</span><span>系统状态</span></a>
<a class="nav-subitem" href="/ui/diagnostics"><span class="nav-icon nav-subicon">{{icon "logs"}}</span><span>日志审计</span></a>
<a class="nav-subitem" href="/ui/tasks"><span class="nav-icon nav-subicon">{{icon "task"}}</span><span>任务中心</span></a>
<a class="nav-subitem expert-only" href="/ui/scene-templates"><span class="nav-icon nav-subicon">{{icon "profile"}}</span><span>场景管理</span></a>
<a class="nav-subitem expert-only" href="/ui/recognition-units"><span class="nav-icon nav-subicon">{{icon "device"}}</span><span>检测通道</span></a>
<a class="nav-subitem expert-only" href="/ui/device-assignments"><span class="nav-icon nav-subicon">{{icon "apply"}}</span><span>通道部署</span></a>
<a class="nav-subitem expert-only" href="/ui/assets"><span class="nav-icon nav-subicon">{{icon "assets"}}</span><span>配置中心</span></a>
<details class="nav-subgroup expert-only" id="detection-config-group">
<summary>
<span class="nav-icon nav-subicon">{{icon "config"}}</span>
<span>检测配置</span>
</summary>
<div class="nav-subgroup-items">
<a class="nav-subitem" href="/ui/scene-templates"><span class="nav-icon nav-subicon">{{icon "template"}}</span><span>场景模板</span></a>
<a class="nav-subitem" href="/ui/recognition-units"><span class="nav-icon nav-subicon">{{icon "device"}}</span><span>检测通道</span></a>
<a class="nav-subitem" href="/ui/device-assignments"><span class="nav-icon nav-subicon">{{icon "apply"}}</span><span>通道部署</span></a>
</div>
</details>
<a class="nav-subitem expert-only" href="/ui/assets"><span class="nav-icon nav-subicon">{{icon "template"}}</span><span>资产管理</span></a>
<a class="nav-subitem expert-only" href="/ui/models"><span class="nav-icon nav-subicon">{{icon "assets"}}</span><span>模型管理</span></a>
<a class="nav-subitem expert-only" href="/ui/resources"><span class="nav-icon nav-subicon">{{icon "template"}}</span><span>资源管理</span></a>
</div>
</details>
</nav>
@ -341,13 +348,23 @@
path === "/ui/device-assignments" ||
path === "/ui/assets" ||
path === "/ui/models" ||
path === "/ui/resources" ||
path === "/ui/audit" ||
path === "/ui/api"
) {
systemNavGroup.open = true;
}
}
const detectionGroup = document.getElementById("detection-config-group");
if (detectionGroup) {
const path = window.location.pathname || "";
if (
path === "/ui/scene-templates" ||
path === "/ui/recognition-units" ||
path === "/ui/device-assignments"
) {
detectionGroup.open = true;
}
}
var modeKey = "safesight-mode";
function applyMode(mode, persist) {