fix: 飞书群绑定租户完善
- tenants.js 去掉已删除的 appid/appsecret 元素引用 - showEditTenantModal 改为从 API 加载完整租户数据(不再传参拼接) - saveTenant 保留已有的非 feishu 配置,只更新 chat_groups - 租户列表显示绑定群数量或'未绑定飞书群' - 飞书 bot/longconn 复用已有会话时同步更新 tenant_id(群重新绑定后立即生效) - 删除租户后同步刷新租户选择器
This commit is contained in:
Binary file not shown.
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 `
|
||||
<div class="card mb-2">
|
||||
<div class="card-body d-flex justify-content-between align-items-center py-2">
|
||||
@@ -26,10 +24,10 @@ Object.assign(TSPDashboard.prototype, {
|
||||
<span class="text-muted ms-2">(${t.tenant_id})</span>
|
||||
${t.description ? `<br><small class="text-muted">${t.description}</small>` : ''}
|
||||
${!t.is_active ? '<span class="badge bg-secondary ms-2">已禁用</span>' : ''}
|
||||
${hasFeishu ? `<span class="badge bg-info ms-2"><i class="fas fa-robot me-1"></i>飞书${groupCount > 0 ? ` (${groupCount}群)` : ''}</span>` : ''}
|
||||
${chatGroups.length > 0 ? `<span class="badge bg-info ms-2"><i class="fas fa-comments me-1"></i>${chatGroups.length} 个飞书群</span>` : '<span class="badge bg-light text-muted ms-2">未绑定飞书群</span>'}
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-outline-primary" onclick="dashboard.showEditTenantModal('${t.tenant_id}', '${(t.name || '').replace(/'/g, "\\'")}', '${(t.description || '').replace(/'/g, "\\'")}')">
|
||||
<button class="btn btn-outline-primary" onclick="dashboard.showEditTenantModal('${t.tenant_id}')">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
${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');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user