فهرست منبع

feat: 增加首单优惠拉取逻辑

陈文艺 1 ماه پیش
والد
کامیت
d9d910b2ab

+ 1 - 0
Lanu/AppDelegate.swift

@@ -30,6 +30,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         _ = LNDeeplinkManager.shared
         _ = LNKeyboardManager.shared
         _ = LNConfigManager.shared
+        _ = LNOrderManager.shared
         
         LNEventDeliver.notifyAppLaunchFinished()
         

+ 41 - 3
Lanu/Manager/Order/LNOrderManager.swift

@@ -10,6 +10,11 @@ import Foundation
 
 protocol LNOrderManagerNotify {
     func onOrderInfoChanged(orderId: String)
+    func onMyDiscountInfoChanged(info: LNOrderDiscountVO?)
+}
+extension LNOrderManagerNotify {
+    func onOrderInfoChanged(orderId: String) { }
+    func onMyDiscountInfoChanged(info: LNOrderDiscountVO?) { }
 }
 
 enum LNOrderErrorCode: Int {
@@ -58,7 +63,11 @@ class LNOrderManager {
     static let orderRefundMaxLength = 500
     static let orderCommentMaxLength = 200
     
-    private init() {}
+    private(set) var discount: LNOrderDiscountVO?
+    
+    private init() {
+        LNEventDeliver.addObserver(self)
+    }
 }
 
 
@@ -130,6 +139,7 @@ extension LNOrderManager {
             if let res, err == nil {
                 LNPurchaseManager.shared.reloadWalletInfo()
                 notifyOrderInfoChanged(orderId: res.orderNo)
+                reloadMyOrderDiscountInfo()
             }
             queue.asyncIfNotGlobal {
                 handler(res?.orderNo)
@@ -317,12 +327,14 @@ extension LNOrderManager {
                        count: Int, type: LNOrderSource,
                        queue: DispatchQueue = .main,
                        handler: @escaping (String?) -> Void) {
-        LNHttpManager.shared.createOrderQR(skillId: skillId, count: count, type: type) { data, err in
+        LNHttpManager.shared.createOrderQR(skillId: skillId, count: count, type: type) { [weak self] data, err in
             queue.asyncIfNotGlobal {
                 handler(data?.qrCode)
             }
             if let err {
                 showToast(err.errorDesc)
+            } else if let self {
+                reloadMyOrderDiscountInfo()
             }
         }
     }
@@ -344,22 +356,48 @@ extension LNOrderManager {
     func createQRCodeOrder(data: String, count: Int, extra: String,
                            queue: DispatchQueue = .main,
                            handler: @escaping (String?) -> Void) {
-        LNHttpManager.shared.createQROrder(data: data, count: count, extra: extra) { res, err in
+        LNHttpManager.shared.createQROrder(data: data, count: count, extra: extra) { [weak self] res, err in
             queue.asyncIfNotGlobal {
                 handler(res?.orderNo)
             }
             
             if let err {
                 showToast(err.errorDesc)
+            } else if let self {
+                reloadMyOrderDiscountInfo()
             }
         }
     }
 }
 
+// MARK: 折扣
+extension LNOrderManager {
+    func reloadMyOrderDiscountInfo() {
+        LNHttpManager.shared.fetchOrderDiscount { [weak self] info, err in
+            guard let self else { return }
+            if err != nil { return }
+            discount = info
+            notifyDiscountInfoChange(info: info)
+        }
+    }
+}
+
+extension LNOrderManager: LNAccountManagerNotify {
+    func onUserLogin() {
+        reloadMyOrderDiscountInfo()
+    }
+}
+
 extension LNOrderManager {
     private func notifyOrderInfoChanged(orderId: String) {
         LNEventDeliver.notifyEvent {
             ($0 as? LNOrderManagerNotify)?.onOrderInfoChanged(orderId: orderId)
         }
     }
+    
+    private func notifyDiscountInfoChange(info: LNOrderDiscountVO?) {
+        LNEventDeliver.notifyEvent {
+            ($0 as? LNOrderManagerNotify)?.onMyDiscountInfoChanged(info: info)
+        }
+    }
 }

+ 8 - 0
Lanu/Manager/Order/Network/LNHttpManager+Order.swift

@@ -28,6 +28,8 @@ private let kNetPath_Order_QR_Order = "/skill/order/qr/payment"
 private let kNetPath_Order_Records = "/playmate/order/list"
 private let kNetPath_Order_Protest = "/playmate/submit/refundVoucher"
 
+private let kNetPath_Order_Discount = "/skill/firstOrder/discount/chance"
+
 private enum LNOrderHandlerType: Int {
     case accept = 1
     case reject = 2
@@ -192,3 +194,9 @@ extension LNHttpManager {
         ], completion: completion)
     }
 }
+
+extension LNHttpManager {
+    func fetchOrderDiscount(completion: @escaping (LNOrderDiscountVO?, LNHttpError?) -> Void) {
+        post(path: kNetPath_Order_Discount, completion: completion)
+    }
+}

+ 7 - 0
Lanu/Manager/Order/Network/LNOrderResponse.swift

@@ -169,3 +169,10 @@ class LNLastOrderResponse: Decodable {
     var finishTime: Int = 0
     var bizCateGoryName: String = ""
 }
+
+@AutoCodable
+class LNOrderDiscountVO: Decodable {
+    var hasChance: Bool = false
+    var discountRate: Double = 0
+    var eligiblePrice: Double = 0
+}

+ 19 - 3
Lanu/Views/Game/MateList/LNGameMateListCell.swift

@@ -59,9 +59,6 @@ class LNGameMateListCell: UITableViewCell {
         priceLabel.text = item.price.toDisplay
         unitLabel.text = "/\(item.unit)"
         
-        saleView.isHidden = false
-        discountView.update(0.9)
-        
         nameLabel.text = item.nickname
         genderView.update(item.gender, item.age)
         
@@ -112,6 +109,8 @@ class LNGameMateListCell: UITableViewCell {
                 playButton.isHidden = false
             }
         }
+        
+        updateDiscount()
     }
     
     required init?(coder: NSCoder) {
@@ -144,6 +143,23 @@ extension LNGameMateListCell: LNVoicePlayerNotify {
     }
 }
 
+extension LNGameMateListCell: LNOrderManagerNotify {
+    func onMyDiscountInfoChanged(info: LNOrderDiscountVO?) {
+        updateDiscount()
+    }
+    
+    private func updateDiscount() {
+        if let discount = LNOrderManager.shared.discount,
+            discount.hasChance,
+            discount.eligiblePrice == curItem?.price {
+            saleView.isHidden = false
+            discountView.update(1 - discount.discountRate)
+        } else {
+            saleView.isHidden = true
+        }
+    }
+}
+
 extension LNGameMateListCell {
     private func setupViews() {
         backgroundColor = .clear

+ 20 - 2
Lanu/Views/Game/Skill/LNSkillBottomMenuView.swift

@@ -24,6 +24,7 @@ class LNSkillBottomMenuView: UIView {
         super.init(frame: frame)
         
         setupViews()
+        LNEventDeliver.addObserver(self)
     }
     
     required init?(coder: NSCoder) {
@@ -78,9 +79,26 @@ class LNSkillBottomMenuView: UIView {
             }
         }
         
-        newbieDiscountView.update(0.9)
-        
         curDetail = detail
+        
+        updateDiscount()
+    }
+}
+
+extension LNSkillBottomMenuView: LNOrderManagerNotify {
+    func onMyDiscountInfoChanged(info: LNOrderDiscountVO?) {
+        updateDiscount()
+    }
+    
+    private func updateDiscount() {
+        if let discount = LNOrderManager.shared.discount,
+            discount.hasChance,
+            discount.eligiblePrice == curDetail?.price {
+            discountView.isHidden = false
+            newbieDiscountView.update(1 - discount.discountRate)
+        } else {
+            discountView.isHidden = true
+        }
     }
 }
 

+ 16 - 2
Lanu/Views/Order/Create/LNCreateOrderFromSkillListPanel.swift

@@ -77,7 +77,14 @@ extension LNCreateOrderFromSkillListPanel {
     private func updatePrice() {
         guard let skill = curSelected else { return }
         let cost = skill.price * Double(curCount)
-        costLabel.text = cost.toDisplay
+        
+        if let discount = LNOrderManager.shared.discount,
+           discount.hasChance,
+           discount.eligiblePrice == skill.price {
+            costLabel.text = (cost - (1 - discount.discountRate) * skill.price).toDisplay
+        } else {
+            costLabel.text = cost.toDisplay
+        }
     }
     
     private func setupViews() {
@@ -273,7 +280,14 @@ private class LNProfileOrderSkillItemView: UIView {
         attrStr.addAttribute(.font, value: UIFont.heading_h4, range: range)
         priceLabel.attributedText = attrStr
         
-        discountView.update(0.9)
+        if let discount = LNOrderManager.shared.discount,
+           discount.hasChance,
+           discount.eligiblePrice == skill.price {
+            discountView.isHidden = false
+            discountView.update(1 - discount.discountRate)
+        } else {
+            discountView.isHidden = true
+        }
         
         cur = skill
     }

+ 35 - 7
Lanu/Views/Order/Create/LNCreateOrderPanel.swift

@@ -41,7 +41,14 @@ class LNCreateOrderPanel: LNPopupView {
         didSet {
             countLabel.text = "x\(curCount)"
             customCountLabel.text = "\(curCount)"
-            costLabel.text = "\((price * Double(curCount)).toDisplay)"
+            
+            if let discount = LNOrderManager.shared.discount,
+               discount.hasChance,
+               discount.eligiblePrice == price {
+                costLabel.text = "\((price * Double(curCount) - (1 - discount.discountRate) * price).toDisplay)"
+            } else {
+                costLabel.text = "\((price * Double(curCount)).toDisplay)"
+            }
             if curCount <= 1 {
                 minuButton.isEnabled = false
             } else {
@@ -74,8 +81,15 @@ class LNCreateOrderPanel: LNPopupView {
         nameLabel.text = detail.nickname
         priceLabel.text = "\(detail.price.toDisplay)/\(detail.unit)"
         
-        newbieView.update(0.9)
-        discountCoinLabel.text = "-4.5"
+        if let discount = LNOrderManager.shared.discount,
+           discount.hasChance,
+           discount.eligiblePrice == detail.price {
+            discountView.isHidden = false
+            newbieView.update(1 - discount.discountRate)
+            discountCoinLabel.text = "-\(detail.price * (1 - discount.discountRate))"
+        } else {
+            discountView.isHidden = true
+        }
         
         skillId = detail.id
         price = detail.price
@@ -90,8 +104,15 @@ class LNCreateOrderPanel: LNPopupView {
         nameLabel.text = user.nickname
         priceLabel.text = "\(skill.price.toDisplay)/\(skill.unit)"
         
-        newbieView.update(0.9)
-        discountCoinLabel.text = "-4.5"
+        if let discount = LNOrderManager.shared.discount,
+           discount.hasChance,
+           discount.eligiblePrice == skill.price {
+            discountView.isHidden = false
+            newbieView.update(1 - discount.discountRate)
+            discountCoinLabel.text = "-\(skill.price * (1 - discount.discountRate))"
+        } else {
+            discountView.isHidden = true
+        }
         
         skillId = skill.id
         price = skill.price
@@ -104,8 +125,15 @@ class LNCreateOrderPanel: LNPopupView {
         nameLabel.text = detail.nickname
         priceLabel.text = "\(detail.price.toDisplay)/\(detail.unit)"
         
-        newbieView.update(0.9)
-        discountCoinLabel.text = "-4.5"
+        if let discount = LNOrderManager.shared.discount,
+           discount.hasChance,
+           discount.eligiblePrice == detail.price {
+            discountView.isHidden = false
+            newbieView.update(1 - discount.discountRate)
+            discountCoinLabel.text = "-\(detail.price * (1 - discount.discountRate))"
+        } else {
+            discountView.isHidden = true
+        }
         
         qrCode = detail.qrCode
         price = detail.price

+ 34 - 10
Lanu/Views/Order/Create/LNCreateOrderViewController.swift

@@ -116,9 +116,17 @@ extension LNCreateOrderViewController {
         skillUnitLabel.text = "/\(detail.unit)"
         curCount = 1
         
-        emptyDiscountView.isHidden = true
-        discountView.update(0.9)
-        discountCoinLabel.text = "-4.5"
+        if let discount = LNOrderManager.shared.discount,
+            discount.hasChance,
+            discount.eligiblePrice == detail.price {
+            emptyDiscountView.isHidden = true
+            newbieDiscountView.isHidden = false
+            discountView.update(1 - discount.discountRate)
+            discountCoinLabel.text = "-\((1 - discount.discountRate) * detail.price)"
+        } else {
+            emptyDiscountView.isHidden = false
+            newbieDiscountView.isHidden = true
+        }
         
         orderButton.isEnabled = true
     }
@@ -139,22 +147,38 @@ extension LNCreateOrderViewController {
             addButton.isEnabled = false
         }
         
-        emptyDiscountView.isHidden = true
-        discountView.update(0.9)
-        discountCoinLabel.text = "-4.5"
+        if let discount = LNOrderManager.shared.discount,
+            discount.hasChance,
+            discount.eligiblePrice == detail.price {
+            emptyDiscountView.isHidden = true
+            newbieDiscountView.isHidden = false
+            discountView.update(1 - discount.discountRate)
+            discountCoinLabel.text = "-\((1 - discount.discountRate) * detail.price)"
+        } else {
+            emptyDiscountView.isHidden = false
+            newbieDiscountView.isHidden = true
+        }
         
         orderButton.isEnabled = !detail.sellerUserNo.isMyUid
     }
     
     private func updateCost() {
-        let cost: Double = if let skill {
-            skill.price * Double(curCount)
+        let price: Double = if let skill {
+            skill.price
         } else if let qrDetail {
-            qrDetail.price * Double(curCount)
+            qrDetail.price
         } else {
             0
         }
-        costLabel.text = cost.toDisplay
+        let cost = price * Double(curCount)
+        
+        if let discount = LNOrderManager.shared.discount,
+           discount.hasChance,
+           discount.eligiblePrice == price {
+            costLabel.text = (cost - (1 - discount.discountRate) * price).toDisplay
+        } else {
+            costLabel.text = cost.toDisplay
+        }
 //        orderUnitLabel.text = "/\(curCount) \(unit)"
     }
     

+ 1 - 1
Lanu/Views/Order/LNNewbieDiscountView.swift

@@ -30,7 +30,7 @@ class LNNewbieDiscountView: UIView {
         setupViews()
     }
     
-    func update(_ discount: Float) {
+    func update(_ discount: Double) {
         discountLabel.text = .init(key: "A00312", "\(Int(discount * 100))%")
     }