Add OperatingArea and PilotCertification modules with live push readiness.

Migrate operating area and pilot certification from home placeholders, extend Live with playback and push readiness flows, and add pilot certificate OSS upload.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 18:15:59 +08:00
parent fdf4659048
commit 41dda3cc9b
33 changed files with 3455 additions and 37 deletions

View File

@ -45,6 +45,9 @@ protocol OSSUploadServing {
/// 访 OSS URL
func uploadBankCardImage(data: Data, fileName: String, scenicId: Int, onProgress: @escaping (Int) -> Void) async throws -> String
/// 访 OSS URL
func uploadPilotCertificateImage(data: Data, fileName: String, scenicId: Int, onProgress: @escaping (Int) -> Void) async throws -> String
}
@MainActor
@ -108,6 +111,11 @@ final class OSSUploadService {
try await uploadFile(data: data, fileName: fileName, fileType: 2, scenicId: scenicId, moduleType: "bank_card", onProgress: onProgress)
}
/// 访 OSS URL
func uploadPilotCertificateImage(data: Data, fileName: String, scenicId: Int, onProgress: @escaping (Int) -> Void) async throws -> String {
try await uploadFile(data: data, fileName: fileName, fileType: 2, scenicId: scenicId, moduleType: "pilot_cert", onProgress: onProgress)
}
/// OSS
private func uploadFile(
data: Data,
@ -218,6 +226,8 @@ enum OSSUploadPolicy {
return "real_name/\(currentDate)/\(scenicId)/\(uploadId)_\(safeName)"
case "bank_card":
return "bank_card/\(currentDate)/\(scenicId)/\(uploadId)_\(safeName)"
case "pilot_cert":
return "pilot_cert/\(currentDate)/\(scenicId)/\(uploadId)_\(safeName)"
default:
return "task/\(currentDate)/\(scenicId)/\(uploadId)_\(safeName)"
}

View File

@ -9,6 +9,18 @@ import Foundation
///
enum AppFormValidator {
///
static func normalizedPhoneNumber(_ value: String) -> String {
value.filter { !$0.isWhitespace }
}
/// 11
static func isValidMainlandPhoneNumber(_ value: String) -> Bool {
let phone = normalizedPhoneNumber(value)
guard phone.count == 11, phone.first == "1" else { return false }
return phone.allSatisfy(\.isNumber)
}
///
static func rangedInteger(_ text: String, name: String, range: ClosedRange<Int>) throws -> Int {
let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)