实现订单 Tab 并接入扫码核销流程
This commit is contained in:
@ -90,6 +90,62 @@ final class APIClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送原始 JSON 字符串请求体(对齐 Android `TextContent` 裸 JSON POST)。
|
||||
func sendRawJSON<Response: Decodable>(
|
||||
method: HTTPMethod,
|
||||
path: String,
|
||||
jsonBody: String,
|
||||
tokenOverride: String? = nil
|
||||
) async throws -> Response {
|
||||
let apiPath = path.hasPrefix("/") ? path : "/" + path
|
||||
guard let url = URL(
|
||||
string: environment.baseURL.absoluteString.trimmingCharacters(in: CharacterSet(charactersIn: "/")) + apiPath
|
||||
) else {
|
||||
throw APIError.invalidURL
|
||||
}
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = method.rawValue
|
||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
||||
request.setValue(appVersion, forHTTPHeaderField: "X-APP-VERSION")
|
||||
request.setValue(osType, forHTTPHeaderField: "X-OS-TYPE")
|
||||
|
||||
let token = tokenOverride ?? authTokenProvider?()
|
||||
if let token = token?.trimmingCharacters(in: .whitespacesAndNewlines), !token.isEmpty {
|
||||
request.setValue(token, forHTTPHeaderField: "token")
|
||||
}
|
||||
|
||||
request.httpBody = jsonBody.data(using: .utf8)
|
||||
logRequest(request)
|
||||
|
||||
let data: Data
|
||||
let response: URLResponse
|
||||
do {
|
||||
(data, response) = try await session.data(for: request)
|
||||
} catch is CancellationError {
|
||||
logCancelled(for: request, reason: "CancellationError")
|
||||
throw CancellationError()
|
||||
} catch let error as URLError {
|
||||
if error.code == .cancelled {
|
||||
logCancelled(for: request, reason: "URLError.cancelled")
|
||||
throw CancellationError()
|
||||
}
|
||||
throw APIError.networkFailed(networkErrorMessage(for: error))
|
||||
} catch {
|
||||
throw APIError.networkFailed(error.localizedDescription)
|
||||
}
|
||||
|
||||
logResponse(for: request, response: response, data: data)
|
||||
do {
|
||||
try validateHTTPResponse(response, data: data)
|
||||
return try decodeEnvelope(Response.self, from: data)
|
||||
} catch let error as APIError {
|
||||
notifySessionExpiredIfNeeded(for: error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/// 将业务请求模型转换为 URLRequest,并注入公共 Header、token 和请求体。
|
||||
private func makeURLRequest<Response: Decodable>(
|
||||
_ apiRequest: APIRequest<Response>,
|
||||
|
||||
Reference in New Issue
Block a user