| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569 |
- //
- // TradeViewController.swift
- // MTP2_iOS
- //
- // Created by Handy_Cao on 2020/10/29.
- // Copyright © 2020 Muchinfo. All rights reserved.
- //
- import UIKit
- import SDWebImage
- import NVActivityIndicatorView
- import WHToast
- /// 购买视图容器控制类
- class TradeViewController: BaseViewController {
-
- // MARK: - 属性列表
- /// 公司名称
- @IBOutlet weak var company: UILabel!
- /// 标题
- @IBOutlet weak var goodsName: UILabel!
- /// 商品图片
- @IBOutlet weak var goodsImage: UIImageView!
- /// 单号
- @IBOutlet weak var orderNo: UILabel!
- /// 资金提示信息
- @IBOutlet weak var amountTips: UILabel!
- /// 提示信息
- @IBOutlet weak var tips: UILabel!
- /// 金额范围
- @IBOutlet weak var priceRange: UILabel!
- /// 价格
- @IBOutlet weak var price: UILabel!
- /// 购买价格
- @IBOutlet weak var priceField: IBNumberEditText! {
- didSet {
- priceField.valueType = 2
- priceField.delegate = self
- }
- }
- /// 购买数量
- @IBOutlet weak var qtyField: IBNumberEditText! {
- didSet {
- qtyField.valueType = 1
- qtyField.delegate = self
- }
- }
- /// 卖家列表
- @IBOutlet weak var tableView: UITableView!
- /// 高度
- @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!
- /// 提交
- @IBOutlet weak var submit: UIButton!
- /// 提交
- @IBOutlet weak var refresh: UIButton!
-
- /// CellIdentifier
- let CellIdentifier = "Trade_Cell"
- /// 商品数据
- override var takeInfo: Any? {
- didSet {
- guard let obj = takeInfo as? MoGoodsInfo else { return }
- DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.5) {
- /// 显示商品详情数据信息
- self.showGoodsDetailInfo(obj)
- /// 行情订阅
- self.subscriptQuote()
- }
- }
- }
- /// 卖家挂牌委托单数据
- var orderDetails: [MoHsbyGoodsOrderDetail] = [] {
- didSet {
- /// 刷新列表数据
- self.tableView.reloadData()
- /// 重新设置高度约束
- self.tableViewHeightConstraint.constant = CGFloat(orderDetails.count)*50.0
- /// 是否隐藏提示
- self.tips.isHidden = orderDetails.count != 0
- /// setTitle
- self.submit.setTitle(orderDetails.count == 0 ? "发布求购" : "提交订单", for: .normal)
- /// orderTips
- orderTips.isHidden = orderDetails.count == 0
- }
- }
- /// 提示信息
- @IBOutlet weak var orderTips: UILabel!
- /// 委托数量
- var orderQty: Int = 0 {
- didSet {
- qtyField.currentIntNumbers = orderQty
- /// 计算购买金额
- self.calculate()
- }
- }
- // MARK: - 生命周期相关
- override func viewDidLoad() {
- super.viewDidLoad()
- // Do any additional setup after loading the view.
- /// UI界面初始化
- buildView()
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
- /// 隐藏导航栏
- self.navigationController?.setNavigationBarHidden(false, animated: true)
-
- /// 侦听行情推送广播
- MTP2BusinessCore.shared.broadcastManager?.addBroadcastListener(owner: self, action: .ReceiveTradeQuote) { [unowned self] in
- /// 异常情况
- guard let goodsQuoteInfo = $0.object as? [(goodsHqCode: String, exchHqCode: String)],
- goodsQuoteInfo.count != 0,
- let goodsManager = MTP2BusinessCore.shared.goodsManager,
- let goods = self.takeInfo as? MoGoodsInfo else { return }
- /// 更新商品行情信息
- goodsQuoteInfo.forEach {
- if $0.goodsHqCode == goods.goodscode {
- DispatchQueue.main.async {
- /// 更新价格
- self.price.text = "\(goods.currencysign)"+(goodsManager.goodsInfos.first(where: {$0.goodsid == (takeInfo as? MoGoodsInfo)?.goodsid})?.getLast().toDownString(reserve: goods.decimalplace) ?? "")
- /// 当前价格
- self.priceField.currentDoubleNumbers = goodsManager.goodsInfos.first(where: {$0.goodsid == (takeInfo as? MoGoodsInfo)?.goodsid})?.getLast() ?? 0.0
- }
- }
- }
- }
- }
-
- deinit {
- /// 移出行情广播
- MTP2BusinessCore.shared.broadcastManager?.removeBroadcastListener(owner: self, forName: .ReceiveTradeQuote)
- }
-
- // MARK: - 数据初始化
- /// UI界面初始化
- fileprivate func buildView() {
- /// addLoadingView
- self.addLoadingView()
- }
-
- /// 显示商品详情数据信息
- /// - Parameter obj: obj
- fileprivate func showGoodsDetailInfo(_ obj: MoGoodsInfo) {
- /// 异常
- guard let accountManager = MTP2BusinessCore.shared.accountManager else { return }
- /// 商品名称
- self.goodsName.text = obj.goodsname
- /// 商品代码
- self.orderNo.text = obj.goodscode
- /// 商品价格
- self.price.text = "\(obj.currencysign) \(obj.getLast() == 0.0 ? obj.last : obj.getLast())"
- /// 价格范围
- priceRange.text = "\(obj.limitdown)<= 价格范围 <= \(obj.limitup)"
- /// 供应商名称
- company.text = obj.vendorname
- /// 输入框价格
- priceField.incrementDoubleNum = obj.stepvalue
- priceField.minDoubleNum = obj.limitdown
- priceField.maxDoubleNum = obj.limitup
- priceField.decimalPlace = obj.decimalplace
- priceField.currentDoubleNumbers = obj.last
- /// 查询对手买家挂牌信息
- self.requestQueryHsbyGoodsOrderDetails(obj.last.toString(reserve: 2))
-
- /// 输入步进值
- qtyField.incrementIntNum = obj.lotsize
- qtyField.minIntNum = obj.lotsize
- qtyField.currentIntNumbers = obj.lotsize
- qtyField.maxIntNum = obj.buymaxqty == 0 ? Int.max : obj.buymaxqty
- /// 查询资金信息
- accountManager.loginQueryReq(queryItem: "1,2") { (isComplete, error) in
- DispatchQueue.main.async {
- /// 计算购买金额
- self.calculate()
- }
- }
- /// 商品图片
- guard let url = StringUtils.getImageUrl(obj.picurls) else { return }
- goodsImage.sd_setImage(with: url, placeholderImage: UIImage(named: "placeholder_image"), options: .queryDiskDataSync, context: nil)
- }
-
- // MARK: - 交互相关
- /// UITextField输入值发生改变响应事件
- /// - Parameter sender: sender
- @IBAction func onValueChanged(_ sender: UITextField) {
-
- }
-
- /// onButtonPressed
- /// - Parameter sender: sender
- @IBAction fileprivate func onButtonPressed(_ sender: UIControl) {
- switch sender {
- case submit:
- let isListing = !tableView.visibleCells.contains { (cell) -> Bool in
- return (cell as? TradeCell)?.isCheck ?? false
- }
- /// 有对手委托单得时候必须选一个
- if isListing, orderDetails.count != 0 {
- WHToast.showError(withMessage: "请选择卖家", duration: 1.5, finishHandler: {})
- return
- }
- if isListing {
- /// 买挂牌
- doListingTrade()
- } else {
- /// 买摘牌
- doDeListingTrade()
- }
- case refresh: /// 刷新按钮
- /// 更新单据
- self.requestQueryHsbyGoodsOrderDetails(priceField.currentDoubleNumbers.toString(reserve: 2))
- default:
- break
- }
- }
- // MARK: - 接口请求
- /// 买挂牌提交请求方法
- fileprivate func doListingTrade() {
- /// 异常
- guard let tradeManager = MTP2BusinessCore.shared.tradeManager,
- let obj = takeInfo as? MoGoodsInfo,
- check() else { return }
-
- /// 构建交易参数
- let tradeParam = MoTradeParam()
- /// 买卖方向
- tradeParam.buyOrSell = .ORDERDIRECTION_BUY
- /// 数量
- tradeParam.orderQty = Double(qtyField.currentIntNumbers)
- /// 挂牌价格
- tradeParam.orderPrice = priceField.currentDoubleNumbers
- /// 挂牌点选类型
- tradeParam.delistingType = .DELISTINGTYPE_SELECTED
- /// 点选成交
- tradeParam.listingSelectType = .LISTINGSELECTTYPE_LISTING
- /// 有效类型
- tradeParam.validType = .VALIDTYPE_DR
- /// 下单类型
- tradeParam.buildType = .BUILDTYPE_OPEN
- /// 时间有效类型
- tradeParam.timevalidType = .VALIDTYPE_DR
- /// 市场编号
- tradeParam.marketID = obj.marketid
- /// 商品ID
- tradeParam.goodsID = obj.goodsid
-
- /// 开启Loading
- NVActivityIndicatorPresenter.sharedInstance.startAnimating(ActivityData(message: "购买中......".localized, type: .ballClipRotate, color: UIColor.loding(), backgroundColor: .clear), NVActivityIndicatorView.DEFAULT_FADE_IN_ANIMATION)
-
- tradeManager.tradeCommision(tradeParam: tradeParam) { [weak self] (isSuccess, error, orderNo) in
- DispatchQueue.main.async {
-
- /// dismisss loding.....
- NVActivityIndicatorPresenter.sharedInstance.stopAnimating(NVActivityIndicatorView.DEFAULT_FADE_OUT_ANIMATION)
-
- if isSuccess {
- /// 返回上次视图
- WHToast.showSuccess(withMessage: "请求成功", duration: 1.5) {
- self?.navigationController?.popViewController(animated: true)
- }
- } else {
- WHToast.showError(withMessage: "请求失败,\(ErrorUtils.getDesc(errorCode: error?.retCode ?? -99999) ?? "未知错误")", duration: 1.5, finishHandler: {})
- }
- }
- }
- }
-
- /// 买摘牌提交请求方法
- fileprivate func doDeListingTrade() {
- /// 异常
- guard let tradeManager = MTP2BusinessCore.shared.tradeManager,
- let obj = takeInfo as? MoGoodsInfo,
- check() else { return }
-
- let group = DispatchGroup()
-
- /// 开启Loading
- NVActivityIndicatorPresenter.sharedInstance.startAnimating(ActivityData(message: "购买中......".localized, type: .ballClipRotate, color: UIColor.loding(), backgroundColor: .clear), NVActivityIndicatorView.DEFAULT_FADE_IN_ANIMATION)
-
- /// 构建交易参数
- let tradeParam = MoTradeParam()
- /// 买卖方向
- tradeParam.buyOrSell = .ORDERDIRECTION_BUY
- /// 挂牌点选类型
- tradeParam.delistingType = .DELISTINGTYPE_SELECTED
- /// 点选成交
- tradeParam.listingSelectType = .LISTINGSELECTTYPE_DELISTING
- /// 有效类型
- tradeParam.validType = .VALIDTYPE_DR
- /// 下单类型
- tradeParam.buildType = .BUILDTYPE_OPEN
- /// 时间有效类型
- tradeParam.timevalidType = .VALIDTYPE_DR
- /// 市场编号
- tradeParam.marketID = obj.marketid
- /// 商品ID
- tradeParam.goodsID = obj.goodsid
-
- for cell in tableView.visibleCells {
- if let cell = cell as? TradeCell, cell.isCheck {
- /// 挂牌价格
- tradeParam.orderPrice = cell.model?.orderprice ?? 0.0
- /// 关联单号
- tradeParam.relatedID = UInt64(cell.model?.orderid ?? "0") ?? 0
- /// 数量
- tradeParam.orderQty = Double(cell.qtyField.currentIntNumbers)
- group.enter()
- tradeManager.tradeCommision(tradeParam: tradeParam) { (isSuccess, error, orderNo) in
- group.leave()
- }
- }
- }
-
- group.notify(queue: DispatchQueue.main) {
- /// dismisss loding.....
- NVActivityIndicatorPresenter.sharedInstance.stopAnimating(NVActivityIndicatorView.DEFAULT_FADE_OUT_ANIMATION)
- WHToast.showSuccess(withMessage: "委托已提交,请前往我的单据页面查看!", duration: 1.5, finishHandler: {
- self.navigationController?.popViewController(animated: true)
- })
- }
- }
-
- /// 查询商品对应委托单的数据信息
- /// - Parameter price: 价格
- fileprivate func requestQueryHsbyGoodsOrderDetails(_ price: String?) {
- /// 异常
- guard let orderManager = MTP2BusinessCore.shared.orderManager,
- let obj = takeInfo as? MoGoodsInfo else { return }
-
- /// startAnimating
- self._anim?.startAnimating()
- /// 发送请求
- orderManager.requestQueryHsbyGoodsOrderDetails(obj.goodsid, price) { (isComplete, error, orderDetails) in
- DispatchQueue.main.async {
- /// stopAnimating
- self._anim?.stopAnimating()
- if isComplete {
- /// 更新数据
- self.orderDetails = orderDetails ?? []
- } else {
- self.orderDetails = []
- WHToast.showError(withMessage: "数据更新失败,原因:\(error?.retMsg ?? "未知错误")", duration: 1.5, finishHandler: {})
- }
- }
- }
- }
-
- /// 合规性校验
- /// - Returns: Bool
- fileprivate func check() -> Bool {
-
- /// 请输入委托价格
- guard priceField.currentDoubleNumbers != 0.0 else {
- WHToast.showError(withMessage: "请输入委托价格", duration: 1.5, finishHandler: {})
- return false
- }
-
- /// 委托价格不在范围内
- let detail = takeInfo as? MoGoodsInfo
- if priceField.currentDoubleNumbers < (detail?.limitdown ?? 0.0) || (priceField.currentDoubleNumbers > detail?.limitup ?? 0.0) {
- WHToast.showError(withMessage: "\(detail?.limitdown ?? 0.0)<=委托价格<=\(detail?.limitup ?? 0.0)", duration: 1.5, finishHandler: {})
- return false
- }
-
- /// 请输入交易数量
- if qtyField.currentIntNumbers == 0 {
- WHToast.showError(withMessage: "请输入交易数量", duration: 1.5, finishHandler: {})
- return false
- }
-
- /// 委托数量不能大于
- if qtyField.currentIntNumbers > qtyField.maxIntNum {
- WHToast.showError(withMessage: "交易数量应小于等于\(qtyField.maxIntNum)", duration: 1.5, finishHandler: {})
- return false
- }
-
- return true
- }
-
- // MARK: - 订阅行情相关
- var uuid: String = UUID().uuidString
- /// 行情订阅
- private func subscriptQuote() {
- var goodsCodes = Set<String>()
- if let goods = self.takeInfo as? MoGoodsInfo {
- goodsCodes.insert(goods.goodscode)
- }
- guard let quoteSubscriptManager = MTP2BusinessCore.shared.quoteSubscriptManager else { return }
- quoteSubscriptManager.updateQuoteSubcriptGoods(uuid: uuid, goodsCode: goodsCodes)
- }
-
- // MARK: - 计算相关
- /// 计算相关
- fileprivate func calculate() {
- /// 异常
- guard let obj = takeInfo as? MoGoodsInfo,
- let accountManager = MTP2BusinessCore.shared.accountManager,
- let taAccountInfo = accountManager.getCurrentTAAccountInfo() else {
- return
- }
-
- let amount = (priceField.currentDoubleNumbers*Double(qtyField.currentIntNumbers)*obj.agreeUnit).toDownString(reserve: obj.decimalplace)
- /// 期末余额
- let blance = taAccountInfo.currentBalance-(taAccountInfo.freezeMargin+taAccountInfo.otherFreezeMargin+taAccountInfo.freezeCharge)
- amountTips.text = "购买金额:\(amount) 可用金额:\(blance.toDownString(reserve: 2))"
- }
- }
- extension TradeViewController: UITableViewDelegate, UITableViewDataSource {
-
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return orderDetails.count
- }
-
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier, for: indexPath) as! TradeCell
- cell.model = orderDetails[indexPath.row]
- cell.block = { (_ model: MoHsbyGoodsOrderDetail?, _ isCheck: Bool, _ qty: Int) in
- var qty: Int = 0
- self.tableView.visibleCells.forEach { (cell) in
- if (cell as! TradeCell).isCheck {
- qty += (cell as! TradeCell).qtyField.currentIntNumbers
- }
- }
- self.orderQty = qty
- /// 输入框是否可用
- self.qtyField.isUserInteractionEnabled = !self.tableView.visibleCells.contains(where: { (cell) -> Bool in
- return ((cell as? TradeCell)?.isCheck ?? false)
- })
- }
- /// 最小交易数量
- if let obj = takeInfo as? MoGoodsInfo {
- cell.qtyField.incrementIntNum = obj.lotsize
- cell.qtyField.minIntNum = obj.lotsize
- }
- return cell
- }
-
- func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
- return 50.0
- }
- }
- extension TradeViewController: IBNumberEditTextDelegate {
-
- func numberInputViewDidEndEditing(_ numberInputView: IBNumberEditText) {
- if numberInputView == priceField {
- let orderPrice = numberInputView.currentDoubleNumbers
- /// 更新单据
- self.requestQueryHsbyGoodsOrderDetails(orderPrice.toString(reserve: 2))
- } else {
- calculate()
- }
- }
-
- func numberInputView(_ numberInputView: IBNumberEditText, _ buttonType: NumberInputViewButtonType) {
- if numberInputView == priceField {
- let orderPrice = numberInputView.currentDoubleNumbers
- /// 更新单据
- self.requestQueryHsbyGoodsOrderDetails(orderPrice.toString(reserve: 2))
- }
- calculate()
- }
-
- func IBNumberEditText(textField: UITextField) {}
- }
- class TradeCell: BaseTableViewCell<MoHsbyGoodsOrderDetail> {
-
- // MARK: - 属性列表
- /// bgView
- @IBOutlet weak var bgView: UIView!
- /// checkBox
- @IBOutlet weak var checkBox: UIButton!
- /// accountName
- @IBOutlet weak var accountName: UILabel!
- /// price
- @IBOutlet weak var price: UILabel!
- /// qty
- @IBOutlet weak var qty: UILabel!
- /// checkBox
- @IBOutlet weak var qtyField: IBNumberEditText! {
- didSet {
- qtyField.valueType = 1
- qtyField.delegate = self
- }
- }
-
- /// 数据模型
- override var model: MoHsbyGoodsOrderDetail? {
- didSet {
- /// 异常
- guard let obj = model else {
- return
- }
- /// 数量范围
- qtyField.maxIntNum = obj.enableqty
- if let vc = self.superController() as? MyUnusedViewController { /// 我的闲置
- qtyField.minIntNum = vc.myGoods?.lotsize ?? 1
- qtyField.incrementIntNum = vc.myGoods?.lotsize ?? 1
- qtyField.currentIntNumbers = vc.myGoods?.lotsize ?? 1
- } else {
- let lotSize = ((self.superController() as? TradeViewController)?.takeInfo as? MoGoodsInfo)?.lotsize ?? 1
- qtyField.minIntNum = lotSize
- qtyField.incrementIntNum = lotSize
- qtyField.currentIntNumbers = lotSize
- }
-
- /// 客户名称
- accountName.text = obj.customername
- /// 委托价格
- price.text = "\(obj.currencysign)\(obj.orderprice)"
- /// 委托数量
- qty.text = "\(obj.enableqty)\(obj.goodunit)"
- }
- }
- /// 是否勾选
- var isCheck: Bool = false {
- didSet {
- /// 异常
- guard let obj = model else { return }
- /// setImage
- checkBox.setImage(UIImage(named: isCheck ? "check_selected" : "check_normal"), for: .normal)
- /// 执行回调
- if let callBack = block { callBack(obj, isCheck, qtyField.currentIntNumbers) }
- /// 设置交互色
- bgView.backgroundColor = UIColorFromHex(rgbValue: isCheck ? 0xecf3fd : 0xf7f7f7)
- /// 为空
- if !isCheck { qtyField.numberField.text = "" }
- }
- }
-
- /// 回调块
- var block: ((_ model: MoHsbyGoodsOrderDetail?, _ isCheck: Bool, _ qty: Int) -> Void)?
-
- /// onButtonPressed
- /// - Parameter sender: sender
- @IBAction func onButtonPressed(_ sender: UIButton) {
- switch sender {
- case checkBox:
- isCheck = !isCheck
- default:
- return
- }
- }
- }
- extension TradeCell: IBNumberEditTextDelegate {
- func IBNumberEditText(textField: UITextField) {
- isCheck = true
- }
-
- func numberInputView(_ numberInputView: IBNumberEditText, _ buttonType: NumberInputViewButtonType) {
- /// 如果大于最大数量 默认设置最大数量
- if numberInputView.currentIntNumbers > numberInputView.maxIntNum {
- isCheck = true
- }
- }
-
- func numberInputViewDidEndEditing(_ numberInputView: IBNumberEditText) {
- /// 如果大于最大数量 默认设置最大数量
- isCheck = true
- }
- }
|