MyUnusedViewController.swift 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. //
  2. // MyUnusedViewController.swift
  3. // MTP2_iOS
  4. //
  5. // Created by Handy_Cao on 2020/10/30.
  6. // Copyright © 2020 Muchinfo. All rights reserved.
  7. //
  8. import UIKit
  9. import JXSegmentedView
  10. import WHToast
  11. import NVActivityIndicatorView
  12. import SwiftDate
  13. /// 我的闲置视图容器控制类
  14. class MyUnusedViewController: BaseViewController {
  15. // MARK: - 属性列表
  16. /// 商品切换按钮
  17. @IBOutlet weak var goods: UIButton!
  18. /// 发布价格
  19. @IBOutlet weak var orderPrice: IBNumberEditText! {
  20. didSet {
  21. orderPrice.valueType = 2
  22. orderPrice.currentIntNumbers = 0
  23. orderPrice.delegate = self
  24. }
  25. }
  26. /// 价格范围
  27. @IBOutlet weak var priceRange: UILabel!
  28. /// 发布数量
  29. @IBOutlet weak var orderQty: IBNumberEditText! {
  30. didSet {
  31. orderQty.valueType = 1
  32. orderQty.delegate = self
  33. }
  34. }
  35. /// 可用数量
  36. @IBOutlet weak var enableQty: UILabel!
  37. /// 提货按钮
  38. @IBOutlet weak var submit: UIButton!
  39. /// 刷新按钮
  40. @IBOutlet weak var refresh: UIButton!
  41. /// 有效期按钮
  42. @IBOutlet weak var valid: UIButton! {
  43. didSet {
  44. valid.isUserInteractionEnabled = false
  45. }
  46. }
  47. /// 有效期
  48. @IBOutlet weak var validStackView: UIStackView!
  49. /// 分段控制器
  50. @IBOutlet weak var segmentedView: JXSegmentedView! {
  51. didSet {
  52. segmentedView.delegate = self
  53. segmentedView.dataSource = dataSource
  54. segmentedView.indicators = [self.indicator]
  55. }
  56. }
  57. /// segmentedDataSource
  58. let dataSource: JXSegmentedTitleDataSource = {
  59. var items: [String] = ["待成交", "待收款", "已完成"]
  60. $0.titles = items
  61. $0.titleNormalColor = UIColorFromHex(rgbValue: 0x333333)
  62. $0.titleNormalFont = .font_14
  63. $0.titleSelectedColor = UIColorFromHex(rgbValue: 0x60a1e3)
  64. $0.titleSelectedFont = .font_14
  65. $0.isTitleColorGradientEnabled = true
  66. return $0
  67. } (JXSegmentedTitleDataSource())
  68. /// 买家委托单列表
  69. @IBOutlet weak var orderTableView: UITableView! {
  70. didSet {
  71. orderDelegate = OrderDelegate(self)
  72. orderTableView.delegate = orderDelegate
  73. orderTableView.dataSource = orderDelegate
  74. }
  75. }
  76. /// 单据视图
  77. @IBOutlet weak var orderView: UIView!
  78. /// orderTableViewHeightConstraint
  79. @IBOutlet weak var orderTableViewHeightConstraint: NSLayoutConstraint! {
  80. didSet {
  81. orderTableViewHeightConstraint.constant = 0.0
  82. }
  83. }
  84. /// 列表
  85. @IBOutlet weak var tableView: UITableView! {
  86. didSet {
  87. myUnusedDelegate = MyUnusedDelegate(self)
  88. tableView.delegate = myUnusedDelegate
  89. tableView.dataSource = myUnusedDelegate
  90. }
  91. }
  92. /// tableViewHeightConstraint
  93. @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint! {
  94. didSet {
  95. tableViewHeightConstraint.constant = 0.0
  96. }
  97. }
  98. /// 提示信息
  99. @IBOutlet weak var tips: UILabel!
  100. /// OrderCellIdentifier
  101. let OrderCellIdentifier = "Trade_Cell"
  102. /// CellIdentifier
  103. let CellIdentifier = "SellMyDetail_Cell"
  104. /// orderDelegate
  105. fileprivate var orderDelegate: OrderDelegate?
  106. /// myUnusedDelegate
  107. fileprivate var myUnusedDelegate: MyUnusedDelegate?
  108. /// 我的商品数据
  109. var myGoods: MoHsbyMyGoods? {
  110. didSet {
  111. /// 异常
  112. guard let obj = myGoods,
  113. let goodsManager = MTP2BusinessCore.shared.goodsManager,
  114. let last = goodsManager.goodsInfos.first(where: {$0.goodsid == obj.goodsid})?.getLast() else { return }
  115. /// 显示商品信息
  116. showGoodsInfo(obj)
  117. /// 行情订阅
  118. self.subscriptQuote()
  119. /// 挂牌点选
  120. if obj.trademode == .TRADEMODE_LISTING_SELECT {
  121. /// 侦听行情推送广播
  122. MTP2BusinessCore.shared.broadcastManager?.addBroadcastListener(owner: self, action: .ReceiveTradeQuote, block: { [unowned self] (notify) in
  123. DispatchQueue.main.async {
  124. /// 异常情况
  125. guard let goodsQuoteInfo = notify.object as? [(goodsHqCode: String, exchHqCode: String)],
  126. goodsQuoteInfo.count != 0 else { return }
  127. /// 更新商品行情信息
  128. goodsQuoteInfo.forEach {
  129. if $0.goodsHqCode == obj.goodscode {
  130. if last != self.orderPrice.currentDoubleNumbers {
  131. /// 查询数据
  132. self.requestQueryHsbyGoodsOrderDetails(self.orderPrice.currentDoubleNumbers.toString(reserve: 2))
  133. }
  134. }
  135. }
  136. }
  137. })
  138. }
  139. /// 隐藏
  140. orderView.isHidden = obj.trademode == .TRADEMODE_TRADEMODE_HSBY_SHOP
  141. /// 挂牌点选默认当日有效
  142. valid.isUserInteractionEnabled = obj.trademode != .TRADEMODE_LISTING_SELECT
  143. /// 小数位
  144. orderPrice.decimalPlace = obj.decimalplace
  145. /// 查询数据
  146. self.requestQueryHsbyGoodsOrderDetails(self.orderPrice.currentDoubleNumbers.toString(reserve: 2))
  147. }
  148. }
  149. /// 委托单数据
  150. var orderDetails: [MoHsbyGoodsOrderDetail] = [] {
  151. didSet {
  152. /// 刷新列表数据
  153. orderTableView.reloadData()
  154. /// 重新设置高度约束
  155. orderTableViewHeightConstraint.constant = CGFloat(orderDetails.count)*50.0
  156. /// 是否隐藏提示
  157. tips.isHidden = orderDetails.count != 0
  158. }
  159. }
  160. /// 我的闲置单据信息
  161. var sellMyDetails: [MoHsbySellMyDetail] = [] {
  162. didSet {
  163. /// 刷新列表数据
  164. tableView.reloadData()
  165. switch self.segmentedView.selectedIndex {
  166. case 0:
  167. /// 重新设置高度约束
  168. tableViewHeightConstraint.constant = CGFloat(sellMyDetails.count)*200.0
  169. default:
  170. /// 重新设置高度约束
  171. tableViewHeightConstraint.constant = CGFloat(sellMyDetails.count)*180.0
  172. }
  173. }
  174. }
  175. /// 委托数量
  176. var qty: Int = 0 {
  177. didSet { orderQty.currentIntNumbers = qty }
  178. }
  179. /// 有效期
  180. var validType: EValidType = .VALIDTYPE_DR {
  181. didSet {
  182. switch validType {
  183. case .VALIDTYPE_DR:
  184. self.valid.setTitle("当日有效", for: .normal)
  185. case .VALIDTYPE_YZ:
  186. self.valid.setTitle("一直有效", for: .normal)
  187. default:
  188. self.valid.setTitle("3天有效", for: .normal)
  189. }
  190. }
  191. }
  192. /// 交易日查询
  193. var run: MoMarketRun? {
  194. get {
  195. /// 结算计划
  196. return MTP2BusinessCore.shared.goodsManager?.marketRun
  197. }
  198. }
  199. // MARK: - 生命周期
  200. override func viewDidLoad() {
  201. super.viewDidLoad()
  202. // Do any additional setup after loading the view.e
  203. /// 数据初始化
  204. initData()
  205. }
  206. override func viewWillAppear(_ animated: Bool) {
  207. super.viewWillAppear(animated)
  208. /// 隐藏导航栏
  209. self.navigationController?.setNavigationBarHidden(false, animated: true)
  210. }
  211. deinit {
  212. /// 移出行情广播
  213. MTP2BusinessCore.shared.broadcastManager?.removeBroadcastListener(owner: self, forName: .ReceiveTradeQuote)
  214. }
  215. // MARK: - 初始化
  216. /// 数据初始化
  217. fileprivate func initData() {
  218. /// 默认查询我的闲置
  219. self.requestQueryHsbySellMyDetails(0)
  220. }
  221. // MARK: - 交互相关
  222. /// 按钮点击响应事件
  223. /// - Parameter sender: sender
  224. @IBAction fileprivate func onButtonPressed(_ sender: UIControl) {
  225. switch sender {
  226. case goods: /// 商品切换
  227. self.performSegue(withIdentifier: "ShowMyGoods", sender: nil)
  228. case submit:
  229. let isListing = !orderTableView.visibleCells.contains { (cell) -> Bool in
  230. return (cell as? TradeCell)?.isCheck ?? false
  231. }
  232. /// 有对手委托单得时候必须选一个
  233. if isListing, orderDetails.count != 0 {
  234. WHToast.showError(withMessage: "请选择买家", duration: 1.5, finishHandler: {})
  235. return
  236. }
  237. if isListing {
  238. /// 买挂牌
  239. doListingTrade()
  240. } else {
  241. /// 买摘牌
  242. doDeListingTrade()
  243. }
  244. case refresh: /// 刷新按钮
  245. let orderPrice = self.orderPrice.currentDoubleNumbers
  246. /// 更新单据
  247. self.requestQueryHsbyGoodsOrderDetails(orderPrice.toString(reserve: 2))
  248. case valid: /// 有效期
  249. let titles: [String] = ["当日有效", "3天有效", "一直有效"]
  250. self.showActionSheetController(title: "有效期", message: nil, cancelTitle: "取消", cancelBlock: {}, actionSheetTitles: titles) { (index, action) in
  251. switch index {
  252. case 0: /// 档期有效
  253. self.validType = EValidType.VALIDTYPE_DR
  254. case 1: /// 3天有效
  255. self.validType = EValidType.VALIDTYPE_ZDRQ
  256. if self.run == nil {
  257. /// 查询市场结算计划
  258. self.queryMarketRun()
  259. }
  260. default: /// 一直有效
  261. self.validType = EValidType.VALIDTYPE_YZ
  262. }
  263. }
  264. default:
  265. break
  266. }
  267. }
  268. // MARK: - 数据显示
  269. /// 显示商品数据信息
  270. /// - Parameter obj: obj
  271. func showGoodsInfo(_ myGoods: MoHsbyMyGoods?) {
  272. /// 异常
  273. guard let obj = myGoods else { return }
  274. if obj.trademode == .TRADEMODE_LISTING_SELECT {
  275. /// 获取商品
  276. guard let goodsInfo = MTP2BusinessCore.shared.goodsManager?.goodsInfos.first(where: {obj.goodsid == $0.goodsid}) else { return }
  277. /// 默认为一直有效
  278. self.validType = .VALIDTYPE_DR
  279. /// 步进值
  280. self.orderPrice.incrementDoubleNum = obj.stepvalue
  281. /// 小数位
  282. self.orderPrice.decimalPlace = obj.decimalplace
  283. /// 最小值
  284. self.orderPrice.minDoubleNum = obj.limitdown
  285. /// 最大值
  286. self.orderPrice.maxDoubleNum = obj.limitup
  287. /// 委托价格
  288. self.orderPrice.currentDoubleNumbers = goodsInfo.getLast()
  289. /// 最大可发布数量
  290. self.orderQty.maxIntNum = obj.buymaxqty == 0 ? obj.enableqty : min(obj.enableqty, obj.buymaxqty)
  291. /// 最小数量
  292. self.orderQty.minIntNum = obj.lotsize
  293. /// 当前数量
  294. self.orderQty.currentIntNumbers = obj.lotsize
  295. /// 下单递增数量
  296. self.orderQty.incrementIntNum = obj.lotsize
  297. /// 价格范围
  298. self.priceRange.text = "\(obj.limitdown) <= 价格范围 <= \(obj.limitup)"
  299. /// 可发不数量
  300. self.enableQty.text = "可发布数量 \(obj.enableqty)"
  301. /// 不允许操作
  302. self.orderPrice.isUserInteractionEnabled = true
  303. } else {
  304. /// 最大可发布数量
  305. self.orderQty.maxIntNum = obj.enableqty
  306. /// 不允许操作
  307. self.orderPrice.isUserInteractionEnabled = false
  308. /// 允许操作
  309. self.orderQty.isUserInteractionEnabled = true
  310. /// 最小数量
  311. self.orderQty.minIntNum = obj.lotsize
  312. /// 当前数量
  313. self.orderQty.currentIntNumbers = obj.lotsize
  314. /// 下单递增数量
  315. self.orderQty.incrementIntNum = obj.lotsize
  316. /// 默认为一直有效
  317. self.validType = .VALIDTYPE_YZ
  318. /// 小数位
  319. self.orderPrice.decimalPlace = obj.decimalplace
  320. /// 步进值
  321. self.orderPrice.incrementDoubleNum = obj.stepvalue
  322. ///  设置大小范围
  323. self.orderPrice.minDoubleNum = Double.zero
  324. /// 最大值
  325. self.orderPrice.maxDoubleNum = 10000000000.00
  326. /// 委托价格
  327. self.orderPrice.currentDoubleNumbers = obj.goodsprice
  328. }
  329. /// 商品名称
  330. self.goods.setTitle("\(obj.goodscode) \(obj.goodsname) ▸", for: .normal)
  331. /// 可发不数量
  332. self.enableQty.text = "可发布数量 \(obj.enableqty)"
  333. /// 隐藏
  334. self.priceRange.isHidden = obj.trademode != .TRADEMODE_LISTING_SELECT
  335. }
  336. // MARK: - 接口请求
  337. /// 买挂牌提交请求方法
  338. fileprivate func doListingTrade() {
  339. /// 异常
  340. guard let obj = myGoods,
  341. let tradeManager = MTP2BusinessCore.shared.tradeManager,
  342. check() else { return }
  343. /// 构建交易参数
  344. let tradeParam = MoTradeParam()
  345. /// 买卖方向
  346. tradeParam.buyOrSell = .ORDERDIRECTION_SELL
  347. /// 数量
  348. tradeParam.orderQty = Double(orderQty.currentIntNumbers)
  349. /// 挂牌价格
  350. tradeParam.orderPrice = orderPrice.currentDoubleNumbers
  351. /// 挂牌点选类型
  352. tradeParam.delistingType = .DELISTINGTYPE_SELECTED
  353. /// 点选成交
  354. tradeParam.listingSelectType = .LISTINGSELECTTYPE_LISTING
  355. /// 有效类型
  356. tradeParam.validType = self.validType
  357. /// 下单类型
  358. tradeParam.buildType = .BUILDTYPE_CLOSE
  359. /// 时间有效类型
  360. tradeParam.timevalidType = self.validType
  361. /// 市场编号
  362. tradeParam.marketID = obj.marketid
  363. /// 商品ID
  364. tradeParam.goodsID = obj.goodsid
  365. /// 指定时间
  366. if tradeParam.validType == .VALIDTYPE_ZDRQ,
  367. let tradeDate = self.run?.tradedate {
  368. tradeParam.validTime = ((tradeDate.toDate(formatter: "yyyyMMdd") ?? Date())+3.days).getString(formatter: "yyyy-MM-dd 00:00:00")
  369. }
  370. /// 开启Loading
  371. NVActivityIndicatorPresenter.sharedInstance.startAnimating(ActivityData(message: "发布中......", type: .ballClipRotate, color: UIColor.loding(), backgroundColor: .clear), NVActivityIndicatorView.DEFAULT_FADE_IN_ANIMATION)
  372. /// 发送请求
  373. tradeManager.tradeCommision(tradeParam: tradeParam) { [weak self] (isSuccess, error, orderNo) in
  374. DispatchQueue.main.async {
  375. /// dismisss loding.....
  376. NVActivityIndicatorPresenter.sharedInstance.stopAnimating(NVActivityIndicatorView.DEFAULT_FADE_OUT_ANIMATION)
  377. if isSuccess {
  378. /// 返回上次视图
  379. WHToast.showSuccess(withMessage: "发布请求成功", duration: 1.5) {
  380. self?.navigationController?.popViewController(animated: true)
  381. }
  382. } else {
  383. WHToast.showError(withMessage: "发布请求失败,\(ErrorUtils.getDesc(errorCode: error?.retCode ?? -99999) ?? "未知错误")", duration: 1.5, finishHandler: {})
  384. }
  385. }
  386. }
  387. }
  388. /// 买摘牌提交请求方法
  389. fileprivate func doDeListingTrade() {
  390. /// 异常
  391. guard let obj = myGoods,
  392. let tradeManager = MTP2BusinessCore.shared.tradeManager,
  393. check() else { return }
  394. /// 构建交易参数
  395. let tradeParam = MoTradeParam()
  396. /// 买卖方向
  397. tradeParam.buyOrSell = .ORDERDIRECTION_SELL
  398. /// 挂牌点选类型
  399. tradeParam.delistingType = .DELISTINGTYPE_SELECTED
  400. /// 点选成交
  401. tradeParam.listingSelectType = .LISTINGSELECTTYPE_DELISTING
  402. /// 有效类型
  403. tradeParam.validType = self.validType
  404. /// 下单类型
  405. tradeParam.buildType = .BUILDTYPE_CLOSE
  406. /// 时间有效类型
  407. tradeParam.timevalidType = self.validType
  408. /// 市场编号
  409. tradeParam.marketID = obj.marketid
  410. /// 商品ID
  411. tradeParam.goodsID = obj.goodsid
  412. /// 指定时间
  413. if tradeParam.validType == .VALIDTYPE_ZDRQ,
  414. let tradeDate = self.run?.tradedate {
  415. tradeParam.validTime = ((tradeDate.toDate(formatter: "yyyyMMdd") ?? Date())+3.days).getString(formatter: "yyyy-MM-dd 00:00:00")
  416. }
  417. /// 开启Loading
  418. NVActivityIndicatorPresenter.sharedInstance.startAnimating(ActivityData(message: "发布中......", type: .ballClipRotate, color: UIColor.loding(), backgroundColor: .clear), NVActivityIndicatorView.DEFAULT_FADE_IN_ANIMATION)
  419. let group = DispatchGroup()
  420. /// 数据构建
  421. for cell in orderTableView.visibleCells {
  422. if let cell = cell as? TradeCell, cell.isCheck {
  423. /// 挂牌价格
  424. tradeParam.orderPrice = cell.model?.orderprice ?? 0.0
  425. /// 关联单号
  426. tradeParam.relatedID = UInt64(cell.model?.orderid ?? "0") ?? 0
  427. /// 数量
  428. tradeParam.orderQty = Double(cell.qtyField.currentIntNumbers)
  429. group.enter()
  430. tradeManager.tradeCommision(tradeParam: tradeParam) { (isSuccess, error, orderNo) in
  431. group.leave()
  432. }
  433. }
  434. }
  435. group.notify(queue: DispatchQueue.main) {
  436. /// dismisss loding.....
  437. NVActivityIndicatorPresenter.sharedInstance.stopAnimating(NVActivityIndicatorView.DEFAULT_FADE_OUT_ANIMATION)
  438. WHToast.showSuccess(withMessage: "委托成功,请刷新后查看!", duration: 1.5, finishHandler: {
  439. self.navigationController?.popViewController(animated: true)
  440. })
  441. }
  442. }
  443. /// 查询商品对应委托单的数据信息
  444. /// - Parameter price: 价格
  445. fileprivate func requestQueryHsbyGoodsOrderDetails(_ price: String?) {
  446. /// 异常
  447. guard let orderManager = MTP2BusinessCore.shared.orderManager,
  448. let obj = myGoods else { return }
  449. /// startAnimating
  450. self._anim?.startAnimating()
  451. /// 发送请求
  452. orderManager.requestQueryHsbyGoodsOrderDetails(obj.goodsid,
  453. buyOrSell: .ORDERDIRECTION_BUY,
  454. price,
  455. 3) { (isComplete, error, orderDetails) in
  456. DispatchQueue.main.async {
  457. /// stopAnimating
  458. self._anim?.stopAnimating()
  459. if isComplete {
  460. /// 更新数据
  461. self.orderDetails = orderDetails ?? []
  462. } else {
  463. self.orderDetails = []
  464. WHToast.showError(withMessage: "数据更新失败,原因:\(error?.retMsg ?? "未知错误")", duration: 1.5, finishHandler: {})
  465. }
  466. }
  467. }
  468. }
  469. /// 查询交易日时间
  470. fileprivate func queryMarketRun() {
  471. /// 异常
  472. guard let goodsManger = MTP2BusinessCore.shared.goodsManager,
  473. let obj = myGoods else { return }
  474. /// startAnimating
  475. self._anim?.startAnimating()
  476. /// 获取交易日时间
  477. goodsManger.requestQueryMarketRun(obj.marketid) { (isComplete, error, marketRun) in }
  478. }
  479. /// 查询"我的闲置"单据信息
  480. /// - Parameter orderType: 单据类型:0 - 已发布(默认), 1 - 已完成
  481. fileprivate func requestQueryHsbySellMyDetails(_ orderType: Int) {
  482. /// 异常
  483. guard let orderManager = MTP2BusinessCore.shared.orderManager else { return }
  484. /// startAnimating
  485. self._anim?.startAnimating()
  486. /// 发送请求
  487. orderManager.requestQueryHsbySellMyDetails(orderType, callback: { (isComplete, error, sellMyDetails) in
  488. DispatchQueue.main.async {
  489. /// stopAnimating
  490. self._anim?.stopAnimating()
  491. if isComplete {
  492. /// 更新数据
  493. self.sellMyDetails = sellMyDetails ?? []
  494. } else {
  495. self.sellMyDetails = []
  496. WHToast.showError(withMessage: "数据更新失败,原因:\(error?.retMsg ?? "未知错误")", duration: 1.5, finishHandler: {})
  497. }
  498. }
  499. })
  500. }
  501. /// 获取待收款单据数据信息
  502. fileprivate func requestQueryMyCollectionOrders() {
  503. /// 数据异常
  504. guard let orderManager = MTP2BusinessCore.shared.orderManager else { return }
  505. /// startAnimating
  506. _anim?.startAnimating()
  507. /// 发送请求
  508. orderManager.requestQueryMyCollectionOrders(callback: { (isComplete, error, collectionOrders) in
  509. DispatchQueue.main.async {
  510. /// stopAnimating
  511. self._anim?.stopAnimating()
  512. /// 单据数据信息
  513. self.sellMyDetails = collectionOrders ?? []
  514. if !isComplete {
  515. WHToast.showError(withMessage: "待付款单据数据信息查询失败,请稍候再试!", duration: 1.5, finishHandler: {})
  516. }
  517. }
  518. })
  519. }
  520. /// 撤单
  521. ///
  522. /// - Parameter orderId: 单号
  523. /// - Parameter accountId: accountId
  524. /// - Parameter goodsID: goodsID
  525. /// - Parameter marketID: marketID
  526. fileprivate func cancelOrder(_ orderId: String?, _ accountId: Int64?, _ goodsID: String?, _ marketID: Int?) {
  527. /// 数据异常
  528. guard let tradeManager = MTP2BusinessCore.shared.tradeManager else { return }
  529. /// alert
  530. showCommitAlertController(title: "提示", message: "确定要撤单吗?"){(_) in
  531. /// startAnimating
  532. self._anim?.startAnimating()
  533. /// 构建数据
  534. let cancelOrderData = CancelOrderData(oldOrderId: orderId ?? "", accountId: accountId ?? 0, goodsID: goodsID ?? "", marketID: marketID ?? 0, operateType: .OPERATETYPE_ORDERCANCEL)
  535. /// 发送撤单请求
  536. tradeManager.cancelOrder(cancelorderData: cancelOrderData, callback: { (isCompleted, errorInfo) in
  537. DispatchQueue.main.async {
  538. /// stopAnimating
  539. self._anim?.stopAnimating()
  540. if isCompleted {
  541. WHToast.showSuccess(withMessage: "撤销成功", duration: 1.5, finishHandler: {
  542. if self.segmentedView.selectedIndex == 1 {
  543. /// 待付款
  544. self.requestQueryMyCollectionOrders()
  545. } else {
  546. /// 查询数据信息
  547. self.requestQueryHsbySellMyDetails(self.segmentedView.selectedIndex)
  548. }
  549. })
  550. } else {
  551. WHToast.showError(withMessage: "撤单失败,原因:\(ErrorUtils.getDesc(errorCode: errorInfo?.retCode ?? -60001) ?? "未知错误")", duration: 1.5, finishHandler: {})
  552. }
  553. }
  554. })
  555. }
  556. }
  557. /// 合规性校验
  558. /// - Returns: Bool
  559. fileprivate func check() -> Bool {
  560. /// 请选择商品
  561. guard let obj = myGoods else {
  562. WHToast.showError(withMessage: "请选择商品", duration: 1.5, finishHandler: {})
  563. return false
  564. }
  565. /// 请输入委托价格
  566. guard orderPrice.currentDoubleNumbers != 0.0 else {
  567. WHToast.showError(withMessage: "请输入委托价格", duration: 1.5, finishHandler: {})
  568. return false
  569. }
  570. /// 挂牌点选
  571. if obj.trademode == .TRADEMODE_LISTING_SELECT {
  572. /// 委托价格不在范围内
  573. if orderPrice.currentDoubleNumbers < (obj.limitdown) || (orderPrice.currentDoubleNumbers > obj.limitup) {
  574. WHToast.showError(withMessage: "\(obj.limitdown)<=委托价格<=\(obj.limitup)", duration: 1.5, finishHandler: {})
  575. return false
  576. }
  577. }
  578. /// 请输入交易数量
  579. if orderQty.currentIntNumbers == 0 {
  580. WHToast.showError(withMessage: "请输入交易数量", duration: 1.5, finishHandler: {})
  581. return false
  582. }
  583. /// 发布数量不能大于可发布数量
  584. if orderQty.currentIntNumbers>orderQty.maxIntNum {
  585. WHToast.showError(withMessage: "发布数量应小于等于\(orderQty.maxIntNum)!", duration: 1.5, finishHandler: {})
  586. return false
  587. }
  588. return true
  589. }
  590. // MARK: - 订阅行情相关
  591. var uuid: String = UUID().uuidString
  592. /// 行情订阅
  593. private func subscriptQuote() {
  594. var goodsCodes = Set<String>()
  595. if let goods = self.myGoods {
  596. goodsCodes = [goods.goodscode]
  597. }
  598. guard let quoteSubscriptManager = MTP2BusinessCore.shared.quoteSubscriptManager else { return }
  599. quoteSubscriptManager.updateQuoteSubcriptGoods(uuid: uuid, goodsCode: goodsCodes)
  600. }
  601. // MARK: - Navigation
  602. // In a storyboard-based application, you will often want to do a little preparation before navigation
  603. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  604. // Get the new view controller using segue.destination.
  605. // Pass the selected object to the new view controller.
  606. if segue.identifier == "ShowMyGoods" {
  607. (segue.destination as? MyGoodsViewController)?.block = { (_ model: MoHsbyMyGoods?) in
  608. /// 执行回调后
  609. self.myGoods = model
  610. }
  611. } else if segue.identifier == "ShowMyUnusedDetail" { /// 我的闲置详情
  612. (segue.destination as? MyUnusedDetailViewController)?.takeInfo = (sender as? OrderCell)?.model
  613. }
  614. }
  615. }
  616. // MARK: - JXSegmentedViewDelegate
  617. extension MyUnusedViewController: JXSegmentedViewDelegate {
  618. func segmentedView(_ segmentedView: JXSegmentedView, didSelectedItemAt index: Int) {
  619. if index == 1 {
  620. /// 待付款
  621. self.requestQueryMyCollectionOrders()
  622. } else {
  623. /// 查询我的闲置单据数据
  624. self.requestQueryHsbySellMyDetails(index)
  625. }
  626. }
  627. }
  628. // MARK: - IBNumberEditTextDelegate
  629. extension MyUnusedViewController: IBNumberEditTextDelegate {
  630. func numberInputViewDidEndEditing(_ numberInputView: IBNumberEditText) {
  631. if numberInputView == orderPrice {
  632. let orderPrice = numberInputView.currentDoubleNumbers
  633. /// 更新单据
  634. self.requestQueryHsbyGoodsOrderDetails(orderPrice.toString(reserve: 2))
  635. } else {
  636. /// 如果大于最大数量 默认设置最大数量
  637. if numberInputView.currentIntNumbers > numberInputView.maxIntNum {
  638. numberInputView.currentIntNumbers = numberInputView.maxIntNum
  639. }
  640. }
  641. }
  642. func numberInputView(_ numberInputView: IBNumberEditText, _ buttonType: NumberInputViewButtonType) {
  643. if numberInputView == orderPrice {
  644. let orderPrice = numberInputView.currentDoubleNumbers
  645. /// 更新单据
  646. self.requestQueryHsbyGoodsOrderDetails(orderPrice.toString(reserve: 2))
  647. } else {
  648. /// 如果大于最大数量 默认设置最大数量
  649. if numberInputView.currentIntNumbers > numberInputView.maxIntNum {
  650. numberInputView.currentIntNumbers = numberInputView.maxIntNum
  651. }
  652. }
  653. }
  654. func IBNumberEditText(textField: UITextField) {}
  655. }
  656. class OrderDelegate: NSCoder, UITableViewDelegate, UITableViewDataSource {
  657. let owner: MyUnusedViewController
  658. init(_ owner: MyUnusedViewController) {
  659. self.owner = owner
  660. }
  661. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  662. return self.owner.orderDetails.count
  663. }
  664. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  665. let cell = tableView.dequeueReusableCell(withIdentifier: owner.OrderCellIdentifier, for: indexPath) as! TradeCell
  666. cell.model = self.owner.orderDetails[indexPath.row]
  667. cell.isCheck = false
  668. cell.block = { (_ model: MoHsbyGoodsOrderDetail?, _ isCheck: Bool, _ qty: Int) in
  669. /// 设置数量
  670. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.2) {
  671. var qty: Int = 0
  672. self.owner.orderTableView.visibleCells.forEach { (cell) in
  673. if (cell as! TradeCell).isCheck {
  674. qty += (cell as! TradeCell).qtyField.currentIntNumbers
  675. }
  676. }
  677. self.owner.qty = qty
  678. /// 输入框是否可用
  679. self.owner.orderQty.isUserInteractionEnabled = !self.owner.orderTableView.visibleCells.contains(where: { (cell) -> Bool in
  680. return (cell as! TradeCell).isCheck
  681. })
  682. }
  683. }
  684. return cell
  685. }
  686. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  687. return 50.0
  688. }
  689. }
  690. // MARK: - UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
  691. class MyUnusedDelegate: NSCoder, UITableViewDelegate, UITableViewDataSource {
  692. let owner: MyUnusedViewController
  693. init(_ owner: MyUnusedViewController) {
  694. self.owner = owner
  695. }
  696. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  697. return owner.sellMyDetails.count
  698. }
  699. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  700. let cell = tableView.dequeueReusableCell(withIdentifier: owner.CellIdentifier, for: indexPath) as! SellMyDetailCell
  701. cell.model = owner.sellMyDetails[indexPath.row]
  702. cell.cancelBlock = { (_ orderId: String?, _ accountId: Int64?, _ goodsID: String?, _ marketID: Int?) in
  703. /// 撤销
  704. self.owner.cancelOrder(orderId, accountId, goodsID, marketID)
  705. }
  706. return cell
  707. }
  708. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  709. /// 待付款
  710. if self.owner.segmentedView.selectedIndex == 1 {
  711. return 180.0
  712. } else {
  713. return owner.sellMyDetails[indexPath.row].ordertype == 1 ? 180.0 : 200.0
  714. }
  715. }
  716. }
  717. // MARK: - OrderCell
  718. class SellMyDetailCell: BaseTableViewCell<MoHsbySellMyDetail> {
  719. /// 供应商名称
  720. @IBOutlet weak var company: UILabel!
  721. /// 状态
  722. @IBOutlet weak var status: UILabel!
  723. /// 单号
  724. @IBOutlet weak var orderNo: UILabel!
  725. /// 商品图片
  726. @IBOutlet weak var goodsImage: UIImageView!
  727. /// 价格
  728. @IBOutlet weak var price: UILabel!
  729. /// 标题
  730. @IBOutlet weak var title: UILabel!
  731. /// 数量
  732. @IBOutlet weak var qty: UILabel!
  733. /// 金额
  734. @IBOutlet weak var amount: UILabel!
  735. /// 待付款金额
  736. @IBOutlet weak var payamount: UILabel!
  737. /// 撤销
  738. @IBOutlet weak var cancel: IBButton!
  739. /// 撤销
  740. @IBOutlet weak var stackView: UIStackView!
  741. /// 数据
  742. override var model: MoHsbySellMyDetail? {
  743. didSet {
  744. /// 数据异常
  745. guard let obj = model else { return }
  746. if let collectionOrder = model as? MoMyCollectionOrders {
  747. /// 隐藏付款金额
  748. payamount.isHidden = false
  749. /// 隐藏金额
  750. amount.isHidden = true
  751. /// 金额详情
  752. payamount.text = "总价:\(collectionOrder.tradeamount.toDownString(reserve: obj.decimalplace)) 优惠:\(collectionOrder.offamount.toDownString(reserve: obj.decimalplace)) 实付款:\(collectionOrder.payamount.toDownString(reserve: obj.decimalplace))"
  753. /// 数量
  754. qty.text = obj.tradeqty.description
  755. /// 等待对方付款
  756. status.text = "等待对方付款"
  757. /// 只有已发布的商品才可以撤销单据
  758. stackView.isHidden = true
  759. } else {
  760. /// 隐藏付款金额
  761. payamount.isHidden = true
  762. /// 待付款数量
  763. amount.text = "金额:\(obj.currencysign) \((Double(obj.qty-obj.cancelqty-obj.tradeqty)*obj.price*obj.agreeunit).toDownString(reserve: obj.decimalplace))"
  764. /// 状态
  765. if obj.buyorsell == EOrderDirection.ORDERDIRECTION_BUY {
  766. /// 已完成
  767. status.text = "已完成"
  768. /// 只有已发布的商品才可以撤销单据
  769. stackView.isHidden = true
  770. } else {
  771. status.text = obj.ordertype == 0 ? "已发布" : "已完成"
  772. /// 只有已发布的商品才可以撤销单据
  773. stackView.isHidden = !(obj.ordertype == 0)
  774. }
  775. /// 数量
  776. qty.text = obj.qty.description
  777. }
  778. /// 单号
  779. orderNo.text = obj.goodscode
  780. /// 商品名称
  781. title.text = obj.goodsname
  782. /// 价格
  783. price.text = "\(obj.currencysign) \(obj.price.toDownString(reserve: obj.decimalplace))"
  784. /// 商品图片
  785. guard let url = StringUtils.getImageUrl(obj.picurls) else { return }
  786. goodsImage.sd_setImage(with: url, placeholderImage: UIImage(named: "placeholder_image"), options: .queryDiskDataSync, context: nil)
  787. /// 我的闲置显示的是委托时间
  788. company.text = DateUtils.getTDateString(obj.time, "yyyy-MM-dd HH:mm:ss")
  789. }
  790. }
  791. /// 撤销回调块
  792. var cancelBlock: ((_ orderId: String?, _ accountId: Int64?, _ goodsID: String?, _ marketID: Int?) -> Void)?
  793. /// 支付回调块
  794. var payBlock: ((_ orderId: String?, _ accountId: Int64?, _ goodsID: String?, _ marketID: Int?, _ amount: Double) -> Void)?
  795. /// 按钮点击响应事件
  796. /// - Parameter sender: sender
  797. @IBAction private func onButtonPressed(_ sender: IBButton) {
  798. switch sender {
  799. case cancel: /// 撤销
  800. if let cancel = cancelBlock { cancel(model?.orderid, model?.accountid ?? 0, model?.goodsid.description, model?.marketid) }
  801. default: break
  802. }
  803. }
  804. }