From 12d08e1f7c859d18c1aa6fd3121f4dff32224b54 Mon Sep 17 00:00:00 2001
From: zjk <852185829@qq.com>
Date: 星期五, 24 七月 2026 11:35:31 +0800
Subject: [PATCH] feat(visitor,admin,home): 优化多模块功能并重构访客导出流程

---
 components/admin/AdminConfigPanel.vue |   99 ++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 84 insertions(+), 15 deletions(-)

diff --git a/components/admin/AdminConfigPanel.vue b/components/admin/AdminConfigPanel.vue
index 49e45c3..7e8fc22 100644
--- a/components/admin/AdminConfigPanel.vue
+++ b/components/admin/AdminConfigPanel.vue
@@ -57,9 +57,9 @@
             <image :src="updateHintIcon" class="inline-icon" mode="aspectFit"></image>
             <text class="update-text">检测到新版本 {{ latestVersion }} 可用</text>
           </view>
-          <view class="update-btn">
+          <view class="update-btn" @click="handleVersionUpdate">
             <image :src="updateBtnIcon" class="banner-btn-icon" mode="aspectFit"></image>
-            <text class="update-btn-text">立即更新</text>
+            <text class="update-btn-text">{{ isUpdatingVersion ? '下载中...' : '立即更新' }}</text>
           </view>
         </view>
         <view class="update-banner" v-else>
@@ -191,6 +191,7 @@
 import { getLatestVersion } from '../../api/visitorRecord';
 import { clearRequestServerConfig, getRequestServerConfig, setRequestServerConfig } from '../../utils/request';
 import { syncAllPendingRecords } from '../../utils/syncEngine';
+import { downloadRemoteFileToLocal } from '../../utils/fs';
 
 const VISITOR_MACHINE_IP_KEY = 'visitor_machine_ip';
 const visitorIp = ref('');
@@ -200,11 +201,17 @@
 const showLogoutHoldDialog = ref(false);
 const isLoggingOut = ref(false);
 const isManualSyncing = ref(false);
+const isUpdatingVersion = ref(false);
 const logoutHoldTimer = ref(null);
 
 const currentVersion = ref('v1.0.0');
 const latestVersion = ref('');
 const hasNewVersion = ref(false);
+const latestVersionInfo = ref(null);
+
+const normalizeVersionNumber = (version = '') => {
+  return String(version || '').trim().replace(/^[vV]/, '');
+};
 
 const normalizeIpValue = (value = '') => {
   return String(value).trim().replace(/^https?:\/\//, '');
@@ -356,6 +363,72 @@
     title: '保存成功',
     icon: 'success',
   });
+};
+
+const handleVersionUpdate = async () => {
+  if (isUpdatingVersion.value) {
+    return;
+  }
+
+  const packageUrl = latestVersionInfo.value?.packageUrl || '';
+  const packageName = latestVersionInfo.value?.packageName || 'visitor-update.apk';
+
+  if (!hasNewVersion.value || !packageUrl) {
+    uni.showToast({
+      title: '未获取到更新包地址',
+      icon: 'none',
+    });
+    return;
+  }
+
+  // #ifndef APP-PLUS
+  uni.showToast({
+    title: '当前环境不支持安装更新包',
+    icon: 'none',
+  });
+  return;
+  // #endif
+
+  try {
+    isUpdatingVersion.value = true;
+    uni.showLoading({
+      title: '更新包下载中...',
+      mask: true,
+    });
+
+    const fileNamePrefix = String(packageName || 'visitor-update')
+      .replace(/\.[^.]+$/, '')
+      .replace(/[^a-zA-Z0-9_-]/g, '-') || 'visitor-update';
+    const localPackagePath = await downloadRemoteFileToLocal(packageUrl, {
+      directoryName: 'apk-updates',
+      fileNamePrefix,
+      fallbackExtension: 'apk',
+    });
+
+    uni.hideLoading();
+
+    plus.runtime.install(localPackagePath, {}, () => {
+      uni.showToast({
+        title: '安装包已打开,请按提示完成更新',
+        icon: 'none',
+      });
+    }, (error) => {
+      console.error('安装更新包失败:', error);
+      uni.showToast({
+        title: error?.message || '安装更新包失败',
+        icon: 'none',
+      });
+    });
+  } catch (error) {
+    console.error('下载更新包失败:', error);
+    uni.showToast({
+      title: error?.message || '下载更新包失败',
+      icon: 'none',
+    });
+  } finally {
+    uni.hideLoading();
+    isUpdatingVersion.value = false;
+  }
 };
 
 const handleManualSync = async () => {
@@ -514,24 +587,20 @@
 
 const checkLatestVersion = async () => {
   try {
-	const appWgtVersion = uni.getAppBaseInfo().appWgtVersion || '';
-	currentVersion.value = appWgtVersion;
+    const appWgtVersion = uni.getAppBaseInfo().appWgtVersion || '';
+    currentVersion.value = normalizeVersionNumber(appWgtVersion) || 'v1.0.0';
     const res = await getLatestVersion();
     if (res && res.code === 200 && res.data) {
-      // 假设后端返回的数据为版本号字符串或者包含 version 字段的对象
-      const versionStr = typeof res.data === 'object' ? (res.data.version || res.data.versionName || '') : res.data;
-      if (versionStr) {
-        latestVersion.value = versionStr;
-        // 简单比对:如果获取到的版本和当前不一致,则认为是新版本(实际业务中可换成语义化版本对比库)
-        if (latestVersion.value !== currentVersion.value) {
-          hasNewVersion.value = true;
-        } else {
-          hasNewVersion.value = false;
-        }
-      }
+      const versionData = typeof res.data === 'object' ? res.data : {};
+      const versionStr = normalizeVersionNumber(versionData.versionNo || '');
+
+      latestVersionInfo.value = versionData;
+      latestVersion.value = versionStr;
+      hasNewVersion.value = Boolean(versionStr && versionStr !== normalizeVersionNumber(currentVersion.value));
     }
   } catch (error) {
     console.error('获取最新版本失败:', error);
+    hasNewVersion.value = false;
   }
 };
 

--
Gitblit v1.7.1