Initial Create

基础框架实现
This commit is contained in:
2025-08-16 23:45:52 +08:00
parent de8ac20776
commit cb7294d722
14 changed files with 472 additions and 24 deletions

View File

@@ -0,0 +1,130 @@
import SwiftUI
import Combine
struct PhotoView: View {
let albumId: String
@StateObject private var viewModel: PhotoViewModel
init(albumId: String) {
self.albumId = albumId
self._viewModel = StateObject(wrappedValue: PhotoViewModel(albumId: albumId))
}
var body: some View {
ZStack {
if viewModel.isLoading {
ProgressView()
} else if let album = viewModel.album {
ScrollView {
VStack(alignment: .leading, spacing: 8) {
Text(album.name)
.font(.headline)
Text("作者: \(album.authors.joined(separator: ", "))")
.font(.subheadline)
Text("标签: \(album.tags.joined(separator: ", "))")
.font(.caption)
.foregroundColor(.gray)
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(.systemBackground))
LazyVStack(spacing: 0) { //
ForEach(Array(album.image_urls.enumerated()), id: \.offset) { index, url in
AsyncImageView(
url: url,
nums: album.nums,
index: index
)
.frame(maxWidth: .infinity) //
.aspectRatio(contentMode: .fill) //
.clipped() //
}
}
}
.edgesIgnoringSafeArea(.all) //
} else if let error = viewModel.error {
Text("加载失败: \(error.localizedDescription)")
}
}
.alert(isPresented: $viewModel.showAlert) {
Alert(
title: Text(viewModel.alertTitle),
message: Text(viewModel.alertMessage),
dismissButton: .default(Text("确定"))
)
}
}
}
// PhotoView, PhotoViewModel, Album
class PhotoViewModel: ObservableObject {
let albumId: String
@Published var album: Album?
@Published var isLoading = false
@Published var error: Error?
@Published var scrollPosition: Double = 0
@Published var showAlert = false
@Published var alertTitle = ""
@Published var alertMessage = ""
private var cancellables = Set<AnyCancellable>()
init(albumId: String) {
self.albumId = albumId
loadAlbumData()
}
func loadAlbumData() {
isLoading = true
error = nil
let urlString = "https://jms.godserver.cn/album/\(albumId)/"
guard let url = URL(string: urlString) else {
error = NSError(domain: "无效的URL", code: 0, userInfo: nil)
isLoading = false
return
}
print("正在加载相册数据: \(urlString)")
URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: Album.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { [weak self] completion in
self?.isLoading = false
if case .failure(let error) = completion {
self?.error = error
print("相册加载失败: \(error.localizedDescription)")
}
}, receiveValue: { [weak self] album in
self?.album = album
print("成功加载相册: \(album.name), 包含 \(album.image_urls.count) 张图片")
})
.store(in: &cancellables)
}
func showAlert(title: String, message: String) {
alertTitle = title
alertMessage = message
showAlert = true
}
}
struct Album: Codable {
let album_id: String
let name: String
let authors: [String]
let actors: [String]
let tags: [String]
let image_urls: [String]
let nums: [Int]
enum CodingKeys: String, CodingKey {
case album_id, name, authors, actors, tags
case image_urls = "image_urls"
case nums
}
}