23 changed files with 1190 additions and 237 deletions
@ -0,0 +1,34 @@ |
|||||
|
import 'package:flutter_intro/flutter_intro.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
import 'package:get_storage/get_storage.dart'; |
||||
|
|
||||
|
class NoviceGuideService extends GetxService { |
||||
|
final GetStorage _storage = GetStorage(); |
||||
|
|
||||
|
bool isHomeGuide = false; |
||||
|
bool isAIGuide = false; |
||||
|
|
||||
|
@override |
||||
|
void onInit() { |
||||
|
super.onInit(); |
||||
|
// isHomeGuide = _storage.read('home_guide') ?? false; |
||||
|
// isAIGuide = _storage.read('ai_guide') ?? false; |
||||
|
} |
||||
|
|
||||
|
void startHomeGuide() { |
||||
|
if (!isHomeGuide) { |
||||
|
isHomeGuide = true; |
||||
|
_storage.write('home_guide', true); |
||||
|
Intro.of(Get.context!).start(group: 'home'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void startAIGuide() async { |
||||
|
if (!isAIGuide) { |
||||
|
await Future.delayed(const Duration(milliseconds: 200)); |
||||
|
isAIGuide = true; |
||||
|
_storage.write('ai_guide', true); |
||||
|
Intro.of(Get.context!).start(group: 'ai'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Binary file not shown.
@ -0,0 +1,214 @@ |
|||||
|
import Foundation |
||||
|
import NaturalLanguage |
||||
|
|
||||
|
/** |
||||
|
* 语言检测工具类 |
||||
|
* 使用iOS自带的自然语言处理框架检测文本语种 |
||||
|
*/ |
||||
|
public class LanguageDetector { |
||||
|
|
||||
|
/** |
||||
|
* 检测文本的主要语言 |
||||
|
* |
||||
|
* @param text 需要检测的文本 |
||||
|
* @return 语言代码(如:"zh-Hans", "en", "ja"等),如果检测失败返回nil |
||||
|
*/ |
||||
|
public static func detectLanguage(from text: String) -> String? { |
||||
|
// 检查输入文本是否为空 |
||||
|
guard !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// 使用NLLanguageRecognizer进行语言检测 |
||||
|
let recognizer = NLLanguageRecognizer() |
||||
|
recognizer.processString(text) |
||||
|
|
||||
|
// 获取最可能的语言 |
||||
|
guard let dominantLanguage = recognizer.dominantLanguage else { |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
return dominantLanguage.rawValue |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 检测文本的语言并返回置信度 |
||||
|
* |
||||
|
* @param text 需要检测的文本 |
||||
|
* @return 语言代码和置信度的字典,按置信度降序排列 |
||||
|
*/ |
||||
|
public static func detectLanguageWithConfidence(from text: String) -> [(language: String, confidence: Double)] { |
||||
|
// 检查输入文本是否为空 |
||||
|
guard !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { |
||||
|
return [] |
||||
|
} |
||||
|
|
||||
|
let recognizer = NLLanguageRecognizer() |
||||
|
recognizer.processString(text) |
||||
|
|
||||
|
// 获取语言假设及其置信度 |
||||
|
let languageHypotheses = recognizer.languageHypotheses(withMaximum: 5) |
||||
|
|
||||
|
// 转换为元组数组并按置信度排序 |
||||
|
return languageHypotheses.map { (language: $0.key.rawValue, confidence: $0.value) } |
||||
|
.sorted { $0.confidence > $1.confidence } |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将语言代码转换为人类可读的语言名称 |
||||
|
* |
||||
|
* @param languageCode 语言代码(如:"zh-Hans", "en"等) |
||||
|
* @return 语言的本地化名称 |
||||
|
*/ |
||||
|
public static func getLanguageName(from languageCode: String) -> String { |
||||
|
let locale = Locale.current |
||||
|
return locale.localizedString(forLanguageCode: languageCode) ?? languageCode |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 检测文本语言并返回Azure语音服务支持的语言代码格式 |
||||
|
* |
||||
|
* @param text 需要检测的文本 |
||||
|
* @return Azure支持的语言代码格式(如:"zh-CN", "en-US"等) |
||||
|
*/ |
||||
|
public static func detectLanguageForAzure(from text: String) -> String? { |
||||
|
guard let detectedLanguage = detectLanguage(from: text) else { |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// 将iOS语言代码转换为Azure语音服务支持的格式 |
||||
|
return convertToAzureLanguageCode(detectedLanguage) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将iOS语言代码转换为Azure语音服务支持的语言代码 |
||||
|
* |
||||
|
* @param iosLanguageCode iOS检测到的语言代码 |
||||
|
* @return Azure支持的语言代码 |
||||
|
*/ |
||||
|
public static func convertToAzureLanguageCode(_ iosLanguageCode: String) -> String { |
||||
|
let languageMapping: [String: String] = [ |
||||
|
// 中文 |
||||
|
"zh-Hans": "zh-CN", // 简体中文 |
||||
|
"zh-Hant": "zh-TW", // 繁体中文 |
||||
|
"zh-HK": "zh-HK", // 香港中文 |
||||
|
|
||||
|
// 英语系 |
||||
|
"en": "en-US", // 英语(美国) |
||||
|
"en-GB": "en-US", // 英语(英国) |
||||
|
"en-AU": "en-US", // 英语(澳大利亚) |
||||
|
"en-CA": "en-US", // 英语(加拿大) |
||||
|
"en-IN": "en-US", // 英语(印度) |
||||
|
"en-IE": "en-US", // 英语(爱尔兰) |
||||
|
"en-NZ": "en-US", // 英语(新西兰) |
||||
|
"en-ZA": "en-US", // 英语(南非) |
||||
|
|
||||
|
// 亚洲语言 |
||||
|
"ja": "ja-JP", // 日语 |
||||
|
"ko": "ko-KR", // 韩语 |
||||
|
"hi": "hi-IN", // 印地语 |
||||
|
"th": "th-TH", // 泰语 |
||||
|
"vi": "vi-VN", // 越南语 |
||||
|
"id": "id-ID", // 印尼语 |
||||
|
"ms": "ms-MY", // 马来语 |
||||
|
"tl": "fil-PH", // 菲律宾语 |
||||
|
"my": "my-MM", // 缅甸语 |
||||
|
"km": "km-KH", // 高棉语(柬埔寨) |
||||
|
"lo": "lo-LA", // 老挝语 |
||||
|
"si": "si-LK", // 僧伽罗语(斯里兰卡) |
||||
|
"ta": "ta-IN", // 泰米尔语 |
||||
|
"te": "te-IN", // 泰卢固语 |
||||
|
"bn": "bn-IN", // 孟加拉语 |
||||
|
"gu": "gu-IN", // 古吉拉特语 |
||||
|
"kn": "kn-IN", // 卡纳达语 |
||||
|
"ml": "ml-IN", // 马拉雅拉姆语 |
||||
|
"mr": "mr-IN", // 马拉地语 |
||||
|
"pa": "pa-IN", // 旁遮普语 |
||||
|
"ur": "ur-PK", // 乌尔都语 |
||||
|
|
||||
|
// 欧洲语言 |
||||
|
"fr": "fr-FR", // 法语(法国) |
||||
|
"fr-CA": "fr-CA", // 法语(加拿大) |
||||
|
"fr-BE": "fr-BE", // 法语(比利时) |
||||
|
"fr-CH": "fr-CH", // 法语(瑞士) |
||||
|
"de": "de-DE", // 德语(德国) |
||||
|
"de-AT": "de-AT", // 德语(奥地利) |
||||
|
"de-CH": "de-CH", // 德语(瑞士) |
||||
|
"es": "es-ES", // 西班牙语(西班牙) |
||||
|
"es-MX": "es-MX", // 西班牙语(墨西哥) |
||||
|
"es-AR": "es-AR", // 西班牙语(阿根廷) |
||||
|
"es-CO": "es-CO", // 西班牙语(哥伦比亚) |
||||
|
"es-CL": "es-CL", // 西班牙语(智利) |
||||
|
"es-PE": "es-PE", // 西班牙语(秘鲁) |
||||
|
"es-VE": "es-VE", // 西班牙语(委内瑞拉) |
||||
|
"it": "it-IT", // 意大利语 |
||||
|
"pt": "pt-BR", // 葡萄牙语(巴西) |
||||
|
"pt-PT": "pt-PT", // 葡萄牙语(葡萄牙) |
||||
|
"ru": "ru-RU", // 俄语 |
||||
|
"nl": "nl-NL", // 荷兰语 |
||||
|
"nl-BE": "nl-BE", // 荷兰语(比利时) |
||||
|
"sv": "sv-SE", // 瑞典语 |
||||
|
"da": "da-DK", // 丹麦语 |
||||
|
"no": "nb-NO", // 挪威语 |
||||
|
"fi": "fi-FI", // 芬兰语 |
||||
|
"is": "is-IS", // 冰岛语 |
||||
|
"pl": "pl-PL", // 波兰语 |
||||
|
"cs": "cs-CZ", // 捷克语 |
||||
|
"sk": "sk-SK", // 斯洛伐克语 |
||||
|
"hu": "hu-HU", // 匈牙利语 |
||||
|
"ro": "ro-RO", // 罗马尼亚语 |
||||
|
"bg": "bg-BG", // 保加利亚语 |
||||
|
"hr": "hr-HR", // 克罗地亚语 |
||||
|
"sr": "sr-RS", // 塞尔维亚语 |
||||
|
"sl": "sl-SI", // 斯洛文尼亚语 |
||||
|
"et": "et-EE", // 爱沙尼亚语 |
||||
|
"lv": "lv-LV", // 拉脱维亚语 |
||||
|
"lt": "lt-LT", // 立陶宛语 |
||||
|
"uk": "uk-UA", // 乌克兰语 |
||||
|
"be": "be-BY", // 白俄罗斯语 |
||||
|
"mk": "mk-MK", // 马其顿语 |
||||
|
"sq": "sq-AL", // 阿尔巴尼亚语 |
||||
|
"mt": "mt-MT", // 马耳他语 |
||||
|
"ga": "ga-IE", // 爱尔兰语 |
||||
|
"cy": "cy-GB", // 威尔士语 |
||||
|
"eu": "eu-ES", // 巴斯克语 |
||||
|
"ca": "ca-ES", // 加泰罗尼亚语 |
||||
|
"gl": "gl-ES", // 加利西亚语 |
||||
|
|
||||
|
// 中东和非洲语言 |
||||
|
"ar": "ar-SA", // 阿拉伯语(沙特阿拉伯) |
||||
|
"ar-EG": "ar-EG", // 阿拉伯语(埃及) |
||||
|
"ar-AE": "ar-AE", // 阿拉伯语(阿联酋) |
||||
|
"ar-BH": "ar-BH", // 阿拉伯语(巴林) |
||||
|
"ar-DZ": "ar-DZ", // 阿拉伯语(阿尔及利亚) |
||||
|
"ar-IQ": "ar-IQ", // 阿拉伯语(伊拉克) |
||||
|
"ar-JO": "ar-JO", // 阿拉伯语(约旦) |
||||
|
"ar-KW": "ar-KW", // 阿拉伯语(科威特) |
||||
|
"ar-LB": "ar-LB", // 阿拉伯语(黎巴嫩) |
||||
|
"ar-LY": "ar-LY", // 阿拉伯语(利比亚) |
||||
|
"ar-MA": "ar-MA", // 阿拉伯语(摩洛哥) |
||||
|
"ar-OM": "ar-OM", // 阿拉伯语(阿曼) |
||||
|
"ar-QA": "ar-QA", // 阿拉伯语(卡塔尔) |
||||
|
"ar-SY": "ar-SY", // 阿拉伯语(叙利亚) |
||||
|
"ar-TN": "ar-TN", // 阿拉伯语(突尼斯) |
||||
|
"ar-YE": "ar-YE", // 阿拉伯语(也门) |
||||
|
"he": "he-IL", // 希伯来语 |
||||
|
"fa": "fa-IR", // 波斯语(伊朗) |
||||
|
"tr": "tr-TR", // 土耳其语 |
||||
|
"az": "az-AZ", // 阿塞拜疆语 |
||||
|
"ka": "ka-GE", // 格鲁吉亚语 |
||||
|
"hy": "hy-AM", // 亚美尼亚语 |
||||
|
"sw": "sw-KE", // 斯瓦希里语 |
||||
|
"am": "am-ET", // 阿姆哈拉语(埃塞俄比亚) |
||||
|
"zu": "zu-ZA", // 祖鲁语(南非) |
||||
|
"af": "af-ZA", // 南非荷兰语 |
||||
|
|
||||
|
// 其他语言 |
||||
|
"el": "el-GR", // 希腊语 |
||||
|
"eo": "eo", // 世界语 |
||||
|
"la": "la", // 拉丁语 |
||||
|
] |
||||
|
|
||||
|
return languageMapping[iosLanguageCode] ?? iosLanguageCode |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue