O2AuthSDK.swift 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224
  1. //
  2. // O2AuthSDK.swift
  3. // O2OA_SDK_Framwork
  4. //
  5. // Created by FancyLou on 2018/11/6.
  6. //
  7. import UIKit
  8. import RxSwift
  9. import Moya
  10. import CommonCrypto
  11. public class O2AuthSDK: NSObject {
  12. /// 单例
  13. public static let shared: O2AuthSDK = O2AuthSDK()
  14. private override init() {}
  15. private let registerAPI: O2MoyaProvider<O2RegisterAPI> = {
  16. return O2MoyaProvider<O2RegisterAPI>()
  17. }()
  18. private let loginAPI: O2MoyaProvider<O2LoginAPI> = {
  19. return O2MoyaProvider<O2LoginAPI>()
  20. }()
  21. //MARK: - public 公开本地对象
  22. /// 当前登录用户信息
  23. ///
  24. /// - Returns:
  25. public func myInfo() -> O2LoginAccountModel? {
  26. return O2UserDefaults.shared.myInfo
  27. }
  28. /// 当前绑定单位服务器信息
  29. ///
  30. /// - Returns:
  31. public func bindUnit() -> O2BindUnitModel? {
  32. return O2UserDefaults.shared.unit
  33. }
  34. /// 当前绑定的设备信息
  35. ///
  36. /// - Returns:
  37. public func bindDevice() -> O2BindDeviceModel? {
  38. return O2UserDefaults.shared.device
  39. }
  40. /// 设置设备token 极光推送用的
  41. ///
  42. /// - Parameter token: 极光推送deviceToken
  43. public func setDeviceToken(token: String) {
  44. O2UserDefaults.shared.deviceToken = token
  45. }
  46. /// 获取设备token
  47. ///
  48. /// - Returns: 极光推送deviceToken
  49. public func getDeviceToken() -> String {
  50. return O2UserDefaults.shared.deviceToken ?? ""
  51. }
  52. /// O2OA服务器信息
  53. ///
  54. /// - Returns:
  55. public func centerServerInfo() -> O2CenterServerModel? {
  56. return O2UserDefaults.shared.centerServer
  57. }
  58. /// O2OA 服务器 各个微服务信息
  59. ///
  60. /// - Parameter context: 微服务
  61. /// - Returns:
  62. public func o2APIServer(context: O2ModuleContext) -> O2APIServerModel? {
  63. guard let dic = O2UserDefaults.shared.centerServer?.assembles else {
  64. return nil
  65. }
  66. switch context {
  67. case .x_processplatform_assemble_surface_script:
  68. return dic["x_processplatform_assemble_surface_script"]
  69. case .x_processplatform_assemble_surface_task:
  70. return dic["x_processplatform_assemble_surface_task"]
  71. case .x_processplatform_assemble_surface_worklog:
  72. return dic["x_processplatform_assemble_surface_worklog"]
  73. case .x_processplatform_assemble_surface_workcompleted:
  74. return dic["x_processplatform_assemble_surface_workcompleted"]
  75. case .x_processplatform_assemble_surface_attachment:
  76. return dic["x_processplatform_assemble_surface_attachment"]
  77. case .x_processplatform_assemble_surface_work:
  78. return dic["x_processplatform_assemble_surface_work"]
  79. case .x_file_assemble_control:
  80. return dic["x_file_assemble_control"]
  81. case .x_meeting_assemble_control:
  82. return dic["x_meeting_assemble_control"]
  83. case .x_attendance_assemble_control:
  84. return dic["x_attendance_assemble_control"]
  85. case .x_okr_assemble_control:
  86. return dic["x_okr_assemble_control"]
  87. case .x_bbs_assemble_control:
  88. return dic["x_bbs_assemble_control"]
  89. case .x_hotpic_assemble_control:
  90. return dic["x_hotpic_assemble_control"]
  91. case .x_processplatform_assemble_surface_applicationdict:
  92. return dic["x_processplatform_assemble_surface_applicationdict"]
  93. case .x_cms_assemble_control:
  94. return dic["x_cms_assemble_control"]
  95. case .x_organization_assemble_control:
  96. return dic["x_organization_assemble_control"]
  97. case .x_collaboration_assemble_websocket:
  98. return dic["x_collaboration_assemble_websocket"]
  99. case .x_organization_assemble_custom:
  100. return dic["x_organization_assemble_custom"]
  101. case .x_processplatform_assemble_surface:
  102. return dic["x_processplatform_assemble_surface"]
  103. case .x_processplatform_assemble_surface_read:
  104. return dic["x_processplatform_assemble_surface_read"]
  105. case .x_processplatform_assemble_surface_readcompleted:
  106. return dic["x_processplatform_assemble_surface_readcompleted"]
  107. case .x_organization_assemble_express:
  108. return dic["x_organization_assemble_express"]
  109. case .x_organization_assemble_personal:
  110. return dic["x_organization_assemble_personal"]
  111. case .x_processplatform_assemble_surface_taskcompleted:
  112. return dic["x_processplatform_assemble_surface_taskcompleted"]
  113. case .x_processplatform_assemble_surface_process:
  114. return dic["x_processplatform_assemble_surface_process"]
  115. case .x_component_assemble_control:
  116. return dic["x_component_assemble_control"]
  117. case .x_processplatform_assemble_surface_application:
  118. return dic["x_processplatform_assemble_surface_application"]
  119. case .x_processplatform_assemble_surface_data:
  120. return dic["x_processplatform_assemble_surface_data"]
  121. case .x_processplatform_assemble_designer:
  122. return dic["x_processplatform_assemble_designer"]
  123. case .x_processplatform_assemble_surface_review:
  124. return dic["x_processplatform_assemble_surface_review"]
  125. case .x_organization_assemble_authentication:
  126. return dic["x_organization_assemble_authentication"]
  127. case .x_portal_assemble_surface:
  128. return dic["x_portal_assemble_surface"]
  129. case .x_calendar_assemble_control:
  130. return dic["x_calendar_assemble_control"]
  131. case .x_jpush_assemble_control:
  132. return dic["x_jpush_assemble_control"]
  133. }
  134. }
  135. /// 移动端配置信息
  136. ///
  137. /// - Returns:
  138. public func customStyle() -> O2CustomStyleModel? {
  139. return O2UserDefaults.shared.customStyle
  140. }
  141. /// 移动端配置hash值
  142. ///
  143. /// - Returns:
  144. public func customStyleHash() -> String? {
  145. return O2UserDefaults.shared.customStyleHash
  146. }
  147. /// 移动端应用列表
  148. ///
  149. /// - Returns:
  150. public func o2AppList() -> [O2AppModel] {
  151. var list: [O2AppModel] = []
  152. if let nativeList = O2UserDefaults.shared.customStyle?.nativeAppList {
  153. for native in nativeList {
  154. let app = O2AppModel()
  155. app.id = native.key
  156. app.name = native.name
  157. app.portalUrl = ""
  158. app.portalCategory = ""
  159. app.type = O2ConfigInfo.O2_APP_TYPE_NATIVE
  160. app.enable = native.enable
  161. list.append(app)
  162. }
  163. }
  164. if let portalList = O2UserDefaults.shared.customStyle?.portalList {
  165. for portal in portalList {
  166. let app = O2AppModel()
  167. app.id = portal.id
  168. app.name = portal.name
  169. if let webserver = O2UserDefaults.shared.centerServer?.webServer {
  170. app.portalUrl = "\(webserver.httpProtocol ?? "http")://\(webserver.host ?? ""):\(webserver.port ?? 80)/\(O2ConfigInfo.O2_DESKTOP_CONTEXT)/appMobile.html?app=portal.Portal&status={\"portalId\":\"\(portal.id ?? "")\"}"
  171. }
  172. app.portalCategory = portal.portalCategory
  173. app.type = O2ConfigInfo.O2_APP_TYPE_PORTAL
  174. app.enable = portal.enable
  175. list.append(app)
  176. }
  177. }
  178. return list
  179. }
  180. //MARK: - public 公开方法
  181. /// 启动
  182. /// 整个过程包括绑定信息检查,客户端信息检查,登录检查
  183. /// - Parameter callback: O2LaunchProcessState
  184. public func launch(callback: @escaping (_ state: O2LaunchProcessState, _ msg: String?)->()) {
  185. _ = checkBindUnit()
  186. // .flatMap { (device) -> Observable<Response> in
  187. // return self.checkBindUnitIsExpired(device: device)
  188. // }
  189. .flatMap { (unit) -> Observable<Response> in
  190. // let o2Res = response.mapObject(BaseO2ResponseData<O2BindUnitModel>.self)
  191. // if o2Res?.isSuccess() == false {
  192. // throw O2AuthError.bindExpireError
  193. // }else {
  194. // guard let unit = o2Res?.data else {
  195. // throw O2AuthError.bindExpireError
  196. // }
  197. // // 每次验证完成后更新unit 信息 , 连接unit的中心服务器
  198. // O2UserDefaults.shared.unit = unit
  199. // return self.connectToCenterServer(unit: unit)
  200. // }
  201. return self.connectToCenterServer(unit: unit)
  202. }.flatMap({ (response) -> Observable<Response> in
  203. let result = response.mapObject(BaseO2ResponseData<O2CenterServerModel>.self)
  204. if let centerServer = result?.data {
  205. let unit = O2UserDefaults.shared.unit
  206. let httpProtocol = unit?.httpProtocol ?? "http"
  207. centerServer.assembles?.forEach({ (key,value) in
  208. value.httpProtocol = httpProtocol
  209. centerServer.assembles![key] = value
  210. })
  211. centerServer.webServer?.httpProtocol = httpProtocol
  212. // 保存中心服务器数据
  213. O2UserDefaults.shared.centerServer = centerServer
  214. return self.checkCustomStyleNeedUpdate(unit: unit!)
  215. }else {
  216. throw O2AuthError.blockError("无法连接中心服务器!")
  217. }
  218. }).flatMap { (response) -> Observable<Bool> in
  219. let o2Res = response.mapObject(BaseO2ResponseData<O2StringValueModel>.self)
  220. let currentHash = O2UserDefaults.shared.customStyleHash ?? ""
  221. if o2Res?.isSuccess() == false {
  222. throw O2AuthError.blockError("检查移动端配置是否需要更新时出错, \(o2Res?.message ?? "")")
  223. }else {
  224. if let newHash = o2Res?.data?.value {
  225. if newHash == currentHash { // 没有更新不需要下载
  226. return self.boolObservableCreate(true)
  227. }else {
  228. //保存这个hash码,并下载
  229. O2UserDefaults.shared.customStyleHash = newHash
  230. return self.downloadCustomStyle()
  231. }
  232. }else {
  233. throw O2AuthError.blockError("检查移动端配置是否需要更新时出错, 没有获取到hash值")
  234. }
  235. }
  236. }.flatMap { (result) -> Observable<Response> in
  237. if result {
  238. if let token = O2UserDefaults.shared.myInfo?.token {
  239. return self.loginWithToken(token)
  240. }else {
  241. guard let mobile = O2UserDefaults.shared.device?.mobile, let code = O2UserDefaults.shared.device?.code else {
  242. throw O2AuthError.noLoginError
  243. }
  244. return self.loginWithPhoneCode(mobile, code)
  245. }
  246. }else {
  247. throw O2AuthError.blockError("下载移动端配置时出错!!!")
  248. }
  249. }.flatMap { (response) -> Observable<Bool> in
  250. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  251. if account?.isSuccess() == true {
  252. if let myInfo = account?.data, myInfo.name != "anonymous" {
  253. O2UserDefaults.shared.myInfo = myInfo
  254. return self.boolObservableCreate(true)
  255. }else {
  256. throw O2AuthError.noLoginError
  257. }
  258. }else {
  259. throw O2AuthError.noLoginError
  260. }
  261. }
  262. .subscribe { (event) in
  263. switch event {
  264. case .next(let element):
  265. if element {
  266. callback(O2LaunchProcessState.success, nil)
  267. }else {
  268. callback(O2LaunchProcessState.loginError, "登录失败!")
  269. }
  270. break
  271. case .error(let error):
  272. if error is O2AuthError {
  273. let aError = error as! O2AuthError
  274. switch aError {
  275. case .noLoginError:
  276. callback(O2LaunchProcessState.loginError, "登录失败!")
  277. break
  278. case .noBindError:
  279. callback(O2LaunchProcessState.bindError, "绑定失败!")
  280. break
  281. case .bindExpireError:
  282. callback(O2LaunchProcessState.bindError, "绑定过期!")
  283. break
  284. case .blockError(let msg):
  285. callback(O2LaunchProcessState.unknownError, msg)
  286. break
  287. }
  288. }else {
  289. callback(O2LaunchProcessState.unknownError, "未知错误,\(String(describing: error))")
  290. }
  291. break
  292. case .completed:
  293. break
  294. }
  295. }
  296. }
  297. /// 内网版本启动入口
  298. ///
  299. /// - Parameters:
  300. /// - unit: 内网服务器信息
  301. /// - callback: O2LaunchProcessState
  302. public func launchInner(unit: O2BindUnitModel, callback: @escaping (_ state: O2LaunchProcessState, _ msg: String?)->()) {
  303. // 保存数据 连接unit的中心服务器
  304. O2UserDefaults.shared.unit = unit
  305. _ = connectToCenterServer(unit: unit).flatMap { (response) -> Observable<Response> in
  306. let result = response.mapObject(BaseO2ResponseData<O2CenterServerModel>.self)
  307. if let centerServer = result?.data {
  308. let httpProtocol = unit.httpProtocol ?? "http"
  309. centerServer.assembles?.forEach({ (key,value) in
  310. value.httpProtocol = httpProtocol
  311. centerServer.assembles![key] = value
  312. })
  313. centerServer.webServer?.httpProtocol = httpProtocol
  314. // 保存中心服务器数据
  315. O2UserDefaults.shared.centerServer = centerServer
  316. return self.checkCustomStyleNeedUpdate(unit: unit)
  317. }else {
  318. throw O2AuthError.blockError("无法连接中心服务器!")
  319. }
  320. }
  321. .flatMap { (response) -> Observable<Bool> in
  322. let o2Res = response.mapObject(BaseO2ResponseData<O2StringValueModel>.self)
  323. let currentHash = O2UserDefaults.shared.customStyleHash ?? ""
  324. if o2Res?.isSuccess() == false {
  325. throw O2AuthError.blockError("检查移动端配置是否需要更新时出错, \(o2Res?.message ?? "")")
  326. }else {
  327. if let newHash = o2Res?.data?.value {
  328. if newHash == currentHash { // 没有更新不需要下载
  329. return self.boolObservableCreate(true)
  330. }else {
  331. //保存这个hash码,并下载
  332. O2UserDefaults.shared.customStyleHash = newHash
  333. return self.downloadCustomStyle()
  334. }
  335. }else {
  336. throw O2AuthError.blockError("检查移动端配置是否需要更新时出错, 没有获取到hash值")
  337. }
  338. }
  339. }.flatMap { (result) -> Observable<Response> in
  340. if result {
  341. if let token = O2UserDefaults.shared.myInfo?.token {
  342. return self.loginWithToken(token)
  343. }else {
  344. guard let mobile = O2UserDefaults.shared.device?.mobile, let code = O2UserDefaults.shared.device?.code else {
  345. throw O2AuthError.noLoginError
  346. }
  347. return self.loginWithPhoneCode(mobile, code)
  348. }
  349. }else {
  350. throw O2AuthError.blockError("下载移动端配置时出错!!!")
  351. }
  352. }.flatMap { (response) -> Observable<Bool> in
  353. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  354. if account?.isSuccess() == true {
  355. if let myInfo = account?.data, myInfo.name != "anonymous" {
  356. O2UserDefaults.shared.myInfo = myInfo
  357. return self.boolObservableCreate(true)
  358. }else {
  359. throw O2AuthError.noLoginError
  360. }
  361. }else {
  362. throw O2AuthError.noLoginError
  363. }
  364. }.subscribe { (event) in
  365. switch event {
  366. case .next(let element):
  367. if element {
  368. callback(O2LaunchProcessState.success, nil)
  369. }else {
  370. callback(O2LaunchProcessState.loginError, "登录失败!")
  371. }
  372. break
  373. case .error(let error):
  374. if error is O2AuthError {
  375. let aError = error as! O2AuthError
  376. switch aError {
  377. case .noLoginError:
  378. callback(O2LaunchProcessState.loginError, "登录失败!")
  379. break
  380. case .blockError(let msg):
  381. callback(O2LaunchProcessState.unknownError, msg)
  382. break
  383. default :
  384. callback(O2LaunchProcessState.unknownError, "")
  385. break
  386. }
  387. }else {
  388. callback(O2LaunchProcessState.unknownError, "未知错误,\(String(describing: error))")
  389. }
  390. break
  391. case .completed:
  392. break
  393. }
  394. }
  395. }
  396. /// 登录 手机号码 验证码
  397. ///
  398. /// - Parameters:
  399. /// - mobile: 手机号码
  400. /// - code: 验证码
  401. /// - callback: 登录结果
  402. public func login(mobile: String, code: String, callback: @escaping (_ result: Bool, _ error: String?) ->() ) {
  403. _ = self.loginWithPhoneCode(mobile, code)
  404. .subscribe(onNext: { (response) in
  405. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  406. if account?.isSuccess() == true {
  407. if let myInfo = account?.data, myInfo.name != "anonymous" {
  408. O2UserDefaults.shared.myInfo = myInfo
  409. callback(true, nil)
  410. }else {
  411. callback(false, "登录失败,用户名是: 找不到该用户信息 ! ")
  412. }
  413. }else {
  414. callback(false, "登录失败,\(account?.message ?? "")")
  415. }
  416. }, onError: { (error) in
  417. callback(false, "登录失败,\(String(describing: error))")
  418. }, onCompleted: {
  419. print("login completed!")
  420. }) {
  421. print("login finish!")
  422. }
  423. }
  424. /// 登录 扫码登录
  425. public func loginWithScanCode(meta: String, callback: @escaping (_ result: Bool, _ error: String?) ->()) {
  426. _ = self.loginAPI.rx.request(.loginWithScanCode(meta)).asObservable().subscribe(onNext: { (response) in
  427. let back = response.mapObject(BaseO2ResponseData<O2NodeResModel>.self)
  428. if back?.isSuccess() == true {
  429. if let v = back?.data, v.value == true {
  430. callback(true, nil)
  431. }else {
  432. callback(false, "登录失败!")
  433. }
  434. }else {
  435. callback(false, "登录失败,\(back?.message ?? "")")
  436. }
  437. }, onError: { (error) in
  438. callback(false, "登录失败,\(String(describing: error))")
  439. }, onCompleted: {
  440. print("loginWithScanCode completed!")
  441. }) {
  442. print("loginWithScanCode finish!")
  443. }
  444. }
  445. public func loginWithPassword(username: String, password: String, callback: @escaping (_ result: Bool, _ error: String?) ->()) {
  446. _ = self.loginWithUsernamePassword(username, password)
  447. .subscribe(onNext: { (response) in
  448. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  449. if account?.isSuccess() == true {
  450. if let myInfo = account?.data, myInfo.name != "anonymous" {
  451. O2UserDefaults.shared.myInfo = myInfo
  452. callback(true, nil)
  453. }else {
  454. callback(false, "登录失败,用户名是: 找不到该用户信息 ! ")
  455. }
  456. }else {
  457. callback(false, "登录失败,\(account?.message ?? "")")
  458. }
  459. }, onError: { (error) in
  460. callback(false, "登录失败,\(String(describing: error))")
  461. }, onCompleted: {
  462. print("login completed!")
  463. }) {
  464. print("login finish!")
  465. }
  466. }
  467. /// 人脸识别登录
  468. ///
  469. /// - Parameters:
  470. /// - userId: 用户uid
  471. /// - callback:
  472. public func faceRecognizeLogin(userId: String, callback: @escaping (_ result: Bool, _ error: String?) ->()) {
  473. _ = self.desEncrypt(userId).flatMap { (token) -> Observable<Response> in
  474. return self.loginWithSSO(token)
  475. }.subscribe(onNext: { (response) in
  476. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  477. if account?.isSuccess() == true {
  478. if let myInfo = account?.data, myInfo.name != "anonymous" {
  479. O2UserDefaults.shared.myInfo = myInfo
  480. callback(true, nil)
  481. }else {
  482. callback(false, "登录失败,找不到该用户信息 ! ")
  483. }
  484. }else {
  485. callback(false, "登录失败,\(account?.message ?? "")")
  486. }
  487. }, onError: { (error) in
  488. callback(false, "登录失败,\(String(describing: error))")
  489. }, onCompleted: nil, onDisposed: nil)
  490. }
  491. /// 登出 清除当前登录的用户信息
  492. ///
  493. /// - Parameter callback:
  494. public func logout(callback: @escaping (_ result: Bool, _ error: String?) ->()) {
  495. _ = Observable<Bool>.create { (observer) -> Disposable in
  496. O2UserDefaults.shared.myInfo = nil
  497. let device = O2UserDefaults.shared.device
  498. device?.code = nil
  499. O2UserDefaults.shared.device = device
  500. observer.onNext(true)
  501. observer.onCompleted()
  502. return Disposables.create()
  503. }.subscribe(onNext: { (result) in
  504. callback(result, nil)
  505. }, onError: { (error) in
  506. callback(false, "\(String(describing: error))")
  507. }, onCompleted: nil, onDisposed: nil)
  508. }
  509. /// 解除绑定前 清空本地数据
  510. ///
  511. /// - Parameter callback: 返回结果
  512. public func clearAllInformationBeforeReBind(callback: @escaping (_ result: Bool, _ error: String?) ->()) {
  513. _ = Observable<Bool>.create { (observer) -> Disposable in
  514. //清除本地关于账号 单位等信息
  515. O2UserDefaults.shared.unit = nil
  516. O2UserDefaults.shared.device = nil
  517. O2UserDefaults.shared.myInfo = nil
  518. O2UserDefaults.shared.customStyle = nil
  519. O2UserDefaults.shared.customStyleHash = nil
  520. O2UserDefaults.shared.centerServer = nil
  521. observer.onNext(true)
  522. observer.onCompleted()
  523. return Disposables.create()
  524. }.subscribe(onNext: { (result) in
  525. callback(result, nil)
  526. }, onError: { (error) in
  527. callback(false, "\(String(describing: error))")
  528. }, onCompleted: nil, onDisposed: nil)
  529. }
  530. /// 登录的时候 发送短信验证码
  531. ///
  532. /// - Parameters:
  533. /// - mobile: 手机号码
  534. /// - callback:
  535. public func sendLoginSMS(mobile: String, callback: @escaping (_ result: Bool, _ error: String?) ->()) {
  536. _ = loginAPI.rx.request(.createLoginCode(mobile)).asObservable()
  537. .subscribe(onNext: { (response) in
  538. let account = response.mapObject(BaseO2ResponseData<O2NodeResModel>.self)
  539. if let result = account?.data?.value, result == true {
  540. callback(true, nil)
  541. }else {
  542. callback(false, "发送短信失败!")
  543. }
  544. }, onError: { (error) in
  545. callback(false, "发送短信失败!\(error)")
  546. }, onCompleted: nil, onDisposed: nil)
  547. }
  548. /// 绑定手机的时候 发送短信验证码
  549. ///
  550. /// - Parameters:
  551. /// - mobile: 手机号码
  552. /// - callback:
  553. public func sendBindSMS(mobile: String, callback: @escaping (_ result: Bool, _ error: String?) ->()) {
  554. let req = O2NodeReqModel()
  555. req.mobile = mobile
  556. _ = registerAPI.rx.request(.generateVerifiyCode(req)).asObservable()
  557. .subscribe(onNext: { (response) in
  558. let account = response.mapObject(BaseO2ResponseData<O2MobileCodeResModel>.self)
  559. if account?.isSuccess() == true {
  560. callback(true, nil)
  561. }else {
  562. callback(false, "发送短信失败!")
  563. }
  564. }, onError: { (error) in
  565. callback(false, "发送短信失败!\(error)")
  566. }, onCompleted: nil, onDisposed: nil)
  567. }
  568. /// 绑定到sample 服务器,苹果上架使用
  569. /// - Parameters:
  570. /// - mobile: 手机号码
  571. public func bindSampleServer(mobile: String, callback: @escaping (_ result: O2BindProcessState, _ error: String?) ->()) {
  572. //填入sample的服务器信息
  573. let _ = Observable<O2BindUnitModel>.create { (observer) -> Disposable in
  574. let unit: O2BindUnitModel = O2BindUnitModel()
  575. unit.id = "61a4d035-81ee-44a6-af3b-ab3d374ee24d"
  576. unit.name = "演示站点"
  577. unit.pinyin = "yanshizhandian"
  578. unit.pinyinInitial = "yszd"
  579. unit.centerHost = "sample.o2oa.net"
  580. unit.centerPort = 40030
  581. unit.centerContext = "/x_program_center"
  582. unit.httpProtocol = "https"
  583. O2UserDefaults.shared.unit = unit
  584. observer.onNext(unit)
  585. observer.onCompleted()
  586. return Disposables.create()
  587. }.flatMap { (unit) -> Observable<Response> in
  588. let bindDevice: O2BindDeviceModel = O2BindDeviceModel()
  589. bindDevice.unit = unit.name
  590. bindDevice.name = O2UserDefaults.shared.deviceToken
  591. bindDevice.mobile = mobile
  592. bindDevice.code = ""
  593. bindDevice.deviceType = "ios"
  594. O2UserDefaults.shared.device = bindDevice
  595. return self.connectToCenterServer(unit: unit)
  596. }.flatMap({ (response) -> Observable<Response> in
  597. let result = response.mapObject(BaseO2ResponseData<O2CenterServerModel>.self)
  598. if let centerServer = result?.data {
  599. let unit = O2UserDefaults.shared.unit
  600. let httpProtocol = unit?.httpProtocol ?? "http"
  601. centerServer.assembles?.forEach({ (key,value) in
  602. value.httpProtocol = httpProtocol
  603. centerServer.assembles![key] = value
  604. })
  605. centerServer.webServer?.httpProtocol = httpProtocol
  606. // 保存中心服务器数据
  607. O2UserDefaults.shared.centerServer = centerServer
  608. return self.checkCustomStyleNeedUpdate(unit: unit!)
  609. }else {
  610. O2UserDefaults.shared.unit = nil
  611. O2UserDefaults.shared.device = nil
  612. throw O2BindDiscontinue.unknownError("无法连接中心服务器!")
  613. }
  614. }).flatMap { (response) -> Observable<Bool> in
  615. let o2Res = response.mapObject(BaseO2ResponseData<O2StringValueModel>.self)
  616. let currentHash = O2UserDefaults.shared.customStyleHash ?? ""
  617. if o2Res?.isSuccess() == false {
  618. throw O2BindDiscontinue.noLoginError("检查移动端配置是否需要更新时出错, \(o2Res?.message ?? "")")
  619. }else {
  620. if let newHash = o2Res?.data?.value {
  621. if newHash == currentHash { // 没有更新不需要下载
  622. return self.boolObservableCreate(true)
  623. }else {
  624. //保存这个hash码,并下载
  625. O2UserDefaults.shared.customStyleHash = newHash
  626. return self.downloadCustomStyle()
  627. }
  628. }else {
  629. throw O2BindDiscontinue.noLoginError("检查移动端配置是否需要更新时出错, 没有获取到hash值")
  630. }
  631. }
  632. }.flatMap { (result) -> Observable<Response> in
  633. if result {
  634. //sample的默认密码
  635. guard let mobile = O2UserDefaults.shared.device?.mobile else {
  636. throw O2BindDiscontinue.noLoginError("登录失败!")
  637. }
  638. return self.loginWithUsernamePassword(mobile, "o2")
  639. // if let token = O2UserDefaults.shared.myInfo?.token {
  640. // return self.loginWithToken(token)
  641. // }else {
  642. // guard let mobile = O2UserDefaults.shared.device?.mobile, let code = O2UserDefaults.shared.device?.code else {
  643. // throw O2BindDiscontinue.noLoginError("登录失败!")
  644. // }
  645. // return self.loginWithPhoneCode(mobile, code)
  646. // }
  647. }else {
  648. throw O2BindDiscontinue.noLoginError("下载移动端配置时出错!!!")
  649. }
  650. }.flatMap { (response) -> Observable<Bool> in
  651. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  652. if account?.isSuccess() == true {
  653. if let myInfo = account?.data, myInfo.name != "anonymous" {
  654. O2UserDefaults.shared.myInfo = myInfo
  655. return self.boolObservableCreate(true)
  656. }else {
  657. throw O2BindDiscontinue.noLoginError("登录失败!")
  658. }
  659. }else {
  660. throw O2BindDiscontinue.noLoginError("登录失败!")
  661. }
  662. }.subscribe(onNext: { (result) in
  663. if result {
  664. callback(O2BindProcessState.success, nil)
  665. }else {
  666. callback(O2BindProcessState.goToLogin, "登录失败!")
  667. }
  668. }, onError: { (error) in
  669. if error is O2BindDiscontinue {
  670. let bError = error as! O2BindDiscontinue
  671. switch bError {
  672. case O2BindDiscontinue.tooManyUnit(let list):
  673. callback(O2BindProcessState.goToChooseBindServer(list), nil)
  674. break
  675. case O2BindDiscontinue.noLoginError(let msg):
  676. callback(O2BindProcessState.goToLogin, msg)
  677. break
  678. case O2BindDiscontinue.noUnitCanBindError:
  679. callback(O2BindProcessState.noUnitCanBindError, nil)
  680. break
  681. case O2BindDiscontinue.unknownError(let msg):
  682. callback(O2BindProcessState.unknownError, msg)
  683. break
  684. }
  685. }else {
  686. callback(O2BindProcessState.unknownError, "\(error)")
  687. }
  688. }, onCompleted: nil, onDisposed: nil)
  689. }
  690. /// 绑定手机号码到服务器, 并且完成全部的登录过程。
  691. /// 第一步绑定的时候用的,如果单位列表大于1个就抛异常, 外面接收到这个特殊异常就走第二步选择单位
  692. ///
  693. /// - Parameters:
  694. /// - mobile: 手机号码
  695. /// - code: 验证码
  696. /// - callback:
  697. public func bindMobileToSever(mobile: String, code: String, callback: @escaping (_ result: O2BindProcessState, _ error: String?) ->()) {
  698. let bindDevice: O2BindDeviceModel = O2BindDeviceModel()
  699. let req = O2NodeReqModel()
  700. req.mobile = mobile
  701. req.value = code
  702. _ = registerAPI.rx.request(.verifiyCode(req)).asObservable()
  703. .flatMap { (response) -> Observable<Response> in
  704. let listResult = response.mapObject(BaseO2ResponseData<[O2BindUnitModel]>.self)
  705. if let list = listResult?.data, list.count > 0 {
  706. if list.count > 1 {
  707. throw O2BindDiscontinue.tooManyUnit(list)
  708. }else {
  709. // 保存单位信息
  710. O2UserDefaults.shared.unit = list[0]
  711. bindDevice.unit = list[0].name
  712. bindDevice.name = O2UserDefaults.shared.deviceToken
  713. bindDevice.mobile = mobile
  714. bindDevice.code = code
  715. return self.bindToCollect(device: bindDevice)
  716. }
  717. }else {
  718. throw O2BindDiscontinue.noUnitCanBindError
  719. }
  720. }
  721. .flatMap { (response) -> Observable<Response> in
  722. let idData = response.mapObject(BaseO2ResponseData<O2IdDataModel>.self)
  723. if idData?.isSuccess() == true {
  724. // 保存device
  725. O2UserDefaults.shared.device = bindDevice
  726. let unit = O2UserDefaults.shared.unit
  727. return self.connectToCenterServer(unit: unit!)
  728. }else {
  729. O2UserDefaults.shared.unit = nil
  730. throw O2BindDiscontinue.unknownError("绑定失败!")
  731. }
  732. }.flatMap({ (response) -> Observable<Response> in
  733. let result = response.mapObject(BaseO2ResponseData<O2CenterServerModel>.self)
  734. if let centerServer = result?.data {
  735. let unit = O2UserDefaults.shared.unit
  736. let httpProtocol = unit?.httpProtocol ?? "http"
  737. centerServer.assembles?.forEach({ (key,value) in
  738. value.httpProtocol = httpProtocol
  739. centerServer.assembles![key] = value
  740. })
  741. centerServer.webServer?.httpProtocol = httpProtocol
  742. // 保存中心服务器数据
  743. O2UserDefaults.shared.centerServer = centerServer
  744. return self.checkCustomStyleNeedUpdate(unit: unit!)
  745. }else {
  746. O2UserDefaults.shared.unit = nil
  747. O2UserDefaults.shared.device = nil
  748. throw O2BindDiscontinue.unknownError("无法连接中心服务器!")
  749. }
  750. }).flatMap { (response) -> Observable<Bool> in
  751. let o2Res = response.mapObject(BaseO2ResponseData<O2StringValueModel>.self)
  752. let currentHash = O2UserDefaults.shared.customStyleHash ?? ""
  753. if o2Res?.isSuccess() == false {
  754. throw O2BindDiscontinue.noLoginError("检查移动端配置是否需要更新时出错, \(o2Res?.message ?? "")")
  755. }else {
  756. if let newHash = o2Res?.data?.value {
  757. if newHash == currentHash { // 没有更新不需要下载
  758. return self.boolObservableCreate(true)
  759. }else {
  760. //保存这个hash码,并下载
  761. O2UserDefaults.shared.customStyleHash = newHash
  762. return self.downloadCustomStyle()
  763. }
  764. }else {
  765. throw O2BindDiscontinue.noLoginError("检查移动端配置是否需要更新时出错, 没有获取到hash值")
  766. }
  767. }
  768. }.flatMap { (result) -> Observable<Response> in
  769. if result {
  770. if let token = O2UserDefaults.shared.myInfo?.token {
  771. return self.loginWithToken(token)
  772. }else {
  773. guard let mobile = O2UserDefaults.shared.device?.mobile, let code = O2UserDefaults.shared.device?.code else {
  774. throw O2BindDiscontinue.noLoginError("登录失败!")
  775. }
  776. return self.loginWithPhoneCode(mobile, code)
  777. }
  778. }else {
  779. throw O2BindDiscontinue.noLoginError("下载移动端配置时出错!!!")
  780. }
  781. }.flatMap { (response) -> Observable<Bool> in
  782. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  783. if account?.isSuccess() == true {
  784. if let myInfo = account?.data, myInfo.name != "anonymous" {
  785. O2UserDefaults.shared.myInfo = myInfo
  786. return self.boolObservableCreate(true)
  787. }else {
  788. throw O2BindDiscontinue.noLoginError("登录失败!")
  789. }
  790. }else {
  791. throw O2BindDiscontinue.noLoginError("登录失败!")
  792. }
  793. }.subscribe(onNext: { (result) in
  794. if result {
  795. callback(O2BindProcessState.success, nil)
  796. }else {
  797. callback(O2BindProcessState.goToLogin, "登录失败!")
  798. }
  799. }, onError: { (error) in
  800. if error is O2BindDiscontinue {
  801. let bError = error as! O2BindDiscontinue
  802. switch bError {
  803. case O2BindDiscontinue.tooManyUnit(let list):
  804. callback(O2BindProcessState.goToChooseBindServer(list), nil)
  805. break
  806. case O2BindDiscontinue.noLoginError(let msg):
  807. callback(O2BindProcessState.goToLogin, msg)
  808. break
  809. case O2BindDiscontinue.noUnitCanBindError:
  810. callback(O2BindProcessState.noUnitCanBindError, nil)
  811. break
  812. case O2BindDiscontinue.unknownError(let msg):
  813. callback(O2BindProcessState.unknownError, msg)
  814. break
  815. }
  816. }else {
  817. callback(O2BindProcessState.unknownError, "\(error)")
  818. }
  819. }, onCompleted: nil, onDisposed: nil)
  820. }
  821. /// 绑定手机到服务器,并完成全部的登录过程
  822. ///
  823. /// - Parameters:
  824. /// - unit: 绑定的单位服务器对象
  825. /// - mobile: 手机号码
  826. /// - code: 验证码
  827. /// - callback:
  828. public func bindMobileToServer(unit: O2BindUnitModel, mobile: String, code: String, callback: @escaping (_ result: O2BindProcessState, _ error: String?) ->()) {
  829. // 保存单位信息
  830. O2UserDefaults.shared.unit = unit
  831. let bindDevice: O2BindDeviceModel = O2BindDeviceModel()
  832. bindDevice.unit = unit.name
  833. bindDevice.name = O2UserDefaults.shared.deviceToken
  834. bindDevice.mobile = mobile
  835. bindDevice.code = code
  836. bindDevice.deviceType = "ios"
  837. _ = self.bindToCollect(device: bindDevice)
  838. .flatMap { (response) -> Observable<Response> in
  839. let idData = response.mapObject(BaseO2ResponseData<O2IdDataModel>.self)
  840. if idData?.isSuccess() == true {
  841. // 保存device
  842. O2UserDefaults.shared.device = bindDevice
  843. let unit = O2UserDefaults.shared.unit
  844. return self.connectToCenterServer(unit: unit!)
  845. }else {
  846. O2UserDefaults.shared.unit = nil
  847. throw O2BindDiscontinue.unknownError("绑定失败!")
  848. }
  849. }.flatMap({ (response) -> Observable<Response> in
  850. let result = response.mapObject(BaseO2ResponseData<O2CenterServerModel>.self)
  851. if let centerServer = result?.data {
  852. let unit = O2UserDefaults.shared.unit
  853. let httpProtocol = unit?.httpProtocol ?? "http"
  854. centerServer.assembles?.forEach({ (key,value) in
  855. value.httpProtocol = httpProtocol
  856. centerServer.assembles![key] = value
  857. })
  858. centerServer.webServer?.httpProtocol = httpProtocol
  859. // 保存中心服务器数据
  860. O2UserDefaults.shared.centerServer = centerServer
  861. return self.checkCustomStyleNeedUpdate(unit: unit!)
  862. }else {
  863. O2UserDefaults.shared.unit = nil
  864. O2UserDefaults.shared.device = nil
  865. throw O2BindDiscontinue.unknownError("无法连接中心服务器!")
  866. }
  867. }).flatMap { (response) -> Observable<Bool> in
  868. let o2Res = response.mapObject(BaseO2ResponseData<O2StringValueModel>.self)
  869. let currentHash = O2UserDefaults.shared.customStyleHash ?? ""
  870. if o2Res?.isSuccess() == false {
  871. throw O2BindDiscontinue.noLoginError("检查移动端配置是否需要更新时出错, \(o2Res?.message ?? "")")
  872. }else {
  873. if let newHash = o2Res?.data?.value {
  874. if newHash == currentHash { // 没有更新不需要下载
  875. return self.boolObservableCreate(true)
  876. }else {
  877. //保存这个hash码,并下载
  878. O2UserDefaults.shared.customStyleHash = newHash
  879. return self.downloadCustomStyle()
  880. }
  881. }else {
  882. throw O2BindDiscontinue.noLoginError("检查移动端配置是否需要更新时出错, 没有获取到hash值")
  883. }
  884. }
  885. }.flatMap { (result) -> Observable<Response> in
  886. if result {
  887. if let token = O2UserDefaults.shared.myInfo?.token {
  888. return self.loginWithToken(token)
  889. }else {
  890. guard let mobile = O2UserDefaults.shared.device?.mobile, let code = O2UserDefaults.shared.device?.code else {
  891. throw O2BindDiscontinue.noLoginError("登录失败!")
  892. }
  893. return self.loginWithPhoneCode(mobile, code)
  894. }
  895. }else {
  896. throw O2BindDiscontinue.noLoginError("下载移动端配置时出错!!!")
  897. }
  898. }.flatMap { (response) -> Observable<Bool> in
  899. let account = response.mapObject(BaseO2ResponseData<O2LoginAccountModel>.self)
  900. if account?.isSuccess() == true {
  901. if let myInfo = account?.data, myInfo.name != "anonymous" {
  902. O2UserDefaults.shared.myInfo = myInfo
  903. return self.boolObservableCreate(true)
  904. }else {
  905. throw O2BindDiscontinue.noLoginError("登录失败!")
  906. }
  907. }else {
  908. throw O2BindDiscontinue.noLoginError("登录失败!")
  909. }
  910. }.subscribe(onNext: { (result) in
  911. if result {
  912. callback(O2BindProcessState.success, nil)
  913. }else {
  914. callback(O2BindProcessState.goToLogin, "登录失败!")
  915. }
  916. }, onError: { (error) in
  917. if error is O2BindDiscontinue {
  918. let bError = error as! O2BindDiscontinue
  919. switch bError {
  920. case O2BindDiscontinue.tooManyUnit(let list):
  921. callback(O2BindProcessState.goToChooseBindServer(list), nil)
  922. break
  923. case O2BindDiscontinue.noLoginError(let msg):
  924. callback(O2BindProcessState.goToLogin, msg)
  925. break
  926. case O2BindDiscontinue.noUnitCanBindError:
  927. callback(O2BindProcessState.noUnitCanBindError, nil)
  928. break
  929. case O2BindDiscontinue.unknownError(let msg):
  930. callback(O2BindProcessState.unknownError, msg)
  931. break
  932. }
  933. }else {
  934. callback(O2BindProcessState.unknownError, "\(error)")
  935. }
  936. }, onCompleted: nil, onDisposed: nil)
  937. }
  938. /// 绑定的设备列表
  939. ///
  940. /// - Parameters:
  941. /// - unitId: 绑定的单位id
  942. /// - mobile: 手机号码
  943. /// - token: 设备号 O2BindDeviceModel.name
  944. /// - callback:
  945. public func bindDeviceList(unitId: String, mobile: String, token: String, callback: @escaping (_ list: [O2BindDeviceModel], _ error: String?)->Void) {
  946. _ = registerAPI.rx.request(.deviceList(unitId, mobile, token)).asObservable()
  947. .subscribe(onNext: { (response) in
  948. let result = response.mapObject(BaseO2ResponseData<[O2BindDeviceModel]>.self)
  949. if result?.isSuccess() == true {
  950. callback(result?.data ?? [], nil)
  951. }else {
  952. let message = "查询设备失败,\(result?.message ?? "")"
  953. callback([], message)
  954. }
  955. }, onError: { (error) in
  956. let message = "查询设备异常,\(error.localizedDescription)"
  957. callback([], message)
  958. }, onCompleted: nil, onDisposed: nil)
  959. }
  960. /// 解除设备绑定
  961. ///
  962. /// - Parameters:
  963. /// - device: 设备对象 主要是name 就是设备号
  964. /// - callback:
  965. public func unBindFromCollect(deviceId: String, callback: @escaping (_ result:Bool, _ error:String?)->Void) {
  966. let device: O2BindDeviceModel = O2BindDeviceModel()
  967. device.name = deviceId
  968. _ = registerAPI.rx.request(.unBindFromDevice(device)).asObservable()
  969. .subscribe(onNext: { (response) in
  970. let result = response.mapObject(BaseO2ResponseData<O2IdDataModel>.self)
  971. if result?.isSuccess() == true {
  972. callback(true, nil)
  973. }else {
  974. let message = "解除绑定失败,\(result?.message ?? "")"
  975. callback(false, message)
  976. }
  977. }, onError: { (error) in
  978. let message = "解除绑定异常,\(error.localizedDescription)"
  979. callback(false, message)
  980. }, onCompleted: nil, onDisposed: nil)
  981. }
  982. //MARK: - private
  983. private func boolObservableCreate(_ result: Bool) -> Observable<Bool> {
  984. return Observable<Bool>.create({ (observer) -> Disposable in
  985. observer.on(.next(result))
  986. observer.on(.completed)
  987. return Disposables.create()
  988. })
  989. }
  990. /// 检查是否绑定过
  991. ///
  992. /// - Returns:
  993. private func checkBindUnit() -> Observable<O2BindUnitModel> {
  994. // return Observable<O2BindDeviceModel>.create({ (any) -> Disposable in
  995. // if let device = O2UserDefaults.shared.device {
  996. // any.onNext(device)
  997. // any.onCompleted()
  998. // }else {
  999. // any.onError(O2AuthError.noBindError)
  1000. // }
  1001. // return Disposables.create()
  1002. // })
  1003. return Observable<O2BindUnitModel>.create ({ (any) -> Disposable in
  1004. if let unit = O2UserDefaults.shared.unit {
  1005. any.onNext(unit)
  1006. any.onCompleted()
  1007. } else {
  1008. any.onError(O2AuthError.noBindError)
  1009. }
  1010. return Disposables.create()
  1011. })
  1012. }
  1013. /// 检查当前绑定信息是否过期
  1014. ///
  1015. /// - Parameter device: 手机号码等设备信息
  1016. /// - Returns:
  1017. private func checkBindUnitIsExpired(device: O2BindDeviceModel) -> Observable<Response> {
  1018. return registerAPI.rx.request(.queryBindInfo(device)).asObservable()
  1019. }
  1020. /// 连接到O2OA中心服务器
  1021. ///
  1022. /// - Parameter unit: 单位服务器信息
  1023. /// - Returns:
  1024. private func connectToCenterServer(unit: O2BindUnitModel) -> Observable<Response> {
  1025. return registerAPI.rx.request(.downloadNodeAPI(unit)).asObservable()
  1026. }
  1027. /// 检查移动端配置信息是否有更新
  1028. ///
  1029. /// - Parameter unit: 当前绑定的党委
  1030. /// - Returns:
  1031. private func checkCustomStyleNeedUpdate(unit: O2BindUnitModel) -> Observable<Response> {
  1032. return registerAPI.rx.request(.verConfigInfo(unit)).asObservable()
  1033. }
  1034. /// 下载移动端配置信息
  1035. ///
  1036. /// - Returns:
  1037. private func downloadCustomStyle() -> Observable<Bool> {
  1038. if let unit = O2UserDefaults.shared.unit {
  1039. return registerAPI.rx.request(.downloadConfigInfo(unit))
  1040. .asObservable()
  1041. .flatMap { (response) -> Observable<Bool> in
  1042. let result = response.mapObject(BaseO2ResponseData<O2CustomStyleModel>.self)
  1043. if result?.isSuccess() == true {
  1044. //保存移动端配置信息
  1045. O2UserDefaults.shared.customStyle = result?.data
  1046. return self.boolObservableCreate(true)
  1047. }else {
  1048. throw O2AuthError.blockError("下载移动端配置时出错, \(result?.message ?? "")")
  1049. }
  1050. }
  1051. }else {
  1052. return self.boolObservableCreate(false)
  1053. }
  1054. }
  1055. /// token登录
  1056. ///
  1057. /// - Parameter token: 用户登录的token
  1058. /// - Returns:
  1059. private func loginWithToken(_ token: String) -> Observable<Response> {
  1060. return loginAPI.rx.request(.loginWithToken(token)).asObservable()
  1061. }
  1062. /// 手机验证码登录
  1063. ///
  1064. /// - Parameters:
  1065. /// - mobile: 手机号码
  1066. /// - code: 验证码
  1067. /// - Returns:
  1068. private func loginWithPhoneCode(_ mobile: String, _ code: String) -> Observable<Response> {
  1069. return loginAPI.rx.request(.loginWithCredntial(mobile, code)).asObservable()
  1070. }
  1071. /// 用户名密码登录
  1072. ///
  1073. /// - Parameters:
  1074. /// - username: 用户名
  1075. /// - password: 密码
  1076. /// - Returns:
  1077. private func loginWithUsernamePassword(_ username: String, _ password: String) -> Observable<Response> {
  1078. return loginAPI.rx.request(.loginWithPassword(username, password)).asObservable()
  1079. }
  1080. /// sso 登录
  1081. ///
  1082. /// - Parameter token: 加密后的token
  1083. /// - Returns:
  1084. private func loginWithSSO(_ token: String) -> Observable<Response> {
  1085. return loginAPI.rx.request(.loginWithSSO(O2ConfigInfo.O2_OA_SSO_CLIENT, token)).asObservable()
  1086. }
  1087. /// 绑定到wcollect服务器
  1088. ///
  1089. /// - Parameters:
  1090. /// - device: 设备对象
  1091. /// - Returns:
  1092. private func bindToCollect(device: O2BindDeviceModel) -> Observable<Response> {
  1093. return registerAPI.rx.request(.bindMobileToDevice(device)).asObservable()
  1094. }
  1095. /// des 加密
  1096. ///
  1097. /// - Parameter uid:
  1098. /// - Returns:
  1099. private func desEncrypt(_ uid: String) -> Observable<String> {
  1100. return Observable<String>.create({ (observer) -> Disposable in
  1101. do {
  1102. let en = SymmetricCryptor(algorithm: .des, options: (kCCOptionECBMode + kCCOptionPKCS7Padding))
  1103. en.setRandomIV()
  1104. let timeInterval = Date().timeIntervalSince1970
  1105. let time = CLongLong(round(timeInterval*1000))
  1106. let code = "\(uid)#\(time)"
  1107. print("code: \(code)")
  1108. let encrypt = try en.crypt(string: code, key: O2ConfigInfo.O2_OA_DES_KEY)
  1109. let base64 = encrypt.base64EncodedString()
  1110. print("加密后的字符串:\(base64)")
  1111. let decrypt = try en.decrypt(encrypt, key: O2ConfigInfo.O2_OA_DES_KEY)
  1112. let deString = String(data: decrypt, encoding: String.Encoding.utf8)
  1113. print("解密后的字符串:\(deString ?? "")")
  1114. let first = base64.replacingOccurrences(of: "+", with: "-")
  1115. let second = first.replacingOccurrences(of: "/", with: "_")
  1116. let token = second.replacingOccurrences(of: "=", with: "")
  1117. print("安全替换后的字符串:\(token)")
  1118. observer.onNext(token)
  1119. }catch {
  1120. print("加密异常,\(error)")
  1121. observer.onError(error)
  1122. }
  1123. observer.onCompleted()
  1124. return Disposables.create()
  1125. })
  1126. }
  1127. }