| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- //
- // ExposureViewController.swift
- // MTP2_iOS
- //
- // Created by Muchinfo on 2021/1/5.
- // Copyright © 2021 Muchinfo. All rights reserved.
- //
- import UIKit
- import JXSegmentedView
- import IBAnimatable
- import WHToast
- import GTMRefresh
- /// 敞口视图容器控制类
- class ExposureViewController: BaseCollectionViewController {
- // MARK: - 属性列表
- /// 主滚动视图
- @IBOutlet weak var mainScrollView: UIScrollView!
- /// 历史内容装载视图
- @IBOutlet weak var hisContetnView: UIView! {
- didSet {
- hisContetnView.isHidden = true
- }
- }
- /// 内容装载视图
- @IBOutlet weak var contetnView: UIStackView! {
- didSet {
- contetnView.isHidden = false
- }
- }
- /// 期货明细
- @IBOutlet weak var futures: UIButton!
- /// 现货明细
- @IBOutlet weak var spot: UIButton!
- /// 交易下单
- @IBOutlet weak var trade: UIButton!
-
- /// 实时敞口数据
- var exposures: [MoRealExposure] = [] {
- didSet {
- /// 左边数据
- leftDatas = exposures.map { (obj) -> String in
- /// 合同编号和采购销售名称
- return "\(obj.middleGoodsName)"+"\n\(obj.middleGoodsCode)"
- }
- /// 右边数据
- rightDatas = exposures.map { (obj) -> [String] in
- let e = obj.enumdicname.isBlank()
- return ["\(obj.hedgeqty.toUpString())\(e)\n\(obj.arbitrageqty.toUpString())\(e)",
- "\(obj.totalSpotQty.toUpString())\(e)\n\(obj.diffSpotQty.toUpString())\(e)",
- "\(obj.diffHedgeQty.toUpString())\(e)\n\(obj.diffArbitrageQty.toUpString())\(e)",
- "\((obj.middleGoodsHedgeRatio*100.0).toUpString())%\n\((obj.needarbitrageratio*100.0).toUpString())%",
- "\(obj.needhedgeqty.toUpString())\(e)\n\(obj.needarbitrageqty.toUpString())\(e)",
- "\(obj.totalNeedHedgeQty.toUpString())\(e)\n\(obj.diffSpotHedgeQty.toUpString())\(e)",
- "\(obj.totalFutureQty.toUpString())\(e)\n\(obj.diffFutuQty.toUpString())\(e)",
- "\(obj.needHedgeExposoure.toUpString())\(e)\n\(obj.diffExposoureQty.toUpString())\(e)",
- "\(obj.totalExposure.toUpString())\(e)\n\(obj.diffqty.toUpString())\(e)"]
- }
- /// 刷新右侧列表数据
- rightTableView.reloadData()
- /// 无数据按钮
- noDataButton.isHidden = exposures.count != 0
- }
- }
-
- /// 敞口现货头寸
- var exposureSpots: [MoExposureSpot] = [] {
- didSet {
- /// 左边数据
- leftDatas = exposureSpots.map { (obj) -> String in
- /// 合同编号和采购销售名称
- return "\(obj.wrstandardname)"
- }
- /// 右边数据
- rightDatas = exposureSpots.map { (obj) -> [String] in
- let e = obj.enumdicname.isBlank()
- return ["\(obj.oritoalspotqty.toUpString())\(e)",
- "\(obj.increaseqty.toUpString())\(e)\n\(obj.decreaseqty.toUpString())\(e)",
- "\(obj.totalspotqty.toUpString())\(e)"]
- }
- /// 刷新右侧列表数据
- rightTableView.reloadData()
- /// 无数据按钮
- noDataButton.isHidden = exposureSpots.count != 0
- }
- }
-
- /// 敞口期货头寸
- var hedgePositions: [MoExposureHedgePosition] = [] {
- didSet {
- /// 左边数据
- leftDatas = hedgePositions.map { (obj) -> String in
- /// 合同编号和采购销售名称
- return "\(obj.goodsname)"+"\n\(obj.goodscode)"
- }
- /// 右边数据
- rightDatas = hedgePositions.map { (obj) -> [String] in
- return ["\(obj.totalydqty.toUpString())手",
- "\(obj.increaseqty.toUpString())手\n\(obj.decreaseqty.toUpString())手",
- "\(obj.totalcurqty.toUpString())手"]
- }
- /// 刷新右侧列表数据
- rightTableView.reloadData()
- /// 无数据按钮
- noDataButton.isHidden = hedgePositions.count != 0
- }
- }
-
- /// 历史敞口视图
- lazy var hisExposure: HisExposuresViewController = {
- $0.view.frame = hisContetnView.bounds
- return $0
- } (self.viewController("Exposure", "HisExposures") as! HisExposuresViewController)
-
- /// AutoTimerID
- let AutoTimerID = "RealExposureTimer"
-
- /// 权限菜单
- var roleTitles: [String] {
- get {
- var titles: [String] = []
- /// 权限控制
- guard let commonManager = MTP2BusinessCore.shared.commonManager else {
- return titles
- }
- if commonManager.containMenu(key: "client_exposure_real") {
- titles.append("实时敞口")
- }
- if commonManager.containMenu(key: "client_exposure_spot") {
- titles.append("现货头寸")
- }
- if commonManager.containMenu(key: "client_exposure_future") {
- titles.append("期货头寸")
- }
- if commonManager.containMenu(key: "client_exposure_his") {
- titles.append("历史敞口")
- }
- return titles
- }
- }
- // MARK: - 生命周期
- override func viewDidLoad() {
- super.viewDidLoad()
- // Do any additional setup after loading the view.
-
- /// loding
- addLoadingView()
- /// 菜单
- dataSource.titles = roleTitles
- segmentedView.dataSource = dataSource
- segmentedView.reloadData()
-
- /// 判断其权限控制
- if let commonManager = MTP2BusinessCore.shared.commonManager {
- /// 交易下单
- trade.isHidden = !commonManager.containMenu(key: "client_exposure_trade")
- /// 期货明细
- futures.isHidden = !commonManager.containMenu(key: "client_exposure_futuresdetail")
- /// 现货明细
- spot.isHidden = !commonManager.containMenu(key: "client_exposure_spotdetail")
- }
-
- /// 分页回调
- segmentBlock = { (_ index: Int, _ segment: JXSegmentedView) in
- switch self.roleTitles[index] {
- case "实时敞口":
- /// 查询实时敞口
- self.reloadData(0)
- case "现货头寸":
- /// 查询现货头寸
- self.reloadData(1)
- case "期货头寸":
- /// 查询期货头寸
- self.reloadData(2)
- default: break
- }
-
- /// 内容视图
- self.contetnView.isHidden = self.roleTitles[index] == "历史敞口"
- /// 历史视图
- if self.roleTitles[index] == "历史敞口" {
- if !self.hisContetnView.subviews.contains(self.hisExposure.view) {
- self.hisContetnView.addSubview(self.hisExposure.view)
- self.addChild(self.hisExposure)
- self.hisExposure.didMove(toParent: self)
- self.noDataButton.isHidden = true
- }
- } else {
- /// 移出
- if self.hisContetnView.subviews.contains(self.hisExposure.view) {
- self.hisExposure.view.removeFromSuperview()
- self.hisExposure.removeFromParent()
- }
- }
- self.hisContetnView.isHidden = self.roleTitles[index] != "历史敞口"
- }
-
- /// 选中回调
- selectBlock = { (_ row: Int?) in
- if self.roleTitles[self.segmentedView.selectedIndex] != "实时敞口" {
- /// 头寸选中
- self.performSegue(withIdentifier: "ShowPositionSpotFutureDetail", sender: self.segmentedView.selectedIndex == 1 ? OperatorType.cashFlow : OperatorType.futuresFlow)
- } else{
- /// 判断选中位置
- if let index = self.selectedRow, let cell = self.rightTableView.cellForRow(at: IndexPath(row: index.row, section: 0)) as? RightCell {
- /// 判断Cell相对于view所处的位置
- let rectInTableView = self.rightTableView.rectForRow(at: IndexPath(row: index.row, section: 0))
- /// 获取
- let rectInSuperview = self.rightTableView.convert(rectInTableView, to: self.view)
- /// 数据显示
- /// 获取对应的位置
- self.operationView.top = rectInSuperview.origin.y + cell.collectionView.height + 5.0
- /// 是否隐藏
- self.operationView.isHidden = !index.isExpland
- }
- }
- }
-
- if roleTitles.count != 0 {
- /// 下拉刷新
- mainScrollView.gtm_addRefreshHeaderView(refreshHeader: DefaultGTMRefreshHeader()) {
- /// 查询实时数据
- self.reloadData(self.segmentedView.selectedIndex)
- }
- /// 默认选中第一个
- segmentedView.defaultSelectedIndex = 0
- segmentedView.delegate?.segmentedView(segmentedView, didSelectedItemAt: 0)
- }
- }
-
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
- /// 重新请求数据
- reloadData(segmentedView.selectedIndex)
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
- /// 列头高度
- columnWidth = 100.0
- /// 开启定时器刷新
- startAutoTimer()
- }
-
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
- /// 取消定时器刷新
- stopAutoTimer()
- }
-
- // MARK: - 交互相关
- /// onButtonPressed
- /// - Parameters:
- /// - sender: sender
- @IBAction fileprivate func onButtonPressed(_ sender: UIButton) {
- switch sender {
- case futures, spot: /// 实时敞口-现货期货明细
- self.performSegue(withIdentifier: "ShowExposureSpotFutureDetail", sender: sender == futures ? OperatorType.futuresFlow : OperatorType.cashFlow)
- case trade: /// 期货下单
- /// 跳转期货下单方法
- doFutureTrade()
- default: break
- }
- }
-
- /// 跳转期货下单方法
- fileprivate func doFutureTrade() {
- /// 异常
- guard let goodsManager = MTP2BusinessCore.shared.goodsManager,
- let goodsInfos = goodsManager.goodsInfos,
- let row = selectedRow?.row else {
- return
- }
- /// 获取对应的主力合约商品信息
- goodsManager.queryExposureGoods(middlegoodsid: exposures[row].middleGoodsID, callback: { isSuccess, er, objs in
- DispatchQueue.main.async {
- /// 获取主力合约商品失败
- if !isSuccess {
- WHToast.showMessage("获取主力合约信息失败,原因:\(er?.retMsg ?? "查询超时")", duration: ToastTimer, finishHandler: {})
- return
- }
- /// 默认带主力合约数据
- if let obj = goodsInfos.first(where: {$0.goodsid == objs?.first?.goodsid}) {
- self.push("Futures", "ATPTrader", obj)
- } else {
- self.push("Futures", "ATPTrader", nil)
- }
- }
- })
- }
-
- // MARK: - 接口请求
- /// 刷新数据信息
- /// - Parameter type: 类型
- fileprivate func reloadData(_ type: Int) {
- /// 历史敞口不做处理
- if roleTitles[segmentedView.selectedIndex] == "历史敞口" {
- /// 结束下拉刷新
- mainScrollView.endRefreshing()
- return
- }
-
- /// 异常
- guard let commonManager = MTP2BusinessCore.shared.commonManager,
- let spotManager = MTP2BusinessCore.shared.spotManager else {
- return
- }
-
- /// startAnimating
- _anim?.startAnimating()
- /// group
- let group = DispatchGroup()
-
- /// 定义列头
- var key = ""
- /// group
- group.enter()
- /// 查询类型
- switch roleTitles[type] {
- case "实时敞口":
- /// 实时敞口
- key = "table_mobile_exposure_realtime"
- /// 允许选中
- canSelected = true
- /// 清空数据
- exposures = []
- /// 查询实时敞口数据
- spotManager.queryRealtimeExposure { (isSuccess, er, objs) in
- DispatchQueue.main.async {
- /// 查询失败
- if !isSuccess {
- self.exposures = []
- WHToast.showMessage("数据查询失败,原因:\(er?.retMsg ?? "查询超时")", duration: ToastTimer, finishHandler: {})
- return
- }
- /// 数据赋值
- self.exposures = objs ?? []
- }
- group.leave()
- }
- case "现货头寸":
- /// 现货头寸
- key = "table_mobile_exposure_spotposition"
- /// 不允许选中
- canSelected = false
- /// 清空数据
- exposureSpots = []
- /// 查询敞口现货头寸
- spotManager.queryExposureSpot { (isSuccess, er, objs) in
- DispatchQueue.main.async {
- /// 查询失败
- if !isSuccess {
- self.exposureSpots = []
- WHToast.showMessage("数据查询失败,原因:\(er?.retMsg ?? "查询超时")", duration: ToastTimer, finishHandler: {})
- return
- }
- /// 数据赋值
- self.exposureSpots = objs ?? []
- }
- group.leave()
- }
- default:
- /// 期货头寸
- key = "table_mobile_exposure_futuresposition"
- /// 不允许选中
- canSelected = false
- /// 清空数据
- hedgePositions = []
- /// queryExposureHedgePosition
- spotManager.queryExposureHedgePosition { (isSuccess, er, objs) in
- DispatchQueue.main.async {
- /// 查询失败
- if !isSuccess {
- self.hedgePositions = []
- WHToast.showMessage("数据查询失败,原因:\(er?.retMsg ?? "查询超时")", duration: ToastTimer, finishHandler: {})
- return
- }
- /// 数据赋值
- self.hedgePositions = objs ?? []
- }
- group.leave()
- }
- }
-
- group.enter()
- /// 查询列头信息
- commonManager.queryTableDefine(tableKey: key) { (isSuccess, er, objs) in
- DispatchQueue.main.async {
- /// 查询失败
- if !isSuccess {
- WHToast.showMessage("数据查询失败,原因:\(er?.retMsg ?? "查询超时")", duration: ToastTimer, finishHandler: {})
- return
- }
- /// 数据
- self.columnHeaders = objs?.first?.columns.sorted(by: { (obj1, obj2) -> Bool in
- return obj1.orderindex<obj2.orderindex
- }).map({ (obj) -> String in
- return obj.columntitle.replacingOccurrences(of: "\\n", with: "\n")
- }) ?? []
- }
- group.leave()
- }
-
- group.notify(queue: .main) {
- /// 结束下拉刷新
- self.mainScrollView.endRefreshing()
- /// stopAnimating
- self._anim?.stopAnimating()
- }
- }
-
- // MARK: - 定时器相关
- /// 定时器刷新
- fileprivate func startAutoTimer() {
- /// 每隔30秒自动刷新一次
- MCGCDTimer.shared.scheduledDispatchTimer(WithTimerName: AutoTimerID, timeInterval: 30, queue: .global(), repeats: true, isNowRun: false) {
- DispatchQueue.main.async {
- self.reloadData(self.segmentedView.selectedIndex)
- }
- }
- }
-
- /// 取消定时器刷新
- fileprivate func stopAutoTimer() {
- MCGCDTimer.shared.cancleTimer(WithTimerName: AutoTimerID)
- }
-
- // MARK: - Navigation
- // In a storyboard-based application, you will often want to do a little preparation before navigation
- override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
- // Get the new view controller using segue.destination.
- // Pass the selected object to the new view controller.
-
- if segue.identifier == "ShowExposureSpotFutureDetail", let f = segue.destination as? ExposureSpotFutureDetailViewController, let row = selectedRow?.row, exposures.count != 0 {
- /// 实时敞口 - 期货现货明细
- f.realExposure = exposures[row]
- if let type = sender as? OperatorType {
- /// title
- f.navigationItem.title = "实时敞口-\(type == .cashFlow ? "现货" : "期货")明细"
- f.operatorType = type
- }
- } else if segue.identifier == "ShowPositionSpotFutureDetail", let p = segue.destination as? PositionSpotFutureDetailViewController,let row = selectedRow?.row {
- /// 头寸-期货现货明细
- if ((sender as! OperatorType) == .cashFlow) {
- /// 现货明细
- p.exposureSpot = exposureSpots[row]
- } else {
- /// 期货明细
- p.hedgePosition = hedgePositions[row]
- }
- if let type = sender as? OperatorType {
- /// title
- p.navigationItem.title = "\(type == .cashFlow ? "现货" : "期货")头寸-\(type == .cashFlow ? "现货" : "期货")明细"
- p.operatorType = type
- }
- }
- }
- }
|