完善注册流程
This commit is contained in:
parent
fd87c244b9
commit
ed6ae5c757
@ -12,12 +12,12 @@ import Observation
|
|||||||
class RegisterModel {
|
class RegisterModel {
|
||||||
|
|
||||||
enum Stage {
|
enum Stage {
|
||||||
case requestVerifyCode
|
case requestVerifyCode(username: String?)
|
||||||
case submitVerifyCode(username: String)
|
case submitVerifyCode(username: String)
|
||||||
case setPassword(username: String)
|
case setPassword(username: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
var stage: Stage = .requestVerifyCode
|
var stage: Stage = .requestVerifyCode(username: nil)
|
||||||
|
|
||||||
private let baseParams: [String: Any] = [
|
private let baseParams: [String: Any] = [
|
||||||
"client_id": SystemConfig.getClientId(),
|
"client_id": SystemConfig.getClientId(),
|
||||||
|
|||||||
@ -19,8 +19,8 @@ struct RegisterRootView: View {
|
|||||||
|
|
||||||
Group {
|
Group {
|
||||||
switch registerModel.stage {
|
switch registerModel.stage {
|
||||||
case .requestVerifyCode:
|
case .requestVerifyCode(let username):
|
||||||
RegisterRequestVerifyCodeView()
|
RegisterRequestVerifyCodeView(username: username ?? "")
|
||||||
case .submitVerifyCode(let username):
|
case .submitVerifyCode(let username):
|
||||||
RegisterSubmitVerifyCodeView(username: username)
|
RegisterSubmitVerifyCodeView(username: username)
|
||||||
case .setPassword(let username):
|
case .setPassword(let username):
|
||||||
@ -71,7 +71,7 @@ struct PunchTextField: View {
|
|||||||
// MARK: - 第一步:获取验证码
|
// MARK: - 第一步:获取验证码
|
||||||
struct RegisterRequestVerifyCodeView: View {
|
struct RegisterRequestVerifyCodeView: View {
|
||||||
@Environment(RegisterModel.self) var registerModel
|
@Environment(RegisterModel.self) var registerModel
|
||||||
@State private var username: String = ""
|
@State var username: String = ""
|
||||||
@State private var isProcessing = false
|
@State private var isProcessing = false
|
||||||
|
|
||||||
// 错误提示
|
// 错误提示
|
||||||
@ -155,18 +155,30 @@ struct RegisterSubmitVerifyCodeView: View {
|
|||||||
@State private var showAlert: Bool = false
|
@State private var showAlert: Bool = false
|
||||||
@State private var errorMessage: String = ""
|
@State private var errorMessage: String = ""
|
||||||
|
|
||||||
|
// 重新发送是否可以使用
|
||||||
|
@State private var isEnabled: Bool = false
|
||||||
|
@State private var remainingSeconds = 60
|
||||||
|
@State private var timer: Timer? = nil
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 24) {
|
VStack(spacing: 24) {
|
||||||
headerSection(title: "身份验证", subtitle: "验证码已发送至 \(username)")
|
headerSection(title: "身份验证", subtitle: "验证码已发送至 \(username)")
|
||||||
|
|
||||||
VStack(spacing: 16) {
|
VStack(alignment: .trailing, spacing: 16) {
|
||||||
PunchTextField(icon: "envelope.badge", placeholder: "输入 4 位验证码", text: $code)
|
PunchTextField(icon: "envelope.badge", placeholder: "输入 4 位验证码", text: $code)
|
||||||
|
|
||||||
Button("没有收到?重新获取") {
|
Button {
|
||||||
// Resend Logic
|
self.resendVerifyCodeAction()
|
||||||
|
} label: {
|
||||||
|
if isEnabled {
|
||||||
|
Text("没有收到?重新获取")
|
||||||
|
} else {
|
||||||
|
Text("重新获取 (\(remainingSeconds)s)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.link)
|
.buttonStyle(.link)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
.disabled(!isEnabled) // 倒计时期间禁用按钮
|
||||||
}
|
}
|
||||||
.frame(width: 280)
|
.frame(width: 280)
|
||||||
|
|
||||||
@ -188,7 +200,7 @@ struct RegisterSubmitVerifyCodeView: View {
|
|||||||
|
|
||||||
Button("返回上一步") {
|
Button("返回上一步") {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
registerModel.stage = .requestVerifyCode
|
registerModel.stage = .requestVerifyCode(username: self.username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
@ -202,8 +214,37 @@ struct RegisterSubmitVerifyCodeView: View {
|
|||||||
.alert(isPresented: $showAlert) {
|
.alert(isPresented: $showAlert) {
|
||||||
Alert(title: Text("提示"), message: Text(errorMessage))
|
Alert(title: Text("提示"), message: Text(errorMessage))
|
||||||
}
|
}
|
||||||
|
.task {
|
||||||
|
await self.startCountdown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重新发送验证码
|
||||||
|
private func resendVerifyCodeAction() {
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
let result = try await self.registerModel.requestVerifyCode(username: username)
|
||||||
|
print("send verify code result: \(result)")
|
||||||
|
} catch let err {
|
||||||
|
print("resend verify get error: \(err)")
|
||||||
|
}
|
||||||
|
// 重新计时
|
||||||
|
await self.startCountdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新倒计时
|
||||||
|
private func startCountdown() async {
|
||||||
|
self.isEnabled = false
|
||||||
|
self.remainingSeconds = 60
|
||||||
|
for sec in (1...self.remainingSeconds).reversed() {
|
||||||
|
self.remainingSeconds = sec
|
||||||
|
try? await Task.sleep(nanoseconds: 1_000_000_000)
|
||||||
|
}
|
||||||
|
self.isEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交验证码
|
||||||
private func submitVerifyCode() {
|
private func submitVerifyCode() {
|
||||||
self.isProcessing = true
|
self.isProcessing = true
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
@ -245,8 +286,22 @@ struct RegisterSetPasswordView: View {
|
|||||||
@State private var isProcessing = false
|
@State private var isProcessing = false
|
||||||
|
|
||||||
// 错误提示
|
// 错误提示
|
||||||
@State private var showAlert: Bool = false
|
@State private var errorMessage: String?
|
||||||
@State private var errorMessage: String = ""
|
|
||||||
|
// 提示错误信息
|
||||||
|
var passwordError: String? {
|
||||||
|
if password.isEmpty || confirm.isEmpty {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if password != confirm {
|
||||||
|
return "两次输入的密码不一致"
|
||||||
|
}
|
||||||
|
if password.count < 8 {
|
||||||
|
return "密码至少需要 8 位"
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 24) {
|
VStack(spacing: 24) {
|
||||||
@ -255,6 +310,12 @@ struct RegisterSetPasswordView: View {
|
|||||||
VStack(spacing: 12) {
|
VStack(spacing: 12) {
|
||||||
PunchTextField(icon: "lock.shield", placeholder: "新密码", text: $password, isSecure: true)
|
PunchTextField(icon: "lock.shield", placeholder: "新密码", text: $password, isSecure: true)
|
||||||
PunchTextField(icon: "lock.shield", placeholder: "确认密码", text: $confirm, isSecure: true)
|
PunchTextField(icon: "lock.shield", placeholder: "确认密码", text: $confirm, isSecure: true)
|
||||||
|
if let error = passwordError {
|
||||||
|
Text(error)
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.red)
|
||||||
|
.frame(width: 280, alignment: .leading)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.frame(width: 280)
|
.frame(width: 280)
|
||||||
|
|
||||||
@ -273,38 +334,20 @@ struct RegisterSetPasswordView: View {
|
|||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
.controlSize(.large)
|
.controlSize(.large)
|
||||||
.frame(width: 280)
|
.frame(width: 280)
|
||||||
.disabled(password.isEmpty || password != confirm)
|
.disabled(passwordError != nil)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.padding(40)
|
.padding(40)
|
||||||
.alert(isPresented: $showAlert) {
|
|
||||||
Alert(title: Text("提示"), message: Text(errorMessage))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleRegister() {
|
private func handleRegister() {
|
||||||
self.isProcessing = true
|
self.isProcessing = true
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
if password.isEmpty {
|
|
||||||
self.showAlert = true
|
|
||||||
self.errorMessage = "请输入新密码"
|
|
||||||
self.isProcessing = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if confirm.isEmpty || confirm != password {
|
|
||||||
self.showAlert = true
|
|
||||||
self.errorMessage = "两次输入的密码不一致"
|
|
||||||
self.isProcessing = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let result = try await self.registerModel.register(username: username, password: self.password)
|
let result = try await self.registerModel.register(username: username, password: self.password)
|
||||||
print("send verify code result: \(result)")
|
print("send verify code result: \(result)")
|
||||||
} catch {
|
} catch {
|
||||||
self.showAlert = true
|
|
||||||
self.errorMessage = error.localizedDescription
|
self.errorMessage = error.localizedDescription
|
||||||
}
|
}
|
||||||
self.isProcessing = false
|
self.isProcessing = false
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user