添加景区入驻申请流程并对齐 Android

This commit is contained in:
2026-07-07 11:09:27 +08:00
parent c4057537d2
commit 187ba990d4
22 changed files with 2202 additions and 216 deletions

View File

@ -0,0 +1,199 @@
//
// ScenicApplicationModels.swift
// suixinkan
//
import Foundation
/// Android `CooperationType`
enum ScenicCooperationType: Int, CaseIterable, Equatable {
case photographer = 1
case resourceProvider = 2
case teamLeader = 3
case photoShop = 4
case efficiencyImprovement = 5
var displayName: String {
switch self {
case .photographer:
"我是摄影师,我想入驻"
case .resourceProvider:
"我是景区资源方,可以合作"
case .teamLeader:
"我有摄影师团队,带队入住"
case .photoShop:
"我是旅拍店,想合作"
case .efficiencyImprovement:
"我已经在景区运营旅拍了,想使用软件,提高效率"
}
}
static func from(rawValue: Int) -> ScenicCooperationType {
ScenicCooperationType(rawValue: rawValue) ?? .photographer
}
}
///
struct ScenicApplicationPendingResponse: Decodable, Equatable {
let id: Int
let code: String
let staffId: Int
let scenicId: Int
let scenicName: String
let scenicImages: String
let scenicProvince: String
let scenicCity: String
let coopType: Int
let remark: String?
let status: Int
let rejectReason: String?
let auditedBy: String?
let auditedAt: String?
let auditNote: String?
enum CodingKeys: String, CodingKey {
case id
case code
case staffId = "staff_id"
case scenicId = "scenic_id"
case scenicName = "scenic_name"
case scenicImages = "scenic_images"
case scenicProvince = "scenic_province"
case scenicCity = "scenic_city"
case coopType = "coop_type"
case remark
case status
case rejectReason = "reject_reason"
case auditedBy = "audited_by"
case auditedAt = "audited_at"
case auditNote = "audit_note"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(Int.self, forKey: .id) ?? 0
code = try container.decodeIfPresent(String.self, forKey: .code) ?? ""
staffId = try container.decodeIfPresent(Int.self, forKey: .staffId) ?? 0
scenicId = try container.decodeIfPresent(Int.self, forKey: .scenicId) ?? 0
scenicName = try container.decodeIfPresent(String.self, forKey: .scenicName) ?? ""
scenicImages = try container.decodeIfPresent(String.self, forKey: .scenicImages) ?? ""
scenicProvince = try container.decodeIfPresent(String.self, forKey: .scenicProvince) ?? ""
scenicCity = try container.decodeIfPresent(String.self, forKey: .scenicCity) ?? ""
coopType = try container.decodeIfPresent(Int.self, forKey: .coopType) ?? 0
remark = try container.decodeIfPresent(String.self, forKey: .remark)
status = try container.decodeIfPresent(Int.self, forKey: .status) ?? 0
rejectReason = try container.decodeIfPresent(String.self, forKey: .rejectReason)
auditedBy = try container.decodeIfPresent(String.self, forKey: .auditedBy)
auditedAt = try container.decodeIfPresent(String.self, forKey: .auditedAt)
auditNote = try container.decodeIfPresent(String.self, forKey: .auditNote)
}
init(
id: Int = 0,
code: String = "",
staffId: Int = 0,
scenicId: Int = 0,
scenicName: String = "",
scenicImages: String = "",
scenicProvince: String = "",
scenicCity: String = "",
coopType: Int = 0,
remark: String? = nil,
status: Int = 0,
rejectReason: String? = nil,
auditedBy: String? = nil,
auditedAt: String? = nil,
auditNote: String? = nil
) {
self.id = id
self.code = code
self.staffId = staffId
self.scenicId = scenicId
self.scenicName = scenicName
self.scenicImages = scenicImages
self.scenicProvince = scenicProvince
self.scenicCity = scenicCity
self.coopType = coopType
self.remark = remark
self.status = status
self.rejectReason = rejectReason
self.auditedBy = auditedBy
self.auditedAt = auditedAt
self.auditNote = auditNote
}
}
///
struct ScenicApplicationPendingsResponse: Decodable, Equatable {
let items: [ScenicApplicationPendingResponse]
init(items: [ScenicApplicationPendingResponse] = []) {
self.items = items
}
}
///
struct ScenicApplicationSubmitRequest: Encodable {
let scenicName: String?
let scenicImages: [String]?
let scenicProvince: String
let scenicCity: String
let coopType: Int
let remark: String
let scenicId: Int
enum CodingKeys: String, CodingKey {
case scenicName = "scenic_name"
case scenicImages = "scenic_images"
case scenicProvince = "scenic_province"
case scenicCity = "scenic_city"
case coopType = "coop_type"
case remark
case scenicId = "scenic_id"
}
}
///
struct ScenicApplicationImageItem: Equatable, Identifiable {
let id: UUID
var localData: Data?
var fileName: String
var remoteURL: String
var isUploading: Bool
var uploadProgress: Int
var errorMessage: String?
var isUploaded: Bool { !remoteURL.isEmpty }
static func fromRemoteURL(_ url: String) -> ScenicApplicationImageItem {
let trimmed = url.trimmingCharacters(in: .whitespacesAndNewlines)
let name = URL(string: trimmed)?.lastPathComponent ?? "image.jpg"
return ScenicApplicationImageItem(
id: UUID(),
localData: nil,
fileName: name,
remoteURL: trimmed,
isUploading: false,
uploadProgress: 100,
errorMessage: nil
)
}
static func fromLocal(data: Data, fileName: String) -> ScenicApplicationImageItem {
ScenicApplicationImageItem(
id: UUID(),
localData: data,
fileName: fileName,
remoteURL: "",
isUploading: false,
uploadProgress: 0,
errorMessage: nil
)
}
}
///
struct ScenicApplicationUploadDialogState: Equatable {
let title: String
let progress: Int
}