package i18n import ( "context" "epic/internal/dao" "epic/internal/model/entity" "epic/internal/util" "fmt" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" "sync" "time" ) // I18nEnToZh 英文->中文映射表(示例) var I18nEnToZh = map[string]string{ "A Little Queen's Huge Crown": "小小女王的巨大王冠", "A Song for Everybody": "献给你和这个世界的歌曲", "A Symbol of Unity": "团结的象征", "Abyssal Crown": "深渊王冠", "Achates": "雅卡泰丝", "Adamant Shield": "金刚石盾牌", "Adin": "艾庭", "Adlay": "亚迪赖", "Adventurer Ras": "冒险家拉斯", "Ainos": "艾诺斯", "Ains": "艾因兹", "Air-to-Surface Missile: MISHA": "空地导弹:美莎 ", "Aither": "埃德勒", "Alabastron": "雪花石膏瓶", "Alencia": "艾莲西雅", "Alencinox's Wrath": "艾莲西诺克斯的逆鳞", "Alexa": "雅莉莎", "Alexa's Basket": "雅莉莎的提篮", "All-Rounder Wanda": "疑难杂症专家汪达", "Alsacian Spear": "艾尔赛斯之矛", "Ambitious Tywin": "野心分子泰温", "Ambrote": "安布罗泰", "Ancient Dragon's Legacy": "古龙遗产", "Ancient Sheath": "古代剑鞘", "Andre's Crossbow": "安德烈斯之弩", "Angel of Light Angelica": "光之天使安洁莉卡", "Angelic Montmorancy": "守护天使蒙茉朗西", "Angelica": "安洁莉卡", "Anti-Magic Mask": "抗魔面具", "Apocalypse Ravi": "末日萝菲", "Aqua Rose": "水玫瑰", "Aramintha": "雅拉敏塔", "Arbiter Vildred": "执行官维德瑞", "Archdemon's Shadow": "魔神的暗影", "Armin": "亚敏", "Arowell": "雅洛薇", "Ascending Axe": "参天斧", "Assassin Cartuja": "杀手卡尔图哈", "Assassin Cidd": "杀手席德", "Assassin Coli": "杀手可丽", "Atma's Portal": "亚特玛的传送门", "Aurius": "亚乌利斯", "Auxiliary Lots": "辅助型拉兹", "Azalea": "亚洁理亚", "Azure Comet": "青光彗星", "Abyssal Yufine": "深渊优芬妮", "Amiki": "雅蜜琪", "Baal & Sezan": "巴尔&塞尚", "Baiken": "梅喧", "Barthez's Orbuculum": "巴泰斯的水晶球", "Basar": "巴萨尔", "Bask": "巴思克", "Bastion of Hope": "希望的堡垒", "Bastion of Perlutia": "波鲁迪亚的堡垒", "Batisse": "巴托斯", "Belian": "伯里安", "Bellona": "维尔萝娜", "Benevolent Romann": "仁慈的洛曼", "Biting Wind Star": "寒风飞镖", "Black Hand of the Goddess": "女神的黑手", "Blaze Dingo": "烈火汀果", "Blessings of Camaraderie": "友情祝福", "Blood Blade Karin": "血剑卡琳", "Blood Moon Haste": "赤月贵族海斯特", "Blood-Seared Moon": "血染之月", "Bloodbead Dagger": "血诛短剑", "Bloodstone": "血玉髓", "Bloody Rose": "血玫瑰", "Bloody Warhammer": "血腥战锤", "Bomb Model Kanna": "爆击型卡农", "Border Coin": "孤注一掷", "Briar Witch Iseria": "灰光森林的伊赛丽亚", "Broken Will of the Priest": "残破的祭司长意志", "Butcher Corps Inquisitor": "屠杀部队员", "Butterfly Mandolin": "蝴蝶的曼陀林", "Blooming Lidica": "花园丽迪卡", "Byblis": "维波里丝", "Beguiling Wings": "迷惑羽翼", "Camilla": "卡蜜拉", "Captain Rikoris": "先锋队长里科黎司", "Card of Small Miracles": "小小奇迹贺年卡", "Carmainerose": "卡麦萝兹", "Carrot": "卡萝", "Cartuja": "卡尔图哈", "Cecilia": "赛西莉亚", "Celeste": "赛雷斯特", "Celestial Mercedes": "外太空的玫勒赛德丝", "Celestial Spear": "天空之矛", "Celestine": "天青石", "Celine": "瑟琳", "Cerise": "赛瑞丝", "Cermia": "洁若米亚", "Challenger Dominiel": "挑战者多米妮尔", "Champion Zerato": "终结者杰拉图", "Champion's Trophy": "优胜者奖杯", "Chaos Inquisitor": "混沌教屠杀追击者", "Chaos Sect Axe": "混沌教巨斧大将军", "Charles": "查尔斯", "Charlotte": "夏绿蒂", "Chatty": "柴迪", "Chloe": "克萝爱", "Choux": "小泡芙", "Christy": "克莉丝媞", "Church of Ilryos Axe": "伊利欧斯教斧兵", "Cidd": "席德", "Circus Fantasia": "奇幻马戏团", "Clarissa": "克莱莉莎", "Closer Charles": "末日指挥官查尔斯", "Coli": "可丽", "Command Model Laika": "指挥型莱伊卡", "Commander Lorina": "指挥官萝里娜", "Conqueror Lilias": "支配者莉莉亚斯", "Corvus": "科尔布思", "Cradle of Life": "生命摇篮", "Creation & Destruction": "创造之福&破坏之颂", "Crescent Moon Rin": "新月舞姬铃儿", "Crimson Armin": "红焰亚敏", "Crimson Moon of Nightmares": "红色噩梦之月", "Crimson Seed": "红焰种子", "Crown of Glory": "荣耀之冠", "Crozet": "克罗泽", "Cruel Mischief": "残酷的玩笑", "Cursed Compass": "诅咒的罗盘", "Claudia": "克劳蒂亚", "Dark Corvus": "黑暗的科尔布思", "Daydream Joker": "白日梦小丑", "Days of Destiny": "命中注定的相遇", "Deadly Sword": "必杀大剑", "Demon's Pistol": "恶魔手枪", "Desert Jewel Basar": "沙漠宝石巴萨尔", "Designer Lilibet": "设计师莉莉贝", "Destina": "戴丝蒂娜", "Devil's Brand": "恶魔烙印", "Diene": "迪埃妮", "Dignus Orb": "尊严宝珠", "Dingo": "汀果", "Dizzy": "蒂姬", "Doctor's Bag": "急救包", "Doll Maker Pearlhorizon": "制偶师波萝莱珍", "Dominiel": "多米妮尔", "Doris": "朵莉思", "Double-Edged Decrescent": "双刃下弦月", "Draco Plate": "龙族板甲", "Dream Scroll": "梦之卷轴", "Durandal": "杜兰月", "Dust Devil": "尘埃恶魔", "Dux Noctis": "暗夜指挥者", "Dragon King Sharun": "龙王莎伦", "Eaton": "伊顿", "Eda": "艾妲", "Egg of Delusion": "迷惑之蛋", "El's Fist": "艾尔之拳", "Elbris Ritual Sword": "埃布利斯的宝剑", "Elena": "艾蕾娜", "Elf's Bow": "妖精之弓", "Elphelt": "爱尔菲特", "Elson": "艾尔森", "Elyha's Knife": "埃里哈刀", "Emilia": "爱蜜莉雅", "Enhanced Gauntlet": "强化拳套", "Enott": "艾诺特", "Envoy's Pipe": "死神烟斗", "Ervalen": "艾尔巴伦", "Eternus": "埃特诺斯", "Etica's Scepter": "艾帝嘉权杖", "Exorcist's Tonfa": "斗鬼的拐棍", "Elvira": "艾碧拉", "Eternal Wanderer Ludwig": "永劫漂流者鲁特比", "Ezra": "艾自拉", "Fairy Tale for a Nightmare": "噩梦童话", "Fairy's Grimoire": "妖精的魔法书", "Fairytale Tenebria": "童话泰妮布里雅", "Faithless Lidica": "无神论者丽迪卡", "Falconer Kluri": "鹰猎人可露莉", "Fallen Cecilia": "堕落的赛西莉亚", "Fighter Maya": "战斗型玛雅", "Firm Shield": "坚定之盾", "Flan": "芙兰", "Flawless Garments": "天衣无缝", "Flower Shower": "洒花", "Forest Totem": "绿林图腾", "Free Spirit Tieria": "永恒不变的黛莉亚", "Furious": "尤贝乌斯", "Fumyr": "芙米尔", "General Purrgis": "大将法济斯", "Glenn": "格伦", "Gloomyrain": "格鲁美兰", "Goblin's Lamp": "鬼怪明灯", "Godmother": "教母", "Golden Cocoa Cookie": "黄金可可豆饼干", "Grail of Blood": "鲜血圣杯", "Great Chief Khawana": "大族长卡瓦娜", "Guardian Ice Crystals": "守护的冰封碎片", "Guide to a Decision": "选择的指标", "Guider Aither": "求道者埃德勒", "Guiding Light": "引导之光", "Gunther": "坤特", "Haste": "海斯特", "Hataan": "哈坦", "Hazel": "海兹", "Helen": "海伦", "Helga": "赫尔嘉", "Hell Cutter": "地狱切割机", "Hilag Lance": "锡拉革骑士长矛", "Holiday Yufine": "度假风优芬妮", "Holy Sacrifice": "神圣牺牲", "Hurado": "修拉杜", "Ian": "伊安", "Idol's Cheer": "歌姬助阵", "Iela Violin": "依埃萝小提琴", "Ilynav": "伊莉娜芙", "Inferno Khawazu": "烈焰的卡瓦朱", "Infinity Basket": "无限提篮", "Iron Fan": "铁扇", "Iseria": "伊赛丽亚", "Jecht": "杰克托", "Jena": "捷娜", "Judge Kise": "审判者绮世", "Judith": "茱迪丝", "Junkyard Dog": "Junkyard Dog", "Justice for All": "为众人的正义", "Kal'adra": "嘉拉特拉", "Karin": "卡琳", "Kawerik": "卡威利", "Kayron": "凯隆", "Ken": "肯恩", "Khawana": "卡瓦娜", "Khawazu": "卡瓦朱", "Kikirat v2": "奇奇拉特V.2", "Kiris": "奇丽丝", "Kise": "绮世", "Kitty Clarissa": "猫咪克莱莉莎", "Kizuna AI": "绊爱", "Kluri": "可露莉", "Knowledge Seed": "知识种子", "Krau": "克劳乌", "Kane": "该隐", "Labyrinth Cube": "迷宫的方块", "Landy": "兰蒂", "Last Rider Krau": "最后的骑士克劳乌", "Last Teatime": "最后的下午茶", "Lena": "雷娜", "Leo": "雷欧", "Lidica": "丽迪卡", "Lilias": "莉莉亚斯", "Lilibet": "莉莉贝", "Little Queen Charlotte": "年轻的女王夏绿蒂", "Lorina": "萝里娜", "Lots": "拉兹", "Love Potion": "爱情灵丹", "Lucy": "露西", "Ludwig": "鲁特比", "Luluca": "璐璐卡", "Luna": "露娜", "Leah": "蕾娅", "Magaraha's Tome": "玛姬拉哈的魔法古书", "Magic Scholar Doris": "魔法学者朵莉思", "Maid Chloe": "仆人克萝爱", "Manica of Control": "控制的护臂", "Manifu": "玛尼普", "Martial Artist Ken": "武斗家肯恩", "Mascot Hazel": "吉祥物海兹", "Maya": "玛雅", "Mediator Kawerik": "协调者卡威利", "Melany": "玫拉妮", "Melissa": "梅丽莎", "Mercedes": "玫勒赛德丝", "Mercenary Helga": "自由自在的佣兵赫尔嘉", "Merciless Glutton": "无情的大食客", "Midnight Bloom": "月夜之花", "Mighty Scout": "侦查兵玛伊堤", "Mighty Yaksha": "金刚夜叉", "Milim": "蜜莉姆", "Mirsa": "米勒莎", "Mistychain": "美丝缇彩", "Montmorancy": "蒙茉朗西", "Moonlight Dreamblade": "皎月梦夜", "Moonlight's Vestige": "月光之痕", "Mort": "魔勒", "Ms. Confille": "Miss Confile", "Mucacha": "穆卡察", "Mui": "缪伊", "Muse Rima": "缪斯黎玛", "Necro & Undine": "恶魔&天使", "Nemunas": "尼姆拉斯", "New Year Cookies": "蕴含幸福的岁末饼干", "Noble Oath": "高洁的誓言", "Oath Key": "誓约钥匙", "Official Levulin Beach Volleyball": "里柏林沙滩排球指定用球", "One Year of Gratitude": "心存感谢的一年", "Operator Sigret": "操作员赛珂兰特", "Otherworldly Machinery": "异界的机械", "Otillie": "奥缇莉尔", "Old Gardening Shears": "老旧园艺剪刀", "Pavel": "帕贝尔", "Pearlhorizon": "波萝莱珍", "Penelope": "潘尼罗佩", "Politis": "佛里蒂丝", "Portrait of the Saviors": "救援者们的画像", "Proof of Valor": "勇猛证据", "Prophetic Candlestick": "预视的烛台", "Pure White Trust": "纯白的信赖", "Purrgis": "法济斯", "Pyllis": "费莉丝", "Radiant Forever": "灿烂的永恒", "Rainbow Scale": "人鱼公主的鳞片", "Ram": "拉姆", "Ran": "岚", "Ranon's Memorandum": "拉农的备忘录", "Ras": "拉斯", "Ravi": "萝菲", "Ray": "雷伊", "Reingar's Special Drink": "雷茵格尔特调饮料", "Rem": "雷姆", "Remnant Violet": "残影的菲奥雷托", "Requiemroar": "雷奎姆洛", "Researcher Carrot": "研究者卡萝", "Resolute Soldier Series": "坚毅的战士", "Rhianna & Luciella": "里安娜&路西艾拉", "Righteous Thief Roozid": "义贼鲁兹德", "Rikoris": "里科黎司", "Rima": "黎玛", "Rimuru": "利姆路", "Rin": "铃儿", "Rise of a Monarch": "王的诞生", "Roaming Warrior Leo": "流浪勇士雷欧", "Roana": "罗安纳", "Rod of Amaryllis": "孤挺花之杖", "Romann": "洛曼", "Roozid": "鲁兹德", "Rosa Hargana": "罗沙哈勒戈纳", "Rose": "萝季", "Ruby Essence": "红玉精髓", "Ruele of Light": "光之瑞儿", "Sage Baal & Sezan": "贤者巴尔&塞尚", "Samsara Prayer Beads": "循环念珠", "Santa Muerte": "死亡圣神", "Sashe Ithanes": "香袋伊妲涅斯", "Schuri": "修里", "Seaside Bellona": "海边的维尔萝娜", "Secret Art - Storm Sword": "秘笈:雷天一剑", "Senya": "赛娜", "Sepulcrum": "塞弗克鲁姆", "Serila": "塞丽拉", "Severed Horn Wand": "被截断的犄角手杖", "Sez": "赛兹", "Shadow Knight Pyllis": "黑骑士费莉丝", "Shadow Rose": "暗影萝季", "Shepherd of the Hollow": "无为的引导者", "Shepherds of Chaos": "混沌的引导者们", "Shimadra Staff": "席玛德拉的手杖", "Shooting Star Achates": "流星雅卡泰丝", "Shuna": "朱菜", "Sigret": "赛珂兰特", "Sigurd Scythe": "席格勒赛斯", "Silk": "席可", "Silver Blade Aramintha": "白银刀刃的雅拉敏塔", "Silver Rain": "银光骤雨", "Sinful Angelica": "罪戾的安洁莉卡", "Sira-Ren": "席拉-莲", "Snow Crystal": "白雪水晶", "Sol": "索尔", "Solitaria of the Snow": "雪国的苏莉塔妮亚", "Song of Stars": "星辰之歌", "Sonia": "苏尼娅", "Spear of a New Dawn": "开辟之枪", "Specimen Sez": "实验体赛兹", "Specter Tenebria": "幻影的泰妮布里雅", "Spirit Eye Celine": "灵眼的瑟琳", "Spirit's Breath": "精灵气息", "Spooky Solayu Stories": "奇闻轶事录", "Staff of Wisdom": "智慧的手杖", "Star of the Deep Sea": "深海漂浮之星", "Star Piercer": "破星者", "Steadfast Gatekeeper": "坚定的看守者", "Stella Harpa": "星之竖琴", "Strak Gauntlet": "史特雷克拳套", "Straze": "史瑞杰思", "Succubus Mirror": "魅魔之镜", "Summertime Iseria": "南国的伊赛丽亚", "Super Duper Water Gun Shooter": "至尊水枪", "Surin": "苏琳", "Sven": "史宾", "Sword of Ezera": "伊杰拉的圣剑", "Sword of Holy Light": "圣光之剑", "Sword of Judgment": "审判之剑", "Sword of Summer Twilight": "夏夜闪刀", "Sword of the Morning": "黎明剑", "Sword of the Sun": "太阳之剑", "Sword of Winter Shadow": "冬晷切刀", "Silvertide Christy": "银波克莉丝媞", "Seductive Flower": "诱惑之花", "Tagehel's Ancient Book": "塔克赫尔古书", "Tamarinne": "塔玛林尔", "Taranor Guard": "塔拉诺尔禁卫队员", "Taranor Royal Guard": "塔拉诺尔王宫士兵", "Tear of the Desert": "沙漠之泪", "Tempest Surin": "风云苏琳", "Tenebria": "泰妮布里雅", "The Guardian Star's Blessing": "守护星的祝福", "Tieria": "黛莉亚", "Time Matter": "时间的物质", "Timeless Anchor": "永劫之锚", "To a New World": "致崭新的时代", "Top Model Luluca": "最强模特儿璐璐卡", "Torn Sleeve": "撕裂的右衣袖", "Touch of Rekos": "列科斯的救援", "Troublemaker Crozet": "不法之徒克罗泽", "Twilight Calamity": "落日之灾", "Tywin": "泰温", "Tyrant's Descent": "暴君的血统", "Uberius's Tooth": "尤贝里乌斯的臼齿", "Unfading Memories": "不凋零的回忆", "Unseen Observer": "隐形的观察者", "Upgraded Dragon Knuckles": "改良型龙指虎", "Umbral Keystones": "暗影源石", "Venus Orb": "金星宝珠", "Victorious Flag": "胜战旗帜", "Vildred": "维德瑞", "Violet Talisman": "紫色护身符", "Violet": "菲奥雷托", "Vivian": "薇薇安", "Wall of Order": "秩序护墙", "Wanda": "汪达", "Wanderer Silk": "流浪者席可", "War Horn": "进攻号角", "Watcher Schuri": "注视者修里", "Water's Origin": "波涛的祈愿", "Wild Angara": "野生安卡拉", "Wind Rider": "乘风者", "Wings of Light and Shadow": "明暗双翼", "Wondrous Potion Vial": "灵药的试管", "XIII. Death": "XIII. Death", "XIV. Temperance": "XIV. Temperance", "XVI. The Tower": "XVI. The Tower", "XVIII. The Moon": "XVIII. The Moon", "Yufine": "优芬妮", "Yuna": "尤娜", "Zahhak": "札哈克", "Zealot Carmainerose": "传道者卡麦萝兹", "Zeno": "杰诺", "Zerato": "杰拉图", "An Offer You Can't Refuse": "无法拒绝的提议", "Benimaru's Tachi": "红丸之刀", "Blazing Full Moon Trophy": "燃烧的满月奖杯", "Brilliant Confidence": "闪耀的自信", "Cutie Pando": "小可爱胖嘟", "Fan of Light and Dark": "昏明之扇", "Fullmetals Automail": "钢铁机械铠", "Glo-Wings 21": "光辉羽翼21", "Goblet of Oath": "誓言之杯", "Golden Rose": "金玫瑰", "Ignition Cloth Gloves": "发火布手套", "Indestructible Gaiters": "金刚绑腿", "Jack-O's Symbol": "洁克·欧的象征", "Magic for Friends": "为了朋友的魔法", "Mature Sunglasses": "成熟的墨镜", "Nostalgic Music Box": "悲恋音乐盒", "Prayer of Solitude": "孤独祈祷", "Prelude to a New Era": "新时代的序幕", "Records of Unity": "团结的记录", "Sacred Tree Branch": "神木树枝", "Scroll of Shadows": "暗影之书", "Seal of Capture": "束缚之印", "Sharpshooters Handgun": "神枪手的手枪", "Sole Consolation": "唯一的慰藉", "Spatiotemporal Fan": "时空折扇", "Spear of Purification": "破邪之矛", "Sphere of Inferno": "焚灭之球", "Sphere of Sadism": "嗜虐之球", "Sword of Autumn Eclipse": "秋端染刀", "Sword of Cycling Seasons": "循环之剑", "Aria": "艾莉雅", "Abigail": "雅碧凯", "Ainos 2.0": "艾诺斯 2.0", "Amid": "雅咪德", "Architect Laika": "策划者莱伊卡", "Arunka": "亚露嘉", "Astromancer Elena": "星辰的神谕艾蕾娜", "Bad Cat Armin": "坏猫猫亚敏", "Beehoo": "雨修", "Benimaru": "红丸", "Brieg": "布里克", "Commander Pavel": "司令官帕贝尔", "Death Dealer Ray": "死亡探究者雷伊", "Edward Elric": "爱德华·艾力克", "Eligos": "艾利戈斯", "Hasol": "夏率", "Holy Flame Adin": "圣炎的艾庭", "Hwayoung": "和英", "Infinite Horizon Achates": "未知可能性雅卡泰丝", "Jack-O": "洁克·欧", "Januta": "扎怒塔", "Juni": "珠妮", "Last Piece Karin": "最后的碎片卡琳", "Lethe": "丽希", "Lilka": "莉珈", "Lionheart Cermia": "狮心王洁若米亚", "Lone Crescent Bellona": "一轮孤月维尔萝娜", "Lua": "路雅", "Moon Bunny Dominiel": "月兔多米尼尔", "Muwi": "武蔚", "Navy Captain Landy": "海军上校兰蒂", "Ocean Breeze Luluca": "海洋香气璐璐卡", "Orte": "奥乐缇", "Peacemaker Furious": "平衡的尤贝乌斯", "Peira": "沛伊拉", "Pirate Captain Flan": "海盗船长芙兰", "Requiem Roana": "镇魂萝安纳", "Riza Hawkeye": "莉莎·霍克爱", "Roy Mustang": "罗伊·马斯坦古", "Savior Adin": "救援者艾庭", "Serene Purity Adin": "清玄的艾庭", "Sharun": "莎伦", "Shepherd Jena": "引导者捷娜", "Summer Break Charlotte": "暑假夏绿蒂", "Summer's Disciple Alexa": "夏日学生雅莉莎", "Suthan": "斯坦", "Sylvan Sage Vivian": "森之贤者薇薇安", "Taeyou": "太悟", "Talaz": "达拉士", "Talia": "达黎儿", "Twisted Eidolon Kayron": "扭曲亡灵凯隆", "Unbound Knight Arowell": "自由骑士雅洛薇", "Verdant Adin": "新绿的艾庭", "Veronica": "贝洛妮卡", "Vigilante Leader Glenn": "自卫队队长格伦", "Yoonryoung": "尹凌", "Yulha": "律荷", "Zio": "智武", "Midnight Gala Lilias": "夜宴莉莉亚斯", "Urban Shadow Choux": "都市暗影小泡芙", "Hostess of the Banquet": "宴会之主", "Nahkwol": "落月", "ae-GISELLE": "ae-GISELLE", "ae-KARINA": "ae-KARINA", "ae-NINGNING": "ae-NINGNING", "ae-WINTER": "ae-WINTER", "Laia": "莱雅", "Elegiac Candles": "慰灵烛光", "_comment_1": "角色神器结束", "scales": "天秤座", "lion": "狮子座", "waterbearer": "水瓶座", "archer": "射手座", "crab": "巨蟹座", "twins": "双子座", "bull": "金牛座", "fish": "双鱼座", "maiden": "处女座", "goat": "摩羯座", "scorpion": "天蝎座", "ram": "白羊座", "knight": "骑士", "warrior": "战士", "assassin": "潜行者", "mage": "魔导士", "ranger": "射手", "manauser": "精灵师", "fire": "火", "wind": "木", "ice": "水", "dark": "暗", "light": "光", "cp": "战斗力", "atk": "战斗力", "hp": "战斗力", "spd": "战斗力", "def": "战斗力", "chc": "战斗力", "chd": "战斗力", "dac": "战斗力", "eff": "战斗力", "efr": "", } // I18nZhToEn 中文->英文映射表(自动生成) var I18nZhToEn = func() map[string]string { m := make(map[string]string, len(I18nEnToZh)) for k, v := range I18nEnToZh { m[v] = k } return m }() type Logic struct { cache map[string]map[string]string // lang -> key -> value mutex sync.RWMutex } func New() *Logic { return &Logic{ cache: make(map[string]map[string]string), } } // 全局i18n实例 var globalI18nLogic *Logic var globalI18nMutex sync.RWMutex func init() { globalI18nLogic = New() } // GetI18nLogic 获取全局i18n实例 func GetI18nLogic() *Logic { globalI18nMutex.RLock() defer globalI18nMutex.RUnlock() return globalI18nLogic } // LoadFromDB 从数据库加载所有翻译到缓存 func (l *Logic) LoadFromDB(ctx context.Context) error { var mappings []*entity.EpicI18NMappings err := dao.EpicI18NMappings.Ctx(ctx). Where(dao.EpicI18NMappings.Columns().Status, 1). Where(dao.EpicI18NMappings.Columns().Deleted, 0). Scan(&mappings) if err != nil { return fmt.Errorf("加载i18n数据失败: %v", err) } l.mutex.Lock() defer l.mutex.Unlock() // 重新构建缓存 l.cache = make(map[string]map[string]string) for _, m := range mappings { if l.cache[m.Language] == nil { l.cache[m.Language] = make(map[string]string) } l.cache[m.Language][m.KeyName] = m.Value } util.Info(ctx, "i18n缓存加载完成,共", len(mappings), "条记录") return nil } // Get 获取指定key的指定语言翻译 func (l *Logic) Get(ctx context.Context, lang, key string) string { l.mutex.RLock() defer l.mutex.RUnlock() if m, ok := l.cache[lang]; ok { if v, ok := m[key]; ok { return v } } return key // 找不到返回原文 } // GetBatch 批量获取翻译 func (l *Logic) GetBatch(ctx context.Context, lang string, keys []string) map[string]string { l.mutex.RLock() defer l.mutex.RUnlock() result := make(map[string]string) if m, ok := l.cache[lang]; ok { for _, key := range keys { if v, ok := m[key]; ok { result[key] = v } else { result[key] = key // 找不到返回原文 } } } else { // 语言不存在,全部返回原文 for _, key := range keys { result[key] = key } } return result } // Refresh 刷新缓存 func (l *Logic) Refresh(ctx context.Context) error { return l.LoadFromDB(ctx) } // Add 添加翻译 func (l *Logic) Add(ctx context.Context, key, lang, value, category string) error { // 先保存到数据库 _, err := dao.EpicI18NMappings.Ctx(ctx).Data(g.Map{ dao.EpicI18NMappings.Columns().KeyName: key, dao.EpicI18NMappings.Columns().Language: lang, dao.EpicI18NMappings.Columns().Value: value, dao.EpicI18NMappings.Columns().Category: category, dao.EpicI18NMappings.Columns().Status: 1, dao.EpicI18NMappings.Columns().CreateTime: gtime.Now(), dao.EpicI18NMappings.Columns().UpdateTime: gtime.Now(), }).OnDuplicate("value", value).Insert() if err != nil { return fmt.Errorf("添加翻译失败: %v", err) } // 更新缓存 l.mutex.Lock() defer l.mutex.Unlock() if l.cache[lang] == nil { l.cache[lang] = make(map[string]string) } l.cache[lang][key] = value util.Info(ctx, "添加翻译:", lang, key, "->", value) return nil } // Update 更新翻译 func (l *Logic) Update(ctx context.Context, key, lang, value string) error { // 更新数据库 _, err := dao.EpicI18NMappings.Ctx(ctx). Where(dao.EpicI18NMappings.Columns().KeyName, key). Where(dao.EpicI18NMappings.Columns().Language, lang). Data(g.Map{ dao.EpicI18NMappings.Columns().Value: value, dao.EpicI18NMappings.Columns().UpdateTime: gtime.Now(), }).Update() if err != nil { return fmt.Errorf("更新翻译失败: %v", err) } // 更新缓存 l.mutex.Lock() defer l.mutex.Unlock() if l.cache[lang] == nil { l.cache[lang] = make(map[string]string) } l.cache[lang][key] = value util.Info(ctx, "更新翻译:", lang, key, "->", value) return nil } // Delete 删除翻译 func (l *Logic) Delete(ctx context.Context, key, lang string) error { // 软删除数据库记录 _, err := dao.EpicI18NMappings.Ctx(ctx). Where(dao.EpicI18NMappings.Columns().KeyName, key). Where(dao.EpicI18NMappings.Columns().Language, lang). Data(g.Map{ dao.EpicI18NMappings.Columns().Deleted: 1, dao.EpicI18NMappings.Columns().UpdateTime: gtime.Now(), }).Update() if err != nil { return fmt.Errorf("删除翻译失败: %v", err) } // 从缓存中删除 l.mutex.Lock() defer l.mutex.Unlock() if m, ok := l.cache[lang]; ok { delete(m, key) } util.Info(ctx, "删除翻译:", lang, key) return nil } // GetByCategory 根据分类获取翻译 func (l *Logic) GetByCategory(ctx context.Context, lang, category string) (map[string]string, error) { var mappings []*entity.EpicI18NMappings err := dao.EpicI18NMappings.Ctx(ctx). Where(dao.EpicI18NMappings.Columns().Language, lang). Where(dao.EpicI18NMappings.Columns().Category, category). Where(dao.EpicI18NMappings.Columns().Status, 1). Where(dao.EpicI18NMappings.Columns().Deleted, 0). Scan(&mappings) if err != nil { return nil, fmt.Errorf("获取分类翻译失败: %v", err) } result := make(map[string]string) for _, m := range mappings { result[m.KeyName] = m.Value } return result, nil } // ImportFromMap 从map批量导入翻译 func (l *Logic) ImportFromMap(ctx context.Context, lang string, mappings map[string]string, category string) error { if len(mappings) == 0 { return nil } // 批量插入数据库 var data []g.Map for key, value := range mappings { data = append(data, g.Map{ dao.EpicI18NMappings.Columns().KeyName: key, dao.EpicI18NMappings.Columns().Language: lang, dao.EpicI18NMappings.Columns().Value: value, dao.EpicI18NMappings.Columns().Category: category, dao.EpicI18NMappings.Columns().Status: 1, dao.EpicI18NMappings.Columns().CreateTime: gtime.Now(), dao.EpicI18NMappings.Columns().UpdateTime: gtime.Now(), }) } _, err := dao.EpicI18NMappings.Ctx(ctx).Data(data).OnDuplicate("value", g.Map{ dao.EpicI18NMappings.Columns().Value: g.Map{"value": "VALUES(value)"}, dao.EpicI18NMappings.Columns().UpdateTime: gtime.Now(), }).Insert() if err != nil { return fmt.Errorf("批量导入翻译失败: %v", err) } // 更新缓存 l.mutex.Lock() defer l.mutex.Unlock() if l.cache[lang] == nil { l.cache[lang] = make(map[string]string) } for key, value := range mappings { l.cache[lang][key] = value } util.Info(ctx, "批量导入翻译完成:", lang, category, "共", len(mappings), "条") return nil } // StartAutoRefresh 启动自动刷新 func (l *Logic) StartAutoRefresh(ctx context.Context) { // 启动时加载 if err := l.LoadFromDB(ctx); err != nil { util.Error(ctx, "初始加载i18n缓存失败:", err) } // 定时刷新(每小时) go func() { ticker := time.NewTicker(1 * time.Hour) defer ticker.Stop() for { select { case <-ticker.C: if err := l.Refresh(ctx); err != nil { util.Error(ctx, "定时刷新i18n缓存失败:", err) } case <-ctx.Done(): return } } }() } // En2Zh 英文转中文(静态映射) func En2Zh(s string) string { if v, ok := I18nEnToZh[s]; ok { return v } return s } // Zh2En 中文转英文(静态映射) func Zh2En(s string) string { if v, ok := I18nZhToEn[s]; ok { return v } return s } // GetI18n 获取指定key的指定语言翻译(优先使用数据库,找不到则使用静态映射) func GetI18n(ctx context.Context, lang, key string) string { // 优先使用数据库服务 if logic := GetI18nLogic(); logic != nil { result := logic.Get(ctx, lang, key) if result != key { return result } } // 数据库找不到,使用静态映射(仅支持中英文) if lang == "zh" { return En2Zh(key) } return key } // GetZh 获取中文翻译(便捷方法) func GetZh(ctx context.Context, key string) string { return GetI18n(ctx, "zh", key) } // GetEn 获取英文翻译(便捷方法) func GetEn(ctx context.Context, key string) string { return GetI18n(ctx, "en", key) } // GetI18nBatch 批量获取翻译 func GetI18nBatch(ctx context.Context, lang string, keys []string) map[string]string { if logic := GetI18nLogic(); logic != nil { return logic.GetBatch(ctx, lang, keys) } // 降级到静态映射 result := make(map[string]string) for _, key := range keys { result[key] = GetI18n(ctx, lang, key) } return result } // GetZhBatch 批量获取中文翻译(便捷方法) func GetZhBatch(ctx context.Context, keys []string) map[string]string { return GetI18nBatch(ctx, "zh", keys) } // GetEnBatch 批量获取英文翻译(便捷方法) func GetEnBatch(ctx context.Context, keys []string) map[string]string { return GetI18nBatch(ctx, "en", keys) } // RefreshI18n 刷新i18n缓存 func RefreshI18n(ctx context.Context) error { if logic := GetI18nLogic(); logic != nil { return logic.Refresh(ctx) } return nil } // AddI18n 添加翻译 func AddI18n(ctx context.Context, key, lang, value, category string) error { if logic := GetI18nLogic(); logic != nil { return logic.Add(ctx, key, lang, value, category) } return nil } // ImportI18nFromMap 从map批量导入翻译 func ImportI18nFromMap(ctx context.Context, lang string, mappings map[string]string, category string) error { if logic := GetI18nLogic(); logic != nil { return logic.ImportFromMap(ctx, lang, mappings, category) } return nil }