PaymentOrderViewController.swift 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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,
  125. let taAccountInfo = accountManager.getCurrentTAAccountInfo() else { return }
  126. /// 商品名称
  127. goodsName.text = obj.goodsname
  128. /// 供应商名称
  129. vendorName.text = obj.vendorname
  130. /// 商品价格
  131. orderPrice.attributedText = (obj.currencysign.withFont(.font_12)+obj.orderprice.toString(reserve: obj.decimalplace).withFont(.font_16)).withTextColor(UIColorFromHex(rgbValue: 0x76c2dd))
  132. /// 输入步进值
  133. qtyField.incrementIntNum = obj.lotsize != 0 ? obj.lotsize : 1
  134. qtyField.currentIntNumbers = obj.lotsize != 0 ? obj.lotsize : 1
  135. qtyField.minIntNum = obj.lotsize != 0 ? obj.lotsize : 1
  136. /// 商品图片
  137. guard let url = StringUtils.getImageUrl(obj.picurls) else { return }
  138. goodsImage.sd_setImage(with: url, placeholderImage: UIImage(named: "placeholder_image"), options: .queryDiskDataSync, context: nil)
  139. /// 查询资金信息
  140. accountManager.loginQueryReq(queryItem: "1,2") { (isComplete, error) in
  141. DispatchQueue.main.async {
  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. fileprivate func showReciveUserInfo() {
  157. /// 数据异常
  158. guard let userAddress = userAddress else { return }
  159. /// 收货人姓名
  160. userName.text = userAddress.receivername
  161. /// 收货人电话号码
  162. mobile.text = String(userAddress.phonenum)
  163. /// 收货人地址信息
  164. address.text = userAddress.provincename + (userAddress.cityname == "null" ? "" : userAddress.cityname) + (userAddress.districtname == "null" ? "" : userAddress.districtname) + userAddress.address
  165. }
  166. // MARK: - 交互相关
  167. /// 按钮点击交互相关
  168. /// - Parameter sender: sender
  169. @IBAction fileprivate func onButtonPressed(_ sender: UIControl) {
  170. switch sender {
  171. case payment: /// 付款下单
  172. doDelistingTrade()
  173. case coupon: /// 优惠券选择
  174. /// 异常
  175. guard let obj = takeInfo as? MoGoodsInfo else {
  176. return
  177. }
  178. let chooseCoupon = viewController(name: "Coupon", identifier: "ChooseCoupon") as! ChooseCouponViewController
  179. chooseCoupon.usedBlock = { (_ obj: MoMyCouponHold?, _ rowNum: Int?) in
  180. /// 优惠券
  181. self.couponHold = rowNum == nil ? nil : obj
  182. self.rowNum = rowNum
  183. }
  184. chooseCoupon.modalTransitionStyle = .crossDissolve
  185. chooseCoupon.modalPresentationStyle = .overFullScreen
  186. chooseCoupon.amount = Double(self.qtyField.currentIntNumbers)*obj.orderprice*obj.agreeUnit
  187. chooseCoupon.coupon = self.couponHold
  188. self.present(chooseCoupon, animated: true, completion: {
  189. chooseCoupon.takeInfo = obj
  190. })
  191. default:
  192. break
  193. }
  194. }
  195. /// onTapGestureRecognizer
  196. /// - Parameter sender: sender
  197. @IBAction fileprivate func onTapGestureRecognizer(_ sender: UITapGestureRecognizer) {
  198. /// 地址切换
  199. let addressController = viewController(name: "Settings", identifier: "PickUpAddress") as! ReceiveGoodsInfoViewController
  200. addressController.delegate = self
  201. self.navigationController?.pushViewController(addressController, animated: true)
  202. }
  203. /// 计算相关
  204. fileprivate func calculate() {
  205. /// 数据异常
  206. guard let goods = takeInfo as? MoGoodsInfo,
  207. let accountManager = MTP2BusinessCore.shared.accountManager,
  208. let taAccountInfo = accountManager.getCurrentTAAccountInfo() else { return }
  209. /// 期末余额
  210. let blance = taAccountInfo.currentBalance-(taAccountInfo.freezeMargin+taAccountInfo.otherFreezeMargin+taAccountInfo.freezeCharge)
  211. /// 商品金额
  212. let amount = goods.goodsprice*goods.agreeUnit*Double(qtyField.currentIntNumbers)
  213. var tlAmount = 0.0
  214. /// 有优惠券
  215. if let obj = self.couponHold {
  216. if obj.couponcategroy == 1 {
  217. tlAmount = (amount - obj.couponvalue) > 0.0 ? (amount - obj.couponvalue) : 0.0
  218. } else if obj.couponcategroy == 2 {
  219. tlAmount = amount*obj.couponvalue
  220. /// 优惠金额 数量*金额*合约单位*折扣
  221. coupon.setTitle("-\(goods.currencysign)\((Double(qtyField.currentIntNumbers)*goods.goodsprice*goods.agreeUnit*(1-obj.couponvalue)).toString(reserve: 2))", for: .normal)
  222. } else {
  223. tlAmount = amount - (goods.goodsprice*goods.agreeUnit*(1-obj.couponvalue))
  224. }
  225. } else {
  226. tlAmount = amount
  227. }
  228. payWay.text = tlAmount <= blance ? "余额支付" : "线上支付"
  229. /// 商品金额
  230. priceAmount.attributedText = (goods.currencysign.withFont(.font_12)+amount.toString(reserve: goods.decimalplace).withFont(.font_16)).withTextColor(UIColorFromHex(rgbValue: 0x999999))
  231. /// 合计金额
  232. totalAmount.attributedText = "合计:\(goods.currencysign)".withFont(.font_12).withTextColor(UIColorFromHex(rgbValue: 0x999999))+tlAmount.toString(reserve: 2).withFont(.font_16).withTextColor(UIColorFromHex(rgbValue: 0xdf5958))
  233. /// 订单金额
  234. orderAmount.attributedText = "合计:\(goods.currencysign)".withFont(.font_12).withTextColor(UIColorFromHex(rgbValue: 0x999999))+tlAmount.toString(reserve: 2).withFont(.font_16).withTextColor(UIColorFromHex(rgbValue: 0xdf5958))
  235. }
  236. // MARK: - 接口请求
  237. /// 获取用户地址信息
  238. func requsetQueryReciveUserInfo() {
  239. /// 数据异常
  240. guard let deliveryManager = MTP2BusinessCore.shared.deliveryManager else { return }
  241. /// startAnimating
  242. _anim?.startAnimating()
  243. /// 请求用户地址信息
  244. deliveryManager.queryUserAddressInfo { (isSuccess, errorInfo, results) in
  245. DispatchQueue.main.async {
  246. self._anim?.stopAnimating()
  247. if isSuccess,
  248. let infos = results {
  249. /// 默认显示地址
  250. if let info = infos.first(where: {$0.isDefault}) {
  251. self.userAddress = info
  252. } else {
  253. self.userAddress = infos.first
  254. }
  255. }
  256. }
  257. }
  258. }
  259. /// 服务端查询商城商品详情请求方法
  260. /// - Parameter orderID: orderID
  261. fileprivate func requestQueryHsbyMarketGoodsDetail(_ orderID: String) {
  262. /// 异常
  263. guard let goodsManager = MTP2BusinessCore.shared.goodsManager else { return }
  264. /// startAnimating
  265. _anim?.startAnimating()
  266. /// 发送请求
  267. goodsManager.requestQueryHsbyMarketGoodsDetail(orderID, callback: { (isComplete, error, detail) in
  268. DispatchQueue.main.async {
  269. /// stopAnimating
  270. self._anim?.stopAnimating()
  271. if isComplete {
  272. /// 显示商品信息
  273. self.showGoodsInfo(detail)
  274. /// 计算
  275. self.calculate()
  276. } else {
  277. WHToast.showMessage("数据加载失败,原因:\(error?.retMsg ?? "未知错误")", duration: 1.5, finishHandler: {})
  278. }
  279. }
  280. })
  281. }
  282. /// 查询我的优惠券
  283. fileprivate func requestQueryMyCoupons(_ amount: Double) {
  284. /// 异常
  285. guard let orderManager = MTP2BusinessCore.shared.orderManager,
  286. let moGoodsInfo = takeInfo as? MoGoodsInfo else { return }
  287. /// startAnimating
  288. _anim?.startAnimating()
  289. /// 查询数据
  290. orderManager.requestQueryMyCouponHolds(moGoodsInfo.goodsid,
  291. amount,
  292. moGoodsInfo.sellUserID,
  293. "1,2") { (isComplete, error, objs) in
  294. DispatchQueue.main.async {
  295. /// stopAnimating
  296. self._anim?.stopAnimating()
  297. /// 查询成功
  298. if isComplete {
  299. if objs?.count != 0 { self.couponHold = objs?.first }
  300. self.rowNum = 0
  301. } else {
  302. /// showError
  303. WHToast.showError(withMessage: "查询失败,请稍候再试!", duration: 1.5, finishHandler: {})
  304. }
  305. }
  306. }
  307. }
  308. /// 预售下单请求
  309. fileprivate func doDelistingTrade() {
  310. /// 数据异常
  311. guard let tradeManager = MTP2BusinessCore.shared.tradeManager,
  312. let obj = takeInfo as? MoGoodsInfo,
  313. check(),
  314. let accountManager = MTP2BusinessCore.shared.accountManager,
  315. let taAccountInfo = accountManager.getCurrentTAAccountInfo() else { return }
  316. /// 构建交易参数
  317. let tradeParam = MoTradeParam()
  318. /// 买卖方向
  319. tradeParam.buyOrSell = .ORDERDIRECTION_BUY
  320. /// 数量
  321. tradeParam.orderQty = Double(qtyField.currentIntNumbers)
  322. /// 点选成交
  323. tradeParam.listingSelectType = .LISTINGSELECTTYPE_DELISTING
  324. /// 有效类型
  325. tradeParam.validType = .VALIDTYPE_DR
  326. /// 下单类型
  327. tradeParam.buildType = .BUILDTYPE_OPEN
  328. /// 时间有效类型
  329. tradeParam.timevalidType = .VALIDTYPE_YZ
  330. /// 市场编号
  331. tradeParam.marketID = obj.marketid
  332. /// 商品ID
  333. tradeParam.goodsID = obj.goodsid
  334. /// 关联单号
  335. tradeParam.relatedID = UInt64(obj.orderid) ?? 0
  336. /// 优惠券
  337. if let id = couponHold?.coupontypeid { tradeParam.couponTypeID = UInt64(id)}
  338. /// 优惠券
  339. if let id = userAddress?.autoid { tradeParam.receiveInfoID = UInt64(id)}
  340. /// 开启Loading
  341. NVActivityIndicatorPresenter.sharedInstance.startAnimating(ActivityData(message: "订单生成中......", type: .ballClipRotate, color: UIColor.loding(), backgroundColor: .clear), NVActivityIndicatorView.DEFAULT_FADE_IN_ANIMATION)
  342. tradeManager.tradeCommision(tradeParam: tradeParam) { [weak self] (isSuccess, error, orderNo) in
  343. DispatchQueue.main.async {
  344. /// dismisss loding.....
  345. NVActivityIndicatorPresenter.sharedInstance.stopAnimating(NVActivityIndicatorView.DEFAULT_FADE_OUT_ANIMATION)
  346. if isSuccess {
  347. /// 期末余额
  348. let blance = taAccountInfo.currentBalance-(taAccountInfo.freezeMargin+taAccountInfo.otherFreezeMargin+taAccountInfo.freezeCharge)
  349. var tlAmount = 0.0
  350. let amount = obj.orderprice*obj.agreeUnit*Double(self?.qtyField.currentIntNumbers ?? 0)
  351. /// 有优惠券
  352. if let hold = self?.couponHold {
  353. if hold.couponcategroy == 1 { /// 现金券
  354. tlAmount = (amount - hold.couponvalue) > 0.0 ? (amount - hold.couponvalue) : 0.0
  355. } else if hold.couponcategroy == 2 { /// 折扣券
  356. tlAmount = amount*hold.couponvalue
  357. } else { /// 单张折扣券
  358. tlAmount = amount - (obj.orderprice*obj.agreeUnit*hold.couponvalue)
  359. }
  360. } else {
  361. tlAmount = amount
  362. }
  363. /// 如果可用金额不够
  364. if tlAmount > blance {
  365. WHToast.showSuccess(withMessage: "订单生成成功", duration: 1.5, finishHandler: {
  366. /// 异常
  367. guard let orderManager = MTP2BusinessCore.shared.orderManager else {
  368. return
  369. }
  370. /// 查询查询单据数据
  371. orderManager.requestQueryMyPayOrders(orderNo, nil) { (isComplete, error, payOrders) in
  372. DispatchQueue.main.async {
  373. if isComplete,
  374. payOrders?.count != 0 {
  375. /// 异常
  376. guard let paymentController = self?.viewController(name: "Order", identifier: "Payment") as? PaymentViewController else { return }
  377. /// 待付款单据
  378. paymentController.myPayOrder = payOrders?.first
  379. /// 页面跳转
  380. self?.navigationController?.pushViewController(paymentController, animated: true)
  381. } else {
  382. WHToast.showError(withMessage: "单据获取失败,请稍候重试!", duration: 1.5, finishHandler: {})
  383. }
  384. }
  385. }
  386. })
  387. } else{
  388. guard let viewController = UIStoryboard(name: "Order", bundle: nil).instantiateViewController(withIdentifier: "Packet") as? BaseViewController else { return }
  389. self?.navigationController?.pushViewController(viewController, animated: true)
  390. viewController.selectedIndex = 0
  391. }
  392. } else {
  393. WHToast.showError(withMessage: "订单生成失败,\(ErrorUtils.getDesc(errorCode: error?.retCode ?? -99999) ?? "未知错误")", duration: 1.5, finishHandler: {})
  394. }
  395. }
  396. }
  397. }
  398. /// 合规性校验
  399. /// - Returns: 是否合规
  400. fileprivate func check() -> Bool {
  401. /// 请先选择收获地址
  402. guard let _ = userAddress else {
  403. WHToast.showError(withMessage: "请先选择收获地址!", duration: 1.5, finishHandler: {})
  404. return false
  405. }
  406. /// 请输入委托数量
  407. if qtyField.currentIntNumbers == 0 {
  408. WHToast.showError(withMessage: "请输入购买数量", duration: 1.5, finishHandler: {})
  409. return false
  410. }
  411. /// 委托数量不能大于
  412. if qtyField.currentIntNumbers > qtyField.maxIntNum {
  413. WHToast.showError(withMessage: "购买数量应小于等于\(qtyField.maxIntNum)", duration: 1.5, finishHandler: {})
  414. return false
  415. }
  416. return true
  417. }
  418. /*
  419. // MARK: - Navigation
  420. // In a storyboard-based application, you will often want to do a little preparation before navigation
  421. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  422. // Get the new view controller using segue.destination.
  423. // Pass the selected object to the new view controller.
  424. }
  425. */
  426. }
  427. // MARK: - IBNumberEditTextDelegate
  428. extension PaymentOrderViewController: IBNumberEditTextDelegate {
  429. func numberInputViewDidEndEditing(_ numberInputView: IBNumberEditText) {
  430. /// 重新获取优惠券
  431. if numberInputView == qtyField,
  432. let obj = takeInfo as? MoGoodsInfo {
  433. /// 请求优惠券
  434. requestQueryMyCoupons(Double(qtyField.currentIntNumbers)*obj.goodsprice*obj.agreeUnit)
  435. }
  436. }
  437. func numberInputView(_ numberInputView: IBNumberEditText, _ buttonType: NumberInputViewButtonType) {
  438. /// 重新获取优惠券
  439. if numberInputView == qtyField,
  440. let obj = takeInfo as? MoGoodsInfo {
  441. /// 请求优惠券
  442. requestQueryMyCoupons(Double(qtyField.currentIntNumbers)*obj.goodsprice*obj.agreeUnit)
  443. }
  444. /// 计算
  445. calculate()
  446. }
  447. func IBNumberEditText(textField: UITextField) {
  448. /// 计算
  449. calculate()
  450. }
  451. }
  452. // MARK: - ReceiveGoodsInfoViewControllerDelegate
  453. extension PaymentOrderViewController: ReceiveGoodsInfoViewControllerDelegate {
  454. /// receiveGoodsInfoViewController
  455. /// - Parameter sender: sender
  456. func receiveGoodsInfoViewController(_ sender: ReceiveGoodsInfoViewController) {}
  457. /// receiveGoodsInfoViewController
  458. /// - Parameters:
  459. /// - sender: sender
  460. /// - model: model
  461. func receiveGoodsInfoViewController(_ sender: ReceiveGoodsInfoViewController, userAddressInfo model: MoUserAddress?) {
  462. self.userAddress = model
  463. }
  464. }