完善样片管理列表、详情与上传页 UI 交互。
对齐 Android 样片模块布局与加载状态,补充共享 UI 组件与图片资源,并增强列表解析容错与单元测试覆盖。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -26,6 +26,7 @@ final class SampleListViewModel {
|
||||
private(set) var canLoadMore = false
|
||||
private(set) var filterStatus: SampleFilterStatus = .all
|
||||
private(set) var searchText = ""
|
||||
private(set) var operatingSampleIDs: Set<Int> = []
|
||||
|
||||
var onStateChange: (() -> Void)?
|
||||
var onShowMessage: ((String) -> Void)?
|
||||
@ -33,6 +34,11 @@ final class SampleListViewModel {
|
||||
private var currentPage = 1
|
||||
private var totalCount = 0
|
||||
private let pageSize = 10
|
||||
private var isRequestingList = false
|
||||
private var isLoadingMore = false
|
||||
|
||||
/// 是否正在执行样片上下架操作。
|
||||
var isOperating: Bool { !operatingSampleIDs.isEmpty }
|
||||
|
||||
/// 首次加载样片列表。
|
||||
func loadInitial(api: any SampleManagementServing) async {
|
||||
@ -67,15 +73,26 @@ final class SampleListViewModel {
|
||||
}
|
||||
|
||||
/// 切换样片上下架状态。
|
||||
func toggleListing(sampleId: Int, checked: Bool, api: any SampleManagementServing) async {
|
||||
guard let currentItem = items.first(where: { $0.id == sampleId }) else { return }
|
||||
@discardableResult
|
||||
func toggleListing(sampleId: Int, checked: Bool, api: any SampleManagementServing) async -> Bool {
|
||||
guard let currentItem = items.first(where: { $0.id == sampleId }) else { return !checked }
|
||||
let previousState = currentItem.isListed
|
||||
guard currentItem.status == 1 else {
|
||||
onShowMessage?("审核通过才可以操作上下架")
|
||||
return
|
||||
notifyStateChange()
|
||||
return previousState
|
||||
}
|
||||
|
||||
let targetStatus = checked ? 1 : 0
|
||||
guard currentItem.listingStatus != targetStatus else { return }
|
||||
guard currentItem.listingStatus != targetStatus else { return previousState }
|
||||
|
||||
guard !operatingSampleIDs.contains(sampleId) else { return previousState }
|
||||
operatingSampleIDs.insert(sampleId)
|
||||
notifyStateChange()
|
||||
defer {
|
||||
operatingSampleIDs.remove(sampleId)
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
do {
|
||||
try await api.setListingStatus(id: sampleId, listingStatus: targetStatus)
|
||||
@ -97,25 +114,38 @@ final class SampleListViewModel {
|
||||
)
|
||||
}
|
||||
notifyStateChange()
|
||||
return checked
|
||||
} catch is CancellationError {
|
||||
return
|
||||
return previousState
|
||||
} catch {
|
||||
onShowMessage?(error.localizedDescription.isEmpty ? "操作失败" : error.localizedDescription)
|
||||
return previousState
|
||||
}
|
||||
}
|
||||
|
||||
private func load(reset: Bool, showLoading: Bool, api: any SampleManagementServing) async {
|
||||
guard !isRequestingList else {
|
||||
if isRefreshing {
|
||||
isRefreshing = false
|
||||
notifyStateChange()
|
||||
}
|
||||
return
|
||||
}
|
||||
if reset {
|
||||
currentPage = 1
|
||||
canLoadMore = false
|
||||
} else {
|
||||
guard canLoadMore, !isLoading else { return }
|
||||
guard canLoadMore, !isLoading, !isLoadingMore else { return }
|
||||
isLoadingMore = true
|
||||
currentPage += 1
|
||||
}
|
||||
|
||||
isRequestingList = true
|
||||
isLoading = showLoading
|
||||
notifyStateChange()
|
||||
defer {
|
||||
isRequestingList = false
|
||||
if !reset { isLoadingMore = false }
|
||||
isLoading = false
|
||||
isRefreshing = false
|
||||
notifyStateChange()
|
||||
@ -276,7 +306,7 @@ final class UploadSampleViewModel {
|
||||
onShowMessage?("请先选择景区")
|
||||
return
|
||||
}
|
||||
if projectIsLoading && !refresh { return }
|
||||
guard !projectIsLoading else { return }
|
||||
if refresh {
|
||||
projectCurrentPage = 1
|
||||
projectList = []
|
||||
|
||||
Reference in New Issue
Block a user