JLChen
2021-05-18 a869383e163a18cdedcf587383c1eca043129754
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
//
//  Copyright © 2018年 Zhejiang Dahua Technology Co.,Ltd. All rights reserved.
//    说明:不要在局部函数中创建DHBindPresenter对象,会导致内部的delegate为nil
 
import UIKit
 
/// 绑定容器(UIViewController)需要实现的协议
protocol DHBindContainerProtocol: DHAddBaseVCProtocol {
    
    func navigationVC() -> UINavigationController?
    
    func mainController() -> UIViewController
    
    func mainView() -> UIView
    
    func retry()
}
 
class DHBindPresenter: NSObject, DHConnectCloudTimeoutVCDelegate {
 
    private weak var container: DHBindContainerProtocol?
    
    private var isInBinding: Bool = false
    
    /// 绑定失败的界面,UE没有考虑,暂时这样处理
    private lazy var failureView: DHConnectCloudTimeoutViewController = {
        let vc = DHConnectCloudTimeoutViewController()
        vc.delegate = self
        vc.failureType = .cloudTimeout
        vc.detailText = nil
        return vc
    }()
    
    /// 已经验证过的密码,再试重试绑定时,就不需要登录设备【海外用】
    private var authedPassword: String = ""
    
    deinit {
        dh_printDeinit(self)
    }
    
    func setup(container: DHBindContainerProtocol?) {
        self.container = container
    }
    
    public func bindDevice(devicePassword: String,
                           isPasswordAuthed: Bool = false,
                           code: String? = nil,
                           deviceKey: String? = nil,
                           showLoading: Bool = true,
                           showErrorTip: Bool = true,
                           complete: ((_ isSucceed: Bool) -> ())?) {
        if self.isInBinding {
            return
        }
         
        if showLoading {
            DispatchQueue.main.async {
                LCProgressHUD.show(on: self.container?.mainView())
            }
        }
        
        if isPasswordAuthed {
            self.authedPassword = devicePassword
        }
 
        self.isInBinding = true
        
        DHAddDeviceManager.sharedInstance.bindDevice(devicePassword: devicePassword, code: code, deviceKey: "", success: {
            DHAddDeviceManager.sharedInstance.getDeviceInfoAfterBind(success: { (successInfo) in
                LCProgressHUD.hideAllHuds(self.container?.mainView())
                self.isInBinding = false
                self.deviceBindedProcessed(successInfo: successInfo)
                complete?(true)
            }) { (error) in
                
            }
        }) { (error) in
            LCProgressHUD.hideAllHuds(self.container?.mainView())
 
            //【*】处理特定的绑定错误码:海外由于是绑定前进行检验,不需要处理
            var errorProcessed = false
            if DHModuleConfig.shareInstance()?.isLeChange == true {
                errorProcessed = self.bindUnsuccessfullyProcessed(error: error, type: .cloudTimeout)
            }
            
            if showErrorTip, errorProcessed == false {
                if error.errorMessage.count > 0 {
                    error.showTips(error.errorMessage)
                } else {
                    error.showTips("device_common_operate_fail_try_again".lc_T)
                }
            }
            
            self.isInBinding = false
            complete?(false)
        }
    }
    
    // MARK: 绑定错误处理
    public func deviceBindedProcessed(successInfo: DHBindDeviceSuccess) {
        //【*】bindStatus为空,跳转正常的绑定成功页面
        //【*】bindStatus为bindByMe,返回到首页,给出提示
        //【*】bindStatus为bindByOther,跳转到被别人绑定的界面
        if successInfo.bindStatus == nil || successInfo.bindStatus.count == 0 {
            let successVc = DHBindSuccessViewController.storyboardInstance()
            successVc.deviceName = successInfo.deviceName ?? ""
            successVc.successInfo = successInfo
            self.container?.navigationVC()?.pushViewController(successVc, animated: true)
        } else if successInfo.bindStatus.dh_caseInsensitiveSame(string: "bindByMe") {
            LCProgressHUD.showMsg("add_device_device_bind_by_yourself".lc_T)
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
                self.container?.baseExitAddDevice(showAlert: false, backToMain: true)
            }
        } else {
            let bindVc = DHBindByOtherViewController.storyboardInstance()
            bindVc.bindAccount = successInfo.userAccount ?? ""
            bindVc.leftAction = .quit
            self.container?.navigationVC()?.pushViewController(bindVc, animated: true)
        }
    }
    
    /// 绑定失败处理:序列号串号、绑定次数过多、局域网限制等特定错误
    ///
    /// - Parameters:
    ///   - error: 错误
    ///   - type: 失败类型
    /// - Returns: 成功处理,返回true; 未处理失败,返回false
    public func bindUnsuccessfullyProcessed(error: LCError, type: DHNetConnectFailureType) -> Bool {
        let errorCode = error.errorCode //EC_DEVICE_BINDING_LAN_LIMIT.rawValue //
        
        var processed = false
        if errorCode == "DV1014" || errorCode == "DV1015" || errorCode == "DV1040" {
            //【*】绑定限制:时间和次数
            let desc = error.errorMessage as? String
            _ = self.showBindFailureView(imagename: "adddevice_fail_rest", content: desc)
            processed = true
        } else if errorCode == "DV1013" || errorCode == "DV1044" || errorCode == "DV1018" {
            //【*】绑定限制:局域网
            let desc = error.errorMessage as? String
            //let testText = "您的设备注册到平台已超过3天\n要求设备与客户端在同一局域网才能绑定\n请断电重启"
            let vc = self.showBindFailureView(imagename: "adddevice_netsetting_power", content: desc)
            if let image = UIImage(named: "adddevice_netsetting_power") {
                vc.errorView.updateTopImageViewConstraint(top: 0, width: image.width, height: image.height)
            }
            
            processed = true
        }
        else if errorCode == "DV1042" {
            //【*】密码错误:设备密码错误达限制次数
            let vc = self.showBindFailureView(imagename: "adddevice_netsetting_power", content: "add_device_device_locked_please_reboot".lc_T)
            if let image = UIImage(named: "adddevice_netsetting_power") {
                vc.errorView.updateTopImageViewConstraint(top: 0, width: image.width, height: image.height)
            }
 
            processed = true
        }
        else if errorCode == "DV1005" || errorCode == "DV1027" || errorCode == "DV1025" || errorCode == "DV1016" {
            //【*】绑定时错误: 旧的密码错误(13005)、通过sc初始化失败(当超时处理)
            //【*】绑定时密码错误:增加SC方式,修改设备密码后,会出现这种情况,以默认的sc码,进行绑定,密码错误
            //【*】如果已在当前界面,则不需要处理
            if container?.mainController().isKind(of: DHAuthPasswordViewController.self) == false {
                let controller = DHAuthPasswordViewController.storyboardInstance()
                controller.presenter = DHAuthPasswordPresenter(container: controller)
                container?.navigationVC()?.pushViewController(controller, animated: true)
                
                processed = true
            }
        } 
        
        return processed
    }
    
    private func showBindFailureView(imagename: String, content: String?) -> DHBindFailureViewController {
 
        let errorVc = DHBindFailureViewController()
        errorVc.imagename = imagename
        errorVc.content = content
        
        if let controller = self.container?.mainController() {
            errorVc.showOnParent(controller: controller)
        }
        
        return errorVc
    }
}
 
 
// MARK: DHConnectCloudTimeoutVCDelegate
extension DHBindPresenter {
    
    func cloudTimeOutReconnectAction(controller: DHConnectCloudTimeoutViewController) {
        if self.authedPassword.count > 0 {
            self.bindDevice(devicePassword: self.authedPassword, isPasswordAuthed: true, code: nil, deviceKey: nil, showLoading: true, showErrorTip: true, complete: nil)
        } else {
            //国内无法验证密码,需要再次进输入密码界面绑定
            self.failureView.dismiss()
        }
    }
}