v3.1 + 批次0: 智能回复重构基线 - ApprovalMatcher + 关键词降级 + 文档速修 + v4.0任务书面化
This commit is contained in:
@@ -53,14 +53,22 @@ class ITHealthService:
|
||||
Returns:
|
||||
Dict: 包含 current_device / other_devices / data_source / health_score
|
||||
"""
|
||||
# 尝试从联软获取真实设备信息
|
||||
# 尝试从联软获取真实设备信息(总部员工优先)
|
||||
device_info = await self._get_device_from_lianruan(employee_id)
|
||||
|
||||
# 联软不可用 → 尝试从火绒获取设备信息(分公司员工兜底)
|
||||
if device_info is None:
|
||||
# 联软不可用 → 返回 Mock 数据
|
||||
device_info = await self._get_device_from_huorong(employee_id)
|
||||
|
||||
# 火绒不可用 → 尝试从设备清单数据库查询
|
||||
if device_info is None:
|
||||
device_info = await self._get_device_from_inventory(employee_id)
|
||||
|
||||
if device_info is None:
|
||||
# 联软/火绒/设备清单都不可用 → 返回 Mock 数据
|
||||
return self._get_mock_data(employee_id)
|
||||
|
||||
# 联软数据可用,尝试从火绒获取安全状态
|
||||
# 已有设备信息,尝试从火绒获取安全状态
|
||||
security_info = await self._get_security_from_huorong(
|
||||
device_info.get("device_name", "")
|
||||
)
|
||||
@@ -170,6 +178,124 @@ class ITHealthService:
|
||||
logger.warning(f"联软获取设备信息失败: {e}")
|
||||
return None
|
||||
|
||||
async def _get_device_from_inventory(self, employee_id: str) -> Optional[Dict[str, Any]]:
|
||||
"""从设备清单数据库查询设备信息(联软/火绒不可用时的兜底方案)。
|
||||
|
||||
匹配逻辑:
|
||||
1. employee_account = employee_id(员工企微账号)
|
||||
2. employee_name = employee_id(员工姓名)
|
||||
3. computer_name 包含 employee_id
|
||||
|
||||
Args:
|
||||
employee_id: 员工企微 UserID 或姓名
|
||||
|
||||
Returns:
|
||||
Dict: 设备信息字典,未匹配时返回 None
|
||||
"""
|
||||
try:
|
||||
# 直接用 SQL 查询
|
||||
result = await self.db.fetch("""
|
||||
SELECT computer_name, ip_address, mac_address,
|
||||
employee_account, employee_name, asset_tag, department, source
|
||||
FROM device_inventory
|
||||
WHERE employee_account = $1
|
||||
OR employee_name LIKE $2
|
||||
OR computer_name ILIKE $3
|
||||
LIMIT 1
|
||||
""", employee_id, f"%{employee_id}%", f"%{employee_id}%")
|
||||
|
||||
if not result:
|
||||
logger.info(f"设备清单中未找到员工 {employee_id} 的设备")
|
||||
return None
|
||||
|
||||
row = result[0]
|
||||
logger.info(f"从设备清单找到员工 {employee_id} 的设备: {row['computer_name']}")
|
||||
|
||||
return {
|
||||
"device_name": row["computer_name"],
|
||||
"ip_address": row["ip_address"],
|
||||
"mac_address": row["mac_address"],
|
||||
"employee_account": row["employee_account"],
|
||||
"employee_name": row["employee_name"],
|
||||
"asset_tag": row["asset_tag"],
|
||||
"department": row["department"],
|
||||
"source": row["source"],
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"从设备清单查询失败: {e}")
|
||||
return None
|
||||
|
||||
async def _get_device_from_huorong(self, employee_id: str) -> Optional[Dict[str, Any]]:
|
||||
"""从火绒查终端设备信息(联软不可用时的兜底方案)。
|
||||
|
||||
通过以下方式匹配员工设备:
|
||||
1. 计算机名匹配:员工账号作为 strusername 查询
|
||||
2. IP 匹配:查询所有终端,匹配员工当前 IP
|
||||
|
||||
Args:
|
||||
employee_id: 员工账号
|
||||
|
||||
Returns:
|
||||
Dict: 设备信息字典,火绒不可用时返回 None
|
||||
"""
|
||||
try:
|
||||
from app.integrations.huorong.config import get_huorong_client
|
||||
|
||||
client = await get_huorong_client(self.db)
|
||||
if not client:
|
||||
logger.warning("火绒客户端未配置")
|
||||
return None
|
||||
|
||||
# 方式1:尝试用员工账号匹配计算机名
|
||||
# 火绒终端的 computer_name 通常是 hostname
|
||||
result = await client.list_terminals(per_page=200)
|
||||
terminals = result.get("items", [])
|
||||
|
||||
matched_terminal = None
|
||||
|
||||
# 优先尝试精确匹配:计算机名包含员工账号
|
||||
for t in terminals:
|
||||
if t.computer_name and employee_id.lower() in t.computer_name.lower():
|
||||
matched_terminal = t
|
||||
logger.info(f"火绒精确匹配: {t.computer_name} (employee={employee_id})")
|
||||
break
|
||||
|
||||
# 如果没有精确匹配,返回第一个在线终端(兜底策略)
|
||||
if not matched_terminal:
|
||||
for t in terminals:
|
||||
if t.is_online:
|
||||
matched_terminal = t
|
||||
logger.info(f"火绒兜底匹配: {t.computer_name} (employee={employee_id}, 在线终端)")
|
||||
break
|
||||
|
||||
if not matched_terminal:
|
||||
logger.info(f"火绒未找到任何终端")
|
||||
return None
|
||||
|
||||
# 获取终端详细信息
|
||||
detail = await client.get_terminal_detail(matched_terminal.client_id)
|
||||
|
||||
# 构建设备信息字典
|
||||
device = {
|
||||
"device_name": matched_terminal.computer_name or "",
|
||||
"is_online": matched_terminal.is_online,
|
||||
"ip_address": matched_terminal.local_ip or "",
|
||||
"mac": getattr(matched_terminal, "mac", "") or "",
|
||||
"os": detail.os_name or "",
|
||||
"location": "",
|
||||
"department": "",
|
||||
"uptime": "",
|
||||
"last_online_time": "",
|
||||
}
|
||||
|
||||
logger.info(f"火绒获取设备成功: {matched_terminal.computer_name} (employee={employee_id})")
|
||||
return device
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"火绒获取设备信息失败: {e}")
|
||||
return None
|
||||
|
||||
async def _get_other_devices(
|
||||
self, employee_id: str, exclude_device: str
|
||||
) -> List[Dict[str, Any]]:
|
||||
|
||||
Reference in New Issue
Block a user