// // HomeViewController.swift // MTP2_iOS // // Created by Handy_Cao on 2020/10/23. // Copyright © 2020 Muchinfo. All rights reserved. // import UIKit import SDCycleScrollView import SafariServices import SDWebImage import SwiftyAttributes import WHToast import GTMRefresh import WebKit /// 首页视图容器管理类 class HomeViewController: BaseViewController { // MARK: - 属性列表 /// 系统设置 @IBOutlet weak var settings: UIButton! /// 新卡抢购 @IBOutlet weak var xkqg: UIButton! /// 热卖专区 @IBOutlet weak var rmzq: UIButton! /// 我的订单 @IBOutlet weak var wddd: UIButton! /// 海南网警 @IBOutlet weak var police: UIButton! /// 海拔资讯 @IBOutlet weak var hbzx: UIButton! /// 海拔资讯 @IBOutlet weak var hbzxStackView: UIStackView! /// 我的卡包 @IBOutlet weak var wdkb: UIButton! /// 主滚动视图 @IBOutlet weak var scrollView: UIScrollView! /// 操作视图 @IBOutlet weak var operationView: UIView! /// 图片轮播图 @IBOutlet weak var bannerView: SDCycleScrollView! { didSet { bannerView.bannerImageViewContentMode = .scaleAspectFill bannerView.autoScrollTimeInterval = 5.0 bannerView.autoScroll = true bannerView.infiniteLoop = true bannerView.scrollDirection = .horizontal bannerView.layer.masksToBounds = true bannerView.layer.cornerRadius = 10.0 bannerView.delegate = self } } /// 商品数据集合视图 @IBOutlet weak var collectionView: UICollectionView! { didSet { if collectionView.responds(to: #selector(setter: UICollectionView.isPrefetchingEnabled)) { collectionView.isPrefetchingEnabled = false } /// 设置约束 collectionView.setCollectionViewLayout(flowLayout, animated: true) } } /// 商品数据列表高度 @IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint! /// 搜索框 @IBOutlet weak var searchBar: UIButton! /// 数据显示集合视图约束 lazy var flowLayout: UICollectionViewFlowLayout = { /// 最小行间距,默认是0 $0.minimumLineSpacing = 0 /// 最小左右间距,默认是10 $0.minimumInteritemSpacing = 0 /// 区域内间距,默认是 UIEdgeInsetsMake(0, 0, 0, 0) $0.sectionInset = UIEdgeInsets(top: 0.0, left: 0, bottom: 0, right: 0) /// 水平滚动 $0.scrollDirection = .vertical return $0 } (UICollectionViewFlowLayout()) /// 轮播图数据 var configs: [MoImageConfigs] = [] /// 商品数据信息 var goods: [MoGoodsInfo] = [] { didSet { /// 刷新数据 self.collectionView.reloadData() /// 设置约束 collectionViewHeightConstraint.constant = CGFloat((goods.count%2 == 0) ? (goods.count/2) : (goods.count/2+1))*(((collectionView.width/2)*0.9)+80.0) DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.5, execute: { if self.goods.count > 0 { /// 等待UI操作完成,也就是tableView刷新完之后执行 DispatchQueue.main.async { [weak self] in if self?.visibleGoodsCodes.count != 0 { self?.shouldSubscriptGoodsCodes = self?.visibleGoodsCodes } } } }) } } /// GoodsCellIdentifier let GoodsCellIdentifier = "Goods_Cell" // MARK: - 生命周期 required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) /// 设置TabBar图片 self.tabBarItem.image = UIImage(named: "home_normal")?.withRenderingMode(.alwaysOriginal) self.tabBarItem.selectedImage = UIImage(named: "home_selected")?.withRenderingMode(.alwaysOriginal) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) /// 隐藏导航栏 self.navigationController?.setNavigationBarHidden(true, animated: true) /// 行情侦听 initListen() } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) /// 清除广播侦听 MTP2BusinessCore.shared.broadcastManager?.removeBroadcastListener(owner: self, forName: .ReceiveTradeQuote) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. /// 不需要返回按钮 addBackBarButtonItem(true) /// UI界面初始化 buildView() /// 数据初始化 initData() } // MARK: - 行情初始化 /// 行情监听 fileprivate func initListen() { if goods.count > 0 { /// 等待UI操作完成,也就是tableView刷新完之后执行 DispatchQueue.main.async { [weak self] in if self?.visibleGoodsCodes.count != 0 { self?.shouldSubscriptGoodsCodes = self?.visibleGoodsCodes } } } /// 侦听行情推送广播 MTP2BusinessCore.shared.broadcastManager?.addBroadcastListener(owner: self, action: .ReceiveTradeQuote) { [weak self] in guard let quoteGoodsInfos = $0.object as? [(goodsHqCode: String, exchHqCode: String)], let weakSelf = self else { return } /// 有数据 if quoteGoodsInfos.count != 0 { /// 待刷新行 var refreshIndexPaths = [IndexPath]() DispatchQueue.main.async { for (index, cell) in weakSelf.collectionView.visibleCells.enumerated() { if quoteGoodsInfos.first(where: { $0.goodsHqCode == (cell as? GoodsCell)?.model?.goodscode }) != nil { let indexPath = IndexPath(row: index, section: 0) if refreshIndexPaths.firstIndex(of: indexPath) == nil { /// 记录待刷新行 /// 判断是否在可见区域 if weakSelf.collectionView.indexPathsForVisibleItems.firstIndex(of: indexPath) != nil { refreshIndexPaths.append(indexPath) } } } } } /// 刷新行情列表 if refreshIndexPaths.count > 0 { DispatchQueue.main.async { weakSelf.collectionView.reloadItems(at: refreshIndexPaths) } } } } } // MARK: - 初始化 /// UI界面初始化 fileprivate func buildView() { /// addLoadingView self.addLoadingView() /// 添加下拉刷新控件 self.scrollView.gtm_addRefreshHeaderView(refreshHeader: DefaultGTMRefreshHeader()) { if let _ = UserDefaultsUtils.addressInfo() { /// 重置请求条件 self.requestHomePageDatas() } else { /// 游客登录 /// startAnimating self._anim?.startAnimating() /// 查询未登录前的相关信息 MTP2BusinessCore.shared.requestCommonDatas { (_) in DispatchQueue.main.async { /// stopAnimating self._anim?.stopAnimating() /// 获取首页相关数据 self.requestHomePageDatas() } } } } } /// 数据初始化 fileprivate func initData() { /// 当前登录了 if let _ = MTP2BusinessCore.shared.accountManager?.loginRsp { /// 获取首页相关数据 self.requestHomePageDatas() } else { /// 游客登录 /// startAnimating self._anim?.startAnimating() /// 查询未登录前的相关信息 MTP2BusinessCore.shared.requestCommonDatas { (_) in DispatchQueue.main.async { /// stopAnimating self._anim?.stopAnimating() /// 获取首页相关数据 self.requestHomePageDatas() } } } } // MARK: - 按钮交互 /// 按钮相应点击事件方法 /// - Parameter sender: sender @IBAction fileprivate func onButtonPressed(_ sender: UIButton) { switch sender { case settings: /// 系统设置 self.push(storyboardName: "Settings", storyboardId: "Settings", checkLogin: false) case rmzq, xkqg: /// 热卖专区 新卡抢购 guard let main = self.appDelegate.window?.rootViewController as? MainViewController, let quoteController = (main.viewControllers?[1] as? BaseNavigationController)?.viewControllers[0] as? QuoteViewController else { return } main.selectedIndex = 1 DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.4) { /// 选中 quoteController.segmentedView.defaultSelectedIndex = (sender == self.rmzq ? 0 : 1) quoteController.segmentedView.reloadData() quoteController.segmentedView.delegate?.segmentedView(quoteController.segmentedView, didSelectedItemAt: sender == self.rmzq ? 0 : 1) } case hbzx: /// 海拔资讯 let auth = UIStoryboard(name: "Settings", bundle: nil).instantiateViewController(withIdentifier: "Auth") as! AuthAddressViewController auth.title = "海拔资讯" auth.url = MTP2BusinessCore.shared.address?.newsUrl ?? "" self.navigationController?.pushViewController(auth, animated: true) case wddd: /// 我的订单 self.push(storyboardName: "Order", storyboardId: "Order") case wdkb: /// 我的商品 self.push(storyboardName: "Quote", storyboardId: "MyGoods") case police: /// 海南网警 push(storyboardName: "Feedback", storyboardId: "Feedback") case searchBar: /// 跳转到检索页面 push(storyboardName: "Quote", storyboardId: "Search", checkLogin: false) default: break } } // MARK: - 接口请求 /// 查询首页数据信息 fileprivate func requestHomePageDatas() { /// 异常 guard let goodsManager = MTP2BusinessCore.shared.goodsManager, let noticeManager = MTP2BusinessCore.shared.noticeManager else { return } let group = DispatchGroup() /// startAnimating self._anim?.startAnimating() var hotGoods: [MoGoodsInfo] = [] /// 已登录 if MTP2BusinessCore.shared.getLoginStatus() { /// 资金账号 let accountID = MTP2BusinessCore.shared.accountManager?.getCurrentTAAccountInfo()?.accountId ?? 0 /// 获取商城商品数据 group.enter() goodsManager.requestQueryHsbyMarketGoodses(goodsManager.getMarketIDs(.TRADEMODE_TRADEMODE_HSBY_SHOP), accountID, nil, nil, nil) { (isComplete, error, marketGoodses) in hotGoods.append(contentsOf: marketGoodses ?? []) group.leave() } } else { /// 获取商城商品数据 group.enter() goodsManager.requestQueryHsbyVisitorMarketGoodses(goodsManager.getMarketIDs(.TRADEMODE_TRADEMODE_HSBY_SHOP), nil, nil, nil) { (isComplete, error, marketGoodses) in hotGoods.append(contentsOf: marketGoodses ?? []) group.leave() } } /// 获取热门商品 group.enter() goodsManager.requestQueryTopGoods(goodsManager.getMarketIDs(.TRADEMODE_LISTING_SELECT), nil, nil) { (isComplete, error, topGoods) in hotGoods.append(contentsOf: topGoods ?? []) group.leave() } /// 发送请求 group.enter() /// 查询轮播图 noticeManager.requestQueryImageConfigs { (isComplete, error, imageConfigs) in self.configs = imageConfigs?.filter({$0.isshow == 1}) ?? [] group.leave() } group.notify(queue: DispatchQueue.main) { /// stopAnimating self._anim?.stopAnimating() /// endRefreshing self.scrollView.endRefreshing() /// 热门商品数据 self.goods = hotGoods.sorted(by: { (obj1, obj2) -> Bool in return obj1.hotindex>obj2.hotindex }) /// 轮播图相关 if self.configs.count != 0 { let paths = self.configs.map({ (model) -> String in let managerUrl = MTP2BusinessCore.shared.address?.openApiUrl ?? "" let url = managerUrl+NSString(string: model.imagepath).replacingOccurrences(of: "./", with: "/") return url }) self.bannerView.imageURLStringsGroup = paths } /// 新闻地址信息 if let url = MTP2BusinessCore.shared.address?.newsUrl, url != "" { self.hbzxStackView.isHidden = false } else { self.hbzxStackView.isHidden = true } } } // MARK: - 订阅行情相关 var uuid: String = UUID().uuidString var shouldSubscriptGoodsCodes: Set? { didSet { guard let quoteSubscriptManager = MTP2BusinessCore.shared.quoteSubscriptManager else { return } quoteSubscriptManager.updateQuoteSubcriptGoods(uuid: uuid, goodsCode: shouldSubscriptGoodsCodes ?? []) } } var visibleGoodsCodes: Set { var goodsCodes = Set() self.collectionView.visibleCells.forEach { (cell) in if let quoteCell = cell as? GoodsCell, let goodsCode = quoteCell.model?.goodscode { goodsCodes.insert(goodsCode) } } return goodsCodes } /* // 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. } */ } // MARK: - SFSafariViewControllerDelegate extension HomeViewController: SFSafariViewControllerDelegate { func safariViewControllerDidFinish(_ controller: SFSafariViewController) { controller.dismiss(animated: true, completion: {}) } } // MARK: - UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return goods.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: GoodsCellIdentifier, for: indexPath) as! GoodsCell cell.model = goods[indexPath.row] return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: collectionView.width/2, height: ((collectionView.width/2)*0.9)+80.0) } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { /// 商品详情 let goodsDetailController = UIStoryboard(name: "Quote", bundle: nil).instantiateViewController(withIdentifier: "GoodsDetail") as! GoodsDetailViewController goodsDetailController.model = self.goods[indexPath.row] self.navigationController?.pushViewController(goodsDetailController, animated: true) } } // MARK: - SDCycleScrollViewDelegate extension HomeViewController: SDCycleScrollViewDelegate { func cycleScrollView(_ cycleScrollView: SDCycleScrollView!, didScrollTo index: Int) {} func cycleScrollView(_ cycleScrollView: SDCycleScrollView!, didSelectItemAt index: Int) { /// 广告跳转 if configs[index].urltype == 1, configs[index].url != "" { let urlString = !configs[index].url.lowercased().hasPrefix("http://") ? ("http://"+configs[index].url) : configs[index].url guard let url = URL(string: urlString) else { return } let safriViewController = SFSafariViewController(url: url) safriViewController.delegate = self self.present(safriViewController, animated: true, completion: {}) } else { /// 商品ID /// 异常 guard let goodsManager = MTP2BusinessCore.shared.goodsManager else { return } if configs[index].trademode == ETradeMode.TRADEMODE_LISTING_SELECT, let goodsInfo = MTP2BusinessCore.shared.goodsManager?.goodsInfos.first(where: {"\($0.goodsid)" == configs[index].url}) { /// 竞价商品 let goodsDetailController = UIStoryboard(name: "Quote", bundle: nil).instantiateViewController(withIdentifier: "GoodsDetail") as! GoodsDetailViewController goodsDetailController.model = goodsInfo self.navigationController?.pushViewController(goodsDetailController, animated: true) } else { /// 商城商品 if MTP2BusinessCore.shared.getLoginStatus() { /// 已登录 goodsManager.requestQueryHsbyMarketGoodses(goodsManager.getMarketIDs(.TRADEMODE_TRADEMODE_HSBY_SHOP), nil, MTP2BusinessCore.shared.accountManager?.getCurrentTAAccountInfo()?.accountId, configs[index].url, nil, callback: { (isComplete, error, objs) in DispatchQueue.main.async { if isComplete, let goodsInfo = objs?.first(where: {"\($0.goodsid)" == self.configs[index].url}) { let goodsDetailController = UIStoryboard(name: "Quote", bundle: nil).instantiateViewController(withIdentifier: "GoodsDetail") as! GoodsDetailViewController goodsDetailController.model = goodsInfo self.navigationController?.pushViewController(goodsDetailController, animated: true) } } }) } else { /// 未登录 goodsManager.requestQueryHsbyVisitorMarketGoodses(goodsManager.getMarketIDs(.TRADEMODE_TRADEMODE_HSBY_SHOP), nil, configs[index].url, nil, callback: { (isComplete, error, objs) in DispatchQueue.main.async { if isComplete, let goodsInfo = objs?.first(where: {"\($0.goodsid)" == self.configs[index].url}) { let goodsDetailController = UIStoryboard(name: "Quote", bundle: nil).instantiateViewController(withIdentifier: "GoodsDetail") as! GoodsDetailViewController goodsDetailController.model = goodsInfo self.navigationController?.pushViewController(goodsDetailController, animated: true) } } }) } } } } } /// 商品数据Cell class GoodsCell: UICollectionViewCell { /// 背景图片 @IBOutlet weak var image: UIImageView! /// 商品名称 @IBOutlet weak var goodsName: UILabel! /// 价格 @IBOutlet weak var price: UILabel! /// 数据集合 var model: MoGoodsInfo? { didSet { /// 更新显示行情数据 guard let obj = MTP2BusinessCore.shared.goodsManager?.goodsInfos.first(where: { $0.goodscode == model?.goodscode }) else { return } /// 商品名称 goodsName.text = obj.goodsname /// 价格 if obj.trademode == .TRADEMODE_LISTING_SELECT { /// 竞价商品 price.attributedText = (obj.currencysign.withFont(.font_12)+" \((obj.getLast() == 0.0 ? obj.last : obj.getLast()).toDownString(reserve: obj.decimalplace))".withFont(.font_16)).withTextColor(.red) } else if obj.trademode == .TRADEMODE_TRADEMODE_HSBY_SHOP { /// 商城商品 price.attributedText = (("\(obj.currencysign)".withFont(.font_12))+("\(obj.goodsprice)".withFont(.font_16))).withTextColor(.red) } else { /// 新品抢购 price.attributedText = (("抢购价:\(obj.currencysign)".withFont(.font_12))+(obj.refprice.description.withFont(.font_16))).withTextColor(.red) } /// 地址异常 if let url = StringUtils.getImageUrl(obj.picurls) { /// 背景图片 image.sd_setImage(with: url, placeholderImage: UIImage(named: "placeholder_image"), options: .queryDiskDataSync, context: nil) } } } }