DatabaseHelper.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. //
  2. // DatabaseHelper.swift
  3. // MTP2_iOS
  4. //
  5. // Created by zhongyuan on 2018/6/9.
  6. // Copyright © 2018年 zhongyuan.All rights reserved.
  7. //
  8. import UIKit
  9. import CoreData
  10. enum DataBaseError: Error {
  11. case NoFindUser
  12. case NoFindSelfGoods
  13. }
  14. /// Database Helper
  15. class DatabaseHelper {
  16. static let appDelegate = UIApplication.shared.delegate as! AppDelegate
  17. // MARK: - 生命周期相关
  18. static func firstOpenInitialData() {
  19. // 判断是否第一次运行
  20. if !UserDefaultsUtils.isFirstOpen() { return }
  21. // 初始化可能与登录相关的错误码
  22. var errorCodeInfos = [MoErrorCodeInfo]()
  23. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1003", errorMsg: "账号或密码不匹配"))
  24. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1004", errorMsg: "无效账号"))
  25. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1005", errorMsg: "账号类型不匹配"))
  26. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1006", errorMsg: "账号不在线"))
  27. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1007", errorMsg: "操作权限不够"))
  28. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1008", errorMsg: "会员无账户在线"))
  29. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1009", errorMsg: "账户在别处登录"))
  30. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1010", errorMsg: "值为空"))
  31. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1011", errorMsg: "登录账户已经存在"))
  32. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1012", errorMsg: "软件版本过低不能登录"))
  33. errorCodeInfos.append(MoErrorCodeInfo(errorCode: "1013", errorMsg: "IP地址不在允许范围内"))
  34. try? updateErrorCodeInfos(errorCodeInfos: errorCodeInfos)
  35. }
  36. // MARK: - 账户相关
  37. /// 获取指定用户id的本地用户信息对象
  38. ///
  39. /// - Parameter userID: 用户id
  40. /// - Returns: 用户信息对象
  41. static func getUser(userID: UInt32) throws -> UserEntity? {
  42. let fetchRequest: NSFetchRequest<UserEntity> = UserEntity.fetchRequest()
  43. fetchRequest.predicate = NSPredicate(format: "userID == %ld", userID)
  44. let result = try appDelegate.mainManagedObjectContext.fetch(fetchRequest)
  45. return result.count != 0 ? result[0] : nil
  46. }
  47. static func getUser(userID: UInt32, type: Int16) throws -> UserEntity? {
  48. let fetchRequest: NSFetchRequest<UserEntity> = UserEntity.fetchRequest()
  49. fetchRequest.predicate = NSPredicate(format: "userID == %ld and type == %ld", userID,type)
  50. let result = try appDelegate.mainManagedObjectContext.fetch(fetchRequest)
  51. return result.count != 0 ? result[0] : nil
  52. }
  53. /// 获取所有保存的用户信息
  54. ///
  55. /// - Parameter type: 类型,0为实盘(默认值);1为模拟盘
  56. /// - Returns: 用户信息数组
  57. /// - Throws: 数据库操作错误
  58. static func getUsers(type: Int16 = 0) throws -> [UserEntity]? {
  59. let fetchRequest: NSFetchRequest<UserEntity> = UserEntity.fetchRequest()
  60. fetchRequest.predicate = NSPredicate(format: "type == %ld", type)
  61. fetchRequest.sortDescriptors = [NSSortDescriptor(key: "loginDate", ascending: false)]
  62. let result = try appDelegate.mainManagedObjectContext.fetch(fetchRequest)
  63. return result.count != 0 ? result : nil
  64. }
  65. /// - Parameters:
  66. /// - userID: 用户id
  67. /// - loginID: 登录id
  68. /// - type: 类型,0为实盘(默认值);1为模拟盘
  69. /// - Throws: 数据库操作错误
  70. static func addUser(userID: UInt32, loginID: String, loginDate: Date, type: Int16 = 0) throws {
  71. if let userEntity = try getUser(userID: userID, type: type) {
  72. userEntity.loginDate = loginDate
  73. } else {
  74. guard let userEntity = NSEntityDescription.insertNewObject(forEntityName: "UserEntity", into: appDelegate.backGroundObjectContext) as? UserEntity else { return }
  75. userEntity.userID = Int64(Int32(userID))
  76. userEntity.loginID = loginID
  77. userEntity.loginDate = loginDate
  78. userEntity.type = type
  79. }
  80. appDelegate.backGroundObjectContext.perform {
  81. if appDelegate.backGroundObjectContext.hasChanges {
  82. try? appDelegate.backGroundObjectContext.save()
  83. }
  84. }
  85. }
  86. static func deleteUser(userID: UInt32) throws {
  87. do {
  88. if let userEntity = try getUser(userID: userID) {
  89. appDelegate.backGroundObjectContext.perform {
  90. appDelegate.backGroundObjectContext.delete(appDelegate.backGroundObjectContext.object(with: userEntity.objectID))
  91. if appDelegate.backGroundObjectContext.hasChanges {
  92. try? appDelegate.backGroundObjectContext.save()
  93. }
  94. }
  95. }
  96. } catch {
  97. throw DataBaseError.NoFindUser
  98. }
  99. }
  100. // MARK: - 错误码相关
  101. static func updateErrorCodeInfos(errorCodeInfos: [MoErrorCodeInfo]) throws {
  102. func deleteAllErrorCodeInfos() throws {
  103. let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ErrorEntity")
  104. let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
  105. try appDelegate.backGroundObjectContext.execute(batchDeleteRequest)
  106. }
  107. if errorCodeInfos.count <= 0 { return }
  108. // 批量删除原有数据
  109. try deleteAllErrorCodeInfos()
  110. appDelegate.backGroundObjectContext.perform {
  111. for moErrorCodeInfo in errorCodeInfos {
  112. // FIXME: 可能会报 EXC_BAD_ACCESS
  113. guard let errorEntity = NSEntityDescription.insertNewObject(forEntityName: "ErrorEntity", into: appDelegate.backGroundObjectContext) as? ErrorEntity else { return }
  114. errorEntity.constkey = moErrorCodeInfo.errorCode
  115. errorEntity.remarks = moErrorCodeInfo.errorMsg
  116. }
  117. if appDelegate.backGroundObjectContext.hasChanges {
  118. try? appDelegate.backGroundObjectContext.save()
  119. }
  120. }
  121. }
  122. static func getError(errorCode: String) throws -> ErrorEntity? {
  123. let fetchRequest: NSFetchRequest<ErrorEntity> = ErrorEntity.fetchRequest()
  124. fetchRequest.predicate = NSPredicate(format: "constkey == %@", errorCode)
  125. let result = try appDelegate.mainManagedObjectContext.fetch(fetchRequest)
  126. return result.count != 0 ? result[0] : nil
  127. }
  128. // MARK: - 自选商品相关
  129. static func getSelfQuotes(userID: UInt32) throws -> [SelfEntity] {
  130. if let userEntity = try getUser(userID: userID) {
  131. if let selfGoods = userEntity.selfGoods?.allObjects as? [SelfEntity] {
  132. return selfGoods
  133. }
  134. }
  135. return []
  136. }
  137. static func addSelfGoods(userID: UInt32, goodsID: Int64, marketID: Int64) throws {
  138. if let userEntity = try getUser(userID: userID) {
  139. guard let selfEntity = NSEntityDescription.insertNewObject(forEntityName: "SelfEntity", into: appDelegate.backGroundObjectContext) as? SelfEntity else { return }
  140. appDelegate.backGroundObjectContext.perform {
  141. selfEntity.goodsID = goodsID
  142. selfEntity.marketID = marketID
  143. selfEntity.createTime = NSDate()
  144. let userEntity: UserEntity = appDelegate.backGroundObjectContext.object(with: userEntity.objectID) as! UserEntity
  145. userEntity.addToSelfGoods(selfEntity)
  146. if appDelegate.backGroundObjectContext.hasChanges {
  147. do {
  148. try appDelegate.backGroundObjectContext.save()
  149. } catch {
  150. dPrint(error.localizedDescription)
  151. }
  152. }
  153. }
  154. } else {
  155. throw DataBaseError.NoFindUser
  156. }
  157. }
  158. static func removeSelfGoods(userID: UInt32, goodsID: Int64) throws {
  159. if let userEntity = try getUser(userID: userID) {
  160. if case let selfEntity as SelfEntity = userEntity.selfGoods?.first(where: { ($0 as! SelfEntity).goodsID == goodsID }) {
  161. appDelegate.backGroundObjectContext.perform {
  162. userEntity.removeFromSelfGoods(selfEntity)
  163. appDelegate.backGroundObjectContext.delete(appDelegate.backGroundObjectContext.object(with: selfEntity.objectID)) // 这一句记得要调用
  164. if appDelegate.backGroundObjectContext.hasChanges {
  165. try? appDelegate.backGroundObjectContext.save()
  166. }
  167. }
  168. } else {
  169. throw DataBaseError.NoFindSelfGoods
  170. }
  171. } else {
  172. throw DataBaseError.NoFindUser
  173. }
  174. }
  175. //MARK: - 商品相关
  176. static func insertGoodsInfos(_ goodsInfos: [MoGoodsInfo]) throws {
  177. /// 先移出商品
  178. do {
  179. for goods in goodsInfos {
  180. let exist = try? self.getGoodsInfo(ById: goods.goodsid)
  181. if exist ?? false { self.removeGoodsInfo(goods.goodsid) }
  182. }
  183. }
  184. appDelegate.backGroundObjectContext.performAndWait {
  185. do {
  186. dPrint("1.当前时间:\(Date().getString())")
  187. for goodsInfo in goodsInfos {
  188. guard let goodsInfoEntity = NSEntityDescription.insertNewObject(forEntityName: "GoodsInfoEntity", into: appDelegate.backGroundObjectContext) as? GoodsInfoEntity else { continue
  189. }
  190. goodsInfoEntity.setupWith(goodsInfo: goodsInfo)
  191. }
  192. dPrint("2.当前时间:\(Date().getString())")
  193. if appDelegate.backGroundObjectContext.hasChanges {
  194. dPrint("3.当前时间:\(Date().getString())")
  195. try appDelegate.backGroundObjectContext.save()
  196. dPrint("4.当前时间:\(Date().getString())")
  197. } else {
  198. dPrint("商品本地化失败")
  199. }
  200. } catch {
  201. fatalError("商品数据插入失败")
  202. }
  203. }
  204. }
  205. /// 判断指定商品信息是否存在
  206. ///
  207. /// - Parameter Id: 商品ID
  208. /// - Returns: yes: 存在 no: 不存在
  209. /// - Throws:
  210. static func getGoodsInfo(ById Id: Int) throws -> Bool {
  211. let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
  212. fetchRequest.predicate = NSPredicate(format: "goodsId == %ld", Int32(Id))
  213. let count = try appDelegate.mainManagedObjectContext.count(for: fetchRequest)
  214. return count > 0
  215. }
  216. /// 获取所有商品信息
  217. ///
  218. /// - Returns: 所有保存的商品信息
  219. /// - Throws:
  220. static func getGoodsInfo() throws -> [MoGoodsInfo] {
  221. let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
  222. fetchRequest.sortDescriptors = [NSSortDescriptor(key: "goodsCode", ascending: true)]
  223. let goodsInfos = try appDelegate.mainManagedObjectContext.fetch(fetchRequest)
  224. let moGoodsInfos = goodsInfos.compactMap({ $0.toMoGoodsInfo() })
  225. return moGoodsInfos
  226. }
  227. /// 判断本地数据库是否有数据
  228. ///
  229. /// - Returns: yes: 存在 no: 不存在
  230. /// - Throws:
  231. static func goodsInfoIsExist() -> Bool {
  232. let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
  233. do {
  234. let count = try appDelegate.mainManagedObjectContext.count(for: fetchRequest)
  235. return count > 0
  236. } catch {
  237. fatalError()
  238. }
  239. }
  240. /// 根据查询条件获取符合条件的商品
  241. ///
  242. /// - Parameter searchCondition: 查询条件
  243. /// - Returns: 符合条件的商品
  244. /// - Throws:
  245. static func getGoodsInfo(ByCondition searchCondition: String) throws -> [MoGoodsInfo] {
  246. guard !searchCondition.isEmpty else { return [] }
  247. let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
  248. if RegularUtils.checkNumber(with: searchCondition) {
  249. let regularString = ".*\(searchCondition).*"
  250. fetchRequest.predicate = NSPredicate(format: "searchCondition MATCHES %@", regularString)
  251. } else {
  252. var regularString = ".*"
  253. for s in searchCondition.uppercased() {
  254. regularString.append(s)
  255. regularString.append(".*")
  256. }
  257. fetchRequest.predicate = NSPredicate(format: "searchCondition MATCHES %@", regularString)
  258. }
  259. fetchRequest.sortDescriptors = [NSSortDescriptor(key: "goodsCode", ascending: true)]
  260. let goodsInfos = try appDelegate.mainManagedObjectContext.fetch(fetchRequest)
  261. let moGoodsInfos = goodsInfos.compactMap({ $0.toMoGoodsInfo() })
  262. return moGoodsInfos
  263. }
  264. /// 删除所有的商品数据信息
  265. static func removeAllGoodsInfo() {
  266. /// 获取上下文对象
  267. let viewContext = appDelegate.persistentContainer.viewContext
  268. /// 获取实例
  269. let entity = NSFetchRequest<NSFetchRequestResult>(entityName: "GoodsInfoEntity")
  270. let deleteRequest = NSBatchDeleteRequest(fetchRequest: entity)
  271. let _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
  272. appDelegate.backGroundObjectContext.perform {
  273. if appDelegate.backGroundObjectContext.hasChanges {
  274. do {
  275. _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
  276. }
  277. }
  278. }
  279. }
  280. /// 删除所有的商品数据信息
  281. static func removeGoodsInfo(_ goodsid: Int) {
  282. /// 获取上下文对象
  283. let viewContext = appDelegate.persistentContainer.viewContext
  284. /// 获取实例
  285. let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "GoodsInfoEntity")
  286. fetchRequest.predicate = NSPredicate(format: "goodsId == %ld", Int64(goodsid))
  287. let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
  288. let _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
  289. appDelegate.backGroundObjectContext.perform {
  290. if appDelegate.backGroundObjectContext.hasChanges {
  291. do {
  292. _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
  293. }
  294. }
  295. }
  296. }
  297. /// 根据goodsid获取对应的商品数据
  298. /// - Parameter goodsid: goodsid
  299. static func getMoGoodsInfo(where goodsids: [Int]) throws -> [MoGoodsInfo]? {
  300. /// 获取商品数据
  301. var goodsInfo: [MoGoodsInfo] = []
  302. let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
  303. for goodsid in goodsids {
  304. fetchRequest.predicate = NSPredicate(format: "goodsId == %ld", Int64(goodsid))
  305. let goodsInfos = try appDelegate.mainManagedObjectContext.fetch(fetchRequest)
  306. if goodsInfos.count != 0 { goodsInfo.append(goodsInfos[0].toMoGoodsInfo()) }
  307. }
  308. return goodsInfo
  309. }
  310. }