Browse Source

feat: 补充部分场景下的折扣界面展示逻辑

陈文艺 1 month ago
parent
commit
2ac8baf38f

+ 9 - 1
Lanu/Manager/Order/LNOrderManager.swift

@@ -63,7 +63,15 @@ class LNOrderManager {
     static let orderRefundMaxLength = 500
     static let orderCommentMaxLength = 200
     
-    private(set) var discount: LNOrderDiscountVO?
+    private var discount: LNOrderDiscountVO?
+    
+    func discountFor(_ price: Double) -> Double? {
+        if let discount, discount.hasChance, discount.eligiblePrice == price {
+            discount.discountRate
+        } else {
+            nil
+        }
+    }
     
     private init() {
         LNEventDeliver.addObserver(self)

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

@@ -48,6 +48,7 @@ class LNOrderListItemVO: Decodable {
     var refundApply: Bool = false
     var customerRemark: String = ""
     var gender: LNUserGender = .unknow
+    var totalAmount: Double = 0
 }
 
 @AutoCodable
@@ -72,6 +73,7 @@ class LNOrderInfoVO: Decodable {
     var refundApply: Bool = false
     var customerRemark: String = ""
     var gender: LNUserGender = .unknow
+    var totalAmount: Double = 0
     
     init () { }
 }
@@ -111,6 +113,7 @@ class LNOrderRecordItemVO: Decodable {
     var refundApply: Bool = false
     var customerRemark: String = ""
     var gender: LNUserGender = .unknow
+    var totalAmount: Double = 0
 }
 
 @AutoCodable

+ 2 - 4
Lanu/Views/Game/MateList/LNGameMateListCell.swift

@@ -149,11 +149,9 @@ extension LNGameMateListCell: LNOrderManagerNotify {
     }
     
     private func updateDiscount() {
-        if let discount = LNOrderManager.shared.discount,
-            discount.hasChance,
-            discount.eligiblePrice == curItem?.price {
+        if let discount = LNOrderManager.shared.discountFor(curItem?.price ?? 0) {
             saleView.isHidden = false
-            discountView.update(1 - discount.discountRate)
+            discountView.update(1 - discount)
         } else {
             saleView.isHidden = true
         }

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

@@ -91,11 +91,9 @@ extension LNSkillBottomMenuView: LNOrderManagerNotify {
     }
     
     private func updateDiscount() {
-        if let discount = LNOrderManager.shared.discount,
-            discount.hasChance,
-            discount.eligiblePrice == curDetail?.price {
+        if let discount = LNOrderManager.shared.discountFor(curDetail?.price ?? 0) {
             discountView.isHidden = false
-            newbieDiscountView.update(1 - discount.discountRate)
+            newbieDiscountView.update(1 - discount)
         } else {
             discountView.isHidden = true
         }

+ 14 - 14
Lanu/Views/Home/LNHomeTopMenuView.swift

@@ -69,20 +69,20 @@ extension LNHomeTopMenuView {
         }), for: .touchUpInside)
         stackView.addArrangedSubview(search)
         
-        createRoom.layer.cornerRadius = 15
-        createRoom.layer.borderWidth = 1
-        createRoom.layer.borderColor = .fill
-        createRoom.backgroundColor = .fill.withAlphaComponent(0.5)
-        createRoom.setImage(.icRoomCreate.withTintColor(.text_6, renderingMode: .alwaysOriginal), for: .normal)
-        createRoom.setTitle(.init(key: "A00318"), for: .normal)
-        createRoom.setTitleColor(.text_6, for: .normal)
-        createRoom.titleLabel?.font = .heading_h5
-        createRoom.contentEdgeInsets = .init(top: 0, left: 6, bottom: 0, right: 6)
-        createRoom.addAction(UIAction(handler: { _ in
-            let panel = LNCreateRoomPanel()
-            panel.popup()
-        }), for: .touchUpInside)
-        stackView.addArrangedSubview(createRoom)
+//        createRoom.layer.cornerRadius = 15
+//        createRoom.layer.borderWidth = 1
+//        createRoom.layer.borderColor = .fill
+//        createRoom.backgroundColor = .fill.withAlphaComponent(0.5)
+//        createRoom.setImage(.icRoomCreate.withTintColor(.text_6, renderingMode: .alwaysOriginal), for: .normal)
+//        createRoom.setTitle(.init(key: "A00318"), for: .normal)
+//        createRoom.setTitleColor(.text_6, for: .normal)
+//        createRoom.titleLabel?.font = .heading_h5
+//        createRoom.contentEdgeInsets = .init(top: 0, left: 6, bottom: 0, right: 6)
+//        createRoom.addAction(UIAction(handler: { _ in
+//            let panel = LNCreateRoomPanel()
+//            panel.popup()
+//        }), for: .touchUpInside)
+//        stackView.addArrangedSubview(createRoom)
     }
 }
 

+ 32 - 11
Lanu/Views/IM/Chat/GameMate/LNIMChatGameMateSkillCell.swift

@@ -20,6 +20,7 @@ class LNIMChatGameMateSkillCell: UIView {
     private let gameIc = UIImageView()
     
     private let gameView = UIView()
+    private let discountView = LNNewbieDiscountView()
     private let gameNameLabel = UILabel()
     private let gamePriceLabel = UILabel()
     
@@ -33,6 +34,7 @@ class LNIMChatGameMateSkillCell: UIView {
         super.init(frame: frame)
         
         setupViews()
+        LNEventDeliver.addObserver(self)
     }
     
     func update(_ skill: LNGameMateSkillVO) {
@@ -42,6 +44,8 @@ class LNIMChatGameMateSkillCell: UIView {
         gameNameLabel.text = skill.name
         gamePriceLabel.text = "\(skill.price.toDisplay) / \(skill.unit)"
         curItem = skill
+        
+        updateDiscount()
     }
     
     required init?(coder: NSCoder) {
@@ -49,6 +53,21 @@ class LNIMChatGameMateSkillCell: UIView {
     }
 }
 
+extension LNIMChatGameMateSkillCell: LNOrderManagerNotify {
+    func onMyDiscountInfoChanged(info: LNOrderDiscountVO?) {
+        updateDiscount()
+    }
+    
+    private func updateDiscount() {
+        if let discount = LNOrderManager.shared.discountFor(curItem?.price ?? 0) {
+            discountView.isHidden = false
+            discountView.update(1 - discount)
+        } else {
+            discountView.isHidden = true
+        }
+    }
+}
+
 extension LNIMChatGameMateSkillCell {
     private func setupViews() {
         let container = UIView()
@@ -152,23 +171,25 @@ extension LNIMChatGameMateSkillCell {
             make.top.equalToSuperview()
         }
         
-        let coin = UIImageView.coinImageView()
-        infoView.addSubview(coin)
-        coin.snp.makeConstraints { make in
+        let priceView = UIStackView()
+        priceView.spacing = 2
+        infoView.addSubview(priceView)
+        priceView.snp.makeConstraints { make in
             make.leading.equalToSuperview()
-            make.bottom.equalToSuperview()
+            make.trailing.lessThanOrEqualToSuperview()
             make.top.equalTo(gameNameLabel.snp.bottom).offset(1)
-            make.width.height.equalTo(18)
+            make.bottom.equalToSuperview()
         }
         
+        discountView.discountOnly = true
+        priceView.addArrangedSubview(discountView)
+        
+        let coin = UIImageView.coinImageView()
+        priceView.addArrangedSubview(coin)
+        
         gamePriceLabel.font = .body_m
         gamePriceLabel.textColor = .text_5
-        infoView.addSubview(gamePriceLabel)
-        gamePriceLabel.snp.makeConstraints { make in
-            make.leading.equalTo(coin.snp.trailing).offset(2)
-            make.centerY.equalTo(coin)
-            make.trailing.lessThanOrEqualToSuperview()
-        }
+        priceView.addArrangedSubview(gamePriceLabel)
         
         return gameView
     }

+ 4 - 8
Lanu/Views/Order/Create/LNCreateOrderFromSkillListPanel.swift

@@ -78,10 +78,8 @@ extension LNCreateOrderFromSkillListPanel {
         guard let skill = curSelected else { return }
         let cost = skill.price * Double(curCount)
         
-        if let discount = LNOrderManager.shared.discount,
-           discount.hasChance,
-           discount.eligiblePrice == skill.price {
-            costLabel.text = (cost - (1 - discount.discountRate) * skill.price).toDisplay
+        if let discount = LNOrderManager.shared.discountFor(skill.price) {
+            costLabel.text = (cost - (1 - discount) * skill.price).toDisplay
         } else {
             costLabel.text = cost.toDisplay
         }
@@ -280,11 +278,9 @@ private class LNProfileOrderSkillItemView: UIView {
         attrStr.addAttribute(.font, value: UIFont.heading_h4, range: range)
         priceLabel.attributedText = attrStr
         
-        if let discount = LNOrderManager.shared.discount,
-           discount.hasChance,
-           discount.eligiblePrice == skill.price {
+        if let discount = LNOrderManager.shared.discountFor(skill.price) {
             discountView.isHidden = false
-            discountView.update(1 - discount.discountRate)
+            discountView.update(1 - discount)
         } else {
             discountView.isHidden = true
         }

+ 12 - 20
Lanu/Views/Order/Create/LNCreateOrderPanel.swift

@@ -42,12 +42,10 @@ class LNCreateOrderPanel: LNPopupView {
             countLabel.text = "x\(curCount)"
             customCountLabel.text = "\(curCount)"
             
-            if let discount = LNOrderManager.shared.discount,
-               discount.hasChance,
-               discount.eligiblePrice == price {
-                costLabel.text = "\((price * Double(curCount) - (1 - discount.discountRate) * price).toDisplay)"
+            if let discount = LNOrderManager.shared.discountFor(price) {
+                costLabel.text = (price * Double(curCount) - (1 - discount) * price).toDisplay
             } else {
-                costLabel.text = "\((price * Double(curCount)).toDisplay)"
+                costLabel.text = (price * Double(curCount)).toDisplay
             }
             if curCount <= 1 {
                 minuButton.isEnabled = false
@@ -81,12 +79,10 @@ class LNCreateOrderPanel: LNPopupView {
         nameLabel.text = detail.nickname
         priceLabel.text = "\(detail.price.toDisplay)/\(detail.unit)"
         
-        if let discount = LNOrderManager.shared.discount,
-           discount.hasChance,
-           discount.eligiblePrice == detail.price {
+        if let discount = LNOrderManager.shared.discountFor(detail.price) {
             discountView.isHidden = false
-            newbieView.update(1 - discount.discountRate)
-            discountCoinLabel.text = "-\(detail.price * (1 - discount.discountRate))"
+            newbieView.update(1 - discount)
+            discountCoinLabel.text = "-\(detail.price * (1 - discount))"
         } else {
             discountView.isHidden = true
         }
@@ -104,12 +100,10 @@ class LNCreateOrderPanel: LNPopupView {
         nameLabel.text = user.nickname
         priceLabel.text = "\(skill.price.toDisplay)/\(skill.unit)"
         
-        if let discount = LNOrderManager.shared.discount,
-           discount.hasChance,
-           discount.eligiblePrice == skill.price {
+        if let discount = LNOrderManager.shared.discountFor(skill.price) {
             discountView.isHidden = false
-            newbieView.update(1 - discount.discountRate)
-            discountCoinLabel.text = "-\(skill.price * (1 - discount.discountRate))"
+            newbieView.update(1 - discount)
+            discountCoinLabel.text = "-\(skill.price * (1 - discount))"
         } else {
             discountView.isHidden = true
         }
@@ -125,12 +119,10 @@ class LNCreateOrderPanel: LNPopupView {
         nameLabel.text = detail.nickname
         priceLabel.text = "\(detail.price.toDisplay)/\(detail.unit)"
         
-        if let discount = LNOrderManager.shared.discount,
-           discount.hasChance,
-           discount.eligiblePrice == detail.price {
+        if let discount = LNOrderManager.shared.discountFor(detail.price) {
             discountView.isHidden = false
-            newbieView.update(1 - discount.discountRate)
-            discountCoinLabel.text = "-\(detail.price * (1 - discount.discountRate))"
+            newbieView.update(1 - discount)
+            discountCoinLabel.text = "-\(detail.price * (1 - discount))"
         } else {
             discountView.isHidden = true
         }

+ 8 - 14
Lanu/Views/Order/Create/LNCreateOrderViewController.swift

@@ -116,13 +116,11 @@ extension LNCreateOrderViewController {
         skillUnitLabel.text = "/\(detail.unit)"
         curCount = 1
         
-        if let discount = LNOrderManager.shared.discount,
-            discount.hasChance,
-            discount.eligiblePrice == detail.price {
+        if let discount = LNOrderManager.shared.discountFor(detail.price) {
             emptyDiscountView.isHidden = true
             newbieDiscountView.isHidden = false
-            discountView.update(1 - discount.discountRate)
-            discountCoinLabel.text = "-\((1 - discount.discountRate) * detail.price)"
+            discountView.update(1 - discount)
+            discountCoinLabel.text = "-\((1 - discount) * detail.price)"
         } else {
             emptyDiscountView.isHidden = false
             newbieDiscountView.isHidden = true
@@ -147,13 +145,11 @@ extension LNCreateOrderViewController {
             addButton.isEnabled = false
         }
         
-        if let discount = LNOrderManager.shared.discount,
-            discount.hasChance,
-            discount.eligiblePrice == detail.price {
+        if let discount = LNOrderManager.shared.discountFor(detail.price) {
             emptyDiscountView.isHidden = true
             newbieDiscountView.isHidden = false
-            discountView.update(1 - discount.discountRate)
-            discountCoinLabel.text = "-\((1 - discount.discountRate) * detail.price)"
+            discountView.update(1 - discount)
+            discountCoinLabel.text = "-\((1 - discount) * detail.price)"
         } else {
             emptyDiscountView.isHidden = false
             newbieDiscountView.isHidden = true
@@ -172,10 +168,8 @@ extension LNCreateOrderViewController {
         }
         let cost = price * Double(curCount)
         
-        if let discount = LNOrderManager.shared.discount,
-           discount.hasChance,
-           discount.eligiblePrice == price {
-            costLabel.text = (cost - (1 - discount.discountRate) * price).toDisplay
+        if let discount = LNOrderManager.shared.discountFor(price) {
+            costLabel.text = (cost - (1 - discount) * price).toDisplay
         } else {
             costLabel.text = cost.toDisplay
         }

+ 32 - 1
Lanu/Views/Order/Detail/LNOrderDetailCardView.swift

@@ -30,6 +30,8 @@ class LNOrderDetailCardView: UIView {
     private let orderIdLabel = UILabel()
     private let timeLabel = UILabel()
     private let totalLabel = UILabel()
+    private var discountView: UIView?
+    private let discountLabel = UILabel()
     
     init(type: LNOrderDetailCardViewType = .normal) {
         curType = type
@@ -48,7 +50,10 @@ class LNOrderDetailCardView: UIView {
         extraView?.isHidden = item.orderInfo.customerRemark.isEmpty
         orderIdLabel.text = item.orderInfo.orderId
         timeLabel.text = (TimeInterval(item.orderInfo.createTime) / 1000.0).formattedFullDateWithTime()
-        totalLabel.text = "\((item.orderInfo.price * Double(item.orderInfo.purchaseQty)).toDisplay)"
+        
+        totalLabel.text = item.orderInfo.totalAmount.toDisplay
+        discountView?.isHidden = item.orderInfo.totalAmount >= item.orderInfo.price * Double(item.orderInfo.purchaseQty)
+        discountLabel.text = "\(item.orderInfo.totalAmount - item.orderInfo.price * Double(item.orderInfo.purchaseQty))"
     }
     
     required init?(coder: NSCoder) {
@@ -89,6 +94,10 @@ extension LNOrderDetailCardView {
         let countView = buildDetailInfo(title: .init(key: "A00122"), contentView: countLabel)
         stackView.addArrangedSubview(countView)
         
+        let discountView = buildDiscount()
+        stackView.addArrangedSubview(discountView)
+        self.discountView = discountView
+        
         extraLabel.font = curType == .normal ? .body_s : .body_xs
         extraLabel.textColor = .text_5
         extraLabel.numberOfLines = 0
@@ -205,6 +214,28 @@ extension LNOrderDetailCardView {
         return buildDetailInfo(title: .init(key: "A00128"), contentView: priceView)
     }
     
+    private func buildDiscount() -> UIView {
+        let discountView = UIView()
+        
+        let coin = UIImageView.coinImageView()
+        discountView.addSubview(coin)
+        coin.snp.makeConstraints { make in
+            make.leading.centerY.equalToSuperview()
+            make.width.height.equalTo(14)
+        }
+        
+        discountLabel.font = .body_s
+        discountLabel.textColor = .text_5
+        discountView.addSubview(discountLabel)
+        discountLabel.snp.makeConstraints { make in
+            make.verticalEdges.equalToSuperview()
+            make.trailing.equalToSuperview()
+            make.leading.equalTo(coin.snp.trailing)
+        }
+        
+        return buildDetailInfo(title: .init(key: "A00129"), contentView: discountView)
+    }
+    
     private func buildTotal() -> UIView {
         let container = UIView()
         container.snp.makeConstraints { make in

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

@@ -11,7 +11,6 @@ import SnapKit
 import Combine
 
 
-
 class LNNewbieDiscountView: UIView {
     var discountOnly = false {
         didSet {

+ 28 - 2
Lanu/Views/Order/OrderList/LNOrderListItemCell.swift

@@ -23,6 +23,7 @@ class LNOrderListItemCell: UITableViewCell {
     
     private let operationButton = UIButton()
     private let descLabel = UILabel()
+    private let discountView = UIView()
     private let totalLabel = UILabel()
 
     private var curItem: LNOrderListItemVO?
@@ -42,7 +43,8 @@ class LNOrderListItemCell: UITableViewCell {
         priceLabel.text = "\(item.price.toDisplay)"
         countLabel.text = "\(item.unit) x \(item.purchaseQty)"
         
-        totalLabel.text = "\((item.price * Double(item.purchaseQty)).toDisplay)"
+        totalLabel.text = item.totalAmount.toDisplay
+        discountView.isHidden = item.totalAmount >= item.price * Double(item.purchaseQty)
         
         curItem = item
         
@@ -283,6 +285,13 @@ extension LNOrderListItemCell {
             make.trailing.equalTo(coin.snp.leading)
         }
         
+        let discount = buildDiscount()
+        container.addSubview(discount)
+        discount.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(text.snp.leading).offset(-5)
+        }
+        
         operationButton.layer.cornerRadius = 15
         operationButton.layer.borderWidth = 1
         operationButton.clipsToBounds = true
@@ -304,7 +313,7 @@ extension LNOrderListItemCell {
         descLabel.snp.makeConstraints { make in
             make.leading.equalToSuperview().offset(12)
             make.centerY.equalToSuperview()
-            make.trailing.lessThanOrEqualTo(text.snp.leading).offset(-16)
+            make.trailing.lessThanOrEqualTo(discount.snp.leading).offset(-16)
         }
         
         return container
@@ -382,6 +391,23 @@ extension LNOrderListItemCell {
         
         return container
     }
+    
+    private func buildDiscount() -> UIView {
+        discountView.layer.cornerRadius = 4
+        discountView.backgroundColor = .init(hex: "#FF6F32")
+        
+        let titleLabel = UILabel()
+        titleLabel.text = .init(key: "A00129")
+        titleLabel.font = .body_xs
+        titleLabel.textColor = .text_1
+        discountView.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.horizontalEdges.equalToSuperview().inset(6)
+            make.verticalEdges.equalToSuperview().inset(3)
+        }
+        
+        return discountView
+    }
 }
 
 #if DEBUG

+ 27 - 1
Lanu/Views/Order/OrderRecords/LNOrderRecordCell.swift

@@ -18,6 +18,7 @@ class LNOrderRecordCell: UITableViewCell {
     private let gameNameLabel = UILabel()
     private let orderIdLabel = UILabel()
     
+    private let discountView = UIView()
     private let priceLabel = UILabel()
     private let countLabel = UILabel()
     
@@ -50,6 +51,7 @@ class LNOrderRecordCell: UITableViewCell {
         gameNameLabel.text = item.bizCategoryName
         orderIdLabel.text = item.orderId
         
+        discountView.isHidden = item.totalAmount >= item.price * Double(item.purchaseQty)
         priceLabel.text = item.price.toDisplay
         countLabel.text = "\(item.unit) x \(item.purchaseQty)"
         
@@ -490,11 +492,18 @@ extension LNOrderRecordCell {
         container.addSubview(coin)
         coin.snp.makeConstraints { make in
             make.centerY.equalTo(priceLabel)
-            make.leading.equalToSuperview()
             make.trailing.equalTo(priceLabel.snp.leading)
             make.width.height.equalTo(16)
         }
         
+        let discount = buildDiscount()
+        container.addSubview(discount)
+        discount.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalToSuperview()
+            make.trailing.equalTo(coin.snp.leading).offset(-4)
+        }
+        
         countLabel.font = .body_m
         countLabel.textColor = .text_5
         countLabel.textAlignment = .right
@@ -508,6 +517,23 @@ extension LNOrderRecordCell {
         
         return container
     }
+    
+    private func buildDiscount() -> UIView {
+        discountView.layer.cornerRadius = 4
+        discountView.backgroundColor = .init(hex: "#FF6F32")
+        
+        let titleLabel = UILabel()
+        titleLabel.text = .init(key: "A00129")
+        titleLabel.font = .body_xs
+        titleLabel.textColor = .text_1
+        discountView.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.horizontalEdges.equalToSuperview().inset(6)
+            make.verticalEdges.equalToSuperview().inset(3)
+        }
+        
+        return discountView
+    }
 }
 
 #if DEBUG

+ 1 - 1
Lanu/Views/Profile/Profile/Detail/LNProfileSkillListProvider.swift

@@ -76,7 +76,7 @@ extension LNProfileSkillListCell {
     private func setupViews() {
         stackView.axis = .vertical
         stackView.spacing = 7
-        addSubview(stackView)
+        contentView.addSubview(stackView)
         stackView.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(16)
             make.bottom.equalToSuperview().offset(-28)