PaymentOrderViewController.swift 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. //
  2. // PaymentOrderViewController.swift
  3. // MTP2_iOS
  4. //
  5. // Created by 曹晓亮 on 2020/12/10.
  6. // Copyright © 2020 Muchinfo. All rights reserved.
  7. //
  8. import UIKit
  9. import SwiftyAttributes
  10. import NVActivityIndicatorView
  11. import WHToast
  12. /// 填写订单视图容器控制类
  13. class PaymentOrderViewController: BaseViewController {
  14. // MARK: - 属性列表
  15. /// 提交订单
  16. @IBOutlet weak var payment: UIButton!
  17. /// 订单金额
  18. @IBOutlet weak var orderAmount: UILabel!
  19. /// 合计
  20. @IBOutlet weak var totalAmount: UILabel!
  21. /// 商品金额
  22. @IBOutlet weak var priceAmount: UILabel!
  23. /// 运费
  24. @IBOutlet weak var freight: UILabel!
  25. /// 商品价格
  26. @IBOutlet weak var orderPrice: UILabel!
  27. /// 商品名称
  28. @IBOutlet weak var goodsName: UILabel!
  29. /// 收货人姓名
  30. @IBOutlet weak var userName: UILabel!
  31. /// 收货人电话号码
  32. @IBOutlet weak var mobile: UILabel!
  33. /// 收货人地址信息
  34. @IBOutlet weak var address: UILabel!
  35. /// 供应商名称
  36. @IBOutlet weak var vendorName: UILabel!
  37. /// 支付方式
  38. @IBOutlet weak var payWay: UILabel!
  39. /// 商品图片
  40. @IBOutlet weak var goodsImage: UIImageView!
  41. /// 最大可购买数量
  42. @IBOutlet weak var maxQty: UILabel!
  43. /// 已选择优惠券
  44. @IBOutlet weak var hasCoupon: UILabel!
  45. /// 优惠券
  46. @IBOutlet weak var coupon: UIButton!
  47. /// 商品输入框
  48. @IBOutlet weak var qtyField: IBNumberEditText! {
  49. didSet {
  50. qtyField.valueType = 1
  51. qtyField.delegate = self
  52. }
  53. }
  54. /// 余额
  55. @IBOutlet weak var blance: UILabel!
  56. /// 商品信息
  57. override var takeInfo: Any? {
  58. didSet {}
  59. }
  60. /// 用户地址信息
  61. var userAddress: MoUserAddress? {
  62. didSet {
  63. /// 显示用户地址信息
  64. self.showReciveUserInfo()
  65. }
  66. }
  67. /// 优惠券
  68. var couponHold: MoMyCouponHold? {
  69. didSet {
  70. /// 异常
  71. if let obj = couponHold,
  72. let goods = takeInfo as? MoGoodsInfo {
  73. /// 已选择优惠券
  74. hasCoupon.attributedText = "已选优惠券".withTextColor(UIColorFromHex(rgbValue: 0x76c2dd))
  75. /// 现金券
  76. if obj.couponcategroy == 1 {
  77. coupon.setTitle("-\(goods.currencysign)\(obj.couponvalue.toString(reserve: 2))", for: .normal)
  78. } else if obj.couponcategroy == 2 {
  79. /// 折扣券
  80. /// 数量*金额*合约单位*折扣
  81. coupon.setTitle("-\(goods.currencysign)\((Double(qtyField.currentIntNumbers)*goods.orderprice*goods.agreeUnit*(1-obj.couponvalue)).toString(reserve: 2))", for: .normal)
  82. } else {
  83. /// 只能用于单个
  84. /// 数量*金额*合约单位*折扣
  85. coupon.setTitle("-\(goods.currencysign)\((goods.orderprice*goods.agreeUnit*(1-obj.couponvalue)).toString(reserve: 2))", for: .normal)
  86. }
  87. } else {
  88. coupon.setTitle("未使用", for: .normal)
  89. /// 已选择优惠券
  90. hasCoupon.attributedText = "".withTextColor(UIColorFromHex(rgbValue: 0x76c2dd))
  91. }
  92. /// 计算
  93. self.calculate()
  94. }
  95. }
  96. /// 选中的优惠券
  97. var rowNum: Int?
  98. // MARK: - 生命周期
  99. override func viewDidLoad() {
  100. super.viewDidLoad()
  101. // Do any additional setup after loading the view.
  102. /// loding.......
  103. self.addLoadingView()
  104. /// 请求用户地址信息
  105. self.requsetQueryReciveUserInfo()
  106. }
  107. override func viewWillAppear(_ animated: Bool) {
  108. super.viewWillAppear(animated)
  109. /// 隐藏导航栏
  110. self.navigationController?.setNavigationBarHidden(false, animated: true)
  111. }
  112. override func viewDidAppear(_ animated: Bool) {
  113. super.viewDidAppear(animated)
  114. /// 异常
  115. guard let goods = takeInfo as? MoGoodsInfo else { return }
  116. /// 商城商品明细
  117. self.requestQueryHsbyMarketGoodsDetail(goods.orderid)
  118. }
  119. // MARK: - 数据显示
  120. /// 商品信息显示
  121. fileprivate func showGoodsInfo(_ goods: MoGoodsInfo?) {
  122. /// 数据异常
  123. guard let obj = goods,
  124. let accountManager = MTP2BusinessCore.shared.accountManager else { return }
  125. /// 商品名称
  126. goodsName.text = obj.goodsname
  127. /// 供应商名称
  128. vendorName.text = obj.vendorname
  129. /// 商品价格
  130. orderPrice.attributedText = (obj.currencysign.withFont(.font_12)+obj.orderprice.toString(reserve: obj.decimalplace).withFont(.font_16)).withTextColor(UIColorFromHex(rgbValue: 0x76c2dd))
  131. /// 输入步进值
  132. qtyField.incrementIntNum = obj.lotsize != 0 ? obj.lotsize : 1
  133. qtyField.currentIntNumbers = obj.lotsize != 0 ? obj.lotsize : 1
  134. qtyField.minIntNum = obj.lotsize != 0 ? obj.lotsize : 1
  135. /// 商品图片
  136. guard let url = StringUtils.getImageUrl(obj.picurls) else { return }
  137. goodsImage.sd_setImage(with: url, placeholderImage: UIImage(named: "placeholder_image"), options: .queryDiskDataSync, context: nil)
  138. /// 查询资金信息
  139. accountManager.loginQueryReq(queryItem: "1,2") { (isComplete, error) in
  140. DispatchQueue.main.async {
  141. if let taAccountInfo = accountManager.getCurrentTAAccountInfo() {
  142. /// 期末余额
  143. let blance = taAccountInfo.currentBalance-(taAccountInfo.freezeMargin+taAccountInfo.otherFreezeMargin+taAccountInfo.freezeCharge)
  144. /// 最大可用数量
  145. self.qtyField.maxIntNum = obj.buymaxqty == 0 ? (obj.orderqty-obj.tradeqty) : min((obj.orderqty-obj.tradeqty), obj.buymaxqty)
  146. /// 最大可用数量
  147. self.maxQty.text = "最大可购买数量:\(self.qtyField.maxIntNum)"
  148. /// 余额
  149. self.blance.text = "可用余额:\(blance.toString(reserve: 2))"
  150. /// 请求优惠券
  151. self.requestQueryMyCoupons(Double(self.qtyField.currentIntNumbers)*obj.orderprice*obj.agreeUnit)
  152. }
  153. }
  154. }
  155. }
  156. /// 显示收货人信息
  157. fileprivate func showReciveUserInfo() {
  158. /// 数据异常
  159. guard let userAddress = userAddress else { return }
  160. /// 收货人姓名
  161. userName.text = userAddress.receivername
  162. /// 收货人电话号码
  163. mobile.text = String(userAddress.phonenum)
  164. /// 收货人地址信息
  165. address.text = userAddress.provincename + (userAddress.cityname == "null" ? "" : userAddress.cityname) + (userAddress.districtname == "null" ? "" : userAddress.districtname) + userAddress.address
  166. }
  167. // MARK: - 交互相关
  168. /// 按钮点击交互相关
  169. /// - Parameter sender: sender
  170. @IBAction fileprivate func onButtonPressed(_ sender: UIControl) {
  171. switch sender {
  172. case payment: /// 付款下单
  173. doDelistingTrade()
  174. case coupon: /// 优惠券选择
  175. /// 异常
  176. guard let obj = takeInfo as? MoGoodsInfo else {
  177. return
  178. }
  179. let chooseCoupon = viewController(name: "Coupon", identifier: "ChooseCoupon") as! ChooseCouponViewController
  180. chooseCoupon.usedBlock = { (_ obj: MoMyCouponHold?, _ rowNum: Int?) in
  181. /// 优惠券 如果选中的是相同的 则删除
  182. self.couponHold = obj?.couponholdid == self.couponHold?.couponholdid ? nil : obj
  183. self.rowNum = rowNum
  184. }
  185. chooseCoupon.modalTransitionStyle = .crossDissolve
  186. chooseCoupon.modalPresentationStyle = .overFullScreen
  187. chooseCoupon.amount = Double(self.qtyField.currentIntNumbers)*obj.orderprice*obj.agreeUnit
  188. chooseCoupon.coupon = self.couponHold
  189. self.present(chooseCoupon, animated: true, completion: {
  190. chooseCoupon.takeInfo = obj
  191. })
  192. default:
  193. break
  194. }
  195. }
  196. /// onTapGestureRecognizer
  197. /// - Parameter sender: sender
  198. @IBAction fileprivate func onTapGestureRecognizer(_ sender: UITapGestureRecognizer) {
  199. /// 地址切换
  200. let addressController = viewController(name: "Settings", identifier: "PickUpAddress") as! ReceiveGoodsInfoViewController
  201. addressController.delegate = self
  202. self.navigationController?.pushViewController(addressController, animated: true)
  203. }
  204. /// 计算相关
  205. fileprivate func calculate() {
  206. /// 数据异常
  207. guard let goods = takeInfo as? MoGoodsInfo,
  208. let accountManager = MTP2BusinessCore.shared.accountManager,
  209. let taAccountInfo = accountManager.getCurrentTAAccountInfo() else { return }
  210. /// 期末余额
  211. let blance = taAccountInfo.currentBalance-(taAccountInfo.freezeMargin+taAccountInfo.otherFreezeMargin+taAccountInfo.freezeCharge)
  212. /// 商品金额
  213. let amount = goods.goodsprice*goods.agreeUnit*Double(qtyField.currentIntNumbers)
  214. var tlAmount = 0.0
  215. /// 有优惠券
  216. if let obj = self.couponHold {
  217. if obj.couponcategroy == 1 {
  218. tlAmount = (amount - obj.couponvalue) > 0.0 ? (amount - obj.couponvalue) : 0.0
  219. } else if obj.couponcategroy == 2 {
  220. tlAmount = amount*obj.couponvalue
  221. /// 优惠金额 数量*金额*合约单位*折扣
  222. coupon.setTitle("-\(goods.currencysign)\((Double(qtyField.currentIntNumbers)*goods.goodsprice*goods.agreeUnit*(1-obj.couponvalue)).toString(reserve: 2))", for: .normal)
  223. } else {
  224. tlAmount = amount - (goods.goodsprice*goods.agreeUnit*(1-obj.couponvalue))
  225. }
  226. } else {
  227. tlAmount = amount
  228. }
  229. payWay.text = tlAmount <= blance ? "余额支付" : "线上支付"
  230. /// 商品金额
  231. priceAmount.attributedText = (goods.currencysign.withFont(.font_12)+amount.toString(reserve: goods.decimalplace).withFont(.font_16)).withTextColor(UIColorFromHex(rgbValue: 0x999999))
  232. /// 合计金额
  233. totalAmount.attributedText = "合计:\(goods.currencysign)".withFont(.font_12).withTextColor(UIColorFromHex(rgbValue: 0x999999))+tlAmount.toString(reserve: 2).withFont(.font_16).withTextColor(UIColorFromHex(rgbValue: 0xdf5958))
  234. /// 订单金额
  235. orderAmount.attributedText = "合计:\(goods.currencysign)".withFont(.font_12).withTextColor(UIColorFromHex(rgbValue: 0x999999))+tlAmount.toString(reserve: 2).withFont(.font_16).withTextColor(UIColorFromHex(rgbValue: 0xdf5958))
  236. }
  237. // MARK: - 接口请求
  238. /// 获取用户地址信息
  239. func requsetQueryReciveUserInfo() {
  240. /// 数据异常
  241. guard let deliveryManager = MTP2BusinessCore.shared.deliveryManager else { return }
  242. /// startAnimating
  243. _anim?.startAnimating()
  244. /// 请求用户地址信息
  245. deliveryManager.queryUserAddressInfo { (isSuccess, errorInfo, results) in
  246. DispatchQueue.main.async {
  247. self._anim?.stopAnimating()
  248. if isSuccess,
  249. let infos = results {
  250. /// 默认显示地址
  251. if let info = infos.first(where: {$0.isDefault}) {
  252. self.userAddress = info
  253. } else {
  254. self.userAddress = infos.first
  255. }
  256. }
  257. }
  258. }
  259. }
  260. /// 服务端查询商城商品详情请求方法
  261. /// - Parameter orderID: orderID
  262. fileprivate func requestQueryHsbyMarketGoodsDetail(_ orderID: String) {
  263. /// 异常
  264. guard let goodsManager = MTP2BusinessCore.shared.goodsManager else { return }
  265. /// startAnimating
  266. _anim?.startAnimating()
  267. /// 发送请求
  268. goodsManager.requestQueryHsbyMarketGoodsDetail(orderID, callback: { (isComplete, error, detail) in
  269. DispatchQueue.main.async {
  270. /// stopAnimating
  271. self._anim?.stopAnimating()
  272. if isComplete {
  273. /// 显示商品信息
  274. self.showGoodsInfo(detail)
  275. /// 计算
  276. self.calculate()
  277. } else {
  278. WHToast.showMessage("数据加载失败,原因:\(error?.retMsg ?? "未知错误")", duration: 1.5, finishHandler: {})
  279. }
  280. }
  281. })
  282. }
  283. /// 查询我的优惠券
  284. fileprivate func requestQueryMyCoupons(_ amount: Double) {
  285. /// 异常
  286. guard let orderManager = MTP2BusinessCore.shared.orderManager,
  287. let moGoodsInfo = takeInfo as? MoGoodsInfo else { return }
  288. /// startAnimating
  289. _anim?.startAnimating()
  290. /// 查询数据
  291. orderManager.requestQueryMyCouponHolds(moGoodsInfo.goodsid,
  292. amount,
  293. moGoodsInfo.sellUserID,
  294. "1,2") { (isComplete, error, objs) in
  295. DispatchQueue.main.async {
  296. /// stopAnimating
  297. self._anim?.stopAnimating()
  298. /// 查询成功
  299. if isComplete {
  300. if objs?.count != 0 { self.couponHold = objs?.first } else { self.couponHold = nil }
  301. self.rowNum = 0
  302. } else {
  303. /// showError
  304. WHToast.showError(withMessage: "查询失败,请稍候再试!", duration: 1.5, finishHandler: {})
  305. }
  306. }
  307. }
  308. }
  309. /// 预售下单请求
  310. fileprivate func doDelistingTrade() {
  311. /// 数据异常
  312. guard let tradeManager = MTP2BusinessCore.shared.tradeManager,
  313. let obj = takeInfo as? MoGoodsInfo,
  314. check(),
  315. let accountManager = MTP2BusinessCore.shared.accountManager,
  316. let taAccountInfo = accountManager.getCurrentTAAccountInfo() else { return }
  317. /// 构建交易参数
  318. let tradeParam = MoTradeParam()
  319. /// 买卖方向
  320. tradeParam.buyOrSell = .ORDERDIRECTION_BUY
  321. /// 数量
  322. tradeParam.orderQty = Double(qtyField.currentIntNumbers)
  323. /// 点选成交
  324. tradeParam.listingSelectType = .LISTINGSELECTTYPE_DELISTING
  325. /// 有效类型
  326. tradeParam.validType = .VALIDTYPE_DR
  327. /// 下单类型
  328. tradeParam.buildType = .BUILDTYPE_OPEN
  329. /// 时间有效类型
  330. tradeParam.timevalidType = .VALIDTYPE_YZ
  331. /// 市场编号
  332. tradeParam.marketID = obj.marketid
  333. /// 商品ID
  334. tradeParam.goodsID = obj.goodsid
  335. /// 关联单号
  336. tradeParam.relatedID = UInt64(obj.orderid) ?? 0
  337. /// 优惠券
  338. if let id = couponHold?.coupontypeid { tradeParam.couponTypeID = UInt64(id)}
  339. /// 优惠券
  340. if let id = userAddress?.autoid { tradeParam.receiveInfoID = UInt64(id)}
  341. /// 开启Loading
  342. NVActivityIndicatorPresenter.sharedInstance.startAnimating(ActivityData(message: "订单生成中......", type: .ballClipRotate, color: UIColor.loding(), backgroundColor: .clear), NVActivityIndicatorView.DEFAULT_FADE_IN_ANIMATION)
  343. tradeManager.tradeCommision(tradeParam: tradeParam) { [weak self] (isSuccess, error, orderNo) in
  344. DispatchQueue.main.async {
  345. /// dismisss loding.....
  346. NVActivityIndicatorPresenter.sharedInstance.stopAnimating(NVActivityIndicatorView.DEFAULT_FADE_OUT_ANIMATION)
  347. if isSuccess {
  348. /// 期末余额
  349. let blance = taAccountInfo.currentBalance-(taAccountInfo.freezeMargin+taAccountInfo.otherFreezeMargin+taAccountInfo.freezeCharge)
  350. var tlAmount = 0.0
  351. let amount = obj.orderprice*obj.agreeUnit*Double(self?.qtyField.currentIntNumbers ?? 0)
  352. /// 有优惠券
  353. if let hold = self?.couponHold {
  354. if hold.couponcategroy == 1 { /// 现金券
  355. tlAmount = (amount - hold.couponvalue) > 0.0 ? (amount - hold.couponvalue) : 0.0
  356. } else if hold.couponcategroy == 2 { /// 折扣券
  357. tlAmount = amount*hold.couponvalue
  358. } else { /// 单张折扣券
  359. tlAmount = amount - (obj.orderprice*obj.agreeUnit*hold.couponvalue)
  360. }
  361. } else {
  362. tlAmount = amount
  363. }
  364. /// 如果可用金额不够
  365. if tlAmount > blance {
  366. WHToast.showSuccess(withMessage: "订单生成成功", duration: 1.5, finishHandler: {
  367. /// 异常
  368. guard let orderManager = MTP2BusinessCore.shared.orderManager else {
  369. return
  370. }
  371. /// 查询查询单据数据
  372. orderManager.requestQueryMyPayOrders(orderNo, nil) { (isComplete, error, payOrders) in
  373. DispatchQueue.main.async {
  374. if isComplete,
  375. payOrders?.count != 0 {
  376. /// 异常
  377. guard let paymentController = self?.viewController(name: "Order", identifier: "Payment") as? PaymentViewController else { return }
  378. /// 待付款单据
  379. paymentController.myPayOrder = payOrders?.first
  380. /// 页面跳转
  381. self?.navigationController?.pushViewController(paymentController, animated: true)
  382. } else {
  383. WHToast.showError(withMessage: "单据获取失败,请稍候重试!", duration: 1.5, finishHandler: {})
  384. }
  385. }
  386. }
  387. })
  388. } else{
  389. guard let viewController = UIStoryboard(name: "Order", bundle: nil).instantiateViewController(withIdentifier: "Packet") as? BaseViewController else { return }
  390. self?.navigationController?.pushViewController(viewController, animated: true)
  391. viewController.selectedIndex = 0
  392. }
  393. } else {
  394. WHToast.showError(withMessage: "订单生成失败,\(ErrorUtils.getDesc(errorCode: error?.retCode ?? -99999) ?? "未知错误")", duration: 1.5, finishHandler: {})
  395. }
  396. }
  397. }
  398. }
  399. /// 合规性校验
  400. /// - Returns: 是否合规
  401. fileprivate func check() -> Bool {
  402. /// 请先选择收获地址
  403. guard let _ = userAddress else {
  404. WHToast.showError(withMessage: "请先选择收获地址!", duration: 1.5, finishHandler: {})
  405. return false
  406. }
  407. /// 请输入委托数量
  408. if qtyField.currentIntNumbers == 0 {
  409. WHToast.showError(withMessage: "请输入购买数量", duration: 1.5, finishHandler: {})
  410. return false
  411. }
  412. /// 委托数量不能大于
  413. if qtyField.currentIntNumbers > qtyField.maxIntNum {
  414. WHToast.showError(withMessage: "购买数量应小于等于\(qtyField.maxIntNum)", duration: 1.5, finishHandler: {})
  415. return false
  416. }
  417. return true
  418. }
  419. /*
  420. // MARK: - Navigation
  421. // In a storyboard-based application, you will often want to do a little preparation before navigation
  422. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  423. // Get the new view controller using segue.destination.
  424. // Pass the selected object to the new view controller.
  425. }
  426. */
  427. }
  428. // MARK: - IBNumberEditTextDelegate
  429. extension PaymentOrderViewController: IBNumberEditTextDelegate {
  430. func numberInputViewDidEndEditing(_ numberInputView: IBNumberEditText) {
  431. /// 重新获取优惠券
  432. if numberInputView == qtyField,
  433. let obj = takeInfo as? MoGoodsInfo {
  434. /// 请求优惠券
  435. requestQueryMyCoupons(Double(qtyField.currentIntNumbers)*obj.goodsprice*obj.agreeUnit)
  436. }
  437. }
  438. func numberInputView(_ numberInputView: IBNumberEditText, _ buttonType: NumberInputViewButtonType) {
  439. /// 重新获取优惠券
  440. if numberInputView == qtyField,
  441. let obj = takeInfo as? MoGoodsInfo {
  442. /// 请求优惠券
  443. requestQueryMyCoupons(Double(qtyField.currentIntNumbers)*obj.goodsprice*obj.agreeUnit)
  444. }
  445. /// 计算
  446. calculate()
  447. }
  448. func IBNumberEditText(textField: UITextField) {
  449. /// 计算
  450. calculate()
  451. }
  452. }
  453. // MARK: - ReceiveGoodsInfoViewControllerDelegate
  454. extension PaymentOrderViewController: ReceiveGoodsInfoViewControllerDelegate {
  455. /// receiveGoodsInfoViewController
  456. /// - Parameter sender: sender
  457. func receiveGoodsInfoViewController(_ sender: ReceiveGoodsInfoViewController) {}
  458. /// receiveGoodsInfoViewController
  459. /// - Parameters:
  460. /// - sender: sender
  461. /// - model: model
  462. func receiveGoodsInfoViewController(_ sender: ReceiveGoodsInfoViewController, userAddressInfo model: MoUserAddress?) {
  463. self.userAddress = model
  464. }
  465. }