feat(detection): 添加当前登录账号检测功能

This commit is contained in:
2977094657
2025-08-19 17:10:32 +08:00
parent ce06384f0a
commit a86e8f762f
6 changed files with 488 additions and 28 deletions

View File

@@ -39,6 +39,9 @@
/* 边框颜色 */ /* 边框颜色 */
--border-color: #e7e7e7; --border-color: #e7e7e7;
--border-light: #f4f4f4; --border-light: #f4f4f4;
/* 统一消息圆角(聊天所有消息共用) */
--message-radius: 4px;
} }
body { body {
@@ -52,6 +55,31 @@
/* 微信风格组件样式 */ /* 微信风格组件样式 */
@layer components { @layer components {
/* 聊天气泡尾巴(左右),与高度 42px 居中对齐 */
.bubble-tail-l, .bubble-tail-r { position: relative; }
.bubble-tail-l::after {
content: '';
position: absolute;
left: -4px;
top: 12px; /* 36px 中线 18px减去 6px ≈ 12px */
width: 12px; height: 12px;
background: #FFFFFF;
transform: rotate(45deg);
border-radius: 2px;
}
.bubble-tail-r::after {
content: '';
position: absolute;
right: -4px;
top: 12px;
width: 12px; height: 12px;
background: #95EC69;
transform: rotate(45deg);
border-radius: 2px;
}
/* 统一的消息圆角工具类 */
.msg-radius { border-radius: var(--message-radius); }
.msg-bubble { @apply leading-normal break-words text-pretty; border-radius: var(--message-radius); }
/* 按钮样式 */ /* 按钮样式 */
.btn { .btn {
@apply px-6 py-3 rounded-full font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 transform active:scale-95; @apply px-6 py-3 rounded-full font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 transform active:scale-95;

View File

@@ -27,8 +27,23 @@ export const useApi = () => {
} }
// 微信检测API // 微信检测API
const detectWechat = async () => { const detectWechat = async (params = {}) => {
return await request('/wechat-detection') const query = new URLSearchParams()
if (params && params.data_root_path) {
query.set('data_root_path', params.data_root_path)
}
const url = '/wechat-detection' + (query.toString() ? `?${query.toString()}` : '')
return await request(url)
}
// 检测当前登录账号API
const detectCurrentAccount = async (params = {}) => {
const query = new URLSearchParams()
if (params && params.data_root_path) {
query.set('data_root_path', params.data_root_path)
}
const url = '/current-account' + (query.toString() ? `?${query.toString()}` : '')
return await request(url)
} }
// 数据库解密API // 数据库解密API
@@ -46,6 +61,7 @@ export const useApi = () => {
return { return {
detectWechat, detectWechat,
detectCurrentAccount,
decryptDatabase, decryptDatabase,
healthCheck healthCheck
} }

View File

@@ -91,7 +91,7 @@
</div> </div>
<div class="w-12 h-12 bg-[#10AEEF]/10 rounded-lg flex items-center justify-center"> <div class="w-12 h-12 bg-[#10AEEF]/10 rounded-lg flex items-center justify-center">
<svg class="w-6 h-6 text-[#10AEEF]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-6 h-6 text-[#10AEEF]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283-.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
</svg> </svg>
</div> </div>
</div> </div>
@@ -110,6 +110,7 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- 账户列表 --> <!-- 账户列表 -->
@@ -119,8 +120,9 @@
<h3 class="text-base font-semibold text-[#000000e6]">微信账户详情</h3> <h3 class="text-base font-semibold text-[#000000e6]">微信账户详情</h3>
</div> </div>
<div class="divide-y divide-[#EDEDED] max-h-64 overflow-y-auto"> <div class="divide-y divide-[#EDEDED] max-h-64 overflow-y-auto">
<div v-for="(account, index) in detectionResult.data.accounts" :key="index" <!-- 将当前登录账号放在第一位 -->
class="p-4 hover:bg-gray-50 transition-all duration-200"> <div v-for="(account, index) in sortedAccounts" :key="index"
:class="['p-4 hover:bg-gray-50 transition-all duration-200', isCurrentAccount(account.account_name) ? 'bg-[#07C160]/5' : '']">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="flex-1"> <div class="flex-1">
<div class="flex items-center"> <div class="flex items-center">
@@ -128,7 +130,17 @@
<span class="text-[#07C160] font-bold text-lg">{{ account.account_name?.charAt(0)?.toUpperCase() || 'U' }}</span> <span class="text-[#07C160] font-bold text-lg">{{ account.account_name?.charAt(0)?.toUpperCase() || 'U' }}</span>
</div> </div>
<div> <div>
<p class="text-lg font-medium text-[#000000e6]">{{ account.account_name || '未知账户' }}</p> <div class="flex items-center">
<p class="text-lg font-medium text-[#000000e6]">{{ account.account_name || '未知账户' }}</p>
<!-- 当前登录账号标识 -->
<span v-if="isCurrentAccount(account.account_name)"
class="ml-2 inline-flex items-center px-2 py-1 bg-[#07C160]/10 text-[#07C160] rounded text-xs font-medium">
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/>
</svg>
当前登录
</span>
</div>
<div class="flex items-center mt-1 space-x-4 text-sm text-[#7F7F7F]"> <div class="flex items-center mt-1 space-x-4 text-sm text-[#7F7F7F]">
<span class="flex items-center"> <span class="flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -192,14 +204,35 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted, computed } from 'vue'
import { useApi } from '~/composables/useApi' import { useApi } from '~/composables/useApi'
import { useAppStore } from '~/stores/app'
const { detectWechat } = useApi() const { detectWechat, detectCurrentAccount } = useApi()
const appStore = useAppStore()
const loading = ref(false) const loading = ref(false)
const detectionResult = ref(null) const detectionResult = ref(null)
const customPath = ref('') const customPath = ref('')
// 计算属性:将当前登录账号排在第一位
const sortedAccounts = computed(() => {
if (!detectionResult.value?.data?.accounts) return []
const accounts = [...detectionResult.value.data.accounts]
const currentAccountName = detectionResult.value.data?.current_account?.current_account
if (!currentAccountName) return accounts
// 将当前登录账号移到第一位
const sorted = accounts.sort((a, b) => {
if (a.account_name === currentAccountName) return -1
if (b.account_name === currentAccountName) return 1
return 0
})
return sorted
})
// 开始检测 // 开始检测
const startDetection = async () => { const startDetection = async () => {
loading.value = true loading.value = true
@@ -209,8 +242,28 @@ const startDetection = async () => {
if (customPath.value && customPath.value.trim()) { if (customPath.value && customPath.value.trim()) {
params.data_root_path = customPath.value.trim() params.data_root_path = customPath.value.trim()
} }
// 检测微信安装信息
const result = await detectWechat(params) const result = await detectWechat(params)
detectionResult.value = result detectionResult.value = result
// 如果检测成功,同时检测当前登录账号
if (result.status === 'success') {
try {
const currentAccountResult = await detectCurrentAccount(params)
if (currentAccountResult.status === 'success') {
// 保存当前账号信息到状态管理
appStore.setCurrentAccount(currentAccountResult.data)
// 同时更新检测结果中的当前账号信息
if (detectionResult.value.data) {
detectionResult.value.data.current_account = currentAccountResult.data
}
}
} catch (accountErr) {
console.error('检测当前登录账号失败:', accountErr)
}
}
} catch (err) { } catch (err) {
console.error('检测过程中发生错误:', err) console.error('检测过程中发生错误:', err)
detectionResult.value = { detectionResult.value = {
@@ -237,6 +290,36 @@ const goToDecrypt = (account) => {
navigateTo('/decrypt') navigateTo('/decrypt')
} }
// 判断是否为当前登录账号
const isCurrentAccount = (accountName) => {
if (!detectionResult.value?.data?.current_account) {
return false
}
return detectionResult.value.data.current_account.current_account === accountName
}
// 获取当前登录账号信息
const getCurrentAccountInfo = () => {
return detectionResult.value?.data?.current_account
}
// 格式化时间显示
const formatTime = (timeString) => {
if (!timeString) return ''
try {
const date = new Date(timeString)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
})
} catch {
return timeString
}
}
// 页面加载时自动检测 // 页面加载时自动检测
onMounted(() => { onMounted(() => {
startDetection() startDetection()

View File

@@ -9,6 +9,9 @@ export const useAppStore = defineStore('app', {
// 最近的检测结果 // 最近的检测结果
lastDetectionResult: null, lastDetectionResult: null,
// 当前登录账号信息
currentAccount: null,
// 全局加载状态 // 全局加载状态
globalLoading: false, globalLoading: false,
@@ -28,6 +31,11 @@ export const useAppStore = defineStore('app', {
this.lastDetectionResult = result this.lastDetectionResult = result
}, },
// 设置当前登录账号
setCurrentAccount(account) {
this.currentAccount = account
},
// 设置全局加载状态 // 设置全局加载状态
setGlobalLoading(loading) { setGlobalLoading(loading) {
this.globalLoading = loading this.globalLoading = loading

View File

@@ -277,9 +277,13 @@ async def detect_wechat_detailed(data_root_path: Optional[str] = None):
"""详细检测微信安装信息,包括版本、路径、消息目录等。""" """详细检测微信安装信息,包括版本、路径、消息目录等。"""
logger.info("开始执行微信检测") logger.info("开始执行微信检测")
try: try:
from .wechat_detection import detect_wechat_installation from .wechat_detection import detect_wechat_installation, detect_current_logged_in_account
info = detect_wechat_installation(data_root_path=data_root_path) info = detect_wechat_installation(data_root_path=data_root_path)
# 检测当前登录账号
current_account_info = detect_current_logged_in_account(data_root_path)
info['current_account'] = current_account_info
# 添加一些统计信息 # 添加一些统计信息
stats = { stats = {
'total_databases': len(info['databases']), 'total_databases': len(info['databases']),
@@ -306,6 +310,29 @@ async def detect_wechat_detailed(data_root_path: Optional[str] = None):
} }
@app.get("/api/current-account", summary="检测当前登录账号")
async def detect_current_account(data_root_path: Optional[str] = None):
"""检测当前登录的微信账号"""
logger.info("开始检测当前登录账号")
try:
from .wechat_detection import detect_current_logged_in_account
result = detect_current_logged_in_account(data_root_path)
logger.info(f"当前账号检测完成: {result.get('message', '无结果')}")
return {
'status': 'success',
'data': result
}
except Exception as e:
logger.error(f"当前账号检测失败: {str(e)}")
return {
'status': 'error',
'error': str(e),
'data': None
}

View File

@@ -11,6 +11,7 @@ import ctypes
from pathlib import Path from pathlib import Path
from typing import List, Dict, Any, Union from typing import List, Dict, Any, Union
from ctypes import wintypes from ctypes import wintypes
from datetime import datetime
@@ -421,6 +422,135 @@ def detect_wechat_accounts_from_backup(backup_base_path: str = None) -> List[Dic
return accounts return accounts
def _resolve_login_paths_from_base(provided_path: str) -> Dict[str, str]:
"""
根据用户提供的路径推断 base_path 和 login_dir。
兼容三种传入:
- 直接传 xwechat_files 根目录
- 传 xwechat_files/all_users
- 传 xwechat_files/all_users/login
"""
base_path = provided_path
login_dir = os.path.join(provided_path, "all_users", "login")
try:
norm = os.path.normpath(provided_path)
last = os.path.basename(norm).lower()
parent = os.path.dirname(norm)
parent_last = os.path.basename(parent).lower() if parent else ""
if last == "login" and parent_last == "all_users":
# .../xwechat_files/all_users/login -> base_path 为 xwechat_files
base_path = os.path.dirname(parent)
login_dir = norm
elif last == "all_users":
# .../xwechat_files/all_users -> login_dir 追加 login
base_path = os.path.dirname(norm)
login_dir = os.path.join(norm, "login")
else:
# 认为传的是 xwechat_files 根
base_path = norm
login_dir = os.path.join(norm, "all_users", "login")
except Exception:
# 兜底:保持初始推断
pass
return {"base_path": base_path, "login_dir": login_dir}
def detect_wechat_accounts_from_login(login_base_path: str = None) -> List[Dict[str, Any]]:
"""
通过登录信息目录检测微信账号,并映射到实际数据目录。
Args:
login_base_path: 可选的微信数据根目录。
Returns:
账号信息列表(与 Backup 检测返回结构一致)
"""
accounts: List[Dict[str, Any]] = []
# 若用户提供路径,则优先按该路径推断
if login_base_path:
paths = _resolve_login_paths_from_base(login_base_path)
base_path = paths["base_path"]
login_dir = paths["login_dir"]
if not os.path.exists(login_dir):
return accounts
else:
# 自动检测:遍历候选根目录,寻找登录信息目录
base_path = None
login_dir = None
detected_dirs = auto_detect_wechat_data_dirs()
for detected_dir in detected_dirs:
try:
test_login = os.path.join(detected_dir, "all_users", "login")
if os.path.exists(test_login):
base_path = detected_dir
login_dir = test_login
break
# 也检查一层子目录
for sub in os.listdir(detected_dir):
sub_path = os.path.join(detected_dir, sub)
if not os.path.isdir(sub_path):
continue
test_login = os.path.join(sub_path, "all_users", "login")
if os.path.exists(test_login):
base_path = sub_path
login_dir = test_login
break
if base_path:
break
except (PermissionError, OSError):
continue
if not base_path or not login_dir:
return accounts
# 枚举 login 目录下的子项,每个子项代表一个账号标识(可能是文件或文件夹)
try:
for item in os.listdir(login_dir):
account_name = item
account_login_item_path = os.path.join(login_dir, item)
# 无论是文件还是文件夹,都视为一个账号标识
if not os.path.exists(account_login_item_path):
continue
# 在 base_path 下查找以 {account_name}_ 开头的数据目录(与 Backup 规则一致)
data_dir = None
try:
for data_item in os.listdir(base_path):
data_item_path = os.path.join(base_path, data_item)
if (
os.path.isdir(data_item_path)
and data_item.startswith(f"{account_name}_")
and data_item not in ["Backup", "all_users"]
):
data_dir = data_item_path
break
except (PermissionError, OSError):
pass
databases = collect_account_databases(data_dir, account_name) if data_dir else []
accounts.append(
{
"account_name": account_name,
"backup_dir": None,
"data_dir": data_dir,
"databases": databases,
"database_count": len(databases),
}
)
except (PermissionError, OSError):
# 无权限访问时返回已收集的账号
return accounts
return accounts
def collect_account_databases(data_dir: str, account_name: str) -> List[Dict[str, Any]]: def collect_account_databases(data_dir: str, account_name: str) -> List[Dict[str, Any]]:
""" """
收集指定账号数据目录下的所有数据库文件 收集指定账号数据目录下的所有数据库文件
@@ -474,7 +604,7 @@ def collect_account_databases(data_dir: str, account_name: str) -> List[Dict[str
return databases return databases
def detect_wechat_installation() -> Dict[str, Any]: def detect_wechat_installation(data_root_path: str | None = None) -> Dict[str, Any]:
""" """
检测微信安装情况 - 改进的多账户检测逻辑 检测微信安装情况 - 改进的多账户检测逻辑
""" """
@@ -528,47 +658,92 @@ def detect_wechat_installation() -> Dict[str, Any]:
if not result["is_running"]: if not result["is_running"]:
result["detection_methods"].append("未检测到微信进程") result["detection_methods"].append("未检测到微信进程")
# 2. 使用新的账号检测逻辑 # 2. 使用新的账号检测逻辑:同时支持 Backup 与登录信息目录,并合并结果
result["detection_methods"].append("多账户检测") result["detection_methods"].append("多账户检测(多来源合并)")
try: try:
# 检测指定路径下的微信账号 # 支持前端兜底路径:若提供 data_root_path则两种方式都以该路径为基准
accounts = detect_wechat_accounts_from_backup() accounts_from_backup = detect_wechat_accounts_from_backup(
backup_base_path=data_root_path
)
accounts_from_login = detect_wechat_accounts_from_login(
login_base_path=data_root_path
)
# 合并账号:按 account_name 去重,优先保留信息更完整者
account_map: Dict[str, Dict[str, Any]] = {}
def _merge_account(acc: Dict[str, Any]):
name = acc.get("account_name")
if not name:
return
if name not in account_map:
account_map[name] = {
"account_name": name,
"backup_dir": acc.get("backup_dir"),
"data_dir": acc.get("data_dir"),
"databases": list(acc.get("databases", [])),
"database_count": int(acc.get("database_count", 0)),
}
else:
existing = account_map[name]
if not existing.get("backup_dir") and acc.get("backup_dir"):
existing["backup_dir"] = acc.get("backup_dir")
if not existing.get("data_dir") and acc.get("data_dir"):
existing["data_dir"] = acc.get("data_dir")
# 合并数据库(按 path 去重)
seen_paths = {d.get("path") for d in existing.get("databases", [])}
for db in acc.get("databases", []):
if db.get("path") not in seen_paths:
existing.setdefault("databases", []).append(db)
seen_paths.add(db.get("path"))
existing["database_count"] = len(existing.get("databases", []))
for acc in accounts_from_backup:
_merge_account(acc)
for acc in accounts_from_login:
_merge_account(acc)
accounts = list(account_map.values())
result["accounts"] = accounts result["accounts"] = accounts
result["total_accounts"] = len(accounts) result["total_accounts"] = len(accounts)
# 统计总数据库数量 # 统计总数据库数量
total_db_count = sum(account["database_count"] for account in accounts) total_db_count = sum(account.get("database_count", 0) for account in accounts)
result["total_databases"] = total_db_count result["total_databases"] = total_db_count
if accounts: if accounts:
result["detection_methods"].append(f"在指定路径检测到 {len(accounts)} 个微信账户") result["detection_methods"].append(
f"检测到 {len(accounts)} 个微信账户(已合并两种来源)"
)
result["detection_methods"].append(f"总计 {total_db_count} 个数据库文件") result["detection_methods"].append(f"总计 {total_db_count} 个数据库文件")
# 为每个账户添加详细信息 # 为每个账户添加详细信息
for account in accounts: for account in accounts:
account_name = account["account_name"] account_name = account.get("account_name")
db_count = account["database_count"] db_count = account.get("database_count", 0)
data_dir_status = "已找到" if account["data_dir"] else "未找到" data_dir_status = "已找到" if account.get("data_dir") else "未找到"
result["detection_methods"].append(f"账户 {account_name}: {db_count} 个数据库, 数据目录{data_dir_status}") result["detection_methods"].append(
f"账户 {account_name}: {db_count} 个数据库, 数据目录{data_dir_status}"
)
else: else:
result["detection_methods"].append("在指定路径检测到微信账户") result["detection_methods"].append("未检测到微信账户")
# 填充向后兼容性字段 # 填充向后兼容性字段
for account in accounts: for account in accounts:
if account["data_dir"]: if account.get("data_dir"):
result["wechat_data_dirs"].append(account["data_dir"]) result["wechat_data_dirs"].append(account["data_dir"])
result["message_dirs"].append(account["data_dir"]) result["message_dirs"].append(account["data_dir"])
result["user_accounts"].append(account["account_name"]) result["user_accounts"].append(account.get("account_name"))
# 添加数据库到兼容性列表 # 添加数据库到兼容性列表
for db in account["databases"]: for db in account.get("databases", []):
result["databases"].append({ result["databases"].append({
"path": db["path"], "path": db["path"],
"name": db["name"], "name": db["name"],
"type": db["type"], "type": db["type"],
"size": db["size"], "size": db["size"],
"user": account["account_name"], "user": account.get("account_name"),
"user_dir": account["data_dir"] "user_dir": account.get("data_dir"),
}) })
except Exception as e: except Exception as e:
@@ -624,6 +799,129 @@ def detect_wechat_installation() -> Dict[str, Any]:
return result return result
def detect_current_logged_in_account(base_path: str = None) -> Dict[str, Any]:
"""
通过key_info.db文件时间检测当前登录的微信账号
Args:
base_path: 微信数据根目录如果为None则自动检测
Returns:
当前登录账号信息
"""
current_account = None
latest_time = None
# 添加调试信息
print(f"[DEBUG] 开始检测当前登录账号提供的base_path: {base_path}")
# 如果没有指定路径,尝试自动检测
if base_path is None:
detected_dirs = auto_detect_wechat_data_dirs()
print(f"[DEBUG] 自动检测到的目录: {detected_dirs}")
if not detected_dirs:
return {
"current_account": None,
"latest_time": None,
"message": "未检测到微信数据目录"
}
base_path = detected_dirs[0]
print(f"[DEBUG] 使用的base_path: {base_path}")
# 查找登录信息目录 - 尝试多个可能的路径
possible_login_paths = [
os.path.join(base_path, "all_users", "login"), # 标准路径
os.path.join(base_path, "login"), # 备选路径1
]
# 也尝试在子目录中查找
try:
for item in os.listdir(base_path):
item_path = os.path.join(base_path, item)
if os.path.isdir(item_path):
possible_login_paths.extend([
os.path.join(item_path, "all_users", "login"), # 子目录中的标准路径
os.path.join(item_path, "login"), # 子目录中的备选路径
])
except (PermissionError, OSError):
pass
login_dir = None
for path in possible_login_paths:
print(f"[DEBUG] 检查路径: {path}")
if os.path.exists(path):
login_dir = path
print(f"[DEBUG] 找到登录目录: {login_dir}")
break
if not login_dir:
return {
"current_account": None,
"latest_time": None,
"message": f"未找到登录信息目录,尝试的路径: {possible_login_paths}"
}
try:
# 遍历登录目录下的所有账号文件夹
items = os.listdir(login_dir)
print(f"[DEBUG] 登录目录内容: {items}")
for item in items:
item_path = os.path.join(login_dir, item)
print(f"[DEBUG] 检查项目: {item}, 路径: {item_path}, 是否为目录: {os.path.isdir(item_path)}")
if not os.path.isdir(item_path):
continue
# 检查key_info.db文件
key_info_path = os.path.join(item_path, "key_info.db")
print(f"[DEBUG] 检查key_info.db文件: {key_info_path}, 是否存在: {os.path.exists(key_info_path)}")
if not os.path.exists(key_info_path):
continue
# 获取文件修改时间
try:
file_time = os.path.getmtime(key_info_path)
file_datetime = datetime.fromtimestamp(file_time)
print(f"[DEBUG] 找到key_info.db文件: {key_info_path}, 修改时间: {file_datetime}")
# 更新最新登录的账号
if latest_time is None or file_time > latest_time:
latest_time = file_time
current_account = item
print(f"[DEBUG] 更新最新登录账号: {current_account}, 时间: {file_datetime}")
except OSError as e:
print(f"[DEBUG] 无法获取文件时间: {key_info_path}, 错误: {e}")
continue
except (PermissionError, OSError) as e:
print(f"[DEBUG] 无法访问登录目录: {login_dir}, 错误: {e}")
return {
"current_account": None,
"latest_time": None,
"message": f"无法访问登录目录: {e}"
}
if current_account:
print(f"[DEBUG] 最终结果: 当前登录账号 {current_account}, 时间 {latest_time}")
return {
"current_account": current_account,
"latest_time": latest_time,
"latest_time_formatted": datetime.fromtimestamp(latest_time).isoformat() if latest_time else None,
"message": f"检测到当前登录账号: {current_account}"
}
else:
print(f"[DEBUG] 最终结果: 未检测到当前登录账号")
return {
"current_account": None,
"latest_time": None,
"message": "未检测到当前登录账号"
}
def get_wechat_info() -> Dict[str, Any]: def get_wechat_info() -> Dict[str, Any]:
"""获取微信安装和数据库信息 """获取微信安装和数据库信息