WanPai/Common/View/ChooseStoreView.swift
@@ -13,7 +13,10 @@ @IBOutlet weak var view_container: UIView! @IBOutlet weak var view_bottomContainer: NSLayoutConstraint! @IBOutlet weak var tableView: UITableView! private var clouse:(()->Void)! private var clouse:((StoreSimpleModel)->Void)! private var models = [StoreSimpleModel]() private var selectIndex = 0 private var defaultModel:StoreSimpleModel? override func awakeFromNib() { super.awakeFromNib() @@ -27,12 +30,22 @@ layoutIfNeeded() } static func show(_ clouse:@escaping ()->Void){ static func show(models:[StoreSimpleModel],defaultModel:StoreSimpleModel? = nil, clouse:@escaping (StoreSimpleModel)->Void){ let chooseStoreView = ChooseStoreView.jq_loadNibView() chooseStoreView.frame = screnDelegate?.window?.frame ?? .zero screnDelegate?.window?.addSubview(chooseStoreView) chooseStoreView.view_bottomContainer.constant = 0 chooseStoreView.defaultModel = defaultModel chooseStoreView.clouse = clouse chooseStoreView.models = models for (index,m) in models.enumerated(){ if m.storeId == defaultModel?.storeId{ chooseStoreView.selectIndex = index;break } } chooseStoreView.tableView.reloadData() UIView.animate(withDuration: 0.4) { chooseStoreView.alpha = 1 chooseStoreView.layoutIfNeeded() @@ -56,7 +69,8 @@ self.layoutIfNeeded() } completion: { _ in self.removeFromSuperview() self.clouse!() let model = self.models[self.selectIndex] self.clouse!(model) } } @@ -67,12 +81,19 @@ } extension ChooseStoreView:UITableViewDelegate{ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { selectIndex = indexPath.row tableView.reloadData() } } extension ChooseStoreView:UITableViewDataSource{ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let model = models[indexPath.row] let cell = tableView.dequeueReusableCell(withIdentifier: "_CommonSingleTCell") as! CommonSingleTCell cell.label_title.text = model.storeName cell.img_select.image = indexPath.row == selectIndex ? UIImage(named: "btn_choose_s") : UIImage(named: "btn_choose") return cell } @@ -81,6 +102,6 @@ } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 5 return models.count } } WanPai/Config/Enums.swift
@@ -152,6 +152,14 @@ } } enum Sort2Type:Int,HandyJSONEnum{ //1积分高到低 2积分从低到高 3兑换从高到低 case coinAsc = 1 case coinDesc = 2 case exAsc = 3 case exDesc = 4 } enum GenderType:Int,HandyJSONEnum{ case man = 1 case woman = 2 @@ -266,3 +274,27 @@ case used = 2 case overdue = 3 } enum ExchangeType:Int,HandyJSONEnum{ //商品类型 1实物 2课包 3门票 4优惠券 case goods = 1 case course = 2 case ticket = 3 case coupon = 4 var strTitle:String{ switch self { case .goods:return "实物" case .coupon:return "优惠券" case .course:return "课程" case .ticket:return "门票" } } } enum ExchangePaymentType:Int,HandyJSONEnum{ case coin = 1 case cashAndCoin = 2 } WanPai/Model/CommonModels.swift
@@ -78,6 +78,16 @@ var stuWeight:Double = 0 } struct StudentProfile2Model:HandyJSON{ var stuAge:Int = 0 var stuId = 0 var stuName:String = "" var stuPhone:String = "" var storeId:Int = 0 var storeName:String = "" } struct CouponInfoModel:HandyJSON{ ///有效时间 var effectiveTime: String = "" @@ -398,6 +408,7 @@ var commodityImg: String = "" var commodityName: String = "" var commodityPrice: Double = 0 var goodsType:ExchangeType = .goods } struct BillingModel:HandyJSON{ @@ -430,4 +441,42 @@ var wpGold:Int = 0 } struct ExchangeGoodsModel:HandyJSON { var belongs: String = "" var belongsScope: RegisterAcitivyType = .allUser var contents: String = "" var cost: Int = 0 var courseHours: Int = 0 var endTime: String = "" var exchangeAddrType: CouponConditionType = .nationwide var exchangeType: ExchangePaymentType = .coin var goodId: Int = 0 var goodName: String = "" var goodType: ExchangeType = .goods var perLimit: Int = 0 var pics = [String]() var redeemedNum: Int = 0 var integral:Int = 0 var cash:Double = 0 var residueNum: Int = 0 var startTime: String = "" } struct StoreSimpleModel:HandyJSON{ var storeName = "" var storeId = 0 } struct MarketMdoel:HandyJSON{ var amount: Double = 0 var belongsType: RegisterAcitivyType = .allUser var condition: ExchangePaymentType = .cashAndCoin var goodId: Int = 0 var goodImg: String = "" var goodName: String = "" var goodsType: ExchangeType = .goods var integral: Int = 0 var nums: Int = 0 } WanPai/Network/Services.swift
@@ -140,11 +140,13 @@ /// 充值明细 /// - Parameters: /// - yearMonth: 记录(1充值 2扣除) class func voucherDetail(recordType:Int?,yearMonth:String)->Observable<BaseResponse<[BillingModel]>>{ class func voucherDetail(recordType:Int?,yearMonth:String,page:Int,pageSize:Int = 20)->Observable<BaseResponse<[BillingModel]>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/account/api/useBenefit/voucherDetail") .append(key: "recordId", value: recordType) .append(key: "yearMonth", value: yearMonth) .append(key: "pageNum", value: page) .append(key: "pageSize", value: pageSize) return NetworkRequest.request(params: params, method: .post, progress: false) } @@ -157,10 +159,10 @@ } /// 支付 class func useBenefitPayment(payAmount:Double,payType:PayType)->Observable<BaseResponse<SimpleModel>>{ class func useBenefitPayment(chargeId:Int,payType:PayType)->Observable<BaseResponse<SimpleModel>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/account/api/useBenefit/payment") .append(key: "payAmount", value: payAmount) .append(key: "chargeId", value: chargeId) .append(key: "payType", value: payType.rawValue) return NetworkRequest.request(params: params, method: .post, progress: true) } @@ -384,6 +386,65 @@ .append(key: "score", value: score) return NetworkRequest.request(params: params, method: .post, progress: true) } } // MARK: -- 商城部分 extension Services{ /// 积分商城-商品详情 static func UseBenefitDetail(goodsId:Int,goodsType:ExchangeType)->Observable<BaseResponse<ExchangeGoodsModel>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/account/api/useBenefit/goodsDetails") .append(key: "goodsId", value: goodsId) .append(key: "goodsType", value: goodsType.rawValue) return NetworkRequest.request(params: params, method: .post, progress: true) } /// 兑换门店 static func exchangeStoreIds(id:Int,type:ExchangeType)->Observable<BaseResponse<[StoreSimpleModel]>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/account/api/useBenefit/exchangeStoreIds") .append(key: "goodsId", value: id) .append(key: "goodsType", value: type.rawValue) return NetworkRequest.request(params: params, method: .post, progress: false) } /// 兑换商品 static func exchangeOperation(exchangeType:ExchangePaymentType,goodsId:Int,goodsType:ExchangeType,num:Int,payType:PayType?,stuIds:String)->Observable<BaseResponse<PaymentModel>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/account/api/useBenefit/productRedemptionOperation") .append(key: "exchangeType", value: exchangeType.rawValue) .append(key: "goodId", value: goodsId) .append(key: "goodsType", value: goodsType.rawValue) .append(key: "nums", value: num) .append(key: "payType", value: payType?.rawValue) .append(key: "stuIds", value: stuIds) return NetworkRequest.request(params: params, method: .post, progress: true) } /// 积分商城-实体、门票、优惠券为默认门店|课包为默认学员 static func goodsOfCourseStore(isCourse:Bool,pointsMerId:Int)->Observable<BaseResponse<StudentProfile2Model>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/account/api/useBenefit/goodsOfCourseStore") .append(key: "isCourse", value: isCourse) .append(key: "pointsMerId", value: pointsMerId) return NetworkRequest.request(params: params, method: .post, progress: false) } /// 商城中心 class func mallList(goodsType:ExchangeType?,rank:Sort2Type?,search:String?)->Observable<BaseResponse<[MarketMdoel]>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/account/api/useBenefit/integralMallList") .append(key: "goodsType", value: goodsType?.rawValue) .append(key: "rank", value: rank?.rawValue) .append(key: "lat", value: locationTool.currentLocation?.coordinate.latitude.string) .append(key: "lon", value: locationTool.currentLocation?.coordinate.longitude.string) return NetworkRequest.request(params: params, method: .post, progress: false) } } // MARK: -- 预约场地 WanPai/Root/Welfare/CCell/CoinStoreCCell.swift
@@ -11,6 +11,25 @@ class CoinStoreCCell: UICollectionViewCell { @IBOutlet weak var img: UIImageView! @IBOutlet weak var view_container: UIView! @IBOutlet weak var label_title: UILabel! @IBOutlet weak var label_cond: UILabel! @IBOutlet weak var label_price: UILabel! @IBOutlet weak var label_type: UILabel! var marketModel:MarketMdoel!{ didSet{ img.sd_setImage(with: URL(string: marketModel.goodImg)) label_title.text = marketModel.goodName label_cond.text = marketModel.belongsType.strTitle label_type.text = marketModel.goodsType.strTitle if marketModel.condition == .coin{ label_price.text = "\(marketModel.integral)积分" }else{ label_price.text = "\(marketModel.integral)积分+\(marketModel.amount.currency())" } } } override func awakeFromNib() { super.awakeFromNib() WanPai/Root/Welfare/CCell/CoinStoreCCell.xib
@@ -81,6 +81,10 @@ <size key="customSize" width="311" height="421"/> <connections> <outlet property="img" destination="MxK-ok-XBK" id="sLv-8g-oVE"/> <outlet property="label_cond" destination="wiA-ab-lxq" id="XD2-Lm-gXY"/> <outlet property="label_price" destination="rHf-PZ-mhf" id="QN9-6l-MM6"/> <outlet property="label_title" destination="lhv-BK-Dvg" id="M3u-qh-jcK"/> <outlet property="label_type" destination="5kE-Rc-Iuu" id="HGO-nt-nth"/> <outlet property="view_container" destination="Seb-oU-zxq" id="U7N-WT-zNI"/> </connections> <point key="canvasLocation" x="154.96183206106869" y="117.95774647887325"/> WanPai/Root/Welfare/VC/CoinStoreCenterVC.swift
@@ -7,10 +7,24 @@ import UIKit import JQTools import RxSwift import RxRelay class CoinStoreViewModel:RefreshModel<MarketMdoel>{ var goodsType = BehaviorRelay<ExchangeType?>(value: nil) var rank = BehaviorRelay<Sort2Type?>(value: nil) let search = BehaviorRelay<String?>(value: nil) override func api() -> (Observable<BaseResponse<[MarketMdoel]>>)? { Services.mallList(goodsType: goodsType.value, rank: rank.value, search: search.value) } } class CoinStoreCenterVC: BaseVC { private lazy var collectionView:UICollectionView = { private let viewModel = CoinStoreViewModel() private lazy var collectionView:BaseCollectionView = { let CellW:Double = (JQ_ScreenW) / 2.0 let CellH:Double = CellW * 1.3428 @@ -19,10 +33,10 @@ flowLayout.minimumLineSpacing = 0 flowLayout.minimumInteritemSpacing = 0 flowLayout.itemSize = CGSize(width: CellW, height: CellH) flowLayout.headerReferenceSize = CGSize(width: JQ_ScreenW, height: 227) flowLayout.headerReferenceSize = CGSize(width: JQ_ScreenW, height: JQ_ScreenW * 0.5564) flowLayout.sectionHeadersPinToVisibleBounds = true let collect = UICollectionView(frame: .zero, collectionViewLayout: flowLayout) let collect = BaseCollectionView(frame: .zero, collectionViewLayout: flowLayout) collect.delegate = self collect.dataSource = self collect.contentInset = UIEdgeInsets(top: 0, left:0, bottom: 14, right: 0) @@ -31,9 +45,15 @@ return collect }() var benefitHomeModel:BenefitHomeModel? override func viewDidLoad() { super.viewDidLoad() title = "积分商城" viewModel.configure(collectionView,needMore: false) collectionView.jq_setEmptyView() viewModel.beginRefresh() } override func setUI() { @@ -48,26 +68,34 @@ extension CoinStoreCenterVC:UICollectionViewDelegate{ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let vc = WelfareRedeemGoodsDetailVC() let model = viewModel.dataSource.value[indexPath.row] let vc = WelfareRedeemGoodsDetailVC(commodityId: model.goodId, goodsType: model.goodsType) push(vc: vc) } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let headView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "_CoinStoreHeadView", for: indexPath) as! CoinStoreHeadView headView.innerView = self.view headView.viewModel = viewModel headView.label_coin.text = "\(benefitHomeModel?.userIntegral ?? 0)积分" headView.label_username.text = benefitHomeModel?.userName ?? "" headView.img_cover.sd_setImage(with: URL(string: benefitHomeModel?.userHeadImg)) headView.tf_search.rx.text.orEmpty.bind(to: viewModel.search).disposed(by: disposeBag) return headView } } extension CoinStoreCenterVC:UICollectionViewDataSource{ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let model = viewModel.dataSource.value[indexPath.row] let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_CoinStoreCCell", for: indexPath) as! CoinStoreCCell cell.marketModel = model return cell } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 15 return viewModel.dataSource.value.count } func numberOfSections(in collectionView: UICollectionView) -> Int { WanPai/Root/Welfare/VC/RechargeCenterVC.swift
@@ -77,7 +77,7 @@ @IBAction func rechargeAction(_ sender: UIButton) { let item = items[selectIndex] PaymentView.show(money: (ali:item.money,wx:item.money,coin:item.coin,course:nil)) { type in PaymentView.show(money: (ali:item.money,wx:item.money,coin:nil,course:nil)) { type in // let result:PaymentResultVC.PaymentResult = status ? .success:.fail // let vc = PaymentResultVC(result: result, objType: .activityApply) WanPai/Root/Welfare/VC/RechargeRecordVC.swift
@@ -16,7 +16,7 @@ var type = BehaviorRelay<Int?>(value: nil) var yearMonth = BehaviorRelay<String>(value: "") override func api() -> (Observable<BaseResponse<[BillingModel]>>)? { return Services.voucherDetail(recordType: type.value, yearMonth: yearMonth.value) return Services.voucherDetail(recordType: type.value, yearMonth: yearMonth.value,page: page,pageSize: pageSize) } } @@ -71,7 +71,7 @@ viewModel.yearMonth.accept(Date().jq_format("yyyy-MM")) btn_date.setTitle("\(Date().jq_format("yyyy年MM月"))>", for: .normal) viewModel.configure(tableView,needMore: false) viewModel.configure(tableView) viewModel.beginRefresh() } WanPai/Root/Welfare/VC/WelfareRedeemGoodsDetailVC.swift
@@ -8,6 +8,7 @@ import UIKit import QMUIKit import JQTools import WebKit class WelfareRedeemGoodsDetailVC: BaseVC { @@ -15,10 +16,97 @@ @IBOutlet weak var btn_store: QMUIButton! @IBOutlet weak var tableView: UITableView! @IBOutlet weak var cons_tableHei: NSLayoutConstraint! @IBOutlet weak var view_banner: UIView! @IBOutlet weak var label_title: UILabel! @IBOutlet weak var label_exchange: UILabel! @IBOutlet weak var label_limit: UILabel! @IBOutlet weak var label_cost: UILabel! @IBOutlet weak var label_redeemedNum: UILabel! @IBOutlet weak var label_residueNum: UILabel! @IBOutlet weak var label_perLimit: UILabel! @IBOutlet weak var label_startTime: UILabel! @IBOutlet weak var label_courseHours: UILabel! @IBOutlet weak var view_courseHours: UIView! @IBOutlet weak var view_exchangeStore: UIView! @IBOutlet weak var webView: WKWebView! @IBOutlet weak var label_storeName: UILabel! @IBOutlet weak var cons_webHei: NSLayoutConstraint! @IBOutlet weak var btn_exchange: UIButton! private var bannerView:CommonBannerView = { let banner = CommonBannerView() return banner }() // private var model:BenefitHomeCommonditiesModel! private var id:Int! private var goodsType:ExchangeType! private var exchangeGoodsModel:ExchangeGoodsModel? private var storeModels = [StoreSimpleModel]() private var selectStoreModel:StoreSimpleModel? private var studentModels = [CourseDetailStudentModel]() init(commodityId:Int,goodsType:ExchangeType) { super.init(nibName: nil, bundle: nil) self.id = commodityId self.goodsType = goodsType } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() title = "商品详情" Services.UseBenefitDetail(goodsId: id, goodsType: goodsType).subscribe(onNext: {[weak self] data in guard let weakSelf = self else { return } if let model = data.data{ self?.exchangeGoodsModel = model self?.label_title.text = model.goodName self?.label_limit.text = String(format: "%@|%@", model.belongsScope.strTitle,model.exchangeAddrType.titleRaw) self?.label_cost.text = String(format: "价值:%ld", model.cost) self?.label_redeemedNum.text = "\(model.redeemedNum)" self?.label_residueNum.text = "\(model.residueNum)" self?.label_perLimit.text = "\(model.perLimit)" self?.label_startTime.text = "\(model.startTime)-\(model.endTime)" self?.label_courseHours.text = "\(model.courseHours)课时" self?.view_courseHours.isHidden = model.courseHours == 0 self?.view_exchangeStore.isHidden = model.exchangeAddrType != .store switch model.exchangeType{ case .coin: self?.label_exchange.text = String(format: "%ld积分", model.integral) case .cashAndCoin: self?.label_exchange.text = String(format: "%ld积分+%@", model.integral,model.cash.currency()) } //加载门店 if model.exchangeAddrType == .store{ Services.exchangeStoreIds(id: model.goodId, type: model.goodType).subscribe(onNext: {[weak self] data in if let models = data.data{ self?.storeModels = models self?.selectStoreModel = models.first self?.label_storeName.text = models.first?.storeName ?? "未知门店" } }).disposed(by: weakSelf.disposeBag) } if model.contents.isEmpty{ self?.webView.loadHTMLString("暂无说明".jq_wrapHtml(), baseURL: nil) }else{ self?.webView.loadHTMLString(model.contents.jq_wrapHtml(), baseURL: nil) } } }).disposed(by: disposeBag) bannerView.setImages(images: exchangeGoodsModel?.pics ?? [], type: .URL) { index in } updateStudenTable() } override func setUI() { @@ -33,34 +121,112 @@ tableView.isScrollEnabled = false tableView.separatorStyle = .none tableView.register(UINib(nibName: "StudentInfoTCell", bundle: nil), forCellReuseIdentifier: "_StudentInfoTCell") view_banner.addSubview(bannerView) bannerView.snp.makeConstraints { make in make.edges.equalToSuperview() } } override func setRx() { self.webView.scrollView.rx.observe(CGSize.self, "contentSize").map { (size) -> CGFloat? in if let size = size{ return size.height } return nil }.subscribe(onNext: { [unowned self](height) in if let height = height{ self.cons_webHei.constant = height } }).disposed(by: disposeBag) } private func updateStudenTable(){ cons_tableHei.constant = Double(studentModels.count) * 100 tableView.reloadData() } @IBAction func chooseAction(_ sender: QMUIButton) { StudentChooseView.show(itemType: .course) { studs in } needAddClouse: { guard exchangeGoodsModel != nil else {return} StudentChooseView.show(itemType: .course, defaultStu: studentModels) {[weak self] studs in guard let weakSelf = self else { return } if studs.count > weakSelf.exchangeGoodsModel!.perLimit{ alert(msg: "最多选择\(weakSelf.exchangeGoodsModel!.perLimit)位学员");return } self?.studentModels = studs as! [CourseDetailStudentModel] self?.updateStudenTable() } needAddClouse: { [weak self] in let vc = ActivityStudentListVC() self.push(vc: vc) self?.push(vc: vc) } } @IBAction func chooseStoreAction(_ sender: QMUIButton) { ChooseStoreView.show { ChooseNumberView.show(maxNumber: 5) { num in let attribute = AttributedStringbuilder() attribute.add(string: "确认消耗", withFont: UIFont.systemFont(ofSize: 16, weight: .medium), withColor: .black.withAlphaComponent(0.9)) .add(string: "0积分和¥0\n", withFont: UIFont.systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexStr: "#E41818").withAlphaComponent(0.8)) .add(string: "兑换此商品吗?", withFont: UIFont.systemFont(ofSize: 16, weight: .medium), withColor: .black.withAlphaComponent(0.9)) CommonAlertView.show(title: "兑换商品", attribute: attribute.mutableAttributedString) { state in PaymentView.show(money: (ali:1,wx:2,coin:2,course:2)) { status in // let result:PaymentResultVC.PaymentResult = status ? .success:.fail // let vc = PaymentResultVC(result: result, objType: .activityApply) // vc.modalPresentationStyle = .fullScreen // self.present(vc, animated: true) guard storeModels.count != 0 else {return} ChooseStoreView.show(models: storeModels,defaultModel: selectStoreModel) {[weak self] m in self?.selectStoreModel = m self?.label_storeName.text = m.storeName } } @IBAction func exchangeAction(_ sender: UIButton) { guard exchangeGoodsModel != nil else {return} guard exchangeGoodsModel!.residueNum != 0 else {alert(msg: "已兑换光啦");return} guard studentModels.count != 0 else {alert(msg: "请选择学员");return} ChooseNumberView.show(maxNumber: exchangeGoodsModel!.perLimit) {[weak self] num in guard let weakSelf = self else { return } let attribute = AttributedStringbuilder() attribute.add(string: "确认消耗", withFont: UIFont.systemFont(ofSize: 16, weight: .medium), withColor: .black.withAlphaComponent(0.9)) if weakSelf.exchangeGoodsModel!.exchangeType == .coin{ attribute.add(string: "\(weakSelf.exchangeGoodsModel!.cost * weakSelf.studentModels.count)积分", withFont: UIFont.systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexStr: "#E41818").withAlphaComponent(0.8)) }else{ attribute.add(string: String(format: "%ld积分和%@", weakSelf.exchangeGoodsModel!.integral * weakSelf.studentModels.count,(weakSelf.exchangeGoodsModel!.cash * Double(weakSelf.studentModels.count)).currency()), withFont: UIFont.systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexStr: "#E41818").withAlphaComponent(0.8)) } attribute.add(string: "兑换此商品吗?", withFont: UIFont.systemFont(ofSize: 16, weight: .medium), withColor: .black.withAlphaComponent(0.9)) CommonAlertView.show(title: "兑换商品", attribute: attribute.mutableAttributedString) { state in if weakSelf.exchangeGoodsModel!.exchangeType == .coin{ Services.exchangeOperation(exchangeType: .coin, goodsId: weakSelf.exchangeGoodsModel!.goodId, goodsType: weakSelf.exchangeGoodsModel!.goodType, num: num, payType: nil, stuIds: weakSelf.studentModels.map({"\($0.id)"}).joined(separator: ",")).subscribe(onNext: {data in alertSuccess(msg: "兑换成功") weakSelf.exchangeSuccessUI() }).disposed(by: weakSelf.disposeBag) }else { //支付金额 let cash = weakSelf.exchangeGoodsModel!.cash PaymentView.show(money: (ali:cash,wx:cash,coin:nil,course:nil)) { payType in Services.exchangeOperation(exchangeType: .cashAndCoin, goodsId: weakSelf.exchangeGoodsModel!.goodId, goodsType: weakSelf.exchangeGoodsModel!.goodType, num: num, payType: payType, stuIds: weakSelf.studentModels.map({"\($0.id)"}).joined(separator: ",")).subscribe(onNext: {data in if let m = data.data{ switch payType { case .aliPay: YYPaymentManager.shared.sendPaymentRequest(YYAlipayRequest(orderString: m.orderString)) { result in switch result { case .success:alertSuccess(msg: "兑换成功") weakSelf.exchangeSuccessUI() case .cancel: alert(msg: "已取消兑换") case .failure(let error): alertError(msg: error.localizedDescription) } } case .wechat:break case .coin:break case .courseNum:break } } }).disposed(by: weakSelf.disposeBag) } } } } } private func exchangeSuccessUI(){ btn_exchange.setTitle("已兑换", for: .normal) btn_exchange.isEnabled = false label_redeemedNum.text = "\(exchangeGoodsModel!.redeemedNum + 1)" label_residueNum.text = "\(exchangeGoodsModel!.residueNum - 1)" } } @@ -71,10 +237,16 @@ extension WelfareRedeemGoodsDetailVC:UITableViewDataSource{ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "_StudentInfoTCell") as! StudentInfoTCell cell.indexPath = indexPath cell.studentModel = studentModels[indexPath.row] cell.deleClouse = {[weak self] index in self?.studentModels.remove(at: index) self?.updateStudenTable() } return cell } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 return studentModels.count } } WanPai/Root/Welfare/VC/WelfareRedeemGoodsDetailVC.xib
@@ -12,11 +12,27 @@ <objects> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="WelfareRedeemGoodsDetailVC" customModule="WanPai" customModuleProvider="target"> <connections> <outlet property="btn_exchange" destination="R3A-cj-kzU" id="zYY-kt-Uxt"/> <outlet property="btn_store" destination="DK1-7I-Zgs" id="P4s-8p-Srp"/> <outlet property="btn_student" destination="NfN-7G-XM4" id="Heh-WX-eDd"/> <outlet property="cons_tableHei" destination="2Vo-tY-Rnk" id="1xt-su-irf"/> <outlet property="cons_webHei" destination="bhR-O6-N5b" id="pLq-LA-JB3"/> <outlet property="label_cost" destination="7Oz-EC-ypg" id="mAM-ff-ZBK"/> <outlet property="label_courseHours" destination="FgM-YE-waa" id="vSp-bJ-SaS"/> <outlet property="label_exchange" destination="wai-5S-si5" id="6Ah-wX-zHO"/> <outlet property="label_limit" destination="Lm4-og-vup" id="a4n-h0-WgY"/> <outlet property="label_perLimit" destination="HyU-Ki-Lwv" id="Eiy-oR-rMF"/> <outlet property="label_redeemedNum" destination="Nun-Hi-Ba8" id="Bf7-w1-Ysg"/> <outlet property="label_residueNum" destination="DpQ-7A-Y6o" id="wV8-M0-a7H"/> <outlet property="label_startTime" destination="RwQ-MS-2sL" id="n3f-g9-OqW"/> <outlet property="label_storeName" destination="4dK-Zl-Jdj" id="yAy-e3-kqY"/> <outlet property="label_title" destination="Xbv-xb-Opx" id="wSK-g7-wYb"/> <outlet property="tableView" destination="Iqj-NB-Sdv" id="whY-na-FVo"/> <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> <outlet property="view_banner" destination="Qqf-lq-tQb" id="nPC-xS-Gbj"/> <outlet property="view_courseHours" destination="FLV-Kf-Avt" id="oDU-BH-bZj"/> <outlet property="view_exchangeStore" destination="PF8-aV-ew9" id="x4R-3l-zbD"/> <outlet property="webView" destination="tQn-lc-7cb" id="xcY-cg-bKR"/> </connections> </placeholder> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> @@ -24,11 +40,24 @@ <rect key="frame" x="0.0" y="0.0" width="393" height="852"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="R3A-cj-kzU"> <rect key="frame" x="0.0" y="770" width="393" height="48"/> <color key="backgroundColor" name="FE6E0D"/> <constraints> <constraint firstAttribute="height" constant="48" id="bSI-1u-taE"/> </constraints> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" title="立即兑换"/> <connections> <action selector="exchangeAction:" destination="-1" eventType="touchUpInside" id="NPs-3e-YIi"/> </connections> </button> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="L61-7B-reh"> <rect key="frame" x="0.0" y="59" width="393" height="759"/> <rect key="frame" x="0.0" y="59" width="393" height="711"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gbh-Le-CoL"> <rect key="frame" x="0.0" y="0.0" width="393" height="872"/> <rect key="frame" x="0.0" y="0.0" width="393" height="829"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Qqf-lq-tQb"> <rect key="frame" x="0.0" y="0.0" width="393" height="221.66666666666666"/> @@ -362,26 +391,30 @@ <nil key="textColor"/> <nil key="highlightedColor"/> </label> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Zp9-nM-vpb"> <rect key="frame" x="0.0" y="724" width="393" height="100"/> <wkWebView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tQn-lc-7cb"> <rect key="frame" x="0.0" y="719" width="393" height="100"/> <constraints> <constraint firstAttribute="height" constant="100" id="XNx-ob-i8c"/> <constraint firstAttribute="height" constant="100" id="bhR-O6-N5b"/> </constraints> </imageView> <wkWebViewConfiguration key="configuration"> <audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/> <wkPreferences key="preferences"/> </wkWebViewConfiguration> </wkWebView> </subviews> <color key="backgroundColor" systemColor="systemBackgroundColor"/> <constraints> <constraint firstItem="37m-yk-F6F" firstAttribute="top" secondItem="Qqf-lq-tQb" secondAttribute="bottom" id="7XC-I0-EDS"/> <constraint firstItem="Qqf-lq-tQb" firstAttribute="leading" secondItem="gbh-Le-CoL" secondAttribute="leading" id="88i-86-LCE"/> <constraint firstItem="Zp9-nM-vpb" firstAttribute="top" secondItem="eGT-qY-7F5" secondAttribute="bottom" constant="15" id="8Jo-IW-w6Q"/> <constraint firstItem="eGT-qY-7F5" firstAttribute="top" secondItem="37m-yk-F6F" secondAttribute="bottom" constant="15" id="8g1-AM-BJ7"/> <constraint firstAttribute="bottom" secondItem="tQn-lc-7cb" secondAttribute="bottom" constant="10" id="HoY-bM-nev"/> <constraint firstItem="37m-yk-F6F" firstAttribute="leading" secondItem="gbh-Le-CoL" secondAttribute="leading" id="Kai-3Z-AgF"/> <constraint firstItem="Zp9-nM-vpb" firstAttribute="leading" secondItem="gbh-Le-CoL" secondAttribute="leading" id="Ual-bZ-2mE"/> <constraint firstItem="Qqf-lq-tQb" firstAttribute="top" secondItem="gbh-Le-CoL" secondAttribute="top" id="VuQ-fm-LhH"/> <constraint firstAttribute="bottom" secondItem="Zp9-nM-vpb" secondAttribute="bottom" constant="48" id="jId-7F-KSB"/> <constraint firstItem="tQn-lc-7cb" firstAttribute="top" secondItem="eGT-qY-7F5" secondAttribute="bottom" constant="10" id="ZbZ-JC-YHg"/> <constraint firstAttribute="trailing" secondItem="tQn-lc-7cb" secondAttribute="trailing" id="ic1-2v-l5U"/> <constraint firstAttribute="trailing" secondItem="37m-yk-F6F" secondAttribute="trailing" id="mq2-n6-vUt"/> <constraint firstItem="tQn-lc-7cb" firstAttribute="leading" secondItem="gbh-Le-CoL" secondAttribute="leading" id="qOA-YH-0DD"/> <constraint firstItem="eGT-qY-7F5" firstAttribute="leading" secondItem="gbh-Le-CoL" secondAttribute="leading" constant="15" id="qc4-es-fxP"/> <constraint firstAttribute="trailing" secondItem="Zp9-nM-vpb" secondAttribute="trailing" id="ueX-OG-jV3"/> <constraint firstAttribute="trailing" secondItem="Qqf-lq-tQb" secondAttribute="trailing" id="yKT-7i-2oY"/> </constraints> </view> @@ -394,16 +427,6 @@ <constraint firstAttribute="trailing" secondItem="gbh-Le-CoL" secondAttribute="trailing" id="m4d-PS-M4I"/> </constraints> </scrollView> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="R3A-cj-kzU"> <rect key="frame" x="0.0" y="770" width="393" height="48"/> <color key="backgroundColor" name="FE6E0D"/> <constraints> <constraint firstAttribute="height" constant="48" id="bSI-1u-taE"/> </constraints> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" title="立即兑换"/> </button> </subviews> <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/> @@ -411,7 +434,7 @@ <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="L61-7B-reh" secondAttribute="trailing" id="NCa-KY-ZtU"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="R3A-cj-kzU" secondAttribute="trailing" id="bv0-9J-Ggi"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="R3A-cj-kzU" secondAttribute="bottom" id="gf4-mg-AOH"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="L61-7B-reh" secondAttribute="bottom" id="iyb-hB-0p6"/> <constraint firstItem="R3A-cj-kzU" firstAttribute="top" secondItem="L61-7B-reh" secondAttribute="bottom" id="hSI-4x-b80"/> <constraint firstItem="L61-7B-reh" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" id="nwi-Ue-UD8"/> <constraint firstItem="R3A-cj-kzU" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="p40-L8-Qdh"/> <constraint firstItem="L61-7B-reh" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="peu-JR-Hp4"/> WanPai/Root/Welfare/VC/WelfareVC.swift
@@ -129,6 +129,7 @@ @IBAction func storeAction(_ sender: Any) { let vc = CoinStoreCenterVC() vc.benefitHomeModel = benefitHomeModel push(vc: vc) } @@ -178,7 +179,7 @@ extension WelfareVC:UICollectionViewDelegate{ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let model = benefitHomeModel!.commodities[indexPath.row] let vc = WelfareRedeemGoodsDetailVC() let vc = WelfareRedeemGoodsDetailVC(commodityId: model.commodityId, goodsType: model.goodsType) push(vc: vc) } } WanPai/Root/Welfare/View/CoinStoreHeadView.swift
@@ -8,14 +8,23 @@ import UIKit import JQTools import QMUIKit import RxSwift import RxRelay class CoinStoreHeadView: UICollectionReusableView { @IBOutlet weak var btn_sort: QMUIButton! @IBOutlet weak var btn_type: QMUIButton! @IBOutlet weak var shadowView: UIView! @IBOutlet weak var img_cover: UIImageView! @IBOutlet weak var label_username: UILabel! @IBOutlet weak var label_coin: UILabel! @IBOutlet weak var tf_search: UITextField! private var resortSubTypeView:CourseSubTypeView? private var typeSubTypeView:CourseSubTypeView? private var disposeBag = DisposeBag() var viewModel:CoinStoreViewModel! var innerView:UIView! override func awakeFromNib() { @@ -25,31 +34,70 @@ btn_type.imagePosition = .right btn_sort.spacingBetweenImageAndTitle = 5 btn_type.spacingBetweenImageAndTitle = 5 tf_search.delegate = self tf_search.returnKeyType = .search } @IBAction func resortAction(_ sender: QMUIButton) { guard !sender.isSelected else {return} hiddenAction() sender.isSelected = true let items = Array<NormalSimpleModel>() CourseSubTypeView.show(inView: self.innerView, afterView: self, items: items) { m in var items = Array<NormalSimpleModel>() items.append(NormalSimpleModel(id: 0, name: "默认排序")) items.append(NormalSimpleModel(id: 1, name: "积分从高到低")) items.append(NormalSimpleModel(id: 2, name: "积分从低到高")) items.append(NormalSimpleModel(id: 3, name: "兑换从高到低")) let model = items.filter({$0.id == viewModel.rank.value?.rawValue}) resortSubTypeView = CourseSubTypeView.show(inView: self.innerView, afterView: self, items: items, selectModel: model.first) {[weak self] m in if m.id == 0{ self?.viewModel.rank.accept(nil) }else{ self?.viewModel.rank.accept(Sort2Type(rawValue: m.id)) } sender.setTitle(m.name, for: .normal) self?.viewModel.beginRefresh() sender.isSelected = false } closeClouse: { sender.isSelected = false } } @IBAction func searchAction(_ sender: Any) { viewModel.beginRefresh() } @IBAction func typeAction(_ sender: UIButton) { guard !sender.isSelected else {return} hiddenAction() sender.isSelected = true var items = Array<NormalSimpleModel>() items.append(NormalSimpleModel(id: 0, name: "商品类型")) items.append(NormalSimpleModel(id: 1, name: "实物")) items.append(NormalSimpleModel(id: 2, name: "课包")) items.append(NormalSimpleModel(id: 3, name: "门票")) items.append(NormalSimpleModel(id: 4, name: "优惠券")) let model = items.filter({$0.id == viewModel.goodsType.value?.rawValue}) typeSubTypeView = CourseSubTypeView.show(inView: self.innerView, afterView: self, items: items, selectModel: model.first) {[weak self] m in sender.setTitle(m.name, for: .normal) if m.id == 0{ self?.viewModel.goodsType.accept(nil) }else{ self?.viewModel.goodsType.accept(ExchangeType(rawValue: m.id)) } self?.viewModel.beginRefresh() sender.isSelected = false } closeClouse: { sender.isSelected = false } } @IBAction func typeAction(_ sender: UIButton) { guard !sender.isSelected else {return} sender.isSelected = true let items = Array<NormalSimpleModel>() CourseSubTypeView.show(inView: self.innerView, afterView: self, items: items) {m in sender.isSelected = false } closeClouse: { sender.isSelected = false } private func hiddenAction(){ btn_sort.isSelected = false btn_type.isSelected = false typeSubTypeView?.removeFromSuperview() resortSubTypeView?.removeFromSuperview() } @IBAction func recoredAction(_ sender: UIButton) { @@ -66,3 +114,11 @@ } } extension CoinStoreHeadView:UITextFieldDelegate{ func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() viewModel.beginRefresh() return true } } WanPai/Root/Welfare/View/CoinStoreHeadView.xib
@@ -145,6 +145,9 @@ <state key="normal" title="搜索"> <color key="titleColor" name="FE6E0D"/> </state> <connections> <action selector="searchAction:" destination="U6b-Vx-4bR" eventType="touchUpInside" id="XIv-oq-WeY"/> </connections> </button> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8CB-nR-iEe"> <rect key="frame" x="0.0" y="164" width="457" height="45"/> @@ -212,7 +215,11 @@ <connections> <outlet property="btn_sort" destination="tGC-9B-kBe" id="gUc-bK-5ep"/> <outlet property="btn_type" destination="CSW-RY-Hpe" id="AQt-Lm-d0P"/> <outlet property="img_cover" destination="Ut2-N8-z8a" id="At4-si-HJQ"/> <outlet property="label_coin" destination="dFh-bC-k5U" id="nrg-pP-kR3"/> <outlet property="label_username" destination="E2A-yI-sez" id="nQQ-0t-IaW"/> <outlet property="shadowView" destination="8CB-nR-iEe" id="Lhn-LX-roE"/> <outlet property="tf_search" destination="kj9-Ot-DUR" id="IBN-9O-U07"/> </connections> <point key="canvasLocation" x="167.17557251908397" y="79.929577464788736"/> </collectionReusableView>