完善注册和找回密码逻辑
This commit is contained in:
parent
9727fd1096
commit
e86cf5e422
@ -16,6 +16,7 @@ class ResetPasswordModel {
|
|||||||
case requestVerifyCode(username: String?)
|
case requestVerifyCode(username: String?)
|
||||||
case submitVerifyCode(username: String, sessionId: Int)
|
case submitVerifyCode(username: String, sessionId: Int)
|
||||||
case resetPassword(username: String, sessionId: Int)
|
case resetPassword(username: String, sessionId: Int)
|
||||||
|
case success
|
||||||
}
|
}
|
||||||
|
|
||||||
var stage: Stage = .requestVerifyCode(username: nil)
|
var stage: Stage = .requestVerifyCode(username: nil)
|
||||||
|
|||||||
@ -25,6 +25,8 @@ struct ResetPasswordRootView: View {
|
|||||||
SubmitVerifyCodeView(username: username, sessionId: sessionId)
|
SubmitVerifyCodeView(username: username, sessionId: sessionId)
|
||||||
case .resetPassword(let username, let sessionId):
|
case .resetPassword(let username, let sessionId):
|
||||||
ResetPasswordView(username: username, sessionId: sessionId)
|
ResetPasswordView(username: username, sessionId: sessionId)
|
||||||
|
case .success:
|
||||||
|
ResetPasswordSuccessView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.transition(.asymmetric(
|
.transition(.asymmetric(
|
||||||
@ -277,9 +279,10 @@ struct ResetPasswordView: View {
|
|||||||
do {
|
do {
|
||||||
let result = try await resetPasswordModel.resetPassword(sessionId: sessionId, newPassword: password)
|
let result = try await resetPasswordModel.resetPassword(sessionId: sessionId, newPassword: password)
|
||||||
print("密码重置成功: \(result)")
|
print("密码重置成功: \(result)")
|
||||||
// 此处可添加重置成功后的跳转逻辑
|
withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
|
||||||
self.showAlert = true
|
self.resetPasswordModel.stage = .success
|
||||||
self.errorMessage = "重置成功,重新登陆"
|
self.resetPasswordModel.transitionEdge = .trailing
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
self.showAlert = true
|
self.showAlert = true
|
||||||
self.errorMessage = "重置失败, 请稍后重试"
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import SwiftUI
|
|||||||
|
|
||||||
// MARK: - 用户反馈页面 (完整逻辑版)
|
// MARK: - 用户反馈页面 (完整逻辑版)
|
||||||
struct SettingsUserIssueView: View {
|
struct SettingsUserIssueView: View {
|
||||||
|
@Environment(UserContext.self) var userContext: UserContext
|
||||||
|
|
||||||
// 表单状态
|
// 表单状态
|
||||||
@State private var account: String = ""
|
@State private var account: String = ""
|
||||||
@State private var text: String = ""
|
@State private var text: String = ""
|
||||||
@ -26,6 +28,7 @@ struct SettingsUserIssueView: View {
|
|||||||
HStack(spacing: 12) {
|
HStack(spacing: 12) {
|
||||||
Image(systemName: "envelope.badge.fill")
|
Image(systemName: "envelope.badge.fill")
|
||||||
.foregroundColor(.blue)
|
.foregroundColor(.blue)
|
||||||
|
|
||||||
Text("用户反馈")
|
Text("用户反馈")
|
||||||
.font(.system(size: 18, weight: .bold))
|
.font(.system(size: 18, weight: .bold))
|
||||||
}
|
}
|
||||||
@ -48,7 +51,10 @@ struct SettingsUserIssueView: View {
|
|||||||
|
|
||||||
// 问题描述 (带 Placeholder 逻辑)
|
// 问题描述 (带 Placeholder 逻辑)
|
||||||
VStack(alignment: .leading, spacing: 8) {
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
Text("问题描述").font(.caption.bold()).foregroundColor(.secondary)
|
Text("问题描述")
|
||||||
|
.font(.caption.bold())
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
ZStack(alignment: .topLeading) {
|
ZStack(alignment: .topLeading) {
|
||||||
if text.isEmpty {
|
if text.isEmpty {
|
||||||
Text("请详细描述您遇到的问题...")
|
Text("请详细描述您遇到的问题...")
|
||||||
@ -73,10 +79,15 @@ struct SettingsUserIssueView: View {
|
|||||||
.overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.primary.opacity(0.05), lineWidth: 1))
|
.overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.primary.opacity(0.05), lineWidth: 1))
|
||||||
|
|
||||||
// 3. 提交按钮
|
// 3. 提交按钮
|
||||||
Button(action: submitFeedback) {
|
Button {
|
||||||
|
Task { @MainActor in
|
||||||
|
await self.submitFeedback()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
if isSubmitting {
|
if isSubmitting {
|
||||||
ProgressView().controlSize(.small).brightness(1)
|
ProgressView()
|
||||||
|
.controlSize(.small).brightness(1)
|
||||||
} else {
|
} else {
|
||||||
Image(systemName: "paperplane.fill")
|
Image(systemName: "paperplane.fill")
|
||||||
}
|
}
|
||||||
@ -105,8 +116,28 @@ struct SettingsUserIssueView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - 提交逻辑
|
// MARK: - 提交逻辑
|
||||||
private func submitFeedback() {
|
private func submitFeedback() async {
|
||||||
withAnimation { isSubmitting = true }
|
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) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
|
||||||
|
|||||||
@ -46,8 +46,7 @@ struct punchnetApp: App {
|
|||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup(id: "main") {
|
WindowGroup(id: "main") {
|
||||||
//RootView()
|
//RootView()
|
||||||
//RegisterRootView()
|
SettingsUserIssueView()
|
||||||
RegisterSuccessView()
|
|
||||||
.navigationTitle("")
|
.navigationTitle("")
|
||||||
.environment(self.appContext)
|
.environment(self.appContext)
|
||||||
.environment(self.userContext)
|
.environment(self.userContext)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user