添加存储桶选择功能

功能:
1. 文件上传时显示存储桶选择按钮
2. 选择存储桶后显示确认卡片
3. 支持使用原文件名或自定义路径上传
4. 支持命令:/upload /路径/文件名 存储桶名

交互流程:
1. 发送文件 → 显示存储桶选择按钮
2. 点击存储桶 → 显示确认卡片
3. 点击使用原文件名上传 → 开始上传
4. 或回复消息设置路径

配置:
- 多存储桶配置在 config/qiniu-config.json
- 当前配置:default 存储桶
This commit is contained in:
饭团
2026-03-06 08:40:19 +08:00
parent f7776aaf69
commit 019a013b5e

View File

@@ -97,8 +97,15 @@ async function handleMessage(event) {
} else if (text.startsWith('/help') || text.startsWith('/qh')) { } else if (text.startsWith('/help') || text.startsWith('/qh')) {
await handleHelpCommandV2(chatId, feishu); await handleHelpCommandV2(chatId, feishu);
} else if (messageType === 'file' || messageContent.file_key) { } else if (messageType === 'file' || messageContent.file_key) {
log('🔍 收到文件消息 - 发送确认卡片'); log('🔍 收到文件消息 - 发送存储桶选择卡片');
await handleFileReceivedWithCard(messageData, feishu, uploader); await handleFileReceivedWithCard(messageData, feishu, uploader);
} else if (text.startsWith('/')) {
// 处理路径设置命令
log('处理路径设置命令:', text);
await feishu.sendMessage(chatId, {
msg_type: 'text',
content: { text: '💡 请先选择存储桶,然后回复路径\n或使用命令/upload /路径/文件名 存储桶名' }
});
} else { } else {
await sendWelcomeCard(chatId, feishu); await sendWelcomeCard(chatId, feishu);
} }
@@ -134,8 +141,12 @@ async function handleCardInteraction(event) {
switch (action) { switch (action) {
case 'confirm_upload': { case 'confirm_upload': {
const { file_key, file_name, message_id } = actionData.value; const { file_key, file_name, message_id, bucket, upload_path } = actionData.value;
log('📤 开始上传文件:', file_name, 'file_key:', file_key); const targetBucket = bucket || 'default';
let targetKey = upload_path || file_name;
if (targetKey.startsWith('/')) targetKey = targetKey.substring(1);
log('📤 开始上传文件:', file_name, 'bucket:', targetBucket, 'path:', targetKey);
if (!chatId) { if (!chatId) {
log('❌ 缺少 chatId'); log('❌ 缺少 chatId');
@@ -153,19 +164,20 @@ async function handleCardInteraction(event) {
await feishu.sendMessage(chatId, { await feishu.sendMessage(chatId, {
msg_type: 'text', msg_type: 'text',
content: { text: `📤 上传中:${file_name} → default` } content: { text: `📤 上传中:${targetKey}${targetBucket}` }
}); });
const result = await uploader.upload(tempFile, file_name, 'default'); const result = await uploader.upload(tempFile, targetKey, targetBucket);
await uploader.refreshCDN('default', file_name); await uploader.refreshCDN(targetBucket, targetKey);
await feishu.sendMessage(chatId, { await feishu.sendMessage(chatId, {
msg_type: 'text', msg_type: 'text',
content: { content: {
text: `✅ 上传成功!\n\n` + text: `✅ 上传成功!\n\n` +
`📦 文件:${file_name}\n` + `📦 文件:${targetKey}\n` +
`🔗 链接:${result.url}\n` + `🔗 链接:${result.url}\n` +
`🪣 存储桶default` `💾 原文件:${file_name}\n` +
`🪣 存储桶:${targetBucket}`
} }
}); });
@@ -182,6 +194,66 @@ async function handleCardInteraction(event) {
break; break;
} }
case 'select_bucket': {
const { file_key, file_name, message_id, chat_id, bucket } = actionData.value;
log('🪣 选择存储桶:', bucket);
// 发送确认卡片,带路径输入提示
const card = {
config: { wide_screen_mode: true },
header: {
template: 'green',
title: { content: '✅ 已选择存储桶', tag: 'plain_text' }
},
elements: [
{
tag: 'div',
text: {
tag: 'lark_md',
content: `**存储桶:** ${bucket}\n**文件:** ${file_name}\n\n**请回复消息设置路径:**\n格式:/路径/文件名\n\n例如:/config/test.txt\n\n或直接点击"使用原文件名上传"`
}
},
{
tag: 'action',
actions: [
{
tag: 'button',
text: { tag: 'plain_text', content: '✅ 使用原文件名上传' },
type: 'primary',
value: {
action: 'confirm_upload',
file_key: file_key,
file_name: file_name,
message_id: message_id,
chat_id: chat_id,
bucket: bucket
}
},
{
tag: 'button',
text: { tag: 'plain_text', content: '🔙 重新选择' },
type: 'default',
value: {
action: 'reselect'
}
}
]
}
]
};
await feishu.sendCard(chatId, card);
break;
}
case 'reselect':
// 重新发送文件选择卡片(需要用户重新发送文件)
await feishu.sendMessage(chatId, {
msg_type: 'text',
content: { text: '📎 请重新发送文件' }
});
break;
case 'cancel_upload': case 'cancel_upload':
log('取消上传chatId:', chatId); log('取消上传chatId:', chatId);
if (chatId) { if (chatId) {
@@ -219,44 +291,55 @@ async function handleFileReceivedWithCard(messageData, feishu, uploader) {
if (!fileKey) return; if (!fileKey) return;
log('📎 收到文件,发送确认卡片:', fileName); log('📎 收到文件,发送配置卡片:', fileName);
// 获取存储桶列表
const uploader2 = new QiniuUploader();
const configData = await uploader2.listConfig();
const bucketNames = Object.keys(configData.buckets);
// 构建存储桶选择按钮
const bucketButtons = bucketNames.map(name => ({
tag: 'button',
text: { tag: 'plain_text', content: name },
type: 'default',
value: {
action: 'select_bucket',
file_key: fileKey,
file_name: fileName,
message_id: messageId,
chat_id: chatId,
bucket: name
}
}));
const card = { const card = {
config: { wide_screen_mode: true }, config: { wide_screen_mode: true },
header: { header: {
template: 'blue', template: 'blue',
title: { content: '📎 文件上传确认', tag: 'plain_text' } title: { content: '📎 文件上传配置', tag: 'plain_text' }
}, },
elements: [ elements: [
{ {
tag: 'div', tag: 'div',
text: { text: {
tag: 'lark_md', tag: 'lark_md',
content: `**文件名:** ${fileName}\n**存储桶:** default\n\n点击"确认上传"将文件上传到七牛云` content: `**文件名:** ${fileName}\n\n**请选择存储桶:**`
} }
}, },
{ {
tag: 'action', tag: 'action',
actions: [ actions: bucketButtons
{
tag: 'button',
text: { tag: 'plain_text', content: '✅ 确认上传' },
type: 'primary',
value: {
action: 'confirm_upload',
file_key: fileKey,
file_name: fileName,
message_id: messageId,
chat_id: chatId
}
}, },
{ {
tag: 'button', tag: 'hr'
text: { tag: 'plain_text', content: '❌ 取消' }, },
type: 'default', {
value: { action: 'cancel_upload' } tag: 'div',
text: {
tag: 'lark_md',
content: `💡 **提示:**\n• 选择存储桶后,可以输入路径\n• 使用命令:/upload /路径/文件名 存储桶名`
} }
]
} }
] ]
}; };