feat: 增强邮箱登录功能和密码恢复流程
- 更新邮箱登录相关功能,新增邮箱验证码获取和登录API端点。 - 添加AccountModel以管理用户认证信息,支持会话票据的存储和更新。 - 实现密码恢复功能,支持通过邮箱获取验证码和重置密码。 - 增加本地化支持,更新相关字符串以适应新功能。 - 引入ValidationHelper以验证邮箱和密码格式,确保用户输入的有效性。 - 更新视图以支持邮箱登录和密码恢复的用户交互。
This commit is contained in:
@@ -11,13 +11,11 @@ struct IDLoginFeature {
|
||||
var isLoading = false
|
||||
var errorMessage: String?
|
||||
|
||||
// 新增:Ticket 相关状态
|
||||
var accessToken: String?
|
||||
var ticket: String?
|
||||
// 新增:Account Model 和 Ticket 相关状态
|
||||
var accountModel: AccountModel?
|
||||
var isTicketLoading = false
|
||||
var ticketError: String?
|
||||
var loginStep: LoginStep = .initial
|
||||
var uid: Int? // 修改:保存用户 uid,类型改为Int
|
||||
|
||||
enum LoginStep: Equatable {
|
||||
case initial // 初始状态
|
||||
@@ -101,22 +99,26 @@ struct IDLoginFeature {
|
||||
if response.isSuccess {
|
||||
// OAuth 认证成功,清除错误信息
|
||||
state.errorMessage = nil
|
||||
state.accessToken = response.data?.accessToken
|
||||
state.uid = response.data?.uid // 保存 uid
|
||||
|
||||
// 保存用户信息(如果有)
|
||||
if let userInfo = response.data?.userInfo {
|
||||
UserInfoManager.saveUserInfo(userInfo)
|
||||
}
|
||||
|
||||
print("✅ ID 登录 OAuth 认证成功")
|
||||
if let accessToken = response.data?.accessToken {
|
||||
print("🔑 Access Token: \(accessToken)")
|
||||
// 自动获取 ticket,传递 uid
|
||||
return .send(.requestTicket(accessToken: accessToken))
|
||||
}
|
||||
if let uid = response.data?.uid {
|
||||
print("🆔 用户 UID: \(uid)")
|
||||
// 从响应数据创建 AccountModel
|
||||
if let loginData = response.data,
|
||||
let accountModel = AccountModel.from(loginData: loginData) {
|
||||
state.accountModel = accountModel
|
||||
|
||||
// 保存用户信息(如果有)
|
||||
if let userInfo = loginData.userInfo {
|
||||
UserInfoManager.saveUserInfo(userInfo)
|
||||
}
|
||||
|
||||
print("✅ ID 登录 OAuth 认证成功")
|
||||
print("🔑 Access Token: \(accountModel.accessToken ?? "nil")")
|
||||
print("🆔 用户 UID: \(accountModel.uid ?? "nil")")
|
||||
|
||||
// 自动获取 ticket
|
||||
return .send(.requestTicket(accessToken: accountModel.accessToken!))
|
||||
} else {
|
||||
state.errorMessage = "登录数据格式错误"
|
||||
state.loginStep = .failed
|
||||
}
|
||||
} else {
|
||||
state.errorMessage = response.errorMessage
|
||||
@@ -135,9 +137,10 @@ struct IDLoginFeature {
|
||||
state.ticketError = nil
|
||||
state.loginStep = .gettingTicket
|
||||
|
||||
return .run { [uid = state.uid] send in
|
||||
return .run { [accountModel = state.accountModel] send in
|
||||
do {
|
||||
// 使用 TicketHelper 创建请求,传递 uid
|
||||
// 从 AccountModel 获取 uid,转换为 Int 类型
|
||||
let uid = accountModel?.uid != nil ? Int(accountModel!.uid!) : nil
|
||||
let ticketRequest = TicketHelper.createTicketRequest(accessToken: accessToken, uid: uid)
|
||||
let response = try await apiService.request(ticketRequest)
|
||||
await send(.ticketResponse(.success(response)))
|
||||
@@ -151,27 +154,32 @@ struct IDLoginFeature {
|
||||
state.isTicketLoading = false
|
||||
if response.isSuccess {
|
||||
state.ticketError = nil
|
||||
state.ticket = response.ticket
|
||||
state.loginStep = .completed
|
||||
|
||||
print("✅ ID 登录完整流程成功")
|
||||
print("🎫 Ticket 获取成功: \(response.ticket ?? "nil")")
|
||||
|
||||
// 保存认证信息到本地存储(包括用户信息)
|
||||
if let accessToken = state.accessToken,
|
||||
let ticket = response.ticket {
|
||||
// 从之前的登录响应中获取用户信息
|
||||
let userInfo = UserInfoManager.getUserInfo()
|
||||
UserInfoManager.saveCompleteAuthenticationData(
|
||||
accessToken: accessToken,
|
||||
ticket: ticket,
|
||||
uid: state.uid,
|
||||
userInfo: userInfo
|
||||
)
|
||||
// 更新 AccountModel 中的 ticket 并保存
|
||||
if let ticket = response.ticket {
|
||||
if var accountModel = state.accountModel {
|
||||
accountModel.ticket = ticket
|
||||
state.accountModel = accountModel
|
||||
|
||||
// 保存完整的 AccountModel
|
||||
UserInfoManager.saveAccountModel(accountModel)
|
||||
|
||||
// 发送 Ticket 获取成功通知,触发导航到主页面
|
||||
NotificationCenter.default.post(name: .ticketSuccess, object: nil)
|
||||
} else {
|
||||
print("❌ AccountModel 不存在,无法保存 ticket")
|
||||
state.ticketError = "内部错误:账户信息丢失"
|
||||
state.loginStep = .failed
|
||||
}
|
||||
} else {
|
||||
state.ticketError = "Ticket 为空"
|
||||
state.loginStep = .failed
|
||||
}
|
||||
|
||||
// TODO: 触发导航到主界面
|
||||
|
||||
} else {
|
||||
state.ticketError = response.errorMessage
|
||||
state.loginStep = .failed
|
||||
@@ -194,9 +202,7 @@ struct IDLoginFeature {
|
||||
state.isTicketLoading = false
|
||||
state.errorMessage = nil
|
||||
state.ticketError = nil
|
||||
state.accessToken = nil
|
||||
state.ticket = nil
|
||||
state.uid = nil // 清除 uid
|
||||
state.accountModel = nil // 清除 AccountModel
|
||||
state.loginStep = .initial
|
||||
|
||||
// 清除本地存储的认证信息
|
||||
|
Reference in New Issue
Block a user