From 67fb63006906e72c58e6ce07d29c604fdaf7b31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A5=AD=E5=9B=A2?= Date: Sat, 14 Mar 2026 21:46:02 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=AF=E6=8C=81=E5=B8=A6=E7=A9=BA?= =?UTF-8?q?=E6=A0=BC=E7=9A=84=E5=90=8D=E7=A7=B0=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 /profile remove 命令,支持删除带空格的配置名称(如 'IPA 上传') - 修改 /config remove 命令,支持删除带空格的存储桶名称 - 修改 /path remove 命令,支持删除带空格的预设路径名称 - 修改 /profile add 命令,支持带空格的配置名称 - 修改 /config add 命令,支持带空格的存储桶名称 - 修改 /path add 命令,支持带空格的路径名称 参数解析逻辑: - 先提取子命令(第一个空格前的内容) - 剩余内容作为参数文本 - remove 命令:整个参数文本作为名称(支持空格) - add 命令:从后往前解析固定参数,其余合并为名称 --- src/index.js | 97 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/src/index.js b/src/index.js index d6e214f..b8b8708 100644 --- a/src/index.js +++ b/src/index.js @@ -527,8 +527,15 @@ async function doUpload(chatId, feishu, uploader, info) { async function handleConfigCommandV2(message, content, feishu, uploader) { const chatId = message.chat_id; const text = content.text || ''; - const args = text.replace(/^\/(config|qc)\s*/i, '').trim().split(/\s+/); - const subCommand = args[0]; + + // 提取命令后的剩余文本 + const remainingText = text.replace(/^\/(config|qc)\s*/i, '').trim(); + + // 先提取子命令 + const spaceIndex = remainingText.indexOf(' '); + const subCommand = spaceIndex === -1 ? remainingText : remainingText.substring(0, spaceIndex); + const paramsText = spaceIndex === -1 ? '' : remainingText.substring(spaceIndex + 1).trim(); + const args = paramsText ? paramsText.split(/\s+/) : []; const configPath = path.join(process.cwd(), 'config', 'qiniu-config.json'); @@ -540,15 +547,16 @@ async function handleConfigCommandV2(message, content, feishu, uploader) { await feishu.sendCard(chatId, createBucketsListCard(configData)); } else if (subCommand === 'add') { // /config add <名称> - if (args.length < 7) { + if (args.length < 6) { throw new Error('用法:/config add <名称> \n示例:/config add mybucket xxxxxx yyyyyy my-bucket z0 https://cdn.example.com'); } - const name = args[1]; - const accessKey = args[2]; - const secretKey = args[3]; - const bucket = args[4]; - const region = args[5]; - const domain = args[6]; + // 名称支持空格:从后往前解析,最后 5 个参数是固定的,其余是名称 + const domain = args[args.length - 1]; + const region = args[args.length - 2]; + const bucket = args[args.length - 3]; + const secretKey = args[args.length - 4]; + const accessKey = args[args.length - 5]; + const name = args.slice(0, args.length - 5).join(' '); // 验证区域代码 const validRegions = ['z0', 'z1', 'z2', 'na0', 'as0']; @@ -570,13 +578,15 @@ async function handleConfigCommandV2(message, content, feishu, uploader) { content: { text: `✅ 已添加存储桶配置:**${name}**\n存储桶:${bucket}\n区域:${region}\n域名:${domain}` } }); } else if (subCommand === 'remove' || subCommand === 'del') { - if (args.length < 2) { - throw new Error('用法:/config remove <名称>'); + if (!paramsText) { + throw new Error('用法:/config remove <名称>\n示例:/config remove my bucket'); } - const name = args[1]; + // 整个 paramsText 就是名称 (支持空格) + const name = paramsText; if (!fullConfig.buckets[name]) { - throw new Error(`存储桶 "${name}" 不存在,可用:${Object.keys(fullConfig.buckets).join(', ')}`); + const availableBuckets = Object.keys(fullConfig.buckets).join(', '); + throw new Error(`存储桶 "${name}" 不存在\n可用存储桶:${availableBuckets || '无'}`); } // 不允许删除 default 存储桶 @@ -621,8 +631,15 @@ async function handleConfigCommandV2(message, content, feishu, uploader) { async function handlePathCommandV2(message, content, feishu) { const chatId = message.chat_id; const text = content.text || ''; - const args = text.replace(/^\/path\s*/i, '').trim().split(/\s+/); - const subCommand = args[0]; + + // 提取命令后的剩余文本 + const remainingText = text.replace(/^\/path\s*/i, '').trim(); + + // 先提取子命令 + const spaceIndex = remainingText.indexOf(' '); + const subCommand = spaceIndex === -1 ? remainingText : remainingText.substring(0, spaceIndex); + const paramsText = spaceIndex === -1 ? '' : remainingText.substring(spaceIndex + 1).trim(); + const args = paramsText ? paramsText.split(/\s+/) : []; const configPath = path.join(process.cwd(), 'config', 'qiniu-config.json'); @@ -633,11 +650,12 @@ async function handlePathCommandV2(message, content, feishu) { const paths = fullConfig.uploadPaths || {}; await feishu.sendCard(chatId, createPathsListCard(paths)); } else if (subCommand === 'add') { - if (args.length < 3) { + if (args.length < 2) { throw new Error('用法:/path add <名称> <路径>\n示例:/path add backup /backup/'); } - const name = args[1]; - const pathValue = args[2]; + // 名称支持空格:第一个参数之后的所有内容作为路径 + const name = args[0]; + const pathValue = args.slice(1).join(' '); fullConfig.uploadPaths = fullConfig.uploadPaths || {}; fullConfig.uploadPaths[name] = pathValue; @@ -647,13 +665,15 @@ async function handlePathCommandV2(message, content, feishu) { content: { text: `✅ 已添加预设路径:**${name}** → ${pathValue}` } }); } else if (subCommand === 'remove' || subCommand === 'del') { - if (args.length < 2) { - throw new Error('用法:/path remove <名称>'); + if (!paramsText) { + throw new Error('用法:/path remove <名称>\n示例:/path remove my path'); } - const name = args[1]; + // 整个 paramsText 就是名称 (支持空格) + const name = paramsText; if (!fullConfig.uploadPaths || !fullConfig.uploadPaths[name]) { - throw new Error(`预设路径 "${name}" 不存在,可用:${Object.keys(fullConfig.uploadPaths || {}).join(', ') || '无'}`); + const availablePaths = Object.keys(fullConfig.uploadPaths || {}).join(', '); + throw new Error(`预设路径 "${name}" 不存在\n可用路径:${availablePaths || '无'}`); } // 检查是否有上传配置引用此路径 @@ -686,8 +706,14 @@ async function handlePathCommandV2(message, content, feishu) { async function handleProfileCommandV2(message, content, feishu) { const chatId = message.chat_id; const text = content.text || ''; - const args = text.replace(/^\/profile\s*/i, '').trim().split(/\s+/); - const subCommand = args[0]; + + // 提取命令后的剩余文本 + const remainingText = text.replace(/^\/profile\s*/i, '').trim(); + + // 先提取子命令 + const spaceIndex = remainingText.indexOf(' '); + const subCommand = spaceIndex === -1 ? remainingText : remainingText.substring(0, spaceIndex); + const paramsText = spaceIndex === -1 ? '' : remainingText.substring(spaceIndex + 1).trim(); const configPath = path.join(process.cwd(), 'config', 'qiniu-config.json'); @@ -700,12 +726,17 @@ async function handleProfileCommandV2(message, content, feishu) { await feishu.sendCard(chatId, createProfilesListCard(profiles, uploadPaths)); } else if (subCommand === 'add') { // /profile add <名称> <存储桶> [路径键名] - if (args.length < 3) { + // 支持带空格的名称,从后往前解析:最后一个是路径 (可选),倒数第二个是存储桶,其余是名称 + const addParams = paramsText.split(/\s+/).filter(p => p); + + if (addParams.length < 2) { throw new Error('用法:/profile add <名称> <存储桶> [路径键名]\n示例:/profile add IPA 上传 default ipa'); } - const name = args[1]; - const bucket = args[2]; - const pathKey = args[3] || ''; + + // 从后往前解析:最后一个参数是路径 (可选),倒数第二个是存储桶,其余是名称 + const pathKey = addParams.length >= 3 ? addParams[addParams.length - 1] : ''; + const bucket = addParams[addParams.length - (pathKey ? 2 : 1)]; + const name = addParams.slice(0, addParams.length - (pathKey ? 2 : 1)).join(' '); // 验证存储桶是否存在 if (!fullConfig.buckets[bucket]) { @@ -732,13 +763,15 @@ async function handleProfileCommandV2(message, content, feishu) { content: { text: `✅ 已添加上传配置:**${name}**\n存储桶:${bucket}\n路径:${pathDisplay}` } }); } else if (subCommand === 'remove' || subCommand === 'del') { - if (args.length < 2) { - throw new Error('用法:/profile remove <名称>'); + if (!paramsText) { + throw new Error('用法:/profile remove <名称>\n示例:/profile remove IPA 上传'); } - const name = args[1]; + // 整个 paramsText 就是名称 (支持空格) + const name = paramsText; if (!fullConfig.uploadProfiles || !fullConfig.uploadProfiles[name]) { - throw new Error(`上传配置 "${name}" 不存在`); + const availableProfiles = Object.keys(fullConfig.uploadProfiles || {}).join(', '); + throw new Error(`上传配置 "${name}" 不存在\n可用配置:${availableProfiles || '无'}`); } delete fullConfig.uploadProfiles[name];