// // GoodsVarietiesViewController.swift // MTP2_iOS // // Created by Muchinfo on 2021/1/2. // Copyright © 2021 Muchinfo. All rights reserved. // import UIKit import JXSegmentedView import IBAnimatable import WHToast import GTMRefresh import SwiftyAttributes import Popover /// 商品信息视图容器控制类 class GoodsVarietiesViewController: BaseViewController { // MARK: - 属性列表 /// new @IBOutlet weak var new: UIBarButtonItem! /// info1 @IBOutlet weak var info1: UIButton! /// info1 @IBOutlet weak var info2: UIButton! { didSet { info2.isHidden = true } } /// 类目 @IBOutlet weak var segmentedView: JXSegmentedView! { didSet { segmentedView.indicators = [indicator] segmentedView.delegate = self } } /// 列表 @IBOutlet weak var tableView: UITableView! /// CellIdentifier let CellIdentifier = "GoodsVarieties_Cell" /// ArborescenceCellIdentifier let ArborescenceCellIdentifier = "Arborescence_Cell" /// 选中的位置 var selectedIndex: (row: Int, isExpland: Bool)? { didSet { if let index = selectedIndex { /// 刷新某一行 tableView.reloadRows(at: [IndexPath(row: index.row, section: 0)], with: .automatic) } } } /// 树状数据 var objs: [Any] = [] { didSet { /// 刷新列表数据 tableView.reloadData() /// 无数据按钮 noDataButton.isHidden = objs.count != 0 } } /// 权限功能 var roleTitles: [String] { get { var titles: [String] = [] /// 权限控制 guard let commonManager = MTP2BusinessCore.shared.commonManager else { return titles } if commonManager.isContainTraderMenu(key: "client_deliverygoods_spot") { titles.append("现货品种") } if commonManager.isContainTraderMenu(key: "client_deliverygoods_hedge") { titles.append("套保品种") } return titles } } // MARK: - 生命周期 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func loadView() { super.loadView() /// addLoadingView addLoadingView() /// title dataSource.titles = roleTitles segmentedView.dataSource = dataSource segmentedView.reloadData() if roleTitles.count != 0 { /// 添加下拉刷新控件 tableView.gtm_addRefreshHeaderView(refreshHeader: DefaultGTMRefreshHeader()) { switch self.roleTitles[self.segmentedView.selectedIndex] { case "现货品种": /// 现货品种 self.queryDeliveryGoodsDetails() default: /// 套保品种 self.queryMiddleGoodsDetails() } } /// 默认选中第一个 segmentedView.defaultSelectedIndex = 0 segmentedView.delegate?.segmentedView(segmentedView, didSelectedItemAt: 0) } } /// onButtonPressed /// - Parameter sender: sender @IBAction fileprivate func onBarButtonItemPressed(_ sender: UIBarButtonItem) { switch sender { case new: /// 新增 /// 新增现货品种 self.performSegue(withIdentifier: "ShowNewGoodsVarieties", sender: OperatorType.add) default: break } } /// onButtonPressed /// - Parameter sender: sender @IBAction fileprivate func onButtonPressed(_ sender: UIButton) { let start = sender.convert(CGPoint.zero, to: self.view) let startPoint = CGPoint(x: start.x+22.0, y: start.y+25.0) let options: [PopoverOption] = [.type(.down), .cornerRadius(10), .showBlackOverlay(true)] var infos = "" switch sender { case info1: /// 信息1 infos = "1.商品对应的是标仓系数,是非标商品转换成现货品种的系数;\n 现货品种数量=现货商品数量*标仓系数;\n 2.套保品种对应的是套保系数,是现货品种转换成套保品种的系数;\n套保品种数量=现货品种数量*套保系数;\n3.期货品种对应的是期货品种系数,是期货品种转换成套保品种的系数;\n套保品种数量=期货品种数量*期货品种系数;" default: /// 信息2 infos = "1.商品对应的是标仓系数,是非标商品转换成现货品种的系数;\n 现货品种数量=现货商品数量*标仓系数;\n 2.套保品种对应的是套保系数,是现货品种转换成套保品种的系数;\n 套保品种数量=现货品种数量*套保系数;\n 3.期货品种对应的是期货品种系数,是期货品种转换成套保品种的系数;\n 套保品种数量=期货品种数量*期货品种系数;\n 4.期货合约对应的是期货合约乘数,是期货合约转换成期货品种的系数;\n 期货品种数量=期货合约手数*期货合约乘数" } info.text = infos let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) popover.show(info, point: startPoint) } // MARK: - 接口请求 /// 查询现货品种详细信息 fileprivate func queryDeliveryGoodsDetails() { /// 异常 guard let contractManager = MTP2BusinessCore.shared.contractManager else { return } /// startAnimating _anim?.startAnimating() /// 发送查询请求 contractManager.queryDeliveryGoodsDetail(deliverygoodsid: nil, qrytradegoods: nil) { (isComplete, er, details) in DispatchQueue.main.async { /// dismisss loding..... self._anim?.stopAnimating() /// endRefreshing self.tableView.endRefreshing() /// 查询失败 if !isComplete { self.objs = [] WHToast.showMessage("数据查询失败,原因:\(er?.retMsg ?? "查询超时")", duration: 1.5, finishHandler: {}) return } /// 数据赋值 self.objs = details?.sorted(by: { (obj1, obj2) -> Bool in if obj1.data?.isvalid == obj2.data?.isvalid { return (obj1.data?.deliverygoodsid ?? 0)>(obj2.data?.deliverygoodsid ?? 0) } return (obj1.data?.isvalid ?? 0)>(obj2.data?.isvalid ?? 0) }) ?? [] } } } /// 查询套保品种(菜单:套保品种) /// - Parameter status: 状态 0-停用 1-正常 fileprivate func queryMiddleGoodsDetails() { /// 异常 guard let planManager = MTP2BusinessCore.shared.planManager else { return } /// startAnimating _anim?.startAnimating() /// 发送请求 planManager.queryMiddleGoodsDetail(middlegoodsid: nil) { (isComplete, er, details) in DispatchQueue.main.async { /// dismisss loding..... self._anim?.stopAnimating() /// endRefreshing self.tableView.endRefreshing() /// 查询失败 if !isComplete { self.objs = [] WHToast.showMessage("数据查询失败,原因:\(er?.retMsg ?? "查询超时")", duration: 1.5, finishHandler: {}) return } /// 数据赋值 self.objs = details?.sorted(by: { (obj1, obj2) -> Bool in if obj1.mg?.isvalid == obj2.mg?.isvalid { return (obj1.mg?.modifytime ?? "")>(obj2.mg?.modifytime ?? "") } return (obj1.mg?.isvalid ?? 0)>(obj2.mg?.isvalid ?? 0) }) ?? [] } } } // 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 == "ShowNewGoodsVarieties", let new = segue.destination as? NewGoodsVarietiesViewController { /// 新增现货品种 if (sender as? OperatorType) == .update { new.goodsDetail = objs[selectedIndex?.row ?? 0] as? MoDeliveryGoodsDetail new.operatorType = .update new.navigationItem.title = "修改现货品种" } new.popBlock = { (_ takeInfo: Any?) in self.tableView.triggerRefreshing() } } else if segue.identifier == "ShowNewHedge", let new = segue.destination as? NewHedgeViewController { /// 新增套保品种 if (sender as? OperatorType) == .update { new.moMiddleGoods = objs[selectedIndex?.row ?? 0] as? MoErmcpMiddleGoodsDetail new.operatorType = .update new.navigationItem.title = "修改套保品种" } new.popBlock = { (_ takeInfo: Any?) in self.tableView.triggerRefreshing() } } else if segue.identifier == "ShowGoodsVarietiesDetail", let detail = segue.destination as? GoodsVarietiesDetailViewController { /// 现货品种详情 detail.deliveryGoodsDetail = objs[selectedIndex?.row ?? 0] as? MoDeliveryGoodsDetail detail.popBlock = { (_ takeInfo: Any?) in self.tableView.triggerRefreshing() } } else if segue.identifier == "ShowHedgeDetail",let detail = segue.destination as? HedgeDetailViewController { /// 套保品种详情 detail.middleGoods = objs[selectedIndex?.row ?? 0] as? MoErmcpMiddleGoodsDetail detail.popBlock = { (_ takeInfo: Any?) in self.tableView.triggerRefreshing() } } } } // MARK: - JXSegmentedViewDelegate extension GoodsVarietiesViewController: JXSegmentedViewDelegate { func segmentedView(_ segmentedView: JXSegmentedView, didSelectedItemAt index: Int) { switch roleTitles[index] { case "现货品种": /// 查询现货商品数据 queryDeliveryGoodsDetails() /// 该账户没权限 guard let commonManager = MTP2BusinessCore.shared.commonManager else { return } /// 没有权限 if !commonManager.isContainTraderMenu(key: "client_deliverygoods_add") { self.new.image = nil self.new.isEnabled = false } else { self.new.image = UIImage(named: "new_contract") self.new.isEnabled = true } default: /// 查询套保品种 queryMiddleGoodsDetails() new.image = nil new.isEnabled = false } info1.isHidden = index != 0 info2.isHidden = index != 1 } } extension GoodsVarietiesViewController: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return objs.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: ArborescenceCellIdentifier, for: indexPath) as! ArborescenceCell cell.model = objs[indexPath.row] cell.indexPath = indexPath cell.block = { (_ model: Any?, _ sender: Any?) in if let type = sender as? OperatorType { switch type { case .detail: /// 详情 self.performSegue(withIdentifier: self.segmentedView.selectedIndex == 0 ? "ShowGoodsVarietiesDetail" : "ShowHedgeDetail", sender: nil) case .stop: /// 停用 self.performSegue(withIdentifier: self.segmentedView.selectedIndex == 0 ? "ShowGoodsVarietiesDetail" : "ShowHedgeDetail", sender: model) case .reused: /// 停用 self.performSegue(withIdentifier: self.segmentedView.selectedIndex == 0 ? "ShowGoodsVarietiesDetail" : "ShowHedgeDetail", sender: model) case .update: /// 修改 if self.segmentedView.selectedIndex == 0 { /// 新增现货品种 self.performSegue(withIdentifier: "ShowNewGoodsVarieties", sender: OperatorType.update) } else { /// 新增套保品种 self.performSegue(withIdentifier: "ShowNewHedge", sender: OperatorType.update) } default: /// 展开 tableView.delegate?.tableView?(tableView, didSelectRowAt: indexPath) } } } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { self.selectedIndex = (row: indexPath.row, true) if self.segmentedView.selectedIndex == 0 { /// 新增现货品种 var obj = self.objs[indexPath.row] as! MoDeliveryGoodsDetail obj.expland = !obj.expland self.objs.replaceSubrange(indexPath.row...indexPath.row, with: [obj]) } else { /// 新增套保品种 var obj = self.objs[indexPath.row] as! MoErmcpMiddleGoodsDetail obj.expland = !obj.expland self.objs.replaceSubrange(indexPath.row...indexPath.row, with: [obj]) } tableView.reloadData() /// 滚动到底部 self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { var height: CGFloat = 45.0 switch objs[indexPath.row].self { case is MoDeliveryGoodsDetail: /// 现货品种 let obj = objs[indexPath.row] as! MoDeliveryGoodsDetail if obj.expland { /// 操作项高度 height += 40.0 if obj.mgExpland { height += CGFloat(obj.mgList.count)*45.0 obj.mgList.forEach { mg in height += CGFloat(mg.gpExpland ? mg.gplist.count : 0)*45.0 } } /// count+1是因为列头高度 height += CGFloat((obj.mgExpland ? obj.mgList.count : 0)+1)*45.0 height += CGFloat((obj.gbExpland ? obj.gblist.count : 0)+1)*45.0 height += CGFloat((obj.gmExpland ? obj.gmlist.count : 0)+1)*45.0 } default: /// 期货品种 let obj = objs[indexPath.row] as! MoErmcpMiddleGoodsDetail if obj.expland { /// 操作项高度 height += 40.0 /// count+1是因为列头高度 height += CGFloat((obj.gpExpland ? obj.gplist.count : 0)+1)*45.0 height += CGFloat((obj.dgExpland ? obj.dglist.count : 0)+1)*45.0 if obj.gpExpland { height += CGFloat(obj.gplist.count)*45.0 obj.gplist.forEach { gp in height += CGFloat(gp.gexpland ? gp.glist.count : 0)*45.0 } } if obj.dgExpland { height += CGFloat(obj.dglist.count)*45.0 obj.dglist.forEach { dg in height += CGFloat(dg.gmExpland ? dg.gmlist.count : 0)*45.0 } } } } return height } } /// 树状Cell class ArborescenceCell: BaseTableViewCell { /// 树状按钮 @IBOutlet weak var arborescence: UIImageView! /// 标题 @IBOutlet weak var titleLabel: UILabel! /// 恢复 @IBOutlet weak var restore: UIButton! /// 修改 @IBOutlet weak var update: UIButton! /// 停用 @IBOutlet weak var stop: UIButton! /// 详情 @IBOutlet weak var detail: UIButton! /// 子树 @IBOutlet weak var tableView: UITableView! /// 所处位置 var indexPath: IndexPath? /// SubArborescenceCellIdentifier let SubArborescenceCellIdentifier = "SubArborescence_Cell" /// 数据 override var model: Any? { didSet { switch model.self { case is MoDeliveryGoodsDetail: /// 现货品种信息 if let obj = (model as? MoDeliveryGoodsDetail)?.data { /// 单位 let enumdicname = (try? DatabaseHelper.getEnumInfo(enumdiccode: "goodsunit")?.first(where: {$0.enumitemname == obj.goodsunitid})?.enumdicname) ?? "--" /// 标题 titleLabel.attributedText = "\(obj.deliverygoodsname.isBlank()) (\(enumdicname))".withFont(.font_16).withTextColor(.hex333())+" \(obj.isvalid == 0 ? "停用" : "正常")".withFont(.font_13).withTextColor(obj.isvalid == 0 ? .FF3E3E() : .hex2FBB4D()) /// 修改按钮 update.isHidden = !(obj.isvalid == 1) /// 停用按钮 stop.isHidden = !(obj.isvalid == 1) /// 恢复 restore.isHidden = !(obj.isvalid == 0) } default: /// 套保品种 if let obj = (model as? MoErmcpMiddleGoodsDetail)?.mg { /// 套保比例 let needarbitrageratio = (obj.needarbitrageratio*100.0).toString(reserve: 2, false)+"%" /// 套利比例 let needhedgeratio = (obj.needhedgeratio*100.0).toString(reserve: 2, false)+"%" titleLabel.attributedText = "\(obj.middlegoodsname.isBlank()) (\(obj.enumdicname.isBlank()))".withFont(.font_16).withTextColor(.hex333())+" 套保比例:\(needhedgeratio) 套利比例:\(needarbitrageratio)".withFont(.font_13).withTextColor(obj.isvalid == 0 ? .FF3E3E() : .hex2FBB4D()) /// 修改按钮 update.isHidden = !(obj.isvalid == 1) /// 停用按钮 stop.isHidden = true /// 恢复 restore.isHidden = true } } /// 刷新数据 tableView.reloadData() } } /// onButtonPressed /// - Parameter sender: sender @IBAction func onButtonPressed(_ sender: UIButton) { switch sender { case detail: /// 详情 if let bk = self.block { bk(self.model, OperatorType.detail) } case stop: /// 停用 if let bk = self.block { bk(self.model, OperatorType.stop) } case restore: /// 恢复 if let bk = self.block { bk(self.model, OperatorType.reused) } case update: /// 修改 if let bk = self.block { bk(self.model, OperatorType.update) } default: if let bk = self.block { bk(self.model, OperatorType.expland) } } } } extension ArborescenceCell: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch model.self { case is MoDeliveryGoodsDetail: /// 现货商品 return 3 default: /// 套保商品 return 2 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: SubArborescenceCellIdentifier, for: indexPath) as! SubArborescenceCell switch model.self { case is MoDeliveryGoodsDetail: /// 现货品种 let obj = model as! MoDeliveryGoodsDetail switch indexPath.row { case 0: /// 商品 cell.model = obj.gmlist /// 单位 cell.unit = (try? DatabaseHelper.getEnumInfo(enumdiccode: "goodsunit")?.first(where: {$0.enumitemname == obj.data?.goodsunitid})?.enumdicname) ?? "--" case 1: /// 品牌 cell.model = obj.gblist default: /// 套保品种 cell.model = obj.mgList } default: /// 套保品种 let obj = model as! MoErmcpMiddleGoodsDetail switch indexPath.row { case 0: /// 期货品种 cell.isEx = true cell.model = obj.gplist default: /// 现货品种 cell.isEx = false cell.model = obj.dglist } } cell.indexPath = (tableView.superview?.superview as? ArborescenceCell)?.indexPath cell.rowNum = indexPath.row cell.block = { (_ model: Any?, _ sender: Any?) in if let index = cell.indexPath?.row { switch cell.parent.self { case is MoDeliveryGoodsDetail: var obj = cell.parent as! MoDeliveryGoodsDetail switch model.self { case is [MoErmcpMiddleGoodsDetail]: /// 套保品种 obj.mgExpland = !obj.mgExpland /// 设置图标 cell.arborescence.setImage(UIImage(named: !obj.mgExpland ? "unsubarborescence" : "subarborescence"), for: .normal) case is [MoGoodsBrand]: /// 品牌 obj.gbExpland = !obj.gbExpland /// 设置图标 cell.arborescence.setImage(UIImage(named: !obj.gbExpland ? "unsubarborescence" : "subarborescence"), for: .normal) default: /// 商品 obj.gmExpland = !obj.gmExpland /// 设置图标 cell.arborescence.setImage(UIImage(named: !obj.gmExpland ? "unsubarborescence" : "subarborescence"), for: .normal) } cell.parent = obj (self.superController() as? GoodsVarietiesViewController)?.objs.replaceSubrange(index...index, with: [obj]) default: var obj = cell.parent as! MoErmcpMiddleGoodsDetail switch model.self { case is [MoGoodsGroupEX]: /// 期货品种 obj.gpExpland = !obj.gpExpland /// 设置图标 cell.arborescence.setImage(UIImage(named: !obj.gpExpland ? "unsubarborescence" : "subarborescence"), for: .normal) default: /// 现货品种 obj.dgExpland = !obj.dgExpland /// 设置图标 cell.arborescence.setImage(UIImage(named: !obj.dgExpland ? "unsubarborescence" : "subarborescence"), for: .normal) } cell.parent = obj (self.superController() as? GoodsVarietiesViewController)?.objs.replaceSubrange(index...index, with: [obj]) } /// 刷新列表 self.tableView.reloadData() } } if let index = cell.indexPath?.row { cell.parent = (self.superController() as? GoodsVarietiesViewController)?.objs[index] } return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { var height: CGFloat = 0.0 switch model.self { case is MoDeliveryGoodsDetail: /// 现货品种 let obj = model as! MoDeliveryGoodsDetail switch indexPath.row { case 0: /// 商品 height += CGFloat((obj.gmExpland ? obj.gmlist.count : 0)+1)*45.0 case 1: /// 品牌 height += CGFloat((obj.gbExpland ? obj.gblist.count : 0)+1)*45.0 default: /// 套保品种 height += CGFloat((obj.mgExpland ? obj.mgList.count : 0)+1)*45.0 if obj.mgExpland { height += CGFloat(obj.mgList.count)*45.0 obj.mgList.forEach { mg in height += CGFloat(mg.gpExpland ? mg.gplist.count : 0)*45.0 } } } default: /// 套保品种 let obj = model as! MoErmcpMiddleGoodsDetail switch indexPath.row { case 0: /// 期货品种 height += CGFloat((obj.gpExpland ? obj.gplist.count : 0)+1)*45.0 if obj.gpExpland { height += CGFloat(obj.gplist.count)*45.0 obj.gplist.forEach { gp in height += CGFloat(gp.gexpland ? gp.glist.count : 0)*45.0 } } default: /// 现货品种 height += CGFloat((obj.dgExpland ? obj.dglist.count : 0)+1)*45.0 if obj.dgExpland { height += CGFloat(obj.dglist.count)*45.0 obj.dglist.forEach { dg in height += CGFloat(dg.gmExpland ? dg.gmlist.count : 0)*45.0 } } } } return height } } /// 第二层视图Cell class SubArborescenceCell: BaseTableViewCell { /// 树状按钮 @IBOutlet weak var arborescence: UIButton! /// 标题 @IBOutlet weak var leftTitle: UILabel! /// 标题 @IBOutlet weak var midleTitle: UILabel! /// 标题 @IBOutlet weak var rightTitle: UILabel! /// 列表 @IBOutlet weak var tableView: UITableView! /// ThirdArborescencCellIdentifier let ThirdArborescencCellIdentifier = "ThirdArborescenc_Cell" /// 父数据 var parent: Any? /// 所处位置 var indexPath: IndexPath? /// 商品单位 var unit: String = "" /// 数据 override var model: Any? { didSet { if let selectIndex = (self.superController() as? GoodsVarietiesViewController)?.segmentedView.selectedIndex { if selectIndex == 0 { switch model.self { case is [MoErmcpMiddleGoodsDetail]: /// 套保品种 let obj = model as! [MoErmcpMiddleGoodsDetail] leftTitle.attributedText = "套保品种".withFont(.font_16).withTextColor(.hex333())+" (\(obj.count))".withFont(.font_14).withTextColor(.hex999()) midleTitle.text = "单位" rightTitle.text = "套保系数" case is [MoWrStandard]: /// 商品 let types = model as! [MoWrStandard] leftTitle.attributedText = "商品".withFont(.font_16).withTextColor(.hex333())+" (\(types.count))".withFont(.font_14).withTextColor(.hex999()) midleTitle.text = "单位" rightTitle.text = "标仓系数" case is [MoGoodsBrand]: /// 品牌 let brands = model as! [MoGoodsBrand] leftTitle.attributedText = "品牌".withFont(.font_16).withTextColor(.hex333())+" (\(brands.count))".withFont(.font_14).withTextColor(.hex999()) midleTitle.text = "" rightTitle.text = "" default: break } } else { if isEx { /// 期货品种 let converts = model as! [MoGoodsGroupEX] leftTitle.attributedText = "期货品种".withFont(.font_16).withTextColor(.hex333())+" (\(converts.count))".withFont(.font_14).withTextColor(.hex999()) midleTitle.text = "单位" rightTitle.text = "品种系数" } else { /// 现货品种 let standards = model as! [MoDeliveryGoodsDetail] leftTitle.attributedText = "现货品种".withFont(.font_16).withTextColor(.hex333())+" (\(standards.count))".withFont(.font_14).withTextColor(.hex999()) midleTitle.text = "单位" rightTitle.text = "套保系数" } } /// 刷新数据 tableView.reloadData() } } } /// 造虐啊 由于数据特殊情况 为空的时候特殊处理 var isEx: Bool = true /// onButtonPressed /// - Parameter sender: sender @IBAction func onButtonPressed(_ sender: UIButton) { if let bk = self.block { bk(self.model, OperatorType.expland) } } } extension SubArborescenceCell: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return (model as? [Any])?.count ?? 0 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: ThirdArborescencCellIdentifier, for: indexPath) as! ThirdArborescenceCell switch model.self { case is [MoErmcpMiddleGoodsDetail]: /// 套保品种 let obj = (model as! [MoErmcpMiddleGoodsDetail])[indexPath.row].mg! let ratio = (model as! [MoErmcpMiddleGoodsDetail])[indexPath.row].convertratio cell.model = (key: "\(obj.middlegoodsname.isBlank())", middle: "\(obj.enumdicname.isBlank())", value: "\(ratio.toString(reserve: 2))") cell.subObj = (model as! [MoErmcpMiddleGoodsDetail])[indexPath.row] case is [MoWrStandard]: /// 商品 let obj = (model as! [MoWrStandard])[indexPath.row] cell.model = (key: "\(obj.wrstandardname.isBlank())", middle: "\(obj.enumdicname.isBlank())", value: "\(obj.convertfactor)") case is [MoGoodsBrand]: /// 品牌 let obj = (model as! [MoGoodsBrand])[indexPath.row] cell.model = (key: "\(obj.brandname.isBlank())", middle: "", value: "") case is [MoGoodsGroupEX]: /// 期货品种 let obj = (model as! [MoGoodsGroupEX])[indexPath.row] cell.model = (key: "\(obj.exexchangecode.isBlank())-\(obj.goodsgroupname.isBlank())", middle: "\(obj.enumdicname.isBlank())", value: "\(obj.convertratio.toString(reserve: 2))") cell.subObj = obj case is [MoDeliveryGoodsDetail]: /// 现货品种 let obj = (model as! [MoDeliveryGoodsDetail])[indexPath.row].data! let convertratio = (model as! [MoDeliveryGoodsDetail])[indexPath.row].convertratio cell.model = (key: "\(obj.deliverygoodsname.isBlank())", middle: "\(obj.enumdicname.isBlank())", value: "\(convertratio)") cell.subObj = (model as! [MoDeliveryGoodsDetail])[indexPath.row] default: break } cell.rowNum = indexPath.row /// 父类 cell.parent = self.parent cell.callBack = { (_ mo: Any?, _ takeInfo: Any?) in if let obj = mo, let topRow = (self.superview?.superview?.superview as? ArborescenceCell)?.indexPath?.row { /// 最顶层的位置 switch obj.self { case is MoErmcpMiddleGoodsDetail: /// 现货品种-套保品种-期货品种 var middle = obj as! MoErmcpMiddleGoodsDetail middle.gpExpland = !middle.gpExpland var good = (self.superController() as! GoodsVarietiesViewController).objs[topRow] as! MoDeliveryGoodsDetail good.mgList.replaceSubrange(cell.rowNum!...cell.rowNum!, with: [middle]) (self.superController() as! GoodsVarietiesViewController).objs.replaceSubrange(topRow...topRow, with: [good]) case is MoGoodsGroupEX: /// 套保品种-期货品种-期货合约 var group = obj as! MoGoodsGroupEX group.gexpland = !group.gexpland var good = (self.superController() as! GoodsVarietiesViewController).objs[topRow] as! MoErmcpMiddleGoodsDetail good.gplist.replaceSubrange(cell.rowNum!...cell.rowNum!, with: [group]) (self.superController() as! GoodsVarietiesViewController).objs.replaceSubrange(topRow...topRow, with: [good]) case is MoDeliveryGoodsDetail: /// 套保品种-现货品种-商品 var goods = obj as! MoDeliveryGoodsDetail goods.gmExpland = !goods.gmExpland var good = (self.superController() as! GoodsVarietiesViewController).objs[topRow] as! MoErmcpMiddleGoodsDetail good.dglist.replaceSubrange(cell.rowNum!...cell.rowNum!, with: [goods]) (self.superController() as! GoodsVarietiesViewController).objs.replaceSubrange(topRow...topRow, with: [good]) default: break } } } return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { switch model.self { case is [MoErmcpMiddleGoodsDetail]: /// 套保品种 let obj = (model as! [MoErmcpMiddleGoodsDetail])[indexPath.row] return CGFloat((obj.gpExpland ? obj.gplist.count : 0)+2)*45.0 case is [MoGoodsGroupEX]: /// 期货品种 let obj = (model as! [MoGoodsGroupEX])[indexPath.row] return CGFloat((obj.gexpland ? obj.glist.count : 0)+2)*45.0 case is [MoDeliveryGoodsDetail]: /// 现货品种 let obj = (model as! [MoDeliveryGoodsDetail])[indexPath.row] return CGFloat((obj.gmExpland ? obj.gmlist.count : 0)+2)*45.0 default: /// 商品、 品牌 return 45.0 } } } /// ThirdArborescenceCell class ThirdArborescenceCell: BaseTableViewCell<(key: String, middle: String, value: String)> { /// 背景视图 @IBOutlet weak var bgView: AnimatableView! /// 右边标题 @IBOutlet weak var rightTitle: UILabel! /// 中间标题 @IBOutlet weak var middleTitle: UILabel! /// 左边标题 @IBOutlet weak var leftTitle: UILabel! /// 左边标题 @IBOutlet weak var tableView: UITableView! /// 树状按钮 @IBOutlet weak var arborescence: UIButton! /// 标题 @IBOutlet weak var headerLeftTitle: UILabel! /// 标题 @IBOutlet weak var headerMidleTitle: UILabel! /// 标题 @IBOutlet weak var headerRightTitle: UILabel! /// 回调 var callBack: ((_ model: Any?, _ sender: Any?) -> Void)? /// 数据 override var model: (key: String, middle: String, value: String)? { didSet { guard let obj = model else { return } /// 左边值 leftTitle.text = obj.key /// 中间标题 middleTitle.text = obj.middle /// 右边值 rightTitle.text = obj.value } } /// 子数据 var subObj: Any? { didSet { /// 异常 guard let obj = subObj else { return } switch obj.self { case is MoErmcpMiddleGoodsDetail: /// 现货品种-套保品种-期货品种 let sub = obj as! MoErmcpMiddleGoodsDetail headerLeftTitle.text = "期货品种" + " (\(sub.gplist.count))" headerMidleTitle.text = "单位" headerRightTitle.text = "品种系数" /// 设置图标 arborescence.setImage(UIImage(named: !sub.gpExpland ? "unsubarborescence" : "subarborescence"), for: .normal) case is MoGoodsGroupEX: /// 套保品种-期货品种-期货合约 let sub = obj as! MoGoodsGroupEX headerLeftTitle.text = "期货合约" + " (\((obj as! MoGoodsGroupEX).glist.count))" headerMidleTitle.text = "单位" headerRightTitle.text = "合约乘数" /// 设置图标 arborescence.setImage(UIImage(named: !sub.gexpland ? "unsubarborescence" : "subarborescence"), for: .normal) case is MoDeliveryGoodsDetail: /// 套保品种-现货品种-商品 let sub = obj as! MoDeliveryGoodsDetail headerLeftTitle.text = "商品" + " (\((obj as! MoDeliveryGoodsDetail).gmlist.count))" headerMidleTitle.text = "单位" headerRightTitle.text = "标仓系数" /// 设置图标 arborescence.setImage(UIImage(named: !sub.gmExpland ? "unsubarborescence" : "subarborescence"), for: .normal) default: break } /// 刷新数据 tableView.reloadData() } } /// CellIdentifier let CellIdentifier = "Four_Cell" /// 父数据 var parent: Any? { didSet { switch parent.self { /// 现货品种 case is MoDeliveryGoodsDetail: let obj = (parent as! MoDeliveryGoodsDetail).data bgView.borderColor = obj?.isvalid == 1 ? .hex90D7FF() : .hexCCC() bgView.backgroundColor = obj?.isvalid == 1 ? .E8F3F6() : .F4F4F4() leftTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() middleTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() rightTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() default: /// 套保品种 let obj = (parent as! MoErmcpMiddleGoodsDetail).mg bgView.borderColor = obj?.isvalid == 1 ? .hex90D7FF() : .hexCCC() bgView.backgroundColor = obj?.isvalid == 1 ? .E8F3F6() : .F4F4F4() leftTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() middleTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() rightTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() } } } @IBAction func onButtonPressed(_ sender: UIButton) { /// 执行回调 if let bk = callBack { bk(subObj, nil) } } } extension ThirdArborescenceCell: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch subObj.self { case is MoErmcpMiddleGoodsDetail: /// 现货品种-套保品种-期货品种 return (subObj as! MoErmcpMiddleGoodsDetail).gplist.count case is MoGoodsGroupEX: /// 套保品种-期货品种-期货合约 return (subObj as! MoGoodsGroupEX).glist.count case is MoDeliveryGoodsDetail: /// 套保品种-现货品种-商品 return (subObj as! MoDeliveryGoodsDetail).gmlist.count default: return 0 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier, for: indexPath) as! FourArborescenceCell switch subObj.self { case is MoErmcpMiddleGoodsDetail: /// 现货品种-套保品种-期货品种 let obj = (subObj as! MoErmcpMiddleGoodsDetail).gplist[indexPath.row] cell.model = (key: "\(obj.exexchangecode.isBlank())-\(obj.goodsgroupname.isBlank())", middle: "\(obj.enumdicname.isBlank())", value: "\(obj.convertratio)") case is MoGoodsGroupEX: /// 套保品种-期货品种-期货合约 let obj = (subObj as! MoGoodsGroupEX).glist[indexPath.row] cell.model = (key: "\(obj.goodsname)", middle: "\(obj.enumdicname)", value: "\(obj.agreeunit)") case is MoDeliveryGoodsDetail: /// 套保品种-现货品种-商品 let obj = (subObj as! MoDeliveryGoodsDetail).gmlist[indexPath.row] cell.model = (key: "\(obj.wrstandardname.isBlank())", middle: "\(obj.enumdicname.isBlank())", value: "\(obj.convertfactor)") default: break } cell.parent = parent return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 45.0 } } /// ThirdArborescenceCell class FourArborescenceCell: BaseTableViewCell<(key: String, middle: String, value: String)> { /// 背景视图 @IBOutlet weak var bgView: AnimatableView! /// 右边标题 @IBOutlet weak var rightTitle: UILabel! /// 中间标题 @IBOutlet weak var middleTitle: UILabel! /// 左边标题 @IBOutlet weak var leftTitle: UILabel! /// 数据 override var model: (key: String, middle: String, value: String)? { didSet { guard let obj = model else { return } /// 左边值 leftTitle.text = obj.key /// 中间标题 middleTitle.text = obj.middle /// 右边值 rightTitle.text = obj.value } } /// 父数据 var parent: Any? { didSet { switch parent.self { /// 现货品种 case is MoDeliveryGoodsDetail: let obj = (parent as! MoDeliveryGoodsDetail).data bgView.borderColor = obj?.isvalid == 1 ? .hex90D7FF() : .hexCCC() bgView.backgroundColor = obj?.isvalid == 1 ? .E8F3F6() : .F4F4F4() leftTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() middleTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() rightTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() default: /// 套保品种 let obj = (parent as! MoErmcpMiddleGoodsDetail).mg bgView.borderColor = obj?.isvalid == 1 ? .hex90D7FF() : .hexCCC() bgView.backgroundColor = obj?.isvalid == 1 ? .E8F3F6() : .F4F4F4() leftTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() middleTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() rightTitle.textColor = obj?.isvalid == 1 ? .hex333() : .hexCCC() } } } }