Files

446 lines
18 KiB
Swift

//
// OrderPaymentView.swift
// SFI
//
// Created by Mac on 2024/10/21.
//
import Foundation
//
import SwiftUI
struct OrderPaymentView: View {
var orderinfo : OrderInfoDatum
@State private var alert: Alert?
@State private var isLoading = false
@State private var errorMessage: String?
@Environment(\.openURL) private var openURL
@State private var showAlert = false
@State private var payment :PaymentReponseDatum?
@State private var ischeckout = false
@Environment(\.presentationMode) var presentationMode // 环境变量用于控制视图的呈现
var body: some View {
NavigationView(content: {
VStack{
// Navigation Bar
ZStack{
HStack{
Button(action: {
presentationMode.wrappedValue.dismiss() // 手动触发返回
}, label: {
Image(systemName: "chevron.left")
.foregroundColor(.white)
Text("返回")
.foregroundColor(.white)
}).padding(10) // 增加可点击区域
Spacer()
if orderinfo.status == 0 {
Button(action: {
alert = Alert(YesOrNOMessage: "确定取消订单吗?"){
Task{
await cancelorder(orderNO: orderinfo.tradeNo)
}
}
}, label: {
Text("取消订单")
.foregroundColor(.red)
})
}
}
Spacer()
Text("订单详情")
.fontWeight(.bold).lineLimit(1).frame(width: UIScreen.main.bounds.width*0.5)
.foregroundColor(.white)
Spacer()
}
.padding(.all)
VStack(spacing: 20) {
ScrollView(.vertical, showsIndicators: false) {
// Product Details Section
VStack(alignment: .leading, spacing: 10) {
Text("订单详情")
.font(.headline)
.foregroundColor(.white)
HStack {
Text("订单号: ")
.font(.subheadline)
.foregroundColor(.white)
Text(orderinfo.tradeNo)
.font(.subheadline)
.foregroundColor(.white)
}
HStack {
Text("创建时间: ")
.font(.subheadline)
.foregroundColor(.white)
Text(TimestampConverter.convertTimestampToDateString(orderinfo.createdAt))
.font(.subheadline)
.foregroundColor(.white)
}
Spacer().frame(height: 20)
Text("商品详情")
.font(.headline)
.foregroundColor(.white)
HStack {
Text("商品名称: ")
.font(.subheadline)
.foregroundColor(.white)
Text(orderinfo.plan.name)
.font(.subheadline)
.foregroundColor(.yellow)
}
HStack {
Text("类型/周期: ")
.font(.subheadline)
.foregroundColor(.white)
Text(orderinfo.period_zh)
.font(.subheadline)
.foregroundColor(.white)
}
HStack {
Text("产品流量: ")
.font(.subheadline)
.foregroundColor(.white)
Text("\(orderinfo.plan.transferEnable ?? 0)GB/月")
.font(.subheadline)
.foregroundColor(.white)
}
// Pending payment stamp (badge)
Spacer()
HStack {
Spacer()
Text(orderinfo.status_zh)
.font(.subheadline)
.padding(10)
.background(orderinfo.status == 1 ? Color.green: (orderinfo.status == 0 ? Color.red : Color.gray))
.cornerRadius(10)
.foregroundColor(.white)
}
}
.padding()
.background(Color.black.opacity(0.2))
.cornerRadius(10)
// Payment Method Section
VStack(alignment: .leading) {
Text("支付方式")
.font(.headline)
.foregroundColor(.white)
if isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
.padding()
.frame(maxWidth: .infinity)
}
if let errorMessage = errorMessage {
Text(errorMessage)
.bold()
.foregroundColor(.red)
.multilineTextAlignment(.center) // 确保多行文本居中
.padding()
.frame(maxWidth: .infinity)
}else{
Text("\(payment?.name ?? "") (\(payment?.handlingFeePercent ?? "")%手续费)")
.font(.subheadline)
.padding()
.frame(maxWidth: .infinity)
.background(Color.red.opacity(0.3))
.foregroundColor(.white)
.cornerRadius(10)
}
}
.padding()
.background(Color.black.opacity(0.2))
.cornerRadius(10)
// Order Summary Section
VStack(alignment: .leading) {
Text("订单摘要")
.font(.headline)
.foregroundColor(.white)
HStack {
Text("商品价格:")
.font(.subheadline)
.foregroundColor(.white)
Spacer()
Text(\(String(format: "%.2f", orderinfo.totalAmount/100))")
.font(.subheadline)
.foregroundColor(.white)
}
HStack {
Text("手续费:")
.font(.subheadline)
.foregroundColor(.white)
Spacer()
Text(\(String(format: "%.2f", shouxufei()))")
.font(.subheadline)
.foregroundColor(.white)
}
HStack {
Text("总计:")
.font(.subheadline)
.foregroundColor(.white)
Spacer()
Text(\(String(format: "%.2f", total()))")
.font(.headline)
.foregroundColor(.white)
}
}
.padding()
.background(Color.black.opacity(0.2))
.cornerRadius(10)
if orderinfo.status == 0 {
// Pay Now Button
Button(action: {
// Trigger the payment action
showAlert = true
}, label: {
HStack {
Image(systemName: "cart")
Text("立即支付")
if ischeckout {
ProgressView()
.progressViewStyle(CircularProgressViewStyle()).tint(.white)
}
}
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue)
.cornerRadius(10)
}).disabled(ischeckout)
.padding()
.alert(isPresented: $showAlert) {
Alert(
title: Text("提示"),
message: Text("确认要支付吗?"),
primaryButton: .default(Text("确定"),action: {
Task{
if let paymentID = payment?.id {
await submitOrder(orderNO:orderinfo.tradeNo,paymentID:paymentID)
}
}
}),
secondaryButton: .cancel(Text("取消"))
)
}
}
}
}
}
.padding()
.navigationBarHidden(true)
.onAppear(){
Task{
await getPayment()
}
}
.edgesIgnoringSafeArea(.bottom)
.background(
BackgroundBg()
)
})
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true) // 隐藏返回按钮
.alertBinding($alert)
}
func shouxufei() -> Double {
return orderinfo.totalAmount/100 * (Double(payment?.handlingFeePercent ?? "") ?? 0.0)/100
}
func total() -> Double{
return orderinfo.totalAmount/100 + shouxufei()
}
func cancelorder(orderNO:String) async {
//cancel?trade_no=2024102108102956235125484
let userInfoUrl = URL(string: "\(UserManager.shared.baseURL())user/order/cancel?trade_no=\(orderNO)")!
var request = URLRequest(url: userInfoUrl)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue(UserManager.shared.getAutoData(), forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async {
if let error = error {
alert = Alert(error)
return
}
guard let data = data else {
alert = Alert(errorMessage: "取消失败,返回数据为空")
return
}
struct cancelResponse: Codable {
let status, message: String?
}
// Parse the user info response
if let message = try? JSONDecoder().decode(cancelResponse.self, from: data) {
if let status = message.status,status == "success" {
alert = Alert(okMessage: "取消成功", {
presentationMode.wrappedValue.dismiss() // 手动触发返回
})
}else{
alert = Alert(errorMessage: message.message ?? "" )
}
//2024101311320180720&sitename=
}
}
}
task.resume()
}
func submitOrder(orderNO:String,paymentID:Int) async {
ischeckout = true
let userInfoUrl = URL(string: "\(UserManager.shared.baseURL())user/order/checkout?trade_no=\(orderNO)&method=\(paymentID)")!
var request = URLRequest(url: userInfoUrl)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue(UserManager.shared.getAutoData(), forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async {
ischeckout = false
if let error = error {
alert = Alert(error)
return
}
guard let data = data else {
alert = Alert(errorMessage: "支付失败,返回数据为空")
return
}
struct saveOrderResponse: Codable {
let status, message, data: String?
}
// Parse the user info response
if let message = try? JSONDecoder().decode(saveOrderResponse.self, from: data) {
if let payurl = message.data,payurl.count > 10 {
openURL(URL(string:payurl)!)
}else{
alert = Alert(errorMessage: message.message ?? "" )
}
//2024101311320180720&sitename=
}
}
}
task.resume()
}
func getPayment() async {
isLoading = true
errorMessage = nil
let userInfoUrl = URL(string: "\(UserManager.shared.baseURL())user/order/getPaymentMethod")!
var request = URLRequest(url: userInfoUrl)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue(UserManager.shared.getAutoData(), forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async {
self.isLoading = false
if let error = error {
self.errorMessage = "数据请求失败: \(error.localizedDescription)"
return
}
guard let data = data else {
self.errorMessage = "数据请求失败"
return
}
// Parse the user info response
if let Subscribe = try? JSONDecoder().decode(PaymentReponse.self, from: data) {
if let data = Subscribe.data {
payment = data.first
}else{
self.errorMessage = Subscribe.message ?? ""
}
}else{
self.errorMessage = "数据请求失败: JSON 解析错误"
}
}
}
task.resume()
}
}
//struct PaymentView_Previews: PreviewProvider {
// static var previews: some View {
// OrderPaymentView()
// }
//}