Explorar el Código

feat: 完善订单部分逻辑

陈文艺 hace 3 meses
padre
commit
30376c4e86

+ 2 - 2
Lanu.xcodeproj/project.pbxproj

@@ -528,7 +528,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 12;
+				CURRENT_PROJECT_VERSION = 13;
 				DEVELOPMENT_TEAM = 5H8D98R72W;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -571,7 +571,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 12;
+				CURRENT_PROJECT_VERSION = 13;
 				DEVELOPMENT_TEAM = 5H8D98R72W;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;

+ 11 - 0
Lanu/AppDelegate.swift

@@ -31,6 +31,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         
         LNEventDeliver.notifyAppLaunchFinished()
         
+        if let url = launchOptions?[.url] as? URL {
+            LNDeeplinkManager.shared.handleDeepLink(url)
+        }
+        
         return true
     }
 
@@ -47,6 +51,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
         // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
     }
+    
+    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
+        LNDeeplinkManager.shared.handleDeepLink(url)
+        return true
+    }
+    
+    
 }
 
 extension AppDelegate {

+ 10 - 0
Lanu/Info.plist

@@ -20,6 +20,16 @@
 				<string>com.googleusercontent.apps.955524882346-8ma09s04jkalgbdk8s41p25pd37hoijm</string>
 			</array>
 		</dict>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLName</key>
+			<string>com.jiehe.gami</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>gami</string>
+			</array>
+		</dict>
 	</array>
 	<key>FireBaseConfigPath</key>
 	<string>$(FIREBASE_PLIST)</string>

+ 23 - 4
Lanu/Manager/Deeplink/LNDeeplinkManager.swift

@@ -14,6 +14,7 @@ struct LNDeeplinkUrls {
     enum web: String {
         case closeWindow
         case userCancellation
+        case page
     }
 }
 
@@ -39,15 +40,33 @@ extension RawRepresentable where RawValue == String {
 
 class LNDeeplinkManager {
     static let shared = LNDeeplinkManager()
-    typealias LNDeeplinkHandler = ([String: Any]) -> Void
+    typealias LNDeeplinkHandler = ([String: Any]?) -> Void
     
+    private let lock = NSLock()
     private var routerMap: [String: LNDeeplinkHandler] = [:]
     
     private init() {
-        
+        DispatchQueue.global().async { [weak self] in
+            guard let self else { return }
+            lock.lock()
+            setupWebDeeplink()
+            lock.unlock()
+        }
     }
     
-    func handleDeepLink(_ url: String) {
-        routerMap[url]?([:])
+    func handleDeepLink(_ url: URL) {
+//        lock.lock()
+//        let handler = routerMap[url]
+//        lock.unlock()
+//        
+//        handler?(params)
+    }
+}
+
+extension LNDeeplinkManager {
+    private func setupWebDeeplink() {
+        routerMap[LNDeeplinkUrls.web.page.deeplinkPath] = { params in
+            
+        }
     }
 }

+ 0 - 6
Lanu/Manager/IM/LNIMManager.swift

@@ -49,7 +49,6 @@ class LNIMManager: NSObject {
         _ = LNIMEmojiManager.shared
         LNEventDeliver.addObserver(self)
         V2TIMManager.sharedInstance().addConversationListener(listener: self)
-        V2TIMManager.sharedInstance().addIMSDKListener(listener: self)
     }
 }
 
@@ -128,11 +127,6 @@ extension LNIMManager: V2TIMConversationListener {
     }
 }
 
-extension LNIMManager: V2TIMSDKListener {
-    func onUserStatusChanged(userStatusList: [V2TIMUserStatus]!) {
-    }
-}
-
 extension LNIMManager: LNAccountManagerNotify {
     func onUserLogin() {
         // 初始化 SDK

+ 45 - 3
Lanu/Views/IM/Chat/GameMate/LNIMChatGameMateOrderView.swift

@@ -21,6 +21,7 @@ class LNIMChatGameMateOrderView: UIView {
     
     private let replyView = UIView()
     private let replyRemainLabel = UILabel()
+    private var countDownTimer: Timer?
     
     private let actionView = UIView()
     
@@ -52,8 +53,40 @@ class LNIMChatGameMateOrderView: UIView {
     }
 }
 
+extension LNIMChatGameMateOrderView {
+    private func startCountDown() {
+        stopCountDown()
+        
+        updateRemain()
+        let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
+            guard let self else { return }
+            if updateRemain() {
+                stopCountDown()
+                viewModel?.getUnfinishOrder()
+            }
+        }
+        RunLoop.current.add(timer, forMode: .common)
+        countDownTimer = timer
+    }
+    
+    private func stopCountDown() {
+        countDownTimer?.invalidate()
+        countDownTimer = nil
+    }
+    
+    @discardableResult
+    private func updateRemain() -> Bool {
+        guard let curOrder else { return true }
+        let remain = 3600 - (Int(curTime) - curOrder.createTime / 1_000)
+        replyRemainLabel.text = String(format: "%02d:%02d", remain/60, remain%60)
+        return remain <= 0
+    }
+}
+
 extension LNIMChatGameMateOrderView {
     private func update(_ order: LNUnfinishedOrderVO) {
+        curOrder = order
+        
         let isCreator = order.buyerUserNo.isMyUid
         
         gameIc.sd_setImage(with: URL(string: order.categoryIcon))
@@ -62,11 +95,17 @@ extension LNIMChatGameMateOrderView {
         
         actionView.isHidden = true
         extraView.isHidden = true
+        stopCountDown()
+        
         switch order.status {
         case .created, .waitingForAccept:
             titleLabel.text = .init(key: "Waiting for Acceptance")
             titleArrow.isHidden = false
             contentArrow.isHidden = true
+            replyView.isHidden = false
+            let remain = 3600 - (Int(curTime) - order.createTime / 1_000)
+            replyRemainLabel.text = String(format: "%02d:%02d", remain/60, remain%60)
+            startCountDown()
             if !isCreator {
                 actionView.isHidden = false
             }
@@ -87,7 +126,6 @@ extension LNIMChatGameMateOrderView {
         case .completed, .refunded, .rejected, .serviceDone, .cancelled:
             break
         }
-        curOrder = order
     }
     
     private func setupViews() {
@@ -96,7 +134,11 @@ extension LNIMChatGameMateOrderView {
         container.layer.cornerRadius = 12
         container.onTap { [weak self] in
             guard let self else { return }
-            pushToOrderRecord()
+            if curOrder?.buyerUserNo.isMyUid != false {
+                pushToOrderList()
+            } else {
+                pushToOrderRecord()
+            }
         }
         addSubview(container)
         container.snp.makeConstraints { make in
@@ -110,7 +152,7 @@ extension LNIMChatGameMateOrderView {
         container.addSubview(stackView)
         stackView.snp.makeConstraints { make in
             make.directionalHorizontalEdges.equalToSuperview()
-            make.verticalEdges.equalToSuperview().inset(6)
+            make.verticalEdges.equalToSuperview().inset(11)
         }
         
         let orderView = buildOrderView()

+ 1 - 1
Lanu/Views/IM/Chat/ViewModel/LNIMChatViewModel.swift

@@ -59,7 +59,7 @@ class LNIMChatViewModel: NSObject {
 }
 
 extension LNIMChatViewModel {
-    private func getUnfinishOrder() {
+    func getUnfinishOrder() {
         var nextTag: String = ""
         var orders: [LNUnfinishedOrderVO] = []
         

+ 4 - 5
Lanu/Views/Order/Create/LNCreateOrderPanel.swift

@@ -55,6 +55,8 @@ class LNCreateOrderPanel: LNPopupView {
         }
     }
     
+    var completionHandler: ((String) -> Void)?
+    
     override init(frame: CGRect) {
         super.init(frame: frame)
         
@@ -148,13 +150,10 @@ extension LNCreateOrderPanel {
                 skillId: skillId, count: curCount, remark: extraInput.text ?? "")
             { [weak self] orderNo in
                 guard let self else { return }
-                guard orderNo != nil else { return }
+                guard let orderNo else { return }
                 
                 dismiss()
-                if let userId {
-                    pushToChat(uid: userId)
-                    navigationController?.viewControllers.removeAll { $0 is LNCreateOrderViewController }
-                }
+                completionHandler?(orderNo)
             }
         }), for: .touchUpInside)
         container.addSubview(confirmButton)

+ 6 - 0
Lanu/Views/Order/Create/LNCreateOrderViewController.swift

@@ -441,6 +441,12 @@ extension LNCreateOrderViewController {
             guard let skill else { return }
             let panel = LNCreateOrderPanel()
             panel.update(skill, count: curCount, extra: extraInput.text ?? "")
+            panel.completionHandler = { [weak self] orderId in
+                guard let self else { return }
+                
+                view.pushToChat(uid: skill.userNo)
+                navigationController?.viewControllers.removeAll { $0 is LNCreateOrderViewController }
+            }
             panel.showIn()
         }), for: .touchUpInside)
         container.addSubview(orderButton)

+ 25 - 7
Lanu/Views/Order/Detail/LNOrderDetailViewController.swift

@@ -31,9 +31,9 @@ class LNOrderDetailViewController: LNViewController {
     private let detailView = LNOrderDetailCardView()
     
     private let cancelButton = UIButton()
+    private let refundButton = UIButton()
     private let commentButton = UIButton()
     private let completeView = UIView()
-    private let refundButton = UIButton()
     
     private let refundView = LNOrderRefundInfoView()
     
@@ -81,6 +81,7 @@ extension LNOrderDetailViewController {
         cancelButton.isHidden = true
         commentButton.isHidden = true
         completeView.isHidden = true
+        refundButton.isHidden = true
         
         detailView.update(item)
         refundView.update(item)
@@ -116,6 +117,8 @@ extension LNOrderDetailViewController {
             backgroundIc.image = .init(named: "ic_order_normal_bg")
             stateIc.image = .init(named: "ic_order_status_waiting")
             stateLabel.text = .init(key: "Accepted")
+            
+            refundButton.isHidden = false
         case .rejected:
             backgroundIc.image = .init(named: "ic_order_cancelled_bg")
             stateIc.image = .init(named: "ic_order_status_cancel")
@@ -124,6 +127,8 @@ extension LNOrderDetailViewController {
             backgroundIc.image = .init(named: "ic_order_normal_bg")
             stateIc.image = .init(named: "ic_order_status_in_progress")
             stateLabel.text = .init(key: "In progress")
+            
+            refundButton.isHidden = false
         case .serviceDone:
             backgroundIc.image = .init(named: "ic_order_normal_bg")
             stateIc.image = .init(named: "ic_order_status_in_progress")
@@ -255,6 +260,23 @@ extension LNOrderDetailViewController {
             make.verticalEdges.equalToSuperview()
         }
         
+        refundButton.isHidden = true
+        refundButton.setTitle(.init(key: "Refund"), for: .normal)
+        refundButton.setTitleColor(.text_3, for: .normal)
+        refundButton.titleLabel?.font = .heading_h3
+        refundButton.layer.cornerRadius = 23.5
+        refundButton.layer.borderWidth = 1
+        refundButton.layer.borderColor = UIColor.text_2.cgColor
+        refundButton.addAction(UIAction(handler: { [weak self] _ in
+            guard let self else { return }
+            view.pushToOrderRefund(orderId)
+        }), for: .touchUpInside)
+        container.addSubview(refundButton)
+        refundButton.snp.makeConstraints { make in
+            make.directionalHorizontalEdges.equalToSuperview().inset(16)
+            make.verticalEdges.equalToSuperview()
+        }
+        
         let cover = UIView()
         cover.backgroundColor = .fill
         cover.layer.cornerRadius = 23
@@ -290,6 +312,7 @@ extension LNOrderDetailViewController {
             make.directionalHorizontalEdges.equalToSuperview().inset(16)
             make.verticalEdges.equalToSuperview()
         }
+        let refundButton = UIButton()
         refundButton.layer.cornerRadius = 23.5
         refundButton.setTitle(.init(key: "Refund"), for: .normal)
         refundButton.setTitleColor(.text_3, for: .normal)
@@ -298,12 +321,7 @@ extension LNOrderDetailViewController {
         refundButton.layer.borderWidth = 1
         refundButton.addAction(UIAction(handler: { [weak self] _ in
             guard let self else { return }
-            view.pushToOrderRefund(orderId) { [weak self] in
-                guard let self else { return }
-                guard let curDetail else { return }
-                curDetail.orderInfo.refundApply = true
-                update(curDetail)
-            }
+            view.pushToOrderRefund(orderId)
         }), for: .touchUpInside)
         completeView.addSubview(refundButton)
         refundButton.snp.makeConstraints { make in

+ 1 - 0
Lanu/Views/Order/OrderList/LNOrderListItemCell.swift

@@ -81,6 +81,7 @@ extension LNOrderListItemCell {
             break
         case .completed: // 可以评价
             let panel = LNOrderCommentPanel()
+            panel.update(orderItem.avatar, orderId: orderItem.orderId)
             panel.handler = { [weak self] star, comment in
                 guard let self else { return }
                 orderItem.star = star

+ 35 - 17
Lanu/Views/Order/OrderRecords/LNOrderRecordCell.swift

@@ -24,6 +24,9 @@ class LNOrderRecordCell: UITableViewCell {
     private let avatar = UIImageView()
     private let nameLabel = UILabel()
     private let genderView = UIImageView()
+    
+    private let requestLine = UIView()
+    private let requestView = UIView()
     private let requestLabel = UILabel()
     
     private let menuView = UIView()
@@ -61,6 +64,8 @@ class LNOrderRecordCell: UITableViewCell {
             genderView.image = nil
         }
         requestLabel.text = item.customerRemark
+        requestLine.isHidden = item.customerRemark.isEmpty
+        requestView.isHidden = item.customerRemark.isEmpty
         
         curItem = item
         
@@ -228,47 +233,60 @@ extension LNOrderRecordCell {
         container.backgroundColor = .fill_1
         container.layer.cornerRadius = 12
         
+        let stackView = UIStackView()
+        stackView.axis = .vertical
+        stackView.spacing = 4
+        container.addSubview(stackView)
+        stackView.snp.makeConstraints { make in
+            make.directionalEdges.equalToSuperview().inset(8)
+        }
+        
+        let userView = UIView()
+        userView.snp.makeConstraints { make in
+            make.height.equalTo(23).priority(.medium)
+        }
+        stackView.addArrangedSubview(userView)
+        
         avatar.layer.cornerRadius = 11.5
         avatar.clipsToBounds = true
-        container.addSubview(avatar)
+        userView.addSubview(avatar)
         avatar.snp.makeConstraints { make in
             make.leading.equalToSuperview()
-            make.top.equalToSuperview().offset(8)
+            make.centerY.equalToSuperview()
             make.width.height.equalTo(23)
         }
         
         nameLabel.font = .body_s
         nameLabel.textColor = .text_5
-        container.addSubview(nameLabel)
+        userView.addSubview(nameLabel)
         nameLabel.snp.makeConstraints { make in
             make.centerY.equalTo(avatar)
             make.leading.equalTo(avatar.snp.trailing).offset(8)
         }
         
-        container.addSubview(genderView)
+        userView.addSubview(genderView)
         genderView.snp.makeConstraints { make in
             make.centerY.equalTo(avatar)
             make.leading.equalTo(nameLabel.snp.trailing).offset(3)
             make.width.height.equalTo(14)
         }
         
-        let line = UIView()
-        line.backgroundColor = .fill_2
-        container.addSubview(line)
-        line.snp.makeConstraints { make in
-            make.directionalHorizontalEdges.equalToSuperview().inset(8)
-            make.top.equalTo(avatar.snp.bottom).offset(4)
+        requestLine.backgroundColor = .fill_2
+        requestLine.snp.makeConstraints { make in
             make.height.equalTo(0.5)
         }
+        stackView.addArrangedSubview(requestLine)
+        
+        stackView.addArrangedSubview(requestView)
         
         let titleLabel = UILabel()
         titleLabel.font = .heading_h5
         titleLabel.textColor = .text_4
         titleLabel.text = .init(key: "Request")
-        container.addSubview(titleLabel)
+        requestView.addSubview(titleLabel)
         titleLabel.snp.makeConstraints { make in
-            make.leading.equalToSuperview().offset(8)
-            make.top.equalTo(line.snp.bottom).offset(4)
+            make.leading.equalToSuperview()
+            make.top.equalToSuperview()
         }
         
         requestLabel.font = .body_xs
@@ -276,11 +294,11 @@ extension LNOrderRecordCell {
         requestLabel.numberOfLines = 0
         requestLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
         requestLabel.setContentCompressionResistancePriority(.defaultHigh , for: .vertical)
-        container.addSubview(requestLabel)
+        requestView.addSubview(requestLabel)
         requestLabel.snp.makeConstraints { make in
-            make.directionalHorizontalEdges.equalToSuperview().inset(8)
+            make.directionalHorizontalEdges.equalToSuperview()
             make.top.equalTo(titleLabel.snp.bottom)
-            make.bottom.equalToSuperview().offset(-8)
+            make.bottom.equalToSuperview()
         }
         
         return container
@@ -443,7 +461,7 @@ extension LNOrderRecordCell {
         gameIc.clipsToBounds = true
         container.addSubview(gameIc)
         gameIc.snp.makeConstraints { make in
-            make.leading.equalToSuperview().offset(10)
+            make.leading.equalToSuperview()
             make.verticalEdges.equalToSuperview()
             make.width.height.equalTo(40)
         }

+ 4 - 6
Lanu/Views/Order/Refund/LNOrderRefundViewController.swift

@@ -11,8 +11,8 @@ import SnapKit
 
 
 extension UIView {
-    func pushToOrderRefund(_ orderId: String, handler: (() -> Void)? = nil) {
-        let vc = LNOrderRefundViewController(orderId: orderId, handler: handler)
+    func pushToOrderRefund(_ orderId: String) {
+        let vc = LNOrderRefundViewController(orderId: orderId)
         navigationController?.pushViewController(vc, animated: true)
     }
 }
@@ -20,7 +20,6 @@ extension UIView {
 
 class LNOrderRefundViewController: LNViewController {
     private let orderId: String
-    private var finishHandler: (() -> Void)?
     private var curDetail: LNOrderDetailResponse?
     
     private let detailView = LNOrderDetailCardView(type: .small)
@@ -31,9 +30,8 @@ class LNOrderRefundViewController: LNViewController {
     
     private let submitButton = UIButton()
     
-    init(orderId: String, handler: (() -> Void)?) {
+    init(orderId: String) {
         self.orderId = orderId
-        finishHandler = handler
         super.init(nibName: nil, bundle: nil)
     }
     
@@ -262,7 +260,7 @@ import SwiftUI
 
 struct LNOrderRefundViewControllerPreview: UIViewControllerRepresentable {
     func makeUIViewController(context: Context) -> some UIViewController {
-        LNOrderRefundViewController(orderId: "", handler: nil)
+        LNOrderRefundViewController(orderId: "")
     }
     
     func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }

+ 4 - 2
Lanu/Views/Web/LNWebViewController.swift

@@ -84,7 +84,9 @@ extension LNWebViewController: WKNavigationDelegate {
         if fullPath == LNDeeplinkUrls.web.closeWindow.deeplinkPath {
             navigationController?.popViewController(animated: true)
         } else if fullPath == LNDeeplinkUrls.web.userCancellation.deeplinkPath {
-            LNAccountManager.shared.logout()
+            LNAccountManager.shared.clean()
+        } else {
+            LNDeeplinkManager.shared.handleDeepLink(url)
         }
         
         decisionHandler(.cancel)
@@ -102,7 +104,7 @@ extension LNWebViewController {
         view.addSubview(webView)
         webView.snp.makeConstraints { make in
             make.directionalHorizontalEdges.equalToSuperview()
-            make.top.equalToSuperview().offset(UIView.statusBarHeight)
+            make.top.equalToSuperview().offset(showNavigationBar ? 0 : UIView.statusBarHeight)
             make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom)
         }
     }