diff --git a/install.sh b/install.sh
index 8b9c997..6e2e24d 100644
--- a/install.sh
+++ b/install.sh
@@ -29,6 +29,7 @@ cd "${SCRIPT_DIR}"
echo "拉取最新代码..."
git pull
+COMMIT_HASH=$(git rev-parse --short HEAD)
echo "编译前端..."
cd "${SCRIPT_DIR}/${FRONTEND_DIR}"
@@ -41,7 +42,7 @@ npm run build
echo "编译 Go 程序..."
cd "${SCRIPT_DIR}"
-go build -o "${BINARY_NAME}" .
+go build -ldflags "-X meshtastic_mqtt_server/internal/web.CommitVersion=${COMMIT_HASH}" -o "${BINARY_NAME}" .
echo "检查系统用户..."
if ! id -u "${SERVICE_USER}" >/dev/null 2>&1; then
diff --git a/internal/web/web.go b/internal/web/web.go
index ae67766..e830e21 100644
--- a/internal/web/web.go
+++ b/internal/web/web.go
@@ -84,6 +84,10 @@ func NewRouter(cfg configpkg.WebConfig, consoleLog bool, store *storepkg.Store,
return r
}
+const BackendVersion = "1.0.0"
+
+var CommitVersion = "dev"
+
func registerAPIRoutes(r gin.IRouter, store *storepkg.Store, mapTileCacheDir string) {
r.GET("/health", func(c *gin.Context) {
status := gin.H{"status": "ok", "database": "ok"}
@@ -96,6 +100,10 @@ func registerAPIRoutes(r gin.IRouter, store *storepkg.Store, mapTileCacheDir str
c.JSON(http.StatusOK, status)
})
+ r.GET("/version", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"version": BackendVersion, "commit": CommitVersion})
+ })
+
registerNodeInfoRoutes(r, store, "/nodeinfo")
registerNodeInfoRoutes(r, store, "/nodes")
registerMapReportRoutes(r, store)
diff --git a/meshmap_frontend/src/App.vue b/meshmap_frontend/src/App.vue
index 5d2e574..339a12c 100644
--- a/meshmap_frontend/src/App.vue
+++ b/meshmap_frontend/src/App.vue
@@ -15,6 +15,7 @@ import AdminMapSource from './components/AdminMapSource.vue'
import AdminMqttForward from './components/AdminMqttForward.vue'
import AdminSignManagement from './components/AdminSignManagement.vue'
import AdminUsers from './components/AdminUsers.vue'
+import AppFooter from './components/AppFooter.vue'
import ChatPanel from './components/ChatPanel.vue'
import ConfirmDeleteModal from './components/ConfirmDeleteModal.vue'
import HelpPage from './components/HelpPage.vue'
@@ -838,6 +839,8 @@ onBeforeUnmount(() => {
/>
+
+
{
return getJSON('/api/health')
}
+export function getBackendVersion(): Promise<{ version: string; commit: string }> {
+ return getJSON<{ version: string; commit: string }>('/api/version')
+}
+
export function getHelpContent(): Promise {
return getJSON('/api/help')
}
diff --git a/meshmap_frontend/src/components/AppFooter.vue b/meshmap_frontend/src/components/AppFooter.vue
new file mode 100644
index 0000000..52ae803
--- /dev/null
+++ b/meshmap_frontend/src/components/AppFooter.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
diff --git a/meshmap_frontend/src/style.css b/meshmap_frontend/src/style.css
index 6280c0f..37c67ae 100644
--- a/meshmap_frontend/src/style.css
+++ b/meshmap_frontend/src/style.css
@@ -75,6 +75,20 @@ a {
padding: 16px;
}
+.app-footer {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 0;
+ font-size: 12px;
+ color: var(--color-muted);
+}
+
+.app-footer-sep {
+ opacity: 0.5;
+}
+
.topbar {
display: flex;
align-items: center;
diff --git a/meshmap_frontend/src/version.ts b/meshmap_frontend/src/version.ts
new file mode 100644
index 0000000..d3b3679
--- /dev/null
+++ b/meshmap_frontend/src/version.ts
@@ -0,0 +1 @@
+export const FRONTEND_VERSION = '0.1.0'