对齐旅拍相册详情页 Android UI,并修复网格预览与布局问题。

重构相册详情为信息卡片、Tab 筛选、排序、批量删除与底部上传栏;修复网格重叠、禁用按钮蒙层,并支持点击预览大图。同步扩展素材列表 API 与 ViewModel 分页逻辑,并优化有线传图缩略图与传输性能。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-30 13:53:59 +08:00
parent c71b45bdfd
commit 5e620623eb
23 changed files with 2000 additions and 288 deletions

View File

@ -61,6 +61,29 @@ final class TravelAlbumAPITests: XCTestCase {
XCTAssertEqual(body["file_url"] as? String, "https://cdn/a.jpg")
}
/// order_by is_purchased
func testMaterialListUsesOrderByAndPurchasedQuery() async throws {
let session = TravelAlbumRecordingURLSession(data: Self.materialListResponse)
let api = TravelAlbumAPI(client: APIClient(session: session))
_ = try await api.materialList(
userEquityTravelId: 8,
page: 2,
pageSize: 30,
orderBy: 3,
isPurchased: 1
)
let components = try XCTUnwrap(URLComponents(url: try XCTUnwrap(session.requests.first?.url), resolvingAgainstBaseURL: false))
let query = Dictionary(uniqueKeysWithValues: (components.queryItems ?? []).map { ($0.name, $0.value) })
XCTAssertEqual(session.requests.first?.url?.path, "/api/yf-handset-app/photog/travel-album/material-list")
XCTAssertEqual(query["user_equity_travel_id"], "8")
XCTAssertEqual(query["page"], "2")
XCTAssertEqual(query["page_size"], "30")
XCTAssertEqual(query["order_by"], "3")
XCTAssertEqual(query["is_purchased"], "1")
}
fileprivate static let listResponse = Data(
#"{"code":100000,"msg":"success","data":{"total":"1","list":[{"id":"8","store_user_id":"1","name":"2026-06-29-001","type":"1","order_number":"","material_num":"3","material_price":"990","material_package_price":"9900","photo_price":"0","cover_url":"","user_id":"100","status":"1","created_at":"2026","updated_at":"2026","user":{"id":"200","phone":"13800138000"}}]}}"#.utf8
)
@ -72,6 +95,10 @@ final class TravelAlbumAPITests: XCTestCase {
fileprivate static let uploadMaterialResponse = Data(
#"{"code":100000,"msg":"success","data":{"id":"11","user_equity_travel_id":"8","status":"1","order_number":"","user_id":"100","file_name":"DSC_001.JPG","file_type":"2","file_url":"https://cdn/a.jpg","file_size":"2048","cover_url":"","is_purchased":"0","created_at":"2026","updated_at":"2026"}}"#.utf8
)
fileprivate static let materialListResponse = Data(
#"{"code":100000,"msg":"success","data":{"total":"0","list":[]}}"#.utf8
)
}
private final class TravelAlbumRecordingURLSession: URLSessionProtocol {