feat(i18n): Enhance internationalization support and error handling messages

- Added i18n keys for various error and info messages related to task management, user handling, and storage operations.
- Updated error messages in the watch and task handling commands to use i18n for better localization.
- Refactored error handling in the database initialization and user synchronization processes to provide clearer messages.
- Improved logging messages for better clarity and consistency across the application.
- Added comprehensive documentation for AI collaboration and project structure in the repository.
This commit is contained in:
krau
2025-12-19 16:01:36 +08:00
parent bc892d9370
commit 9ed2c425be
21 changed files with 564 additions and 142 deletions

View File

@@ -1,7 +1,6 @@
package handlers
import (
"fmt"
"strings"
"time"
@@ -9,6 +8,8 @@ import (
"github.com/celestix/gotgproto/ext"
"github.com/charmbracelet/log"
"github.com/gotd/td/telegram/message/styling"
"github.com/krau/SaveAny-Bot/common/i18n"
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
"github.com/krau/SaveAny-Bot/core"
)
@@ -27,21 +28,21 @@ func handleTaskCmd(ctx *ext.Context, update *ext.Update) error {
showQueuedTasks(ctx, update)
case "cancel", "c":
if len(args) < 3 {
ctx.Reply(update, ext.ReplyTextString("用法: /tasks cancel <task_id>"), nil)
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgTasksUsageCancel)), nil)
return dispatcher.EndGroups
}
taskID := args[2]
if err := core.CancelTask(ctx, taskID); err != nil {
logger.Errorf("取消任务 %s 失败: %v", taskID, err)
ctx.Reply(update, ext.ReplyTextString("取消任务失败: "+err.Error()), nil)
logger.Errorf("Failed to cancel task %s: %v", taskID, err)
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgTasksCancelFailed, map[string]any{"Error": err.Error()})), nil)
return dispatcher.EndGroups
}
ctx.Reply(update, ext.ReplyTextStyledTextArray([]styling.StyledTextOption{
styling.Plain("已请求取消任务: "),
styling.Plain(i18n.T(i18nk.BotMsgTasksCancelRequestedPrefix)),
styling.Code(taskID),
}), nil)
default:
ctx.Reply(update, ext.ReplyTextString("用法: /tasks [running|queued|cancel <task_id>]"), nil)
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgTasksUsage)), nil)
}
return dispatcher.EndGroups
}
@@ -49,28 +50,28 @@ func handleTaskCmd(ctx *ext.Context, update *ext.Update) error {
func showRunningTasks(ctx *ext.Context, update *ext.Update) {
tasks := core.GetRunningTasks(ctx)
if len(tasks) == 0 {
ctx.Reply(update, ext.ReplyTextString("当前没有正在运行的任务"), nil)
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgTasksRunningEmpty)), nil)
return
}
opts := make([]styling.StyledTextOption, 0, 2+len(tasks)*4)
opts = append(opts,
styling.Bold("当前正在运行的任务:"),
styling.Plain(fmt.Sprintf("\n总数: %d\n", len(tasks))),
styling.Bold(i18n.T(i18nk.BotMsgTasksRunningTitle)),
styling.Plain(i18n.T(i18nk.BotMsgTasksTotalPrefix, map[string]any{"Count": len(tasks)})),
)
for _, t := range tasks {
created := t.Created.In(time.Local).Format("2006-01-02 15:04:05")
status := "运行中"
status := i18n.T(i18nk.BotMsgTasksStatusRunning)
if t.Cancelled {
status = "已请求取消"
status = i18n.T(i18nk.BotMsgTasksStatusCancelRequested)
}
opts = append(opts,
styling.Plain("\nID: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldId)),
styling.Code(t.ID),
styling.Plain("\n名称: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldTitle)),
styling.Code(t.Title),
styling.Plain("\n创建时间: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldCreated)),
styling.Code(created),
styling.Plain("\n状态: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldStatus)),
styling.Code(status),
)
}
@@ -80,32 +81,32 @@ func showRunningTasks(ctx *ext.Context, update *ext.Update) {
func showQueuedTasks(ctx *ext.Context, update *ext.Update) {
tasks := core.GetQueuedTasks(ctx)
if len(tasks) == 0 {
ctx.Reply(update, ext.ReplyTextString("当前没有排队中的任务"), nil)
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgTasksQueuedEmpty)), nil)
return
}
opts := make([]styling.StyledTextOption, 0, 2+len(tasks)*3)
opts = append(opts,
styling.Bold("当前排队中的任务:"),
styling.Plain(fmt.Sprintf("\n总数: %d\n", len(tasks))),
styling.Bold(i18n.T(i18nk.BotMsgTasksQueuedTitle)),
styling.Plain(i18n.T(i18nk.BotMsgTasksTotalPrefix, map[string]any{"Count": len(tasks)})),
)
for _, t := range tasks {
created := t.Created.In(time.Local).Format("2006-01-02 15:04:05")
status := "排队中"
status := i18n.T(i18nk.BotMsgTasksStatusQueued)
if t.Cancelled {
status = "已请求取消"
status = i18n.T(i18nk.BotMsgTasksStatusCancelRequested)
}
opts = append(opts,
styling.Plain("\nID: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldId)),
styling.Code(t.ID),
styling.Plain("\n名称: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldTitle)),
styling.Code(t.Title),
styling.Plain("\n创建时间: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldCreated)),
styling.Code(created),
styling.Plain("\n状态: "),
styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksFieldStatus)),
styling.Code(status),
)
if len(tasks) > 10 {
opts = append(opts, styling.Plain("\n...\n只显示前 10 个任务, 共 "+fmt.Sprintf("%d", len(tasks))+" 个任务"))
opts = append(opts, styling.Plain("\n"+i18n.T(i18nk.BotMsgTasksTruncatedNote, map[string]any{"Count": len(tasks)})))
break
}
}