完善注册和找回密码逻辑

This commit is contained in:
anlicheng 2026-03-20 22:17:45 +08:00
parent 9727fd1096
commit e86cf5e422
4 changed files with 110 additions and 10 deletions

View File

@ -16,6 +16,7 @@ class ResetPasswordModel {
case requestVerifyCode(username: String?)
case submitVerifyCode(username: String, sessionId: Int)
case resetPassword(username: String, sessionId: Int)
case success
}
var stage: Stage = .requestVerifyCode(username: nil)

View File

@ -25,6 +25,8 @@ struct ResetPasswordRootView: View {
SubmitVerifyCodeView(username: username, sessionId: sessionId)
case .resetPassword(let username, let sessionId):
ResetPasswordView(username: username, sessionId: sessionId)
case .success:
ResetPasswordSuccessView()
}
}
.transition(.asymmetric(
@ -277,9 +279,10 @@ struct ResetPasswordView: View {
do {
let result = try await resetPasswordModel.resetPassword(sessionId: sessionId, newPassword: password)
print("密码重置成功: \(result)")
//
self.showAlert = true
self.errorMessage = "重置成功,重新登陆"
withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
self.resetPasswordModel.stage = .success
self.resetPasswordModel.transitionEdge = .trailing
}
} catch {
self.showAlert = true
self.errorMessage = "重置失败, 请稍后重试"
@ -289,3 +292,69 @@ struct ResetPasswordView: View {
}
}
struct ResetPasswordSuccessView: View {
@Environment(\.dismiss) private var dismiss
//
@State private var animateIcon = false
@State private var animateText = false
var body: some View {
VStack(spacing: 32) {
Spacer()
// (使绿)
ZStack {
Circle()
.fill(Color.blue.opacity(0.1))
.frame(width: 100, height: 100)
.scaleEffect(animateIcon ? 1.1 : 0.95)
.opacity(animateIcon ? 0.8 : 1.0)
Image(systemName: "lock.circle.fill")
.font(.system(size: 56))
.foregroundStyle(.blue.gradient)
.scaleEffect(animateIcon ? 1.05 : 1.0)
}
.transition(.move(edge: .bottom).combined(with: .opacity))
VStack(spacing: 32) {
VStack(spacing: 12) {
Text("密码重置成功")
.font(.title2.bold())
Text("您的新密码已生效。\n为了安全,建议您立即尝试使用新密码登录。")
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
}
Button(action: {
dismiss() //
}) {
Text("返回登录")
.fontWeight(.bold)
.frame(width: 200)
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
.tint(.blue)
}
.opacity(animateText ? 1.0 : 0.0)
.offset(y: animateText ? 0 : 20)
Spacer()
}
.padding(40)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onAppear {
withAnimation(.easeInOut(duration: 1.5).repeatForever(autoreverses: true)) {
animateIcon = true
}
withAnimation(.spring(duration: 0.6, bounce: 0.3).delay(0.4)) {
animateText = true
}
}
}
}

View File

@ -8,6 +8,8 @@ import SwiftUI
// MARK: - ()
struct SettingsUserIssueView: View {
@Environment(UserContext.self) var userContext: UserContext
//
@State private var account: String = ""
@State private var text: String = ""
@ -26,6 +28,7 @@ struct SettingsUserIssueView: View {
HStack(spacing: 12) {
Image(systemName: "envelope.badge.fill")
.foregroundColor(.blue)
Text("用户反馈")
.font(.system(size: 18, weight: .bold))
}
@ -48,7 +51,10 @@ struct SettingsUserIssueView: View {
// ( Placeholder )
VStack(alignment: .leading, spacing: 8) {
Text("问题描述").font(.caption.bold()).foregroundColor(.secondary)
Text("问题描述")
.font(.caption.bold())
.foregroundColor(.secondary)
ZStack(alignment: .topLeading) {
if text.isEmpty {
Text("请详细描述您遇到的问题...")
@ -73,10 +79,15 @@ struct SettingsUserIssueView: View {
.overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.primary.opacity(0.05), lineWidth: 1))
// 3.
Button(action: submitFeedback) {
Button {
Task { @MainActor in
await self.submitFeedback()
}
} label: {
HStack {
if isSubmitting {
ProgressView().controlSize(.small).brightness(1)
ProgressView()
.controlSize(.small).brightness(1)
} else {
Image(systemName: "paperplane.fill")
}
@ -105,8 +116,28 @@ struct SettingsUserIssueView: View {
}
// MARK: -
private func submitFeedback() {
withAnimation { isSubmitting = true }
private func submitFeedback() async {
withAnimation {
isSubmitting = true
}
var params: [String: Any] = [
"access_token": self.userContext.networkSession?.accessToken ?? "",
"contact": self.account,
"platform": SystemConfig.systemInfo,
"content": self.text,
"client_id": SystemConfig.getClientId(),
"mac": SystemConfig.macAddressString(mac: SystemConfig.getMacAddress())
]
do {
_ = try await SDLAPIClient.doPost(path: "/app/issue", params: params, as: String.self)
} catch let err as SDLAPIError {
} catch let err {
}
//
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {

View File

@ -46,8 +46,7 @@ struct punchnetApp: App {
var body: some Scene {
WindowGroup(id: "main") {
//RootView()
//RegisterRootView()
RegisterSuccessView()
SettingsUserIssueView()
.navigationTitle("")
.environment(self.appContext)
.environment(self.userContext)