diff --git a/mateclaw-server/src/main/java/vip/mate/channel/controller/ChannelController.java b/mateclaw-server/src/main/java/vip/mate/channel/controller/ChannelController.java index 6792b8c0..6eb790ce 100644 --- a/mateclaw-server/src/main/java/vip/mate/channel/controller/ChannelController.java +++ b/mateclaw-server/src/main/java/vip/mate/channel/controller/ChannelController.java @@ -69,6 +69,10 @@ public class ChannelController { @RequestBody ChannelEntity channel) { channel.setWorkspaceId(workspaceId != null ? workspaceId : 1L); ChannelEntity created = channelService.createChannel(channel); + // 创建后如果渠道已启用,自动启动(与 toggle 行为对齐) + if (Boolean.TRUE.equals(created.getEnabled())) { + channelManager.startChannel(created); + } auditEventService.record("CREATE", "CHANNEL", String.valueOf(created.getId()), created.getName(), null); return R.ok(created); } diff --git a/mateclaw-ui/src/i18n/locales/en-US.ts b/mateclaw-ui/src/i18n/locales/en-US.ts index 518e6d20..ee86db89 100644 --- a/mateclaw-ui/src/i18n/locales/en-US.ts +++ b/mateclaw-ui/src/i18n/locales/en-US.ts @@ -1307,6 +1307,7 @@ export default { weixin: { authHint: 'Click the button below to get a WeChat login QR code. After scanning with WeChat, the Bot Token will be automatically filled in. Requires iLink Bot beta access.', qrcodeButton: 'Get Login QR Code', + rescanButton: 'Re-scan (replaces current account)', qrcodeLoading: 'Fetching...', qrcodeFailed: 'Failed to get QR code. Please check your network.', qrcodeExpired: 'QR code expired. Please get a new one.', @@ -1316,6 +1317,9 @@ export default { confirmed: 'Login successful', expired: 'QR code expired', loginSuccess: 'WeChat login successful, token has been filled in', + replaceWarning: 'Re-scanning will replace the currently bound WeChat account. To bind an additional account, click the button below to add a new channel.', + addNewAccount: 'Bind New WeChat Account (Add Channel)', + newAccountName: 'WeChat', }, wecom: { authHint: 'Click the button to open a WeChat Work QR code window. After scanning, the Bot ID and Secret will be automatically filled in.', diff --git a/mateclaw-ui/src/i18n/locales/zh-CN.ts b/mateclaw-ui/src/i18n/locales/zh-CN.ts index 5f1db64e..151300ec 100644 --- a/mateclaw-ui/src/i18n/locales/zh-CN.ts +++ b/mateclaw-ui/src/i18n/locales/zh-CN.ts @@ -1317,6 +1317,7 @@ export default { weixin: { authHint: '点击下方按钮获取微信登录二维码,使用微信扫一扫确认后 Bot Token 将自动填入。需要 iLink Bot 内测资格。', qrcodeButton: '获取登录二维码', + rescanButton: '重新扫码(将替换当前账号)', qrcodeLoading: '正在获取...', qrcodeFailed: '获取二维码失败,请检查网络连接', qrcodeExpired: '二维码已过期,请重新获取', @@ -1326,6 +1327,9 @@ export default { confirmed: '登录成功', expired: '二维码已过期', loginSuccess: '微信扫码登录成功,Token 已自动填入', + replaceWarning: '重新扫码将替换当前绑定的微信账号。如需绑定额外的微信账号,请点击下方按钮添加新渠道。', + addNewAccount: '绑定新微信账号(添加新渠道)', + newAccountName: '微信', }, wecom: { authHint: '点击按钮后会弹出企业微信二维码窗口,使用企业微信扫码确认后 Bot ID 与 Secret 将自动填入。', diff --git a/mateclaw-ui/src/views/Channels.vue b/mateclaw-ui/src/views/Channels.vue index 26bb8115..89415cd0 100644 --- a/mateclaw-ui/src/views/Channels.vue +++ b/mateclaw-ui/src/views/Channels.vue @@ -171,6 +171,16 @@

{{ t('channels.weixin.authHint') }}

+ +
+

⚠️ {{ t('channels.weixin.replaceWarning') }}

+ +
@@ -771,6 +784,14 @@ async function handleWeixinQrcode() { if (s.base_url) { channelConfig.value.base_url = s.base_url } + // 新建模式且名称为默认值时,自动追加 token 后缀便于区分多账号 + if (!editingChannel.value) { + const suffix = s.bot_token.slice(-6) + const currentName = form.value.name || '' + if (!currentName || currentName === t('channels.weixin.newAccountName') || currentName === t('channels.types.weixin')) { + form.value.name = t('channels.weixin.newAccountName') + ' (' + suffix + ')' + } + } weixinQrcodeImg.value = '' weixinPollStatus.value = 'confirmed' ElMessage.success(t('channels.weixin.loginSuccess')) @@ -1018,6 +1039,21 @@ function closeModal() { editingChannel.value = null } +/** 绑定新微信账号:关闭当前编辑弹窗,以新建模式打开微信渠道 */ +function addNewWeixinChannel() { + closeModal() + // 计算已有微信渠道数量,用于自动递增命名 + const existingCount = channels.value.filter(c => c.channelType === 'weixin').length + const newName = t('channels.weixin.newAccountName') + ' ' + (existingCount + 1) + // 延迟打开新建弹窗,确保关闭动画完成 + setTimeout(() => { + openCreateModal() + form.value.channelType = 'weixin' + form.value.name = newName + onChannelTypeChange() + }, 200) +} + /** 渠道类型变更时重置配置字段 */ function onChannelTypeChange() { channelConfig.value = {} @@ -1298,6 +1334,10 @@ function getChannelIconPath(type: string) { .weixin-auth-btn:hover:not(:disabled) { background: #06AD56; transform: translateY(-1px); box-shadow: 0 2px 8px rgba(7,193,96,0.3); } .weixin-auth-btn:active:not(:disabled) { transform: translateY(0); } .weixin-auth-btn:disabled { opacity: 0.6; cursor: not-allowed; } +.weixin-multi-account-hint { margin-bottom: 12px; padding: 12px; background: #FFF7E6; border: 1px solid #FFD666; border-radius: 8px; } +.weixin-multi-account-hint .hint-warning { font-size: 13px; color: #D48806; margin: 0 0 10px 0; line-height: 1.5; } +.weixin-add-account-btn { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; padding: 8px 14px; background: var(--mc-primary); color: #fff; border: none; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s; } +.weixin-add-account-btn:hover { opacity: 0.9; transform: translateY(-1px); } .weixin-qrcode-area { display: flex; flex-direction: column; align-items: center; margin-top: 16px; padding: 16px; background: #fff; border-radius: 8px; border: 1px solid var(--mc-border); } .weixin-qrcode-img { width: 200px; height: 200px; border-radius: 4px; } .weixin-scan-hint { font-size: 13px; color: var(--mc-text-secondary); margin-top: 10px; transition: color 0.2s; }