koishi-plugin-adapter-onebot-multi 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +151 -37
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -1628,6 +1628,32 @@ var StatusPanel = class {
|
|
|
1628
1628
|
this.ctx.logger.info(`重启 Bot 配置: #${id} ${config.name}`);
|
|
1629
1629
|
ctx.body = { success: true };
|
|
1630
1630
|
});
|
|
1631
|
+
router.post(`${adminPath}/api/bots/update`, authMiddleware, async (ctx) => {
|
|
1632
|
+
const data = await this.parseJsonBody(ctx);
|
|
1633
|
+
const id = Number(data.id);
|
|
1634
|
+
const existing = await this.configManager.getConfigById(id);
|
|
1635
|
+
if (!existing) {
|
|
1636
|
+
ctx.status = 404;
|
|
1637
|
+
ctx.body = { error: `配置 #${id} 不存在` };
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
const updates = {};
|
|
1641
|
+
if (data.name !== void 0) updates.name = data.name;
|
|
1642
|
+
if (data.protocol !== void 0) updates.protocol = data.protocol;
|
|
1643
|
+
if (data.endpoint !== void 0) updates.endpoint = data.endpoint;
|
|
1644
|
+
if (data.path !== void 0) updates.path = data.path;
|
|
1645
|
+
if (data.token !== void 0) updates.token = data.token;
|
|
1646
|
+
await this.configManager.updateConfigById(id, updates);
|
|
1647
|
+
this.ctx.logger.info(`更新 Bot 配置: #${id} ${existing.name}`);
|
|
1648
|
+
if (existing.enabled && existing.selfId) {
|
|
1649
|
+
await this.stopBot(existing.selfId);
|
|
1650
|
+
const newConfig = await this.configManager.getConfigById(id);
|
|
1651
|
+
if (newConfig) {
|
|
1652
|
+
await this.startBot(this.configManager.toBotConfig(newConfig));
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
ctx.body = { success: true };
|
|
1656
|
+
});
|
|
1631
1657
|
router.post(`${adminPath}/api/bots/profile`, authMiddleware, async (ctx) => {
|
|
1632
1658
|
const data = await this.parseJsonBody(ctx);
|
|
1633
1659
|
const selfId = String(data.selfId);
|
|
@@ -1640,6 +1666,10 @@ var StatusPanel = class {
|
|
|
1640
1666
|
}
|
|
1641
1667
|
try {
|
|
1642
1668
|
await bot.internal.setQqProfile(nickname, "", "", "", "");
|
|
1669
|
+
const loginInfo = await bot.internal.getLoginInfo();
|
|
1670
|
+
if (loginInfo?.nickname) {
|
|
1671
|
+
bot.user.name = loginInfo.nickname;
|
|
1672
|
+
}
|
|
1643
1673
|
this.ctx.logger.info(`修改 Bot ${selfId} 昵称为: ${nickname}`);
|
|
1644
1674
|
ctx.body = { success: true };
|
|
1645
1675
|
} catch (error) {
|
|
@@ -1975,30 +2005,67 @@ var StatusPanel = class {
|
|
|
1975
2005
|
</div>
|
|
1976
2006
|
</div>
|
|
1977
2007
|
|
|
1978
|
-
<!-- 编辑 Bot
|
|
1979
|
-
<div class="modal" id="
|
|
2008
|
+
<!-- 编辑 Bot 配置模态框 -->
|
|
2009
|
+
<div class="modal" id="configModal">
|
|
1980
2010
|
<div class="modal-content">
|
|
1981
|
-
<h2>编辑 Bot
|
|
1982
|
-
<form id="
|
|
1983
|
-
<input type="hidden" id="
|
|
2011
|
+
<h2>编辑 Bot 配置</h2>
|
|
2012
|
+
<form id="configForm">
|
|
2013
|
+
<input type="hidden" id="configId">
|
|
2014
|
+
<div class="form-group">
|
|
2015
|
+
<label for="configEditName">配置名称 *</label>
|
|
2016
|
+
<input type="text" id="configEditName" required placeholder="例如: 主号、小号">
|
|
2017
|
+
</div>
|
|
1984
2018
|
<div class="form-group">
|
|
1985
|
-
<label for="
|
|
1986
|
-
<
|
|
2019
|
+
<label for="configProtocol">协议</label>
|
|
2020
|
+
<select id="configProtocol" onchange="toggleConfigEndpoint()">
|
|
2021
|
+
<option value="ws-reverse">反向 WebSocket (ws-reverse)</option>
|
|
2022
|
+
<option value="ws">正向 WebSocket (ws)</option>
|
|
2023
|
+
</select>
|
|
2024
|
+
</div>
|
|
2025
|
+
<div class="form-group" id="configEndpointGroup" style="display: none;">
|
|
2026
|
+
<label for="configEndpoint">Endpoint *</label>
|
|
2027
|
+
<input type="text" id="configEndpoint" placeholder="例如: ws://127.0.0.1:6700">
|
|
2028
|
+
</div>
|
|
2029
|
+
<div class="form-group" id="configPathGroup">
|
|
2030
|
+
<label for="configPath">路径</label>
|
|
2031
|
+
<input type="text" id="configPath" placeholder="例如: /onebot">
|
|
1987
2032
|
</div>
|
|
1988
2033
|
<div class="form-group">
|
|
1989
|
-
<label for="
|
|
1990
|
-
<input type="
|
|
2034
|
+
<label for="configToken">Token(可选)</label>
|
|
2035
|
+
<input type="password" id="configToken" placeholder="访问令牌(留空不修改)">
|
|
2036
|
+
</div>
|
|
2037
|
+
<div class="modal-actions">
|
|
2038
|
+
<button type="submit" class="btn">保存</button>
|
|
2039
|
+
<button type="button" class="btn btn-secondary" onclick="hideConfigModal()">取消</button>
|
|
2040
|
+
</div>
|
|
2041
|
+
</form>
|
|
2042
|
+
</div>
|
|
2043
|
+
</div>
|
|
2044
|
+
|
|
2045
|
+
<!-- 修改 Bot 资料模态框 -->
|
|
2046
|
+
<div class="modal" id="profileModal">
|
|
2047
|
+
<div class="modal-content">
|
|
2048
|
+
<h2>修改 Bot 资料</h2>
|
|
2049
|
+
<form id="profileForm">
|
|
2050
|
+
<input type="hidden" id="profileSelfId">
|
|
2051
|
+
<div class="form-group">
|
|
2052
|
+
<label for="profileNickname">昵称</label>
|
|
2053
|
+
<input type="text" id="profileNickname" placeholder="新的QQ昵称">
|
|
2054
|
+
</div>
|
|
2055
|
+
<div class="form-group">
|
|
2056
|
+
<label for="profileAvatar">头像</label>
|
|
2057
|
+
<input type="file" id="profileAvatar" accept="image/*" style="display:none">
|
|
1991
2058
|
<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;">
|
|
1992
2059
|
<img id="avatarPreview" style="width:64px;height:64px;border:var(--nl-border);border-radius:50%;object-fit:cover;">
|
|
1993
|
-
<button type="button" class="btn btn-secondary" onclick="document.getElementById('
|
|
2060
|
+
<button type="button" class="btn btn-secondary" onclick="document.getElementById('profileAvatar').click()" style="padding:0.5rem 1rem;">选择图片</button>
|
|
1994
2061
|
<span id="avatarFileName" style="font-size:0.85rem;color:#92400e;"></span>
|
|
1995
2062
|
</div>
|
|
1996
2063
|
<p style="font-size:0.8rem;color:#92400e;margin-top:0.5rem;">支持本地图片或输入图片URL</p>
|
|
1997
|
-
<input type="text" id="
|
|
2064
|
+
<input type="text" id="profileAvatarUrl" placeholder="或输入图片URL" style="margin-top:0.5rem;">
|
|
1998
2065
|
</div>
|
|
1999
2066
|
<div class="modal-actions">
|
|
2000
2067
|
<button type="submit" class="btn">保存</button>
|
|
2001
|
-
<button type="button" class="btn btn-secondary" onclick="
|
|
2068
|
+
<button type="button" class="btn btn-secondary" onclick="hideProfileModal()">取消</button>
|
|
2002
2069
|
</div>
|
|
2003
2070
|
</form>
|
|
2004
2071
|
</div>
|
|
@@ -2190,7 +2257,7 @@ var StatusPanel = class {
|
|
|
2190
2257
|
const selfIdDisplay = bot.selfId ? ('QQ: ' + bot.selfId) : '等待连接...'
|
|
2191
2258
|
const uptime = bot.startupTime ? formatUptime(bot.startupTime) : '-'
|
|
2192
2259
|
const lastMsg = bot.lastMessageTime ? new Date(bot.lastMessageTime * 1000).toLocaleTimeString() : '-'
|
|
2193
|
-
const avatarUrl = bot.selfId ? ('http://q.qlogo.cn/headimg_dl?dst_uin=' + bot.selfId + '&spec=640') : ''
|
|
2260
|
+
const avatarUrl = bot.selfId ? ('http://q.qlogo.cn/headimg_dl?dst_uin=' + bot.selfId + '&spec=640&t=' + Date.now()) : ''
|
|
2194
2261
|
|
|
2195
2262
|
return '<div class="bot-card' + (!bot.enabled ? ' disabled' : '') + '">' +
|
|
2196
2263
|
'<div class="bot-header">' +
|
|
@@ -2212,8 +2279,9 @@ var StatusPanel = class {
|
|
|
2212
2279
|
'<div class="bot-actions">' +
|
|
2213
2280
|
'<button class="btn btn-secondary" onclick="toggleBot(' + bot.id + ')">' + (bot.enabled ? '禁用' : '启用') + '</button>' +
|
|
2214
2281
|
'<button class="btn btn-secondary" onclick="restartBot(' + bot.id + ')">重启</button>' +
|
|
2215
|
-
|
|
2216
|
-
'<button class="btn btn-
|
|
2282
|
+
'<button class="btn btn-secondary" onclick="showConfigModal(' + bot.id + ', \\'' + bot.name.replace(/'/g, "\\\\'") + '\\', \\'' + (bot.protocol || 'ws-reverse') + '\\', \\'' + (bot.endpoint || '').replace(/'/g, "\\\\'") + '\\', \\'' + (bot.path || '/onebot').replace(/'/g, "\\\\'") + '\\')">配置</button>' +
|
|
2283
|
+
(bot.status === 'online' ? '<button class="btn btn-secondary" onclick="showProfileModal(\\'' + bot.selfId + '\\', \\'' + (bot.nickname || '').replace(/'/g, "\\\\'") + '\\')">资料</button>' : '') +
|
|
2284
|
+
'<button class="btn btn-danger" onclick="deleteBot(' + bot.id + ', \\'' + bot.name.replace(/'/g, "\\\\'") + '\\')">删除</button>' +
|
|
2217
2285
|
'</div>' +
|
|
2218
2286
|
'</div>'
|
|
2219
2287
|
}).join('')
|
|
@@ -2296,29 +2364,75 @@ var StatusPanel = class {
|
|
|
2296
2364
|
}
|
|
2297
2365
|
})
|
|
2298
2366
|
|
|
2299
|
-
// 编辑 Bot
|
|
2300
|
-
|
|
2367
|
+
// 编辑 Bot 配置模态框
|
|
2368
|
+
function showConfigModal(id, name, protocol, endpoint, path) {
|
|
2369
|
+
document.getElementById('configId').value = id
|
|
2370
|
+
document.getElementById('configEditName').value = name || ''
|
|
2371
|
+
document.getElementById('configProtocol').value = protocol || 'ws-reverse'
|
|
2372
|
+
document.getElementById('configEndpoint').value = endpoint || ''
|
|
2373
|
+
document.getElementById('configPath').value = path || '/onebot'
|
|
2374
|
+
document.getElementById('configToken').value = ''
|
|
2375
|
+
toggleConfigEndpoint()
|
|
2376
|
+
document.getElementById('configModal').classList.add('active')
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
function hideConfigModal() {
|
|
2380
|
+
document.getElementById('configModal').classList.remove('active')
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
function toggleConfigEndpoint() {
|
|
2384
|
+
const protocol = document.getElementById('configProtocol').value
|
|
2385
|
+
document.getElementById('configEndpointGroup').style.display = protocol === 'ws' ? 'block' : 'none'
|
|
2386
|
+
document.getElementById('configPathGroup').style.display = protocol === 'ws-reverse' ? 'block' : 'none'
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
document.getElementById('configForm').addEventListener('submit', async (e) => {
|
|
2390
|
+
e.preventDefault()
|
|
2391
|
+
const id = document.getElementById('configId').value
|
|
2392
|
+
const data = {
|
|
2393
|
+
id: Number(id),
|
|
2394
|
+
name: document.getElementById('configEditName').value,
|
|
2395
|
+
protocol: document.getElementById('configProtocol').value,
|
|
2396
|
+
endpoint: document.getElementById('configEndpoint').value || undefined,
|
|
2397
|
+
path: document.getElementById('configPath').value || undefined,
|
|
2398
|
+
}
|
|
2399
|
+
// Token 留空不修改
|
|
2400
|
+
const token = document.getElementById('configToken').value
|
|
2401
|
+
if (token) data.token = token
|
|
2402
|
+
|
|
2403
|
+
try {
|
|
2404
|
+
await api('/bots/update', data)
|
|
2405
|
+
showToast('配置更新成功')
|
|
2406
|
+
hideConfigModal()
|
|
2407
|
+
refreshBots()
|
|
2408
|
+
} catch (e) {
|
|
2409
|
+
showToast('更新失败: ' + e.message, 'error')
|
|
2410
|
+
}
|
|
2411
|
+
})
|
|
2412
|
+
|
|
2413
|
+
// 修改 Bot 资料模态框
|
|
2414
|
+
let profileAvatarFile = null
|
|
2301
2415
|
|
|
2302
|
-
function
|
|
2303
|
-
document.getElementById('
|
|
2304
|
-
document.getElementById('
|
|
2416
|
+
function showProfileModal(selfId, nickname) {
|
|
2417
|
+
document.getElementById('profileSelfId').value = selfId
|
|
2418
|
+
document.getElementById('profileNickname').value = nickname || ''
|
|
2305
2419
|
document.getElementById('avatarPreview').src = 'http://q.qlogo.cn/headimg_dl?dst_uin=' + selfId + '&spec=640'
|
|
2306
2420
|
document.getElementById('avatarFileName').textContent = ''
|
|
2307
|
-
document.getElementById('
|
|
2308
|
-
|
|
2309
|
-
document.getElementById('
|
|
2421
|
+
document.getElementById('profileAvatarUrl').value = ''
|
|
2422
|
+
profileAvatarFile = null
|
|
2423
|
+
document.getElementById('profileModal').classList.add('active')
|
|
2310
2424
|
}
|
|
2311
2425
|
|
|
2312
|
-
function
|
|
2313
|
-
document.getElementById('
|
|
2314
|
-
|
|
2426
|
+
function hideProfileModal() {
|
|
2427
|
+
document.getElementById('profileModal').classList.remove('active')
|
|
2428
|
+
profileAvatarFile = null
|
|
2315
2429
|
}
|
|
2316
2430
|
|
|
2317
2431
|
// 头像文件选择
|
|
2318
|
-
document.getElementById('
|
|
2432
|
+
document.getElementById('profileAvatar').addEventListener('change', function(e) {
|
|
2319
2433
|
const file = e.target.files[0]
|
|
2320
2434
|
if (file) {
|
|
2321
|
-
|
|
2435
|
+
profileAvatarFile = file
|
|
2322
2436
|
document.getElementById('avatarFileName').textContent = file.name
|
|
2323
2437
|
// 预览
|
|
2324
2438
|
const reader = new FileReader()
|
|
@@ -2329,12 +2443,12 @@ var StatusPanel = class {
|
|
|
2329
2443
|
}
|
|
2330
2444
|
})
|
|
2331
2445
|
|
|
2332
|
-
//
|
|
2333
|
-
document.getElementById('
|
|
2446
|
+
// 资料表单提交
|
|
2447
|
+
document.getElementById('profileForm').addEventListener('submit', async (e) => {
|
|
2334
2448
|
e.preventDefault()
|
|
2335
|
-
const selfId = document.getElementById('
|
|
2336
|
-
const nickname = document.getElementById('
|
|
2337
|
-
const avatarUrl = document.getElementById('
|
|
2449
|
+
const selfId = document.getElementById('profileSelfId').value
|
|
2450
|
+
const nickname = document.getElementById('profileNickname').value
|
|
2451
|
+
const avatarUrl = document.getElementById('profileAvatarUrl').value
|
|
2338
2452
|
|
|
2339
2453
|
let hasChange = false
|
|
2340
2454
|
|
|
@@ -2350,7 +2464,7 @@ var StatusPanel = class {
|
|
|
2350
2464
|
}
|
|
2351
2465
|
|
|
2352
2466
|
// 修改头像
|
|
2353
|
-
if (
|
|
2467
|
+
if (profileAvatarFile) {
|
|
2354
2468
|
// 本地文件转 base64
|
|
2355
2469
|
const reader = new FileReader()
|
|
2356
2470
|
reader.onload = async function(ev) {
|
|
@@ -2362,7 +2476,7 @@ var StatusPanel = class {
|
|
|
2362
2476
|
showToast('头像修改失败: ' + e.message, 'error')
|
|
2363
2477
|
}
|
|
2364
2478
|
}
|
|
2365
|
-
reader.readAsDataURL(
|
|
2479
|
+
reader.readAsDataURL(profileAvatarFile)
|
|
2366
2480
|
hasChange = true
|
|
2367
2481
|
} else if (avatarUrl) {
|
|
2368
2482
|
// URL 方式
|
|
@@ -2376,7 +2490,7 @@ var StatusPanel = class {
|
|
|
2376
2490
|
}
|
|
2377
2491
|
|
|
2378
2492
|
if (hasChange) {
|
|
2379
|
-
|
|
2493
|
+
hideProfileModal()
|
|
2380
2494
|
setTimeout(refreshBots, 1000)
|
|
2381
2495
|
} else {
|
|
2382
2496
|
showToast('未做任何修改', 'error')
|
|
@@ -2414,7 +2528,7 @@ var StatusPanel = class {
|
|
|
2414
2528
|
return `
|
|
2415
2529
|
<div class="bot-card">
|
|
2416
2530
|
<div class="bot-header">
|
|
2417
|
-
<img class="bot-avatar" src="http://q.qlogo.cn/headimg_dl?dst_uin=${bot.selfId}&spec=640" alt="avatar">
|
|
2531
|
+
<img class="bot-avatar" src="http://q.qlogo.cn/headimg_dl?dst_uin=${bot.selfId}&spec=640&t=${Date.now()}" alt="avatar">
|
|
2418
2532
|
<div class="bot-info">
|
|
2419
2533
|
<div class="bot-id">${displayName}</div>
|
|
2420
2534
|
<a class="bot-protocol" href="tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=${bot.selfId}" target="_blank" title="点击添加好友">QQ: ${bot.selfId}</a>
|
package/package.json
CHANGED