修复转发跳收藏;修复若干小bug

This commit is contained in:
dela
2026-02-05 21:29:48 +08:00
parent 098fd57c19
commit 270369ae0a
6 changed files with 96 additions and 11 deletions

View File

@@ -72,6 +72,7 @@ toc:
|------|------|
| `/cat_add <名称> [排序]` | 创建分类 |
| `/cat_del <名称>` | 删除分类 |
| `/cat_rename <旧名称> <新名称>` | 重命名分类(自动更新所有条目) |
| `/cat_list` | 列出所有分类 |
### 管理员管理 (仅超级管理员)

View File

@@ -105,6 +105,62 @@ func (s *Storage) UpdateCategoryOrder(name string, order int) error {
})
}
func (s *Storage) RenameCategory(oldName, newName string) error {
return s.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket(bucketCategories)
// 检查旧分类是否存在
data := b.Get([]byte(oldName))
if data == nil {
return fmt.Errorf("category %q not found", oldName)
}
// 检查新名称是否已存在
if b.Get([]byte(newName)) != nil {
return fmt.Errorf("category %q already exists", newName)
}
// 解码旧分类
var cat Category
if err := decodeJSON(data, &cat); err != nil {
return err
}
// 更新名称
cat.Name = newName
newData, err := encodeJSON(cat)
if err != nil {
return err
}
// 删除旧键,写入新键
if err := b.Delete([]byte(oldName)); err != nil {
return err
}
if err := b.Put([]byte(newName), newData); err != nil {
return err
}
// 同步更新所有条目的分类名
entries := tx.Bucket(bucketEntries)
return entries.ForEach(func(k, v []byte) error {
var entry Entry
if err := decodeJSON(v, &entry); err != nil {
return err
}
if entry.Category == oldName {
entry.Category = newName
newEntryData, err := encodeJSON(entry)
if err != nil {
return err
}
return entries.Put(k, newEntryData)
}
return nil
})
})
}
func (s *Storage) CategoryExists(name string) bool {
exists := false
s.db.View(func(tx *bolt.Tx) error {

View File

@@ -51,6 +51,7 @@ func (b *Bot) setupRoutes() {
// Category management
adminOnly.Handle("/cat_add", b.handleCatAdd)
adminOnly.Handle("/cat_del", b.handleCatDel)
adminOnly.Handle("/cat_rename", b.handleCatRename)
adminOnly.Handle("/cat_list", b.handleCatList)
// Post flow
@@ -97,6 +98,7 @@ func (b *Bot) setCommands() {
{Text: "cat_list", Description: "分类列表"},
{Text: "cat_add", Description: "添加分类 <名称> [排序]"},
{Text: "cat_del", Description: "删除分类 <名称>"},
{Text: "cat_rename", Description: "重命名分类 <旧名称> <新名称>"},
{Text: "del", Description: "删除条目 <ID>"},
{Text: "edit", Description: "编辑标题 <ID> <新标题>"},
{Text: "move", Description: "移动条目 <ID> <新分类>"},

View File

@@ -42,6 +42,24 @@ func (b *Bot) handleCatDel(c tele.Context) error {
return c.Reply(fmt.Sprintf("✅ 分类 [%s] 已删除", name))
}
func (b *Bot) handleCatRename(c tele.Context) error {
args := strings.Fields(c.Message().Payload)
if len(args) < 2 {
return c.Reply("用法: /cat_rename <旧名称> <新名称>\n例如: /cat_rename iOS Apple")
}
oldName := args[0]
newName := args[1]
if err := b.storage.RenameCategory(oldName, newName); err != nil {
return c.Reply(fmt.Sprintf("❌ 重命名失败: %v", err))
}
b.toc.TriggerUpdate()
return c.Reply(fmt.Sprintf("✅ 分类 [%s] 已重命名为 [%s]", oldName, newName))
}
func (b *Bot) handleCatList(c tele.Context) error {
categories, err := b.storage.ListCategories()
if err != nil {

View File

@@ -2,6 +2,7 @@ package telegram
import (
"fmt"
"html"
"strconv"
"strings"
@@ -94,7 +95,7 @@ func (b *Bot) handleEntryList(c tele.Context) error {
var sb strings.Builder
if category != "" {
sb.WriteString(fmt.Sprintf("📋 分类 [%s] 的条目:\n\n", category))
sb.WriteString(fmt.Sprintf("📋 分类 [%s] 的条目:\n\n", html.EscapeString(category)))
} else {
sb.WriteString("📋 所有条目:\n\n")
}
@@ -103,12 +104,12 @@ func (b *Bot) handleEntryList(c tele.Context) error {
for _, e := range entries {
if category == "" && e.Category != currentCat {
currentCat = e.Category
sb.WriteString(fmt.Sprintf("\n【%s】\n", currentCat))
sb.WriteString(fmt.Sprintf("\n【%s】\n", html.EscapeString(currentCat)))
}
sb.WriteString(fmt.Sprintf("• [%s] %s\n", e.ID, e.Title))
sb.WriteString(fmt.Sprintf("• <code>%s</code> %s\n", e.ID, html.EscapeString(e.Title)))
}
return c.Reply(sb.String())
return c.Reply(sb.String(), tele.ModeHTML)
}
func (b *Bot) handleRefresh(c tele.Context) error {

View File

@@ -110,8 +110,8 @@ func (b *Bot) handleTextInput(c tele.Context) error {
return nil
}
// 检查是否为转发消息
isForwarded := msg.OriginalChat != nil || msg.OriginalSender != nil
// 检查是否为转发消息OriginalUnixtime 在隐私设置隐藏来源时仍存在)
isForwarded := msg.OriginalChat != nil || msg.OriginalSender != nil || msg.OriginalUnixtime > 0
state := b.states.Get(c.Sender().ID)
@@ -148,8 +148,8 @@ func (b *Bot) handleForwarded(c tele.Context) error {
}
msg := c.Message()
// 检查是否为转发消息(来自频道/群组或个人用户
if msg.OriginalChat == nil && msg.OriginalSender == nil {
// 检查是否为转发消息(OriginalUnixtime 在隐私设置隐藏来源时仍存在
if msg.OriginalChat == nil && msg.OriginalSender == nil && msg.OriginalUnixtime == 0 {
return c.Reply("❌ 这不是一条转发消息,请转发一条消息给我")
}
@@ -438,7 +438,7 @@ func (b *Bot) handleConfirmCallback(c tele.Context, userID int64, action string)
}
// 使用频道消息的链接
link := buildChannelLink(b.cfg.Channel.ID, channelMsg.ID)
link := b.buildChannelLink(channelMsg.ID)
entry, err := b.storage.CreateEntry(state.SelectedCat, title, link)
if err != nil {
@@ -484,8 +484,15 @@ func (b *Bot) sendAlbumCopy(to *tele.Chat, msgs []*tele.Message) (*tele.Message,
return &sentMsgs[0], nil
}
func buildChannelLink(channelID int64, msgID int) string {
chatID := channelID
func (b *Bot) buildChannelLink(msgID int) string {
// 尝试获取频道信息,检查是否为公开频道
chat, err := b.bot.ChatByID(b.cfg.Channel.ID)
if err == nil && chat.Username != "" {
return fmt.Sprintf("https://t.me/%s/%d", chat.Username, msgID)
}
// 私有频道 fallback
chatID := b.cfg.Channel.ID
if chatID < 0 {
chatID = -chatID - 1000000000000
}