
- 新增多语言问题修复计划文档,详细描述了多语言支持的现状与解决方案。 - 在LocalizationManager中启用全局本地化方法,替换多个视图中的NSLocalizedString调用为LocalizedString。 - 更新MainFeature以确保在MeView标签页时正确加载用户数据。 - 在多个视图中添加语言切换测试区域,确保文本实时更新。 - 修复MeView显示问题,确保用户信息和动态内容正确加载。
176 lines
6.6 KiB
Swift
176 lines
6.6 KiB
Swift
import SwiftUI
|
||
import ComposableArchitecture
|
||
|
||
struct LanguageSettingsView: View {
|
||
@ObservedObject private var localizationManager = LocalizationManager.shared
|
||
@StateObject private var cosManager = COSManager.shared
|
||
@Binding var isPresented: Bool
|
||
|
||
// 使用 TCA 的依赖注入获取 API 服务
|
||
@Dependency(\.apiService) private var apiService
|
||
|
||
init(isPresented: Binding<Bool> = .constant(true)) {
|
||
self._isPresented = isPresented
|
||
}
|
||
|
||
var body: some View {
|
||
NavigationStack {
|
||
List {
|
||
Section {
|
||
ForEach(LocalizationManager.SupportedLanguage.allCases, id: \.rawValue) { language in
|
||
LanguageRow(
|
||
language: language,
|
||
isSelected: localizationManager.currentLanguage == language
|
||
) {
|
||
localizationManager.switchLanguage(to: language)
|
||
}
|
||
}
|
||
} header: {
|
||
Text("选择语言 / Select Language")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
Section {
|
||
HStack {
|
||
Text("当前语言 / Current Language")
|
||
.font(.body)
|
||
|
||
Spacer()
|
||
|
||
Text(localizationManager.currentLanguage.localizedDisplayName)
|
||
.font(.body)
|
||
.foregroundColor(.blue)
|
||
}
|
||
} header: {
|
||
Text("语言信息 / Language Info")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
// 新增:语言切换测试区域
|
||
Section {
|
||
VStack(alignment: .leading, spacing: 8) {
|
||
Text("语言切换测试")
|
||
.font(.headline)
|
||
.foregroundColor(.primary)
|
||
|
||
Text("应用标题: \(LocalizedString("login.app_title", comment: ""))")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
|
||
Text("登录按钮: \(LocalizedString("login.id_login", comment: ""))")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
|
||
Text("当前语言代码: \(localizationManager.currentLanguage.rawValue)")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
.padding(.vertical, 4)
|
||
} header: {
|
||
Text("测试区域")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
#if DEBUG
|
||
Section("调试功能") {
|
||
Button("测试腾讯云 COS Token") {
|
||
Task {
|
||
await testCOToken()
|
||
}
|
||
}
|
||
.foregroundColor(.blue)
|
||
|
||
if let tokenData = cosManager.token {
|
||
VStack(alignment: .leading, spacing: 8) {
|
||
Text("✅ Token 获取成功")
|
||
.font(.headline)
|
||
.foregroundColor(.green)
|
||
|
||
Group {
|
||
Text("存储桶: \(tokenData.bucket)")
|
||
Text("地域: \(tokenData.region)")
|
||
Text("应用ID: \(tokenData.appId)")
|
||
Text("自定义域名: \(tokenData.customDomain)")
|
||
Text("加速: \(tokenData.accelerate ? "启用" : "禁用")")
|
||
Text("过期时间: \(tokenData.expirationDate, style: .date)")
|
||
Text("剩余时间: \(tokenData.remainingTime)秒")
|
||
}
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
.padding(.vertical, 4)
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
.navigationTitle("语言设置 / Language")
|
||
.navigationBarTitleDisplayMode(.inline)
|
||
.navigationBarBackButtonHidden(true)
|
||
.onAppear {
|
||
#if DEBUG
|
||
// 调试环境下,页面显示时自动调用 tcToken API
|
||
Task {
|
||
await cosManager.testTokenRetrieval(apiService: apiService)
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
private func testCOToken() async {
|
||
// do {
|
||
let token = await cosManager.getToken(apiService: apiService)
|
||
if let token = token {
|
||
print("✅ Token 测试成功")
|
||
print(" - 存储桶: \(token.bucket)")
|
||
print(" - 地域: \(token.region)")
|
||
print(" - 剩余时间: \(token.remainingTime)秒")
|
||
} else {
|
||
print("❌ Token 测试失败: 未能获取 Token")
|
||
}
|
||
// } catch {
|
||
// print("❌ Token 测试异常: \(error.localizedDescription)")
|
||
// }
|
||
}
|
||
}
|
||
|
||
struct LanguageRow: View {
|
||
let language: LocalizationManager.SupportedLanguage
|
||
let isSelected: Bool
|
||
let onTap: () -> Void
|
||
|
||
var body: some View {
|
||
Button(action: onTap) {
|
||
HStack {
|
||
VStack(alignment: .leading, spacing: 4) {
|
||
Text(language.localizedDisplayName)
|
||
.font(.body)
|
||
.foregroundColor(.primary)
|
||
|
||
Text(language.displayName)
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
Spacer()
|
||
|
||
if isSelected {
|
||
Image(systemName: "checkmark.circle.fill")
|
||
.foregroundColor(.blue)
|
||
.font(.system(size: 20))
|
||
}
|
||
}
|
||
.contentShape(Rectangle())
|
||
}
|
||
.buttonStyle(PlainButtonStyle())
|
||
}
|
||
}
|
||
|
||
// MARK: - Preview
|
||
//#Preview {
|
||
// LanguageSettingsView(isPresented: .constant(true))
|
||
//}
|