feat: 企业微信机器人集成到后端服务,网页端可配置和重启
- BotManager: 后端启动时自动检测配置并拉起机器人(后台线程) - WeComBotService: 新增 start_async() 异步模式,支持嵌入事件循环 - settings API: 增加 bot 配置字段(enabled/bot_id/secret) - settings API: 增加 bot/status 和 bot/restart 端点 - 前端设置页: 增加企业微信机器人配置卡片(启用开关/ID/Secret) - 前端设置页: 增加机器人状态徽章和重启按钮 - Secret 脱敏显示,仅展示前4位
This commit is contained in:
@@ -1041,6 +1041,38 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 企业微信机器人 -->
|
||||
<div class="card" style="margin-bottom:16px;">
|
||||
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:16px;">
|
||||
<h3 class="section-title" style="margin-bottom:0;">企业微信机器人</h3>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span id="bot-status-badge" class="badge badge-pending">检测中</span>
|
||||
<button class="btn btn-secondary" onclick="restartBot()" id="bot-restart-btn" style="font-size:13px; padding:4px 12px;">重启机器人</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns:1fr 1fr; gap:0 24px;">
|
||||
<div class="form-group">
|
||||
<label class="form-label">启用机器人</label>
|
||||
<label style="display:flex; align-items:center; gap:8px; cursor:pointer; padding:6px 0;">
|
||||
<input type="checkbox" id="setting-wework-bot-enabled" onchange="toggleBotEnabled()" style="width:16px; height:16px;">
|
||||
<span style="font-size:13px; color:var(--text-secondary);">启用后服务启动时自动连接</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Bot ID</label>
|
||||
<input type="text" id="setting-wework-bot-id" placeholder="企业微信机器人 ID" class="input-field">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Secret</label>
|
||||
<input type="password" id="setting-wework-bot-secret" placeholder="企业微信机器人 Secret" class="input-field">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">服务地址</label>
|
||||
<input type="text" id="setting-edubrain-base-url" value="http://localhost:8765" class="input-field" style="color:var(--text-secondary); font-size:13px;" readonly>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片搜索设置 -->
|
||||
<div class="card" style="margin-bottom:16px;">
|
||||
<h3 class="section-title">图片搜索设置</h3>
|
||||
@@ -2612,12 +2644,22 @@
|
||||
if (data.judge_batch_size != null) {
|
||||
document.getElementById('setting-judge-batch-size').value = data.judge_batch_size;
|
||||
}
|
||||
// 企业微信机器人
|
||||
document.getElementById('setting-wework-bot-enabled').checked = data.wework_bot_enabled;
|
||||
document.getElementById('setting-wework-bot-id').value = data.wework_bot_id || '';
|
||||
// secret 只显示脱敏值作为 placeholder
|
||||
const secretInput = document.getElementById('setting-wework-bot-secret');
|
||||
if (data.wework_bot_secret_masked) {
|
||||
secretInput.placeholder = '当前: ' + data.wework_bot_secret_masked;
|
||||
}
|
||||
} catch (_) {
|
||||
// 静默处理
|
||||
}
|
||||
// 初始化字段显示状态
|
||||
toggleEmbedFields();
|
||||
toggleOcrFields();
|
||||
// 加载机器人状态
|
||||
loadBotStatus();
|
||||
}
|
||||
|
||||
/** 保存设置 */
|
||||
@@ -2631,6 +2673,12 @@
|
||||
if (!isNaN(judgeBatchSize) && judgeBatchSize >= 1 && judgeBatchSize <= 50) {
|
||||
body.judge_batch_size = judgeBatchSize;
|
||||
}
|
||||
// 企业微信机器人
|
||||
body.wework_bot_enabled = document.getElementById('setting-wework-bot-enabled').checked;
|
||||
const botId = document.getElementById('setting-wework-bot-id').value.trim();
|
||||
if (botId) body.wework_bot_id = botId;
|
||||
const botSecret = document.getElementById('setting-wework-bot-secret').value.trim();
|
||||
if (botSecret) body.wework_bot_secret = botSecret;
|
||||
if (Object.keys(body).length === 0) {
|
||||
showToast('没有需要保存的更改', 'info');
|
||||
return;
|
||||
@@ -2643,6 +2691,53 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** 加载机器人状态 */
|
||||
async function loadBotStatus() {
|
||||
try {
|
||||
const data = await api('GET', '/settings/bot/status');
|
||||
const badge = document.getElementById('bot-status-badge');
|
||||
if (data.running) {
|
||||
badge.className = 'badge badge-completed';
|
||||
badge.textContent = '运行中';
|
||||
} else if (data.configured) {
|
||||
badge.className = 'badge badge-failed';
|
||||
badge.textContent = '已停止';
|
||||
} else {
|
||||
badge.className = 'badge badge-pending';
|
||||
badge.textContent = '未配置';
|
||||
}
|
||||
} catch (_) {
|
||||
document.getElementById('bot-status-badge').className = 'badge badge-pending';
|
||||
document.getElementById('bot-status-badge').textContent = '未知';
|
||||
}
|
||||
}
|
||||
|
||||
/** 重启企业微信机器人 */
|
||||
async function restartBot() {
|
||||
const btn = document.getElementById('bot-restart-btn');
|
||||
btn.disabled = true;
|
||||
btn.textContent = '重启中...';
|
||||
try {
|
||||
const result = await api('POST', '/settings/bot/restart');
|
||||
if (result.success) {
|
||||
showToast(result.message, 'success');
|
||||
} else {
|
||||
showToast(result.message, 'error');
|
||||
}
|
||||
setTimeout(() => loadBotStatus(), 2000);
|
||||
} catch (err) {
|
||||
showToast('重启失败: ' + err.message, 'error');
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = '重启机器人';
|
||||
}
|
||||
}
|
||||
|
||||
/** 切换机器人启用状态 */
|
||||
function toggleBotEnabled() {
|
||||
// 仅切换 UI 状态,实际保存需要点"保存设置"
|
||||
}
|
||||
|
||||
/** 测试嵌入模型连接 */
|
||||
async function testEmbedding() {
|
||||
showToast('正在测试嵌入模型连接...', 'info');
|
||||
|
||||
Reference in New Issue
Block a user