package i18nx import ( "fmt" "regexp" "strings" ) var maxScheduleBatchMessagePattern = regexp.MustCompile(`^单次最多生成 ([0-9]+) 条排班$`) var knownMessages = map[string]map[string]string{ LocaleEnUS: { "未登录或登录已过期": "Your session has expired. Please sign in again.", "无权限执行该操作": "You do not have permission to perform this action.", "无权限操作": "You do not have permission to perform this action.", "参数不合法": "Invalid request parameters.", "路径参数错误": "Invalid path parameter.", "状态值不合法": "Invalid status value.", "用户名和密码不能为空": "Enter both username and password.", "用户名或密码错误": "The username or password is incorrect.", "登录失败次数过多,请稍后再试": "Too many failed sign-in attempts. Please try again later.", "用户不存在": "User not found.", "用户不存在或已被禁用": "The user does not exist or has been disabled.", "用户名不能为空": "Enter a username.", "用户名已存在": "This username is already in use.", "手机号已存在": "This phone number is already in use.", "邮箱已存在": "This email address is already in use.", "新密码不能为空": "Enter a new password.", "禁用角色不允许分配": "Disabled roles cannot be assigned.", "角色不存在": "Role not found.", "角色名称和编码不能为空": "Enter both role name and role code.", "角色编码已存在": "This role code is already in use.", "系统内置角色不允许删除": "Built-in system roles cannot be deleted.", "角色已被用户使用,无法删除": "This role is assigned to users and cannot be deleted.", "权限不存在": "Permission not found.", "会话不存在": "Conversation not found.", "会话筛选项不合法": "Invalid conversation filter.", "只有待接入会话允许分配": "Only queued conversations can be assigned.", "只有待接入会话允许自动分配": "Only queued conversations can be auto-assigned.", "当前会话已分配客服": "This conversation has already been assigned.", "当前暂不在人工客服服务时间内": "Human support is currently outside service hours.", "目标客服不能为空": "Select a target agent.", "目标客服不存在": "Target agent not found.", "无权转接该会话": "You do not have permission to transfer this conversation.", "只有处理中会话允许转接": "Only active conversations can be transferred.", "当前会话未分配客服": "This conversation is not assigned to an agent.", "目标客服不能与当前指派人相同": "The target agent must be different from the current assignee.", "无权访问该会话": "You do not have permission to access this conversation.", "当前状态不允许关闭会话": "This conversation cannot be closed in its current status.", "关闭原因不能为空": "Enter a close reason.", "无权关闭该会话": "You do not have permission to close this conversation.", "已关闭的会话无法关联客户": "Closed conversations cannot be linked to customers.", "无权限关联该会话": "You do not have permission to link this conversation.", "外部用户标识不能为空": "External user ID is required.", "接入渠道未初始化": "The channel is not initialized.", "接入渠道不存在或已停用": "The channel does not exist or has been disabled.", "接入渠道异常": "Channel error.", "channel not found": "Channel not found.", "该渠道不支持开放客服配置": "This channel does not support public support configuration.", "外部身份未初始化": "External identity is not initialized.", "conversationId不能为空": "Conversation ID is required.", "请选择上传图片": "Choose an image to upload.", "仅支持上传图片文件": "Only image files are supported.", "请选择上传附件": "Choose an attachment to upload.", "请选择上传文件": "Choose a file to upload.", "文件不存在": "File not found.", "文件不可访问": "This file cannot be accessed.", "上传文件超过大小限制": "The uploaded file exceeds the size limit.", "图片资源不存在": "Image asset not found.", "当前暂不支持该存储类型的文件读取": "Reading files from this storage provider is not supported yet.", "客户不存在": "Customer not found.", "客户名称不能为空": "Enter a customer name.", "所属公司不存在": "Company not found.", "公司不存在": "Company not found.", "公司名称不能为空": "Enter a company name.", "公司名称已存在": "This company name is already in use.", "工单不存在": "Ticket not found.", "工单标题不能为空": "Enter a ticket title.", "工单描述不能为空": "Enter a ticket description.", "工单来源不合法": "Invalid ticket source.", "工单状态不合法": "Invalid ticket status.", "处理进展不能为空": "Enter a progress update.", "负责人不存在": "Assignee not found.", "会话与客户不匹配": "The conversation does not belong to this customer.", "视图名称不能为空": "Enter a view name.", "视图筛选条件格式不正确": "The view filter format is invalid.", "视图不存在": "View not found.", "标签不存在": "Tag not found.", "标签名称不能为空": "Enter a tag name.", "父标签不存在": "Parent tag not found.", "同级下已存在相同名称的标签": "A tag with this name already exists at the same level.", "不能将标签设为自己的子标签": "A tag cannot be moved under itself.", "该标签下存在子标签,无法删除": "This tag has child tags and cannot be deleted.", "该标签已关联会话,无法删除": "This tag is linked to conversations and cannot be deleted.", "该标签已关联工单,无法删除": "This tag is linked to tickets and cannot be deleted.", "快捷回复不存在": "Quick reply not found.", "客服档案不存在": "Agent profile not found.", "请选择关联用户": "Select a user to link.", "关联用户不存在": "Linked user not found.", "请选择所属客服组": "Select an agent team.", "所属客服组不存在": "Agent team not found.", "客服工号和展示名不能为空": "Enter both agent ID and display name.", "该用户已存在客服档案": "This user already has an agent profile.", "客服工号已存在": "This agent ID is already in use.", "客服状态不合法": "Invalid agent status.", "最大并发接待数不能小于 0": "Maximum concurrent conversations cannot be less than 0.", "客服组不存在": "Agent team not found.", "客服组排班不存在": "Agent team schedule not found.", "知识库不存在": "Knowledge base not found.", "FAQ不存在": "FAQ not found.", "FAQ知识库不支持文档": "FAQ knowledge bases do not support documents.", "文档不存在": "Document not found.", "内容类型不支持": "Unsupported content type.", "问题不能为空": "Enter a question.", "答案不能为空": "Enter an answer.", "相似问格式不合法": "Invalid similar-question format.", "当前知识库不是FAQ知识库": "This knowledge base is not an FAQ knowledge base.", "documentId或faqId不能为空": "Document ID or FAQ ID is required.", "检索日志不存在": "Retrieval log not found.", "indexStatus参数不合法": "Invalid index status.", "AI配置不存在": "AI configuration not found.", "启用中的AI配置不允许删除": "Enabled AI configurations cannot be deleted.", "配置名称不能为空": "Enter a configuration name.", "供应商不能为空": "Select a provider.", "基础地址不能为空": "Enter a base URL.", "模型类型不能为空": "Select a model type.", "模型名称不能为空": "Enter a model name.", "AI Agent 不存在": "AI Agent not found.", "AI Agent不存在或未启用": "AI Agent not found or not enabled.", "AI Agent 不存在或已停用": "AI Agent not found or disabled.", "AI Agent关联的AI配置不存在": "The AI configuration linked to this AI Agent does not exist.", "CheckPoint 不存在": "Checkpoint not found.", "CheckPoint 与 AI Agent 不匹配": "The checkpoint does not belong to this AI Agent.", "会话与 AI Agent 不匹配": "The conversation does not belong to this AI Agent.", "Skill 不存在或未启用": "Skill not found or not enabled.", "Skill 不存在": "Skill not found.", "Skill ID 不合法": "Invalid Skill ID.", "Skill 编码已存在": "This Skill code is already in use.", "Skill 编码不能为空": "Enter a Skill code.", "Skill 名称不能为空": "Enter a Skill name.", "技能说明不能为空": "Enter a Skill description.", "JSON 数组格式不合法": "Invalid JSON array format.", "已删除的 Skill 不能直接修改状态,请先恢复": "Restore this deleted Skill before changing its status.", "请使用删除接口处理删除状态": "Use the delete endpoint to mark a Skill as deleted.", "仅已删除的 Skill 支持恢复": "Only deleted Skills can be restored.", "MCP未启用": "MCP is not enabled.", "serverCode不能为空": "Server code is required.", "MCP endpoint不能为空": "MCP endpoint is required.", "MCP服务配置不存在": "MCP server configuration not found.", "MCP服务未启用": "MCP server is not enabled.", "toolName不能为空": "Tool name is required.", "toolCode不能为空": "Tool code is required.", "toolCode格式不合法": "Invalid tool code format.", "toolCode 绑定的 MCP 服务不存在或未启用": "The MCP server bound to this tool code does not exist or is not enabled.", "文本内容不能为空": "Text content is required.", "文本列表不能为空": "Text list is required.", "密码长度不合法": "Invalid password length.", "AI Agent 不存在或未启用": "AI Agent not found or not enabled.", "AI Agent 名称不能为空": "Enter an AI Agent name.", "AI Agent 名称已存在": "This AI Agent name is already in use.", "AI 配置不存在": "AI configuration not found.", "AI 配置不能为空": "Select an AI configuration.", "AI 配置未启用": "The AI configuration is not enabled.", "Agent 运行日志不存在": "Agent run log not found.", "Direct Tool 的 toolCode 与 serverCode 不一致": "Direct Tool toolCode does not match serverCode.", "Direct Tool 的 toolCode 与 toolName 不一致": "Direct Tool toolCode does not match toolName.", "Direct Tool 的 toolCode 格式不合法": "Invalid Direct Tool toolCode format.", "Direct Tool 的 toolCode、serverCode 和 toolName 不能为空": "Direct Tool toolCode, serverCode, and toolName are required.", "Direct Tools 仅允许配置 MCP 工具": "Direct Tools can only contain MCP tools.", "Direct Tools 配置格式不合法": "Invalid Direct Tools configuration format.", "Graph Tools 仅允许配置 Graph Tool": "Graph Tools can only contain Graph tools.", "Graph Tools 配置格式不合法": "Invalid Graph Tools configuration format.", "HTML消息中的图片必须使用已上传文件": "Images in HTML messages must use uploaded files.", "OIDC id_token 不存在": "OIDC id_token is missing.", "OIDC clientId 未配置": "OIDC clientId is not configured.", "OIDC clientSecret 未配置": "OIDC clientSecret is not configured.", "OIDC issuer 未配置": "OIDC issuer is not configured.", "OIDC redirectUrl 未配置": "OIDC redirectUrl is not configured.", "OIDC 授权 code 不能为空": "OIDC authorization code is required.", "OIDC 用户信息不存在": "OIDC user information not found.", "OIDC 用户标识不存在": "OIDC user identifier not found.", "OIDC 登录密钥未配置": "OIDC sign-in secret is not configured.", "OIDC 登录未启用": "OIDC sign-in is not enabled.", "OIDC 登录状态无效或已过期": "OIDC sign-in state is invalid or has expired.", "OIDC 账号绑定的系统用户不存在": "The system user linked to this OIDC account does not exist.", "OSS accessKeyId 未配置": "OSS accessKeyId is not configured.", "OSS accessKeySecret 未配置": "OSS accessKeySecret is not configured.", "OSS bucket 未配置": "OSS bucket is not configured.", "OSS endpoint 未配置": "OSS endpoint is not configured.", "Skill 未启用": "Skill is not enabled.", "Web渠道配置 position 只能为 left 或 right": "Web channel position must be left or right.", "Web渠道配置不合法": "Invalid web channel configuration.", "aiAgentId不能为空": "AI Agent ID is required.", "checkPointId不能为空": "Checkpoint ID is required.", "customerId 必填": "Customer ID is required.", "openKfID不能为空": "openKfID is required.", "openKfId 已被其他渠道使用": "This openKfId is already used by another channel.", "skillCode不能为空": "Skill code is required.", "ticket 不能为空": "Ticket is required.", "userMessage不能为空": "User message is required.", "登录结果不能为空": "Sign-in result is required.", "不支持的发送人类型": "Unsupported sender type.", "不支持的已读操作类型": "Unsupported read operation type.", "不支持的文件存储类型": "Unsupported file storage type.", "不能添加或修改历史日期的排班": "Schedules cannot be added or changed for past dates.", "事务上下文不能为空": "Transaction context is required.", "仅允许撤回自己发送的消息": "You can only recall messages you sent.", "仅支持撤回客服消息": "Only agent messages can be recalled.", "仅能指定一条主联系方式": "Only one primary contact method can be set.", "企业微信 openKfID 不能为空": "WeCom openKfID is required.", "企业微信媒体ID不能为空": "WeCom media ID is required.", "企业微信客户ID不能为空": "WeCom customer ID is required.", "企业微信手机号已被系统用户占用": "This WeCom phone number is already used by a system user.", "企业微信接入渠道未绑定AI Agent": "The WeCom channel is not linked to an AI Agent.", "企业微信接入渠道绑定的AI Agent不存在或已禁用": "The AI Agent linked to this WeCom channel does not exist or has been disabled.", "企业微信未启用或配置不完整": "WeCom is not enabled or its configuration is incomplete.", "企业微信消息ID不能为空": "WeCom message ID is required.", "企业微信渠道配置不合法": "Invalid WeCom channel configuration.", "企业微信渠道配置缺少 openKfId": "WeCom channel configuration is missing openKfId.", "企业微信用户ID已被系统用户名占用": "This WeCom user ID is already used as a system username.", "企业微信用户ID获取失败": "Failed to get the WeCom user ID.", "企业微信用户信息不存在": "WeCom user information not found.", "企业微信登录密钥未配置": "WeCom sign-in secret is not configured.", "企业微信登录未启用": "WeCom sign-in is not enabled.", "企业微信登录状态无效或已过期": "WeCom sign-in state is invalid or has expired.", "企业微信账号绑定的系统用户不存在": "The system user linked to this WeCom account does not exist.", "企业微信邮箱已被系统用户占用": "This WeCom email address is already used by a system user.", "会话已关闭": "This conversation is closed.", "会话未分配客服,暂不允许发送消息": "This conversation has not been assigned to an agent, so messages cannot be sent yet.", "兜底策略不合法": "Invalid fallback policy.", "分块策略不支持": "Unsupported chunking strategy.", "创建会话失败": "Failed to create the conversation.", "单条排班记录不能跨天": "A single schedule entry cannot span multiple days.", "只有待接入未分配会话允许自动分配": "Only queued unassigned conversations can be auto-assigned.", "回复超时秒数不能小于 0": "Reply timeout seconds cannot be less than 0.", "存在冲突排班,请先处理冲突": "There are conflicting schedules. Resolve the conflicts first.", "存在无效工单标签": "Some ticket tags are invalid.", "存在未启用的工单标签": "Some ticket tags are disabled.", "客服会话不能为空": "Support session is required.", "客服会话参数不完整": "Support session parameters are incomplete.", "客服会话密钥未配置": "Support session secret is not configured.", "客服会话已过期": "The support session has expired.", "客服会话校验失败": "Support session verification failed.", "客服组下仍有关联 AI Agent,无法删除": "This agent team is linked to AI Agents and cannot be deleted.", "客服组下仍有关联客服档案,无法删除": "This agent team has linked agent profiles and cannot be deleted.", "客服组下仍有关联组排班,无法删除": "This agent team has schedules and cannot be deleted.", "客服组名称不能为空": "Enter an agent team name.", "客服组名称已存在": "This agent team name is already in use.", "客服组未启用": "Agent team is not enabled.", "客服组状态不合法": "Invalid agent team status.", "已有接入渠道绑定该 AI Agent,无法删除": "This AI Agent is linked to channels and cannot be deleted.", "当前 OIDC 绑定已停用": "The current OIDC binding has been disabled.", "当前企业微信绑定已停用": "The current WeCom binding has been disabled.", "当前会话不处于 AI 接待状态": "This conversation is not currently handled by AI.", "当前会话已分配给其他客服": "This conversation has been assigned to another agent.", "当前会话已由人工客服接管": "This conversation has already been taken over by a human agent.", "当前渠道不支持用户 JWT Secret": "This channel does not support a user JWT secret.", "当前系统账号已被禁用": "The current system account has been disabled.", "微信公众号渠道配置不合法": "Invalid WeChat Official Account channel configuration.", "接入渠道不存在": "Channel not found.", "接收人不能为空": "Recipient is required.", "文档知识库不能使用FAQ分块策略": "Document knowledge bases cannot use the FAQ chunking strategy.", "时间格式错误": "Invalid time format.", "星期必须在 1 到 7 之间": "Weekday must be between 1 and 7.", "服务模式不合法": "Invalid service mode.", "未找到匹配的企业微信接入渠道": "No matching WeCom channel was found.", "未生成任何排班": "No schedules were generated.", "未配置可用的 AI 配置": "No available AI configuration is configured.", "未配置可用的 Embedding 模型": "No available embedding model is configured.", "标题和内容不能为空": "Enter both title and content.", "消息不存在": "Message not found.", "消息内容不能为空": "Message content is required.", "消息已撤回": "This message has been recalled.", "渠道名称不能为空": "Enter a channel name.", "渠道标识已存在": "This channel code is already in use.", "渠道状态不合法": "Invalid channel status.", "渠道类型不合法": "Invalid channel type.", "用户名称不能为空": "User name is required.", "用户标识不能为空": "User ID is required.", "用户身份不能为空": "User identity is required.", "用户身份已过期": "User identity has expired.", "用户身份校验失败": "User identity verification failed.", "用户身份校验未配置": "User identity verification is not configured.", "登录票据无效或已过期": "The sign-in ticket is invalid or has expired.", "知识库下存在FAQ,无法删除": "This knowledge base contains FAQs and cannot be deleted.", "知识库下存在文档,无法删除": "This knowledge base contains documents and cannot be deleted.", "知识库不能为空": "Knowledge base is required.", "知识库未启用": "Knowledge base is not enabled.", "知识库类型不支持": "Unsupported knowledge base type.", "组长用户不存在": "Team lead user not found.", "结束日期必须晚于或等于开始日期": "End date must be later than or equal to start date.", "结束时间必须晚于开始时间": "End time must be later than start time.", "联系方式不存在": "Contact method not found.", "联系方式不能为空": "Contact method is required.", "联系方式类型不合法": "Invalid contact method type.", "该客服组在所选时间段已存在排班": "This agent team already has a schedule in the selected time period.", "该联系方式已存在": "This contact method already exists.", "请至少选择一个知识库": "Select at least one knowledge base.", "请选择 AI Agent": "Select an AI Agent.", "请选择客服组": "Select an agent team.", "请选择星期": "Select a weekday.", "转人工模式不合法": "Invalid human handoff mode.", "通知不存在": "Notification not found.", "附件不存在": "Attachment not found.", "附件尚未上传完成": "The attachment has not finished uploading.", "附件消息 payload 格式错误": "Invalid attachment message payload format.", "附件消息缺少 assetId": "Attachment message is missing assetId.", "附件消息缺少 payload": "Attachment message is missing payload.", "默认客服组待接入池模式必须至少选择一个客服组": "Default team queue mode requires at least one agent team.", }, } func TranslateKnownMessage(locale string, message string) string { normalized := NormalizeLocale(locale) if normalized == LocaleZhCN { return message } if translations, ok := knownMessages[normalized]; ok { if translated, exists := translations[message]; exists { return translated } } if translated, ok := translateKnownPattern(normalized, message); ok { return translated } return message } func translateKnownPattern(locale string, message string) (string, bool) { if locale != LocaleEnUS { return "", false } if matches := maxScheduleBatchMessagePattern.FindStringSubmatch(message); len(matches) == 2 { return fmt.Sprintf("You can generate at most %s schedule entries at a time.", matches[1]), true } if strings.HasPrefix(message, "开始时间格式错误,请使用 ") { return translateTimeFormatMessage(message, "开始时间格式错误,请使用 ", "start time") } if strings.HasPrefix(message, "结束时间格式错误,请使用 ") { return translateTimeFormatMessage(message, "结束时间格式错误,请使用 ", "end time") } return "", false } func translateTimeFormatMessage(message string, prefix string, field string) (string, bool) { format := strings.TrimPrefix(message, prefix) if format == message || format == "" { return "", false } format = strings.ReplaceAll(format, " 或 ", " or ") return fmt.Sprintf("Invalid %s format. Use %s.", field, format), true }