新增线下收款记录和 ai 修图优化

This commit is contained in:
han xin
2026-08-21 15:51:52 +08:00
parent 6fe9928b49
commit 5cf4409bad
40 changed files with 5482 additions and 56 deletions
@@ -0,0 +1,134 @@
//
// AccountDeletionModels.swift
// suixinkan
//
import Foundation
/// 注销核验资产,使用中性文案展示当前账号拥有的数据与权益。
struct AccountDeletionAssetSummary: Codable, Hashable, Sendable {
/// 注销核验覆盖的资产类型。
enum Kind: String, Codable, CaseIterable, Sendable {
case wallet
case works
case projects
case cloudFiles
}
let kind: Kind
let title: String
let valueText: String
}
/// 注销前置核验结果,包含资产快照和注销影响说明。
struct AccountDeletionPrecheck: Equatable, Sendable {
let assets: [AccountDeletionAssetSummary]
let consequences: [String]
}
/// 注销申请当前状态。
enum AccountDeletionRequestStatus: String, Codable, Sendable {
case pending
case canceled
case completed
}
/// 注销申请记录,保存7天冷静期及用户确认的资产范围。
struct AccountDeletionRequest: Codable, Equatable, Sendable {
let id: UUID
let clientRequestID: UUID
let username: String
let submittedAt: Date
let scheduledDeletionAt: Date
var status: AccountDeletionRequestStatus
let acknowledgedAssetKinds: [AccountDeletionAssetSummary.Kind]
}
/// 登录时需要处理的注销状态。
enum AccountDeletionLoginState: Equatable, Sendable {
case none
case pending(AccountDeletionRequest)
case completed(AccountDeletionRequest)
}
/// 注销短信验证页所需的稳定上下文。
struct AccountDeletionVerificationContext: Equatable, Sendable {
let username: String
let maskedPhone: String
let assets: [AccountDeletionAssetSummary]
}
/// 注销业务错误,统一提供可直接展示的中文提示。
enum AccountDeletionError: LocalizedError, Equatable {
case missingIdentity
case invalidVerificationCode
case incompleteAcknowledgement
case noPendingRequest
case cancellationExpired
case deletionCompleted
case persistenceFailed
var errorDescription: String? {
switch self {
case .missingIdentity:
"当前登录账号缺少手机号,暂时无法提交注销"
case .invalidVerificationCode:
"验证码错误,请输入演示验证码 123456"
case .incompleteAcknowledgement:
"请先确认已了解全部资产和注销后果"
case .noPendingRequest:
"当前账号没有待取消的注销申请"
case .cancellationExpired:
"7天取消期限已过,无法恢复账号"
case .deletionCompleted:
"账号已完成注销,无法继续登录"
case .persistenceFailed:
"注销状态保存失败,请稍后重试"
}
}
}
/// 注销账号身份工具,统一手机号规范化、掩码和当前登录身份解析。
enum AccountDeletionIdentity {
/// 从当前会话读取登录手机号,优先使用登录页保存的原始账号。
static func currentUsername(session: AppSessionStore = AppStore.shared.session) -> String? {
let candidates = [session.lastLoginUsername, session.phone]
return candidates
.compactMap { $0 }
.map(normalizedUsername)
.first { !$0.isEmpty }
}
/// 将手机号账号规范化为纯数字,并兼容 +86 前缀。
static func normalizedUsername(_ value: String) -> String {
var digits = value.filter(\.isNumber)
if digits.hasPrefix("86"), digits.count == 13 {
digits.removeFirst(2)
}
return digits
}
/// 将手机号转换为用于页面展示的脱敏格式。
static func maskedPhone(_ value: String) -> String {
let username = normalizedUsername(value)
guard username.count == 11 else { return username }
let start = username.prefix(3)
let end = username.suffix(4)
return "\(start)****\(end)"
}
}
/// 注销时间格式化工具,统一成功页和登录恢复弹窗的中文时间。
enum AccountDeletionDateFormatter {
/// 将服务端计划删除时间格式化为中文日期时间。
static func displayText(_ date: Date) -> String {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "zh_CN")
formatter.timeZone = TimeZone(identifier: "Asia/Shanghai")
formatter.dateFormat = "yyyy年M月d日 HH:mm"
return formatter.string(from: date)
}
}