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];