531 lines
22 KiB
Go
531 lines
22 KiB
Go
package i18n
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"strings"
|
||
"sync"
|
||
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
)
|
||
|
||
// 支持的语言列表
|
||
var SupportedLanguages = []string{"zh-CN", "en-US"}
|
||
|
||
// 默认语言
|
||
const DefaultLanguage = "en-US"
|
||
|
||
// 语言映射表
|
||
var languageMap = map[string]map[string]string{
|
||
"zh-CN": {
|
||
"hello": "你好,世界",
|
||
// 通用消息
|
||
"success": "操作成功",
|
||
"server_error": "服务器内部错误",
|
||
"invalid_operation": "非法的操作请求",
|
||
"params_error": "请求参数错误",
|
||
"not_login": "用户未登录",
|
||
"account_disabled": "账户已被禁用",
|
||
"permission_denied": "没有权限执行该操作",
|
||
"token_expired": "token已过期",
|
||
"not_found": "资源不存在",
|
||
"forbidden": "禁止访问",
|
||
"unauthorized": "未授权访问",
|
||
"unknown_error": "未知错误",
|
||
"user_id_invalid": "用户ID无效,请重新登录",
|
||
|
||
// 用户相关
|
||
"auth_failed": "账户名或密码不正确",
|
||
"password_incorrect": "密码不正确",
|
||
"email_exists": "该邮箱已被注册",
|
||
"password_mismatch": "两次密码输入不一致",
|
||
"database_query_failed": "数据库查询失败",
|
||
"data_conversion_failed": "数据转换失败",
|
||
"token_generation_failed": "Token 生成失败",
|
||
"password_encryption_failed": "密码加密失败",
|
||
"registration_failed": "注册失败",
|
||
"user_not_found": "用户不存在或已被禁用",
|
||
"email_not_found": "未找到该邮箱注册账户",
|
||
"user_id_required": "用户ID不能为空",
|
||
"user_query_failed": "用户查询失败",
|
||
"purchase_query_failed": "购买记录查询失败",
|
||
"score_deduction_failed": "积分扣除失败",
|
||
"purchase_record_failed": "购买记录创建失败",
|
||
|
||
// 管理员相关
|
||
"admin_not_found": "管理员不存在",
|
||
"admin_query_failed": "查询管理员信息失败",
|
||
"invalid_token_format": "无效的token格式",
|
||
"password_update_failed": "密码更新失败",
|
||
"token_parse_failed": "Token解析失败",
|
||
"invalid_token": "无效的Token",
|
||
|
||
// 小说相关
|
||
"book_query_failed": "小说查询失败",
|
||
"book_exists": "小说已存在",
|
||
"book_create_failed": "小说创建失败",
|
||
"book_not_found": "小说不存在",
|
||
"book_update_failed": "小说更新失败",
|
||
"book_delete_failed": "小说删除失败",
|
||
"chapter_not_found": "章节不存在",
|
||
"insufficient_points": "积分不足",
|
||
"chapter_locked": "章节已锁定,需要积分解锁",
|
||
"book_id_required": "书籍ID不能为空",
|
||
|
||
// 分类相关
|
||
"category_query_failed": "分类查询失败",
|
||
"category_exists": "分类已存在",
|
||
"category_create_failed": "分类创建失败",
|
||
"category_not_found": "分类不存在",
|
||
"category_update_failed": "分类更新失败",
|
||
"category_delete_failed": "分类删除失败",
|
||
"category_type_invalid": "分类类型无效,只能为1(男频)或2(女频)",
|
||
|
||
// 标签相关
|
||
"tag_query_failed": "标签查询失败",
|
||
"tag_exists": "标签已存在",
|
||
"tag_create_failed": "标签创建失败",
|
||
"tag_not_found": "标签不存在",
|
||
"tag_update_failed": "标签更新失败",
|
||
"tag_delete_failed": "标签删除失败",
|
||
// 章节相关
|
||
"chapter_query_failed": "章节查询失败",
|
||
"chapter_create_failed": "章节创建失败",
|
||
"chapter_update_failed": "章节更新失败",
|
||
"chapter_delete_failed": "章节删除失败",
|
||
"chapter_book_id_required": "书籍ID不能为空",
|
||
"chapter_id_required": "章节ID不能为空",
|
||
"point_log_failed": "积分日志记录失败",
|
||
"purchase_id_failed": "获取购买记录ID失败",
|
||
"progress_invalid": "阅读进度无效,必须在0-100之间",
|
||
"read_record_update_failed": "阅读记录更新失败",
|
||
// 反馈相关
|
||
"feedback_create_failed": "反馈提交失败",
|
||
// 阅读记录相关
|
||
"read_record_create_failed": "阅读记录创建失败",
|
||
"read_record_query_failed": "阅读记录查询失败",
|
||
"read_record_not_found": "阅读记录不存在",
|
||
"read_record_delete_failed": "阅读记录删除失败",
|
||
// 关注作者相关
|
||
"user_follow_author_query_failed": "关注作者查询失败",
|
||
"user_follow_author_exists": "已关注该作者",
|
||
"user_follow_author_create_failed": "关注作者失败",
|
||
"user_follow_author_not_found": "关注记录不存在",
|
||
"user_follow_author_delete_failed": "取消关注失败",
|
||
"user_follow_author_update_failed": "关注作者更新失败",
|
||
// 作者相关
|
||
"author_query_failed": "作者查询失败",
|
||
"author_user_exists": "该用户已绑定作者",
|
||
"author_create_failed": "作者创建失败",
|
||
"author_not_found": "作者不存在",
|
||
"author_update_failed": "作者更新失败",
|
||
"author_delete_failed": "作者删除失败",
|
||
"author_info_failed": "获取作者信息失败",
|
||
"not_author": "当前用户不是作者",
|
||
"author_id_required": "作者ID不能为空",
|
||
"author_review_failed": "作者审核失败",
|
||
"author_review_status_invalid": "审核状态无效",
|
||
"author_review_remark_too_long": "审核备注过长",
|
||
// 书架相关
|
||
"bookshelve_query_failed": "书架查询失败",
|
||
"bookshelve_exists": "该书已在书架中",
|
||
"bookshelve_create_failed": "加入书架失败",
|
||
"bookshelve_bookids_empty": "请选择要移除的书籍",
|
||
"bookshelve_delete_failed": "移除书架失败",
|
||
// 评分相关
|
||
"rating_invalid": "评分无效,必须在1-10分之间",
|
||
"rating_query_failed": "评分查询失败",
|
||
"rating_update_failed": "评分更新失败",
|
||
"rating_create_failed": "评分创建失败",
|
||
"rating_calculation_failed": "评分计算失败",
|
||
"book_rating_update_failed": "书籍评分更新失败",
|
||
// 我的书籍列表相关
|
||
"type_invalid": "类型参数无效,必须为1-3",
|
||
"bookshelf_query_failed": "书架查询失败",
|
||
"history_query_failed": "历史记录查询失败",
|
||
"history_create_failed": "历史记录创建失败",
|
||
"history_delete_failed": "历史记录删除失败",
|
||
"history_bookids_empty": "请选择要删除的历史记录",
|
||
"history_update_failed": "历史记录更新失败",
|
||
"bookshelf_update_failed": "书架更新失败",
|
||
"chapter_count_failed": "章节统计失败",
|
||
"read_chapter_count_failed": "已读章节统计失败",
|
||
// 图片上传相关
|
||
"image_file_required": "图片文件不能为空",
|
||
"image_type_invalid": "只允许上传图片文件",
|
||
"image_format_invalid": "仅支持 jpg、png、gif、webp 格式的图片",
|
||
"image_size_exceeded": "图片大小不能超过1MB",
|
||
"image_read_failed": "无法读取图片内容",
|
||
"image_upload_failed": "图片上传失败",
|
||
// 推荐相关
|
||
"book_recommendation_query_failed": "推荐查询失败",
|
||
"book_recommendation_exists": "该类型下该书籍已存在推荐",
|
||
"book_recommendation_create_failed": "推荐创建失败",
|
||
"book_recommendation_not_found": "推荐不存在",
|
||
"book_recommendation_update_failed": "推荐更新失败",
|
||
"book_recommendation_delete_failed": "推荐删除失败",
|
||
// 签到奖励规则相关
|
||
"sign_in_reward_rule_query_failed": "签到奖励规则查询失败",
|
||
"sign_in_reward_rule_exists": "规则名称已存在",
|
||
"sign_in_reward_rule_create_failed": "签到奖励规则创建失败",
|
||
"sign_in_reward_rule_not_found": "签到奖励规则不存在",
|
||
"sign_in_reward_rule_update_failed": "签到奖励规则更新失败",
|
||
"sign_in_reward_rule_delete_failed": "签到奖励规则删除失败",
|
||
// 签到奖励明细相关
|
||
"sign_in_reward_detail_query_failed": "签到奖励明细查询失败",
|
||
"sign_in_reward_detail_exists": "该规则下该天奖励已存在",
|
||
"sign_in_reward_detail_create_failed": "签到奖励明细创建失败",
|
||
"sign_in_reward_detail_not_found": "签到奖励明细不存在",
|
||
"sign_in_reward_detail_update_failed": "签到奖励明细更新失败",
|
||
"sign_in_reward_detail_delete_failed": "签到奖励明细删除失败",
|
||
// 签到日志相关
|
||
"user_sign_in_log_query_failed": "签到日志查询失败",
|
||
"user_sign_in_log_create_failed": "签到日志创建失败",
|
||
"user_points_log_create_failed": "积分日志创建失败",
|
||
"user_points_update_failed": "用户积分更新失败",
|
||
// 用户阅读历史相关
|
||
"user_read_history_query_failed": "历史记录查询失败",
|
||
"user_read_history_update_failed": "历史记录更新失败",
|
||
"user_read_history_create_failed": "历史记录创建失败",
|
||
"user_read_history_delete_failed": "历史记录删除失败",
|
||
"user_read_history_not_found": "历史记录不存在",
|
||
"user_id_or_book_id_or_chapter_id_invalid": "用户ID、书籍ID或章节ID无效",
|
||
"user_id_or_book_ids_invalid": "用户ID或书籍ID列表无效",
|
||
// 任务相关
|
||
"task_query_failed": "任务查询失败",
|
||
"task_add_failed": "任务添加失败",
|
||
"task_edit_failed": "任务编辑失败",
|
||
"task_delete_failed": "任务删除失败",
|
||
"task_not_found": "任务不存在",
|
||
"task_log_query_failed": "任务日志查询失败",
|
||
// 任务类型相关
|
||
"task_type_query_failed": "任务类型查询失败",
|
||
"task_type_add_failed": "任务类型添加失败",
|
||
"task_type_edit_failed": "任务类型编辑失败",
|
||
"task_type_delete_failed": "任务类型删除失败",
|
||
"task_type_not_found": "任务类型不存在",
|
||
},
|
||
"en-US": {
|
||
"hello": "Hello World!",
|
||
// Common messages
|
||
"success": "Operation successful",
|
||
"server_error": "Internal server error",
|
||
"invalid_operation": "Invalid operation request",
|
||
"params_error": "Request parameter error",
|
||
"not_login": "User not logged in",
|
||
"account_disabled": "Account has been disabled",
|
||
"permission_denied": "No permission to perform this operation",
|
||
"token_expired": "Token has expired",
|
||
"not_found": "Resource not found",
|
||
"forbidden": "Access forbidden",
|
||
"unauthorized": "Unauthorized access",
|
||
"unknown_error": "Unknown error",
|
||
"user_id_invalid": "Invalid user ID, please re-login",
|
||
|
||
// User related
|
||
"auth_failed": "Incorrect username or password",
|
||
"password_incorrect": "Incorrect password",
|
||
"email_exists": "This email has already been registered",
|
||
"password_mismatch": "Passwords do not match",
|
||
"database_query_failed": "Database query failed",
|
||
"data_conversion_failed": "Data conversion failed",
|
||
"token_generation_failed": "Token generation failed",
|
||
"password_encryption_failed": "Password encryption failed",
|
||
"registration_failed": "Registration failed",
|
||
"user_not_found": "User does not exist or has been disabled",
|
||
"email_not_found": "No registered account found for this email",
|
||
"user_id_required": "User ID cannot be empty",
|
||
"user_query_failed": "User query failed",
|
||
"purchase_query_failed": "Purchase record query failed",
|
||
"score_deduction_failed": "Score deduction failed",
|
||
"purchase_record_failed": "Purchase record creation failed",
|
||
|
||
// Admin related
|
||
"admin_not_found": "Administrator not found",
|
||
"admin_query_failed": "Failed to query administrator information",
|
||
"invalid_token_format": "Invalid token format",
|
||
"password_update_failed": "Password update failed",
|
||
"token_parse_failed": "Token parsing failed",
|
||
"invalid_token": "Invalid token",
|
||
|
||
// Novel related
|
||
"book_query_failed": "Book query failed",
|
||
"book_exists": "Book already exists",
|
||
"book_create_failed": "Book creation failed",
|
||
"book_not_found": "Book not found",
|
||
"book_update_failed": "Book update failed",
|
||
"book_delete_failed": "Book deletion failed",
|
||
"chapter_not_found": "Chapter not found",
|
||
"insufficient_points": "Insufficient points",
|
||
"chapter_locked": "Chapter is locked, requires points to unlock",
|
||
"book_id_required": "Book ID cannot be empty",
|
||
|
||
// Category related
|
||
"category_query_failed": "Category query failed",
|
||
"category_exists": "Category already exists",
|
||
"category_create_failed": "Category creation failed",
|
||
"category_not_found": "Category not found",
|
||
"category_update_failed": "Category update failed",
|
||
"category_delete_failed": "Category deletion failed",
|
||
"category_type_invalid": "Invalid category type, must be 1 (male) or 2 (female)",
|
||
|
||
// Tag related
|
||
"tag_query_failed": "Tag query failed",
|
||
"tag_exists": "Tag already exists",
|
||
"tag_create_failed": "Tag creation failed",
|
||
"tag_not_found": "Tag not found",
|
||
"tag_update_failed": "Tag update failed",
|
||
"tag_delete_failed": "Tag deletion failed",
|
||
// Chapter related
|
||
"chapter_query_failed": "Chapter query failed",
|
||
"chapter_create_failed": "Chapter creation failed",
|
||
"chapter_update_failed": "Chapter update failed",
|
||
"chapter_delete_failed": "Chapter deletion failed",
|
||
"chapter_book_id_required": "Book ID cannot be empty",
|
||
"chapter_id_required": "Chapter ID cannot be empty",
|
||
"point_log_failed": "Point log creation failed",
|
||
"purchase_id_failed": "Failed to get purchase record ID",
|
||
"progress_invalid": "Reading progress is invalid, must be between 0 and 100",
|
||
"read_record_query_failed": "Read record query failed",
|
||
"read_record_update_failed": "Read record update failed",
|
||
"read_record_create_failed": "Read record creation failed",
|
||
// Feedback related
|
||
"feedback_create_failed": "Feedback creation failed",
|
||
// ReadRecord related
|
||
"read_record_not_found": "Read record not found",
|
||
"read_record_delete_failed": "Read record deletion failed",
|
||
// UserFollowAuthor related
|
||
"user_follow_author_query_failed": "User follow author query failed",
|
||
"user_follow_author_exists": "Already followed this author",
|
||
"user_follow_author_create_failed": "User follow author creation failed",
|
||
"user_follow_author_not_found": "Follow record not found",
|
||
"user_follow_author_delete_failed": "Unfollow failed",
|
||
// Author related
|
||
"author_query_failed": "Author query failed",
|
||
"author_user_exists": "User already has an author profile",
|
||
"author_create_failed": "Author creation failed",
|
||
"author_not_found": "Author not found",
|
||
"author_update_failed": "Author update failed",
|
||
"author_delete_failed": "Author deletion failed",
|
||
"author_info_failed": "Failed to get author info",
|
||
"not_author": "Current user is not an author",
|
||
"author_id_required": "Author ID cannot be empty",
|
||
"author_review_failed": "Author review failed",
|
||
"author_review_status_invalid": "Invalid review status",
|
||
"author_review_remark_too_long": "Review remark is too long",
|
||
"user_follow_author_update_failed": "Author update failed",
|
||
|
||
// Bookshelve related
|
||
"bookshelve_query_failed": "Bookshelf query failed",
|
||
"bookshelve_exists": "Book already in bookshelf",
|
||
"bookshelve_create_failed": "Failed to add to bookshelf",
|
||
"bookshelve_bookids_empty": "Please select books to remove",
|
||
"bookshelve_delete_failed": "Failed to remove from bookshelf",
|
||
// 评分相关
|
||
"rating_invalid": "Rating is invalid, must be between 1-10",
|
||
"rating_query_failed": "Rating query failed",
|
||
"rating_update_failed": "Rating update failed",
|
||
"rating_create_failed": "Rating creation failed",
|
||
"rating_calculation_failed": "Rating calculation failed",
|
||
"book_rating_update_failed": "Book rating update failed",
|
||
// 我的书籍列表相关
|
||
"type_invalid": "Type parameter is invalid, must be 1-3",
|
||
"bookshelf_query_failed": "Bookshelf query failed",
|
||
"history_query_failed": "History query failed",
|
||
"history_create_failed": "History creation failed",
|
||
"history_delete_failed": "History deletion failed",
|
||
"history_bookids_empty": "Please select history records to delete",
|
||
"history_update_failed": "History update failed",
|
||
"bookshelf_update_failed": "Bookshelf update failed",
|
||
"chapter_count_failed": "Chapter count failed",
|
||
"read_chapter_count_failed": "Read chapter count failed",
|
||
// 图片上传相关
|
||
"image_file_required": "Image file is required",
|
||
"image_type_invalid": "Only image files are allowed",
|
||
"image_format_invalid": "Only jpg, png, gif, webp formats are supported",
|
||
"image_size_exceeded": "Image size cannot exceed 1MB",
|
||
"image_read_failed": "Failed to read image file",
|
||
"image_upload_failed": "Image upload failed",
|
||
// Recommendation related
|
||
"book_recommendation_query_failed": "Recommendation query failed",
|
||
"book_recommendation_exists": "The book already exists in this recommendation type",
|
||
"book_recommendation_create_failed": "Recommendation creation failed",
|
||
"book_recommendation_not_found": "Recommendation not found",
|
||
"book_recommendation_update_failed": "Recommendation update failed",
|
||
"book_recommendation_delete_failed": "Recommendation deletion failed",
|
||
// 签到奖励规则相关
|
||
"sign_in_reward_rule_query_failed": "Sign-in reward rule query failed",
|
||
"sign_in_reward_rule_exists": "Rule name already exists",
|
||
"sign_in_reward_rule_create_failed": "Sign-in reward rule creation failed",
|
||
"sign_in_reward_rule_not_found": "Sign-in reward rule not found",
|
||
"sign_in_reward_rule_update_failed": "Sign-in reward rule update failed",
|
||
"sign_in_reward_rule_delete_failed": "Sign-in reward rule deletion failed",
|
||
// Sign-in reward detail related
|
||
"sign_in_reward_detail_query_failed": "Sign-in reward detail query failed",
|
||
"sign_in_reward_detail_exists": "Reward for this day already exists under the rule",
|
||
"sign_in_reward_detail_create_failed": "Sign-in reward detail creation failed",
|
||
"sign_in_reward_detail_not_found": "Sign-in reward detail not found",
|
||
"sign_in_reward_detail_update_failed": "Sign-in reward detail update failed",
|
||
"sign_in_reward_detail_delete_failed": "Sign-in reward detail deletion failed",
|
||
// Sign-in log related
|
||
"user_sign_in_log_query_failed": "Sign-in log query failed",
|
||
"user_sign_in_log_create_failed": "Sign-in log creation failed",
|
||
"user_points_log_create_failed": "Points log creation failed",
|
||
"user_points_update_failed": "User points update failed",
|
||
// User read history related
|
||
"user_read_history_query_failed": "Read history query failed",
|
||
"user_read_history_update_failed": "Read history update failed",
|
||
"user_read_history_create_failed": "Read history creation failed",
|
||
"user_read_history_delete_failed": "Read history deletion failed",
|
||
"user_read_history_not_found": "Read history not found",
|
||
"user_id_or_book_id_or_chapter_id_invalid": "User ID, Book ID or Chapter ID is invalid",
|
||
"user_id_or_book_ids_invalid": "User ID or Book IDs is invalid",
|
||
// Task related
|
||
"task_query_failed": "Task query failed",
|
||
"task_add_failed": "Task add failed",
|
||
"task_edit_failed": "Task edit failed",
|
||
"task_delete_failed": "Task delete failed",
|
||
"task_not_found": "Task not found",
|
||
"task_log_query_failed": "Task log query failed",
|
||
// TaskType related
|
||
"task_type_query_failed": "Task type query failed",
|
||
"task_type_add_failed": "Task type add failed",
|
||
"task_type_edit_failed": "Task type edit failed",
|
||
"task_type_delete_failed": "Task type delete failed",
|
||
"task_type_not_found": "Task type not found",
|
||
},
|
||
}
|
||
|
||
// I18n 单例结构体
|
||
type I18n struct {
|
||
languageMap map[string]map[string]string
|
||
mu sync.RWMutex
|
||
}
|
||
|
||
var (
|
||
instance *I18n
|
||
once sync.Once
|
||
)
|
||
|
||
// GetInstance 获取单例实例
|
||
func GetInstance() *I18n {
|
||
once.Do(func() {
|
||
instance = &I18n{
|
||
languageMap: languageMap,
|
||
}
|
||
})
|
||
return instance
|
||
}
|
||
|
||
// init 初始化函数
|
||
func init() {
|
||
// 确保单例实例被创建
|
||
GetInstance()
|
||
}
|
||
|
||
// GetLanguage 从请求头或查询参数获取语言设置
|
||
func (i *I18n) GetLanguage(ctx context.Context) string {
|
||
// 优先从请求头获取
|
||
if r := g.RequestFromCtx(ctx); r != nil {
|
||
// 从 Accept-Language 头获取
|
||
acceptLang := r.GetHeader("Accept-Language")
|
||
if acceptLang != "" {
|
||
lang := parseAcceptLanguage(acceptLang)
|
||
if isSupportedLanguage(lang) {
|
||
return lang
|
||
}
|
||
}
|
||
|
||
// 从查询参数获取
|
||
lang := r.Get("lang").String()
|
||
if isSupportedLanguage(lang) {
|
||
return lang
|
||
}
|
||
|
||
// 从请求头获取自定义语言头
|
||
lang = r.GetHeader("X-Language")
|
||
if isSupportedLanguage(lang) {
|
||
return lang
|
||
}
|
||
}
|
||
|
||
return DefaultLanguage
|
||
}
|
||
|
||
// T 翻译消息
|
||
func (i *I18n) T(ctx context.Context, key string) string {
|
||
lang := i.GetLanguage(ctx)
|
||
i.mu.RLock()
|
||
defer i.mu.RUnlock()
|
||
|
||
if messages, exists := i.languageMap[lang]; exists {
|
||
if message, exists := messages[key]; exists {
|
||
return message
|
||
}
|
||
}
|
||
|
||
// 如果当前语言没有找到,尝试默认语言
|
||
if lang != DefaultLanguage {
|
||
if messages, exists := i.languageMap[DefaultLanguage]; exists {
|
||
if message, exists := messages[key]; exists {
|
||
return message
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果都没有找到,返回key本身
|
||
return key
|
||
}
|
||
|
||
// Tf 翻译消息并格式化
|
||
func (i *I18n) Tf(ctx context.Context, key string, args ...interface{}) string {
|
||
message := i.T(ctx, key)
|
||
if len(args) > 0 {
|
||
message = fmt.Sprintf(message, args...)
|
||
}
|
||
return message
|
||
}
|
||
|
||
// 为了保持向后兼容,提供全局函数
|
||
func GetLanguage(ctx context.Context) string {
|
||
return GetInstance().GetLanguage(ctx)
|
||
}
|
||
|
||
func T(ctx context.Context, key string) string {
|
||
return GetInstance().T(ctx, key)
|
||
}
|
||
|
||
func Tf(ctx context.Context, key string, args ...interface{}) string {
|
||
return GetInstance().Tf(ctx, key, args...)
|
||
}
|
||
|
||
// isSupportedLanguage 检查是否为支持的语言
|
||
func isSupportedLanguage(lang string) bool {
|
||
for _, supported := range SupportedLanguages {
|
||
if supported == lang {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// parseAcceptLanguage 解析Accept-Language头
|
||
func parseAcceptLanguage(acceptLang string) string {
|
||
// 简单的解析,取第一个语言代码
|
||
parts := strings.Split(acceptLang, ",")
|
||
if len(parts) > 0 {
|
||
lang := strings.TrimSpace(parts[0])
|
||
// 移除质量值
|
||
if idx := strings.Index(lang, ";"); idx != -1 {
|
||
lang = lang[:idx]
|
||
}
|
||
return lang
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// GetSupportedLanguages 获取支持的语言列表
|
||
func GetSupportedLanguages() []string {
|
||
return SupportedLanguages
|
||
}
|