PaymentOrderViewController.swift 22 KB

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