Refactor localization strings to English across various services and UI components

- Updated titles and subtitles in channel_service.go for web channel and WeChat MP channel configurations.
- Changed handoff messages in conversation_human_dispatch_service.go to English.
- Modified notification messages in event handlers for ticket and conversation assignments to English.
- Adjusted ticket creation messages in ticket_service.go to reflect English localization.
- Updated default locale settings in i18n configuration files to English (en-US).
- Changed HTML language attribute in layout.tsx to English.
- Refactored widget locale detection logic in agent-desk-sdk.ts to prioritize English.
This commit is contained in:
mlogclub
2026-05-31 20:06:44 +08:00
parent bcf2ee38c0
commit b128447a7e
36 changed files with 315 additions and 164 deletions
+6 -6
View File
@@ -208,8 +208,8 @@ func (s *channelService) ListWxWorkKFAccounts() ([]response.WxWorkKFAccountRespo
func (s *channelService) ParseWebChannelConfig(raw string) (*dto.WebChannelConfig, error) {
raw = strings.TrimSpace(raw)
cfg := &dto.WebChannelConfig{
Title: "在线客服",
Subtitle: "欢迎咨询",
Title: "Support",
Subtitle: "How can we help?",
ThemeColor: "#2563eb",
Position: "right",
Width: "380px",
@@ -221,7 +221,7 @@ func (s *channelService) ParseWebChannelConfig(raw string) (*dto.WebChannelConfi
}
cfg.Title = strings.TrimSpace(cfg.Title)
if cfg.Title == "" {
cfg.Title = "在线客服"
cfg.Title = "Support"
}
cfg.Subtitle = strings.TrimSpace(cfg.Subtitle)
cfg.ThemeColor = strings.TrimSpace(cfg.ThemeColor)
@@ -246,8 +246,8 @@ func (s *channelService) ParseWebChannelConfig(raw string) (*dto.WebChannelConfi
func (s *channelService) ParseWechatMPChannelConfig(raw string) (*dto.WechatMPChannelConfig, error) {
raw = strings.TrimSpace(raw)
cfg := &dto.WechatMPChannelConfig{
Title: "公众号客服",
Subtitle: "欢迎咨询",
Title: "Official Account Support",
Subtitle: "How can we help?",
ThemeColor: "#2563eb",
}
if raw != "" {
@@ -257,7 +257,7 @@ func (s *channelService) ParseWechatMPChannelConfig(raw string) (*dto.WechatMPCh
}
cfg.Title = strings.TrimSpace(cfg.Title)
if cfg.Title == "" {
cfg.Title = "公众号客服"
cfg.Title = "Official Account Support"
}
cfg.Subtitle = strings.TrimSpace(cfg.Subtitle)
cfg.ThemeColor = strings.TrimSpace(cfg.ThemeColor)
@@ -19,8 +19,8 @@ import (
var ConversationHumanDispatchService = newConversationHumanDispatchService()
const (
HandoffWaitingMessage = "已为你转接人工客服,请稍候。"
HandoffOffHoursMessage = "当前暂不在人工客服服务时间内,你可以先继续描述问题,我会尽力协助;服务时间开始后也可以再次转人工。"
HandoffWaitingMessage = "We are connecting you to a human support agent. Please wait."
HandoffOffHoursMessage = "Human support is currently outside service hours. You can keep describing the issue and I will do my best to help. You can also request a human agent again when service hours resume."
)
type HandoffDecisionType string
@@ -42,7 +42,7 @@ func TestConversationHumanDispatchAIHandoffOffHoursKeepsAIServingAndSendsNotice(
if message == nil {
t.Fatalf("expected off-hours notice message")
}
if message.SenderType != enums.IMSenderTypeAI || !strings.Contains(message.Content, "当前暂不在人工客服服务时间内") {
if message.SenderType != enums.IMSenderTypeAI || !strings.Contains(message.Content, "Human support is currently outside service hours") {
t.Fatalf("unexpected off-hours message: %+v", message)
}
}
@@ -37,11 +37,11 @@ func handleConversationAssignedNotify(ctx context.Context, event events.Conversa
func conversationAssignedNotifyTitle(assignType string) string {
switch strings.TrimSpace(assignType) {
case events.ConversationAssignTypeTransfer:
return "会话转接提醒"
return "Conversation transferred"
case events.ConversationAssignTypeAutoAssign:
return "会话自动分配提醒"
return "Conversation auto-assigned"
default:
return "会话分配提醒"
return "Conversation assigned"
}
}
@@ -49,21 +49,21 @@ func buildConversationAssignedNotifyBody(conversation *models.Conversation, assi
if conversation == nil {
return ""
}
reasonLabel := "分配原因"
reasonLabel := "Assignment reason"
if strings.TrimSpace(assignType) == events.ConversationAssignTypeTransfer {
reasonLabel = "转接原因"
reasonLabel = "Transfer reason"
}
lines := []string{
fmt.Sprintf("会话ID: #%d", conversation.ID),
fmt.Sprintf("会话摘要: %s", strs.DefaultIfBlank(services.ConversationService.BuildConversationSummary(conversation), "-")),
fmt.Sprintf("接入渠道: %s", resolveConversationChannelLabel(conversation)),
fmt.Sprintf("当前状态: %s", enums.GetIMConversationStatusLabel(conversation.Status)),
fmt.Sprintf("处理人: %s", resolveNotifyUserLabel(assigneeID)),
fmt.Sprintf("Conversation ID: #%d", conversation.ID),
fmt.Sprintf("Summary: %s", strs.DefaultIfBlank(services.ConversationService.BuildConversationSummary(conversation), "-")),
fmt.Sprintf("Channel: %s", resolveConversationChannelLabel(conversation)),
fmt.Sprintf("Status: %s", enums.GetIMConversationStatusLabel(conversation.Status)),
fmt.Sprintf("Assignee: %s", resolveNotifyUserLabel(assigneeID)),
}
if strings.TrimSpace(reason) != "" {
lines = append(lines, fmt.Sprintf("%s: %s", reasonLabel, strings.TrimSpace(reason)))
}
lines = append(lines, fmt.Sprintf("时间: %s", time.Now().Format("2006-01-02 15:04:05")))
lines = append(lines, fmt.Sprintf("Time: %s", time.Now().Format("2006-01-02 15:04:05")))
return strings.Join(lines, "\n")
}
@@ -31,16 +31,16 @@ func handleTicketAssignedInAppNotification(ctx context.Context, event events.Tic
if ticket == nil {
return nil
}
content := fmt.Sprintf("工单 %s 已指派给你", strs.DefaultIfBlank(ticket.TicketNo, fmt.Sprintf("#%d", ticket.ID)))
content := fmt.Sprintf("Ticket %s has been assigned to you.", strs.DefaultIfBlank(ticket.TicketNo, fmt.Sprintf("#%d", ticket.ID)))
if title := strings.TrimSpace(ticket.Title); title != "" {
content = content + "\n" + title
}
if reason := strings.TrimSpace(event.Reason); reason != "" {
content = content + "\n指派原因: " + reason
content = content + "\nAssignment reason: " + reason
}
_, err := services.NotificationService.CreateAndPush(request.CreateNotificationRequest{
RecipientUserID: event.ToUserID,
Title: "工单指派提醒",
Title: "Ticket assigned",
Content: content,
NotificationType: "ticket_assigned",
BizType: "ticket",
@@ -61,12 +61,12 @@ func handleConversationAssignedInAppNotification(ctx context.Context, event even
if conversation == nil {
return nil
}
content := fmt.Sprintf("会话 #%d 已分配给你", conversation.ID)
content := fmt.Sprintf("Conversation #%d has been assigned to you.", conversation.ID)
if summary := strings.TrimSpace(services.ConversationService.BuildConversationSummary(conversation)); summary != "" {
content = content + "\n" + summary
}
if reason := strings.TrimSpace(event.Reason); reason != "" {
content = content + "\n分配原因: " + reason
content = content + "\nAssignment reason: " + reason
}
_, err := services.NotificationService.CreateAndPush(request.CreateNotificationRequest{
RecipientUserID: event.ToUserID,
@@ -29,7 +29,7 @@ func handleTicketAssignedNotify(ctx context.Context, event events.TicketAssigned
return nil
}
content := buildTicketAssignedNotifyBody(ticket, event.ToUserID, event.Reason)
return services.WxWorkNotifyService.SendTextToAssigneeOrDefault(event.ToUserID, "工单指派提醒", content)
return services.WxWorkNotifyService.SendTextToAssigneeOrDefault(event.ToUserID, "Ticket assigned", content)
}
func buildTicketAssignedNotifyBody(ticket *models.Ticket, assigneeID int64, reason string) string {
@@ -37,14 +37,14 @@ func buildTicketAssignedNotifyBody(ticket *models.Ticket, assigneeID int64, reas
return ""
}
lines := []string{
fmt.Sprintf("工单号: %s", strs.DefaultIfBlank(ticket.TicketNo, fmt.Sprintf("#%d", ticket.ID))),
fmt.Sprintf("工单标题: %s", strs.DefaultIfBlank(ticket.Title, "-")),
fmt.Sprintf("当前状态: %s", enums.GetTicketStatusLabel(ticket.Status)),
fmt.Sprintf("处理人: %s", resolveNotifyUserLabel(assigneeID)),
fmt.Sprintf("Ticket no: %s", strs.DefaultIfBlank(ticket.TicketNo, fmt.Sprintf("#%d", ticket.ID))),
fmt.Sprintf("Title: %s", strs.DefaultIfBlank(ticket.Title, "-")),
fmt.Sprintf("Status: %s", enums.GetTicketStatusLabel(ticket.Status)),
fmt.Sprintf("Assignee: %s", resolveNotifyUserLabel(assigneeID)),
}
if strings.TrimSpace(reason) != "" {
lines = append(lines, fmt.Sprintf("指派原因: %s", strings.TrimSpace(reason)))
lines = append(lines, fmt.Sprintf("Assignment reason: %s", strings.TrimSpace(reason)))
}
lines = append(lines, fmt.Sprintf("时间: %s", time.Now().Format("2006-01-02 15:04:05")))
lines = append(lines, fmt.Sprintf("Time: %s", time.Now().Format("2006-01-02 15:04:05")))
return strings.Join(lines, "\n")
}
+2 -2
View File
@@ -237,7 +237,7 @@ func (s *ticketService) CreateTicket(req request.CreateTicketRequest, operator *
}
return repositories.TicketProgressRepository.Create(ctx.Tx, &models.TicketProgress{
TicketID: ticket.ID,
Content: "创建工单",
Content: "Created ticket",
AuthorID: operator.UserID,
CreatedAt: time.Now(),
})
@@ -265,7 +265,7 @@ func (s *ticketService) CreateFromConversation(req request.CreateTicketFromConve
title = strings.TrimSpace(ConversationService.BuildConversationSummary(conversation))
}
if title == "" {
title = "会话工单"
title = "Conversation ticket"
}
description := strings.TrimSpace(req.Description)
if description == "" {
+1 -1
View File
@@ -81,7 +81,7 @@ func TestTicketServiceCreateTicketSetsPendingStatusAndTicketNo(t *testing.T) {
if len(progresses) != 1 {
t.Fatalf("expected initial progress, got %d", len(progresses))
}
if progresses[0].Content != "创建工单" || progresses[0].AuthorID != operator.UserID {
if progresses[0].Content != "Created ticket" || progresses[0].AuthorID != operator.UserID {
t.Fatalf("unexpected initial progress: %+v", progresses[0])
}
+1 -1
View File
@@ -34,7 +34,7 @@ type MCPToolCatalogItem struct {
}
func (s *toolCatalogService) ListMCPTools(ctx context.Context) ([]MCPToolCatalogItem, error) {
return s.ListMCPToolsWithLocale(ctx, i18nx.LocaleZhCN)
return s.ListMCPToolsWithLocale(ctx, i18nx.DefaultLocale)
}
func (s *toolCatalogService) ListMCPToolsWithLocale(ctx context.Context, locale string) ([]MCPToolCatalogItem, error) {