diff --git a/data/tsp_assistant.db b/data/tsp_assistant.db index ebaa332..2df7fb7 100644 Binary files a/data/tsp_assistant.db and b/data/tsp_assistant.db differ diff --git a/src/integrations/feishu_longconn_service.py b/src/integrations/feishu_longconn_service.py index 652cda9..06e38b3 100644 --- a/src/integrations/feishu_longconn_service.py +++ b/src/integrations/feishu_longconn_service.py @@ -150,6 +150,9 @@ class FeishuLongConnService: for session in active_sessions: if session.get('user_id') == session_user_id: session_id = session.get('session_id') + # 更新会话的 tenant_id(群可能重新绑定了租户) + if session_id in chat_manager.active_sessions: + chat_manager.active_sessions[session_id]['tenant_id'] = tenant_id logger.info(f"✅ 找到已有会话: {session_id}") break diff --git a/src/web/blueprints/feishu_bot.py b/src/web/blueprints/feishu_bot.py index ad9d993..3e721f9 100644 --- a/src/web/blueprints/feishu_bot.py +++ b/src/web/blueprints/feishu_bot.py @@ -117,6 +117,9 @@ def _process_message_in_background(app, event_data: dict): for session in active_sessions: if session.get('user_id') == user_id: session_id = session.get('session_id') + # 更新会话的 tenant_id(群可能重新绑定了租户) + if session_id in chat_manager.active_sessions: + chat_manager.active_sessions[session_id]['tenant_id'] = tenant_id logger.info(f"[Feishu Bot] 找到已有会话: {session_id}") break diff --git a/src/web/static/js/modules/tenants.js b/src/web/static/js/modules/tenants.js index 1b32f8f..095e5b4 100644 --- a/src/web/static/js/modules/tenants.js +++ b/src/web/static/js/modules/tenants.js @@ -15,9 +15,7 @@ Object.assign(TSPDashboard.prototype, { } container.innerHTML = tenants.map(t => { - const feishuCfg = t.config?.feishu || {}; - const groupCount = (feishuCfg.chat_groups || []).length; - const hasFeishu = feishuCfg.app_id || groupCount > 0; + const chatGroups = t.config?.feishu?.chat_groups || []; return `
@@ -26,10 +24,10 @@ Object.assign(TSPDashboard.prototype, { (${t.tenant_id}) ${t.description ? `
${t.description}` : ''} ${!t.is_active ? '已禁用' : ''} - ${hasFeishu ? `飞书${groupCount > 0 ? ` (${groupCount}群)` : ''}` : ''} + ${chatGroups.length > 0 ? `${chatGroups.length} 个飞书群` : '未绑定飞书群'}
- ${t.tenant_id !== 'default' ? ` @@ -54,33 +52,30 @@ Object.assign(TSPDashboard.prototype, { document.getElementById('tenant-id-group').style.display = ''; document.getElementById('tenant-name-input').value = ''; document.getElementById('tenant-desc-input').value = ''; - document.getElementById('tenant-feishu-appid').value = ''; - document.getElementById('tenant-feishu-appsecret').value = ''; document.getElementById('tenant-feishu-chatgroups').value = ''; new bootstrap.Modal(document.getElementById('tenantModal')).show(); }, - async showEditTenantModal(tenantId, name, description) { + async showEditTenantModal(tenantId) { document.getElementById('tenantModalTitle').textContent = '编辑租户'; document.getElementById('tenant-edit-id').value = tenantId; document.getElementById('tenant-id-input').value = tenantId; document.getElementById('tenant-id-input').disabled = true; - document.getElementById('tenant-name-input').value = name; - document.getElementById('tenant-desc-input').value = description; + document.getElementById('tenant-id-group').style.display = 'none'; - // 加载租户的飞书配置 + // 加载租户完整数据 try { const resp = await fetch('/api/tenants'); const tenants = await resp.json(); const tenant = tenants.find(t => t.tenant_id === tenantId); - const feishuCfg = tenant?.config?.feishu || {}; - document.getElementById('tenant-feishu-appid').value = feishuCfg.app_id || ''; - document.getElementById('tenant-feishu-appsecret').value = feishuCfg.app_secret || ''; - document.getElementById('tenant-feishu-chatgroups').value = (feishuCfg.chat_groups || []).join('\n'); + if (tenant) { + document.getElementById('tenant-name-input').value = tenant.name || ''; + document.getElementById('tenant-desc-input').value = tenant.description || ''; + const chatGroups = tenant.config?.feishu?.chat_groups || []; + document.getElementById('tenant-feishu-chatgroups').value = chatGroups.join('\n'); + } } catch (e) { - document.getElementById('tenant-feishu-appid').value = ''; - document.getElementById('tenant-feishu-appsecret').value = ''; - document.getElementById('tenant-feishu-chatgroups').value = ''; + console.warn('加载租户数据失败:', e); } new bootstrap.Modal(document.getElementById('tenantModal')).show(); @@ -92,24 +87,32 @@ Object.assign(TSPDashboard.prototype, { const name = document.getElementById('tenant-name-input').value.trim(); const description = document.getElementById('tenant-desc-input').value.trim(); - // 飞书配置 - const feishuAppId = document.getElementById('tenant-feishu-appid').value.trim(); - const feishuAppSecret = document.getElementById('tenant-feishu-appsecret').value.trim(); + // 飞书群绑定 const chatGroupsText = document.getElementById('tenant-feishu-chatgroups').value.trim(); const chatGroups = chatGroupsText ? chatGroupsText.split('\n').map(s => s.trim()).filter(Boolean) : []; - const config = {}; - if (feishuAppId || feishuAppSecret || chatGroups.length > 0) { - config.feishu = {}; - if (feishuAppId) config.feishu.app_id = feishuAppId; - if (feishuAppSecret) config.feishu.app_secret = feishuAppSecret; - if (chatGroups.length > 0) config.feishu.chat_groups = chatGroups; + // 构建 config,保留已有的非 feishu 配置 + let existingConfig = {}; + if (editId) { + try { + const resp = await fetch('/api/tenants'); + const tenants = await resp.json(); + const tenant = tenants.find(t => t.tenant_id === editId); + existingConfig = tenant?.config || {}; + } catch (e) {} + } + const config = { ...existingConfig }; + if (chatGroups.length > 0) { + config.feishu = { ...(config.feishu || {}), chat_groups: chatGroups }; + } else { + // 清空飞书群绑定 + if (config.feishu) { + delete config.feishu.chat_groups; + if (Object.keys(config.feishu).length === 0) delete config.feishu; + } } - if (!name) { - this.showNotification('租户名称不能为空', 'error'); - return; - } + if (!name) { this.showNotification('租户名称不能为空', 'error'); return; } try { let response; @@ -120,10 +123,7 @@ Object.assign(TSPDashboard.prototype, { body: JSON.stringify({ name, description, config }) }); } else { - if (!tenantId) { - this.showNotification('租户标识不能为空', 'error'); - return; - } + if (!tenantId) { this.showNotification('租户标识不能为空', 'error'); return; } response = await fetch('/api/tenants', { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -154,6 +154,7 @@ Object.assign(TSPDashboard.prototype, { if (data.success) { this.showNotification('租户已删除', 'success'); this.loadTenantList(); + this.populateTenantSelectors(); } else { this.showNotification(data.error || '删除失败', 'error'); }