
- 创建SettingPage视图,包含用户信息管理、头像设置、昵称编辑等功能。 - 实现SettingViewModel,处理设置页面的业务逻辑,包括头像上传、昵称更新等。 - 添加相机和相册选择功能,支持头像更换。 - 更新MainPage和MainViewModel,添加导航逻辑以支持设置页面的访问。 - 完善本地化支持,确保多语言兼容性。 - 新增相关测试建议,确保功能完整性和用户体验。
269 lines
7.9 KiB
Swift
269 lines
7.9 KiB
Swift
import SwiftUI
|
|
import PhotosUI
|
|
import UIKit
|
|
|
|
// MARK: - Setting ViewModel
|
|
|
|
@MainActor
|
|
class SettingViewModel: ObservableObject {
|
|
// MARK: - Published Properties
|
|
@Published var userInfo: UserInfo?
|
|
@Published var isLoadingUserInfo: Bool = false
|
|
@Published var userInfoError: String?
|
|
|
|
// 头像相关
|
|
@Published var isUploadingAvatar: Bool = false
|
|
@Published var avatarUploadError: String?
|
|
|
|
// 昵称编辑相关
|
|
@Published var isEditingNickname: Bool = false
|
|
@Published var nicknameInput: String = ""
|
|
@Published var isUpdatingUser: Bool = false
|
|
@Published var updateUserError: String?
|
|
|
|
// 图片选择相关
|
|
@Published var showImageSourceActionSheet: Bool = false
|
|
@Published var showCamera: Bool = false
|
|
@Published var showPhotoPicker: Bool = false
|
|
@Published var selectedPhotoItems: [PhotosPickerItem] = []
|
|
|
|
// 弹窗状态
|
|
@Published var showLogoutConfirmation: Bool = false
|
|
@Published var showAboutUs: Bool = false
|
|
@Published var showPrivacyPolicy: Bool = false
|
|
@Published var showUserAgreement: Bool = false
|
|
@Published var showDeactivateAccount: Bool = false
|
|
|
|
// MARK: - Callbacks
|
|
var onBack: (() -> Void)?
|
|
var onLogout: (() -> Void)?
|
|
|
|
// MARK: - Private Properties
|
|
private let apiService: APIServiceProtocol
|
|
|
|
// MARK: - Initialization
|
|
init(apiService: APIServiceProtocol = LiveAPIService()) {
|
|
self.apiService = apiService
|
|
}
|
|
|
|
// MARK: - Public Methods
|
|
func onAppear() {
|
|
debugInfoSync("⚙️ SettingPage onAppear")
|
|
loadUserInfo()
|
|
}
|
|
|
|
func onBackTapped() {
|
|
onBack?()
|
|
}
|
|
|
|
// MARK: - User Info Management
|
|
private func loadUserInfo() {
|
|
isLoadingUserInfo = true
|
|
userInfoError = nil
|
|
|
|
Task {
|
|
if let userInfo = await UserInfoManager.getUserInfo() {
|
|
self.userInfo = userInfo
|
|
debugInfoSync("✅ 用户信息加载成功")
|
|
} else {
|
|
// 尝试从服务器获取
|
|
if let userInfo = await UserInfoManager.fetchUserInfoFromServer(apiService: apiService) {
|
|
self.userInfo = userInfo
|
|
debugInfoSync("✅ 从服务器获取用户信息成功")
|
|
} else {
|
|
self.userInfoError = "获取用户信息失败"
|
|
debugErrorSync("❌ 获取用户信息失败")
|
|
}
|
|
}
|
|
self.isLoadingUserInfo = false
|
|
}
|
|
}
|
|
|
|
// MARK: - Avatar Management
|
|
func onAvatarTapped() {
|
|
showImageSourceActionSheet = true
|
|
}
|
|
|
|
func selectImageSource(_ source: AppImageSource) {
|
|
showImageSourceActionSheet = false
|
|
|
|
switch source {
|
|
case .camera:
|
|
showCamera = true
|
|
case .photoLibrary:
|
|
showPhotoPicker = true
|
|
}
|
|
}
|
|
|
|
func onCameraImagePicked(_ image: UIImage) {
|
|
showCamera = false
|
|
uploadAvatar(image)
|
|
}
|
|
|
|
func onPhotoPickerItemsChanged(_ items: [PhotosPickerItem]) {
|
|
selectedPhotoItems = items
|
|
|
|
Task {
|
|
if let item = items.first {
|
|
if let data = try? await item.loadTransferable(type: Data.self),
|
|
let image = UIImage(data: data) {
|
|
await MainActor.run {
|
|
showPhotoPicker = false
|
|
uploadAvatar(image)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func uploadAvatar(_ image: UIImage) {
|
|
isUploadingAvatar = true
|
|
avatarUploadError = nil
|
|
|
|
Task {
|
|
if let url = await COSManagerAdapter.shared.uploadUIImage(image, apiService: apiService) {
|
|
await MainActor.run {
|
|
self.isUploadingAvatar = false
|
|
self.updateUserAvatar(url)
|
|
}
|
|
} else {
|
|
await MainActor.run {
|
|
self.isUploadingAvatar = false
|
|
self.avatarUploadError = "头像上传失败"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func updateUserAvatar(_ avatarUrl: String) {
|
|
guard let userInfo = userInfo else { return }
|
|
|
|
isUpdatingUser = true
|
|
updateUserError = nil
|
|
|
|
Task {
|
|
do {
|
|
let ticket = await UserInfoManager.getCurrentUserTicket() ?? ""
|
|
let request = UpdateUserRequest(avatar: avatarUrl, nick: nil, uid: userInfo.uid ?? 0, ticket: ticket)
|
|
let response: UpdateUserResponse = try await apiService.request(request)
|
|
|
|
await MainActor.run {
|
|
self.isUpdatingUser = false
|
|
if response.code == 200 {
|
|
// 刷新用户信息
|
|
self.loadUserInfo()
|
|
} else {
|
|
self.updateUserError = response.message
|
|
}
|
|
}
|
|
} catch {
|
|
await MainActor.run {
|
|
self.isUpdatingUser = false
|
|
self.updateUserError = error.localizedDescription
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Nickname Management
|
|
func onNicknameTapped() {
|
|
nicknameInput = userInfo?.nick ?? ""
|
|
isEditingNickname = true
|
|
}
|
|
|
|
func onNicknameInputChanged(_ text: String) {
|
|
nicknameInput = String(text.prefix(15))
|
|
}
|
|
|
|
func onNicknameEditConfirmed() {
|
|
let trimmed = nicknameInput.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
guard !trimmed.isEmpty else { return }
|
|
|
|
isEditingNickname = false
|
|
updateUserNickname(trimmed)
|
|
}
|
|
|
|
private func updateUserNickname(_ nickname: String) {
|
|
guard let userInfo = userInfo else { return }
|
|
|
|
isUpdatingUser = true
|
|
updateUserError = nil
|
|
|
|
Task {
|
|
do {
|
|
let ticket = await UserInfoManager.getCurrentUserTicket() ?? ""
|
|
let request = UpdateUserRequest(avatar: nil, nick: nickname, uid: userInfo.uid ?? 0, ticket: ticket)
|
|
let response: UpdateUserResponse = try await apiService.request(request)
|
|
|
|
await MainActor.run {
|
|
self.isUpdatingUser = false
|
|
if response.code == 200 {
|
|
// 刷新用户信息
|
|
self.loadUserInfo()
|
|
} else {
|
|
self.updateUserError = response.message
|
|
}
|
|
}
|
|
} catch {
|
|
await MainActor.run {
|
|
self.isUpdatingUser = false
|
|
self.updateUserError = error.localizedDescription
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Settings Actions
|
|
func onPersonalInfoPermissionsTapped() {
|
|
showPrivacyPolicy = true
|
|
}
|
|
|
|
func onHelpTapped() {
|
|
showUserAgreement = true
|
|
}
|
|
|
|
func onClearCacheTapped() {
|
|
// TODO: 实现清除缓存逻辑
|
|
debugInfoSync("🗑️ 清除缓存")
|
|
}
|
|
|
|
func onCheckUpdatesTapped() {
|
|
// TODO: 实现检查更新逻辑
|
|
debugInfoSync("🔄 检查更新")
|
|
}
|
|
|
|
func onDeactivateAccountTapped() {
|
|
showDeactivateAccount = true
|
|
}
|
|
|
|
func onAboutUsTapped() {
|
|
showAboutUs = true
|
|
}
|
|
|
|
func onLogoutTapped() {
|
|
showLogoutConfirmation = true
|
|
}
|
|
|
|
func onLogoutConfirmed() {
|
|
Task {
|
|
await UserInfoManager.clearAllAuthenticationData()
|
|
await MainActor.run {
|
|
onLogout?()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - WebView Dismissal
|
|
func onPrivacyPolicyDismissed() {
|
|
showPrivacyPolicy = false
|
|
}
|
|
|
|
func onUserAgreementDismissed() {
|
|
showUserAgreement = false
|
|
}
|
|
|
|
func onDeactivateAccountDismissed() {
|
|
showDeactivateAccount = false
|
|
}
|
|
}
|