Podfile
@@ -6,20 +6,20 @@ use_frameworks! # Pods for WanPai pod 'JQTools',:path=> '/Users/yvkd/MyProject/JQTools' pod 'SwifterSwift' pod 'FFPage' pod 'SPPageMenu' pod 'FSCalendar' pod 'Alamofire' pod 'Lantern' pod 'SVProgressHUD' pod 'AliyunOSSiOS' pod 'WechatOpenSDK-XCFramework' pod 'AlipaySDK-iOS' pod 'AMap2DMap-NO-IDFA' pod 'CryptoSwift' pod 'RHSocketKit/Extend' pod 'JQTools',:path=> '/Users/yvkd/MyProject/JQTools' # 个人开发库 pod 'SwifterSwift' # Swift便捷常用工具库 pod 'FFPage' # 分页 pod 'SPPageMenu' # 配合FFPage 顶部导航分页 pod 'FSCalendar' # 日历选择器 pod 'Alamofire' # 网络请求框架 pod 'Lantern' # 图片浏览器 pod 'SVProgressHUD' # 提示框组件 pod 'AliyunOSSiOS' # 阿里云OSS pod 'WechatOpenSDK-XCFramework' # 微信开放平台组件 pod 'AlipaySDK-iOS' # 支付宝组件 pod 'AMap2DMap-NO-IDFA' # 高德地图2D,无广告IDFA标识 pod 'CryptoSwift' # 常用加密算法 pod 'RHSocketKit/Extend'# 长连接【备用】 post_install do |installer| WanPai.xcodeproj/project.pbxproj
@@ -256,7 +256,6 @@ 8D70178A2A3308DC00473C40 /* Common_1_TCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8D7017882A3308DC00473C40 /* Common_1_TCell.xib */; }; 8D70178D2A330E5700473C40 /* CourseDetailVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D70178B2A330E5700473C40 /* CourseDetailVC.swift */; }; 8D70178E2A330E5700473C40 /* CourseDetailVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8D70178C2A330E5700473C40 /* CourseDetailVC.xib */; }; 8D710F6D2A31897C0031E2D1 /* WaterFallFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D710F6C2A31897C0031E2D1 /* WaterFallFlowLayout.swift */; }; 8D79A58F2A3957420029874B /* StudentInfo_2_TCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D79A58D2A3957420029874B /* StudentInfo_2_TCell.swift */; }; 8D79A5902A3957420029874B /* StudentInfo_2_TCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8D79A58E2A3957420029874B /* StudentInfo_2_TCell.xib */; }; 8D79A5932A395BF40029874B /* ActivityStudentListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D79A5912A395BF40029874B /* ActivityStudentListVC.swift */; }; @@ -561,7 +560,6 @@ 8D7017882A3308DC00473C40 /* Common_1_TCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Common_1_TCell.xib; sourceTree = "<group>"; }; 8D70178B2A330E5700473C40 /* CourseDetailVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDetailVC.swift; sourceTree = "<group>"; }; 8D70178C2A330E5700473C40 /* CourseDetailVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CourseDetailVC.xib; sourceTree = "<group>"; }; 8D710F6C2A31897C0031E2D1 /* WaterFallFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaterFallFlowLayout.swift; sourceTree = "<group>"; }; 8D79A58D2A3957420029874B /* StudentInfo_2_TCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudentInfo_2_TCell.swift; sourceTree = "<group>"; }; 8D79A58E2A3957420029874B /* StudentInfo_2_TCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StudentInfo_2_TCell.xib; sourceTree = "<group>"; }; 8D79A5912A395BF40029874B /* ActivityStudentListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityStudentListVC.swift; sourceTree = "<group>"; }; @@ -972,7 +970,6 @@ children = ( 13CE11D32AF25C6400F6ACA4 /* UCCateDecorationView.swift */, 13CE11D12AF2595100F6ACA4 /* FlowLayout.swift */, 8D710F6C2A31897C0031E2D1 /* WaterFallFlowLayout.swift */, ); path = Layout; sourceTree = "<group>"; @@ -1703,7 +1700,6 @@ 8DF184402A3327EE0095687B /* Common_1_CCell.swift in Sources */, 13DA7D4C2AAEFD630085ABF9 /* CommonWebVC.swift in Sources */, 8DAEB54A2A30593C00814766 /* BaseNav.swift in Sources */, 8D710F6D2A31897C0031E2D1 /* WaterFallFlowLayout.swift in Sources */, 13FBD7842A4ADD0600037156 /* StudentMentalTCell.swift in Sources */, 8DA51DFA2A32C6C10085F4BA /* StoresChooseView.swift in Sources */, 136E0EE92AB30DD200EDBB8F /* QRPreview.swift in Sources */, WanPai/Common/Layout/WaterFallFlowLayout.swift
File was deleted WanPai/Config/Def.swift
@@ -64,22 +64,18 @@ //提示框 func alert(msg: String) { // hiddenHUD() SVProgressHUD.showInfo(withStatus: msg,maskType: .clear) SVProgressHUD.showInfo(withStatus: msg) } func alertError(msg:String){ // hiddenHUD() SVProgressHUD.showError(withStatus: msg,maskType: .clear) SVProgressHUD.showError(withStatus: msg) } func alertSuccess(msg:String){ // hiddenHUD() SVProgressHUD.showSuccess(withStatus: msg,maskType: .clear) SVProgressHUD.showSuccess(withStatus: msg) } func showHUD(_ text:String? = nil){ SVProgressHUD.setContainerView(sceneDelegate?.window) SVProgressHUD.show(withStatus: text) } WanPai/Model/CommonModels.swift
@@ -52,6 +52,12 @@ var time = "" var list = [CourseDetailListModel]() var chooseHours = 0 var payType:PayType = .aliPay var payPrice:Double = 0 var orinPrice:Double = 0 var coinPrice:Int = 0 var stuIds = [Int]() } struct CourseDetailModel:HandyJSON { @@ -438,6 +444,7 @@ var id = 0 var courseType = 0 //1:常规,2:假期 var orderId:Int? var coursePayId:Int? } struct StartClouseVideoListModel:HandyJSON { @@ -587,6 +594,7 @@ var consumeTime = "" var type:DetailType?//1扣减 2增加 var recordId:Int? var detailsType:DetailType?//1扣减 2增加 // mutating func mapping(mapper: HelpingMapper) { // mapper <<< @@ -786,7 +794,7 @@ var time = [String]() var num = 0 var money:Double = 0 var isType = 0 //1不能请假,0:可以请假 var isType = 0 //1不能请假,0:可以请假 3:已取消 var courseType = 0 // 1:常规,2:假期课 required init(){} WanPai/Network/Services.swift
@@ -467,7 +467,7 @@ /// 购买运动营 class func courcePayment(conponId:Int? = nil,courseConfigId:Int,id:Int,price:Double,payType:PayType,stuId:[Int])->Observable<BaseResponse<PaymentModel>>{ class func courcePayment(conponId:Int? = nil,courseConfigId:Int,id:Int,price:Double,payType:PayType,stuId:[Int],orderId:Int? = nil)->Observable<BaseResponse<PaymentModel>>{ let params = ParamsAppender.build(url: All_Url) .interface(url: "/course/api/course/paymentCourse") .append(key: "couponId", value: conponId) @@ -476,6 +476,7 @@ .append(key: "payType", value: payType.rawValue) .append(key: "price", value: price.string) .append(key: "studentIds", value: stuId.map({"\($0)"}).joined(separator: ";")) .append(key: "orderId", value: orderId) return NetworkRequest.request(params: params, method: .post, progress: true) } WanPai/Root/Activity/VC/ActivityDetailApplyVC.swift
@@ -143,6 +143,12 @@ if status{ let isStudent = weakSelf.students.filter({$0.isStudent == 0}).count > 0 ? true:false //零元购 if price == 0 && coin == 0 && course == 0{ weakSelf.payment(type: .coin,paymentId: 0) return } PaymentView.show(money: (ali:price,wx:price,coin:coin,course:course,integral:nil),hasNotStudent: isStudent) { [weak self] type in guard let weakSelf = self else { return } if type == .courseNum{ @@ -168,6 +174,12 @@ let course = weakSelf.activityDetailModel.classPrice * weakSelf.students.count if status{ //零元购 if price == 0 && coin == 0 && course == 0{ weakSelf.payment(type: .coin,paymentId: 0) return } let isStudent = weakSelf.students.filter({$0.isStudent == 0}).count > 0 ? true:false PaymentView.show(money: (ali:price,wx:price,coin:coin,course:course,integral:nil),hasNotStudent: isStudent) { [weak self] type in guard let weakSelf = self else { return } WanPai/Root/Course/TCell/CourseBookingTCell.swift
@@ -33,10 +33,15 @@ btn_handle.backgroundColor = UIColor(hexStr: "#C0C0C0") } // btn_handle.isHidden = (weeklyCourseItemModel.courseType == 2 && weeklyCourseItemModel.type == 2) //visibility = if ((data.courseType != 1&&data.type == 2)||(data.type == 1&&data.isType == 1)) View.GONE else View.VISIBLE //||(data.isType == 0) 1、假期班隐藏:报名 按钮 2、报名体验购课,需隐藏按钮:请假 btn_handle.isHidden = weeklyCourseItemModel.courseType != 1 && weeklyCourseItemModel.type == 2 || weeklyCourseItemModel.type == 1 && weeklyCourseItemModel.type == 2 if weeklyCourseItemModel.isType == 3{ btn_handle.setTitle("已取消", for: .normal) btn_handle.isEnabled = false btn_handle.isHidden = false btn_handle.backgroundColor = UIColor(hexStr: "#C0C0C0") } } } @IBOutlet weak var label_title: UILabel! WanPai/Root/Course/VC/CourseDetailApplyVC.swift
@@ -30,7 +30,7 @@ @IBOutlet weak var label_originPrice: UILabel! @IBOutlet weak var label_vipPrice: UILabel! @IBOutlet weak var label_coin: UILabel! @IBOutlet weak var btn_hasCoupon: TapBtn! // @IBOutlet weak var btn_hasCoupon: TapBtn! @IBOutlet weak var btn_couponInfo: UIButton! @IBOutlet weak var label_courseType: UILabel! @@ -101,11 +101,6 @@ cons_tableHei.constant = CGFloat(studentModels.count * 87) tableView.reloadData() queryCouponInfo {[weak self] () in guard let weakSelf = self else { return } self?.changePrice(weakSelf.selectClassIndex) } let imgs = m.detailDrawing.components(separatedBy: ",") var items = [CommonBannerModel]() for (index,img) in imgs.enumerated(){ @@ -114,13 +109,28 @@ view_banner.setItems(items: items) } if var m = signUpModel{ if let m = signUpModel{ classHours = m.chooseHours detailModel?.list = m.list.filter({$0.classHours == classHours}) if m.payStatus == .unPayment{ btn_handleBtn.setTitle("待支付", for: .normal) btn_addStudent.isHidden = true btn_coupon.isHidden = true studentModels.removeAll() Services.queryStudentList().subscribe(onNext: {[weak self] data in guard let weakSelf = self else { return } if let students = data.data{ for stu in students{ if m.stuIds.contains(where: {$0 == stu.id}){ weakSelf.studentModels.append(stu) weakSelf.cons_tableHei.constant = CGFloat(weakSelf.studentModels.count * 87) weakSelf.tableView.reloadData() } } } }).disposed(by: disposeBag) } if m.payStatus == .paymented{ @@ -128,11 +138,16 @@ btn_addStudent.isHidden = true } } queryCouponInfo {[weak self] () in guard let weakSelf = self else { return } self?.changePrice(weakSelf.selectClassIndex) } } override func setUI() { btn_hasCoupon.isHidden = true btn_coupon.isHidden = true CellW = (JQ_ScreenW - 155) / 3.0 CellH = CellW * 0.439 @@ -226,12 +241,18 @@ price = model.paymentPrice } //计算人数总价 //计算人数总价 price = price * Double(weakSelf.studentModels.count) //减去优惠 let discountPrice = price - (weakSelf.selectCouponModel?.favorable ?? 0) let coin = model.playPaiCoin * weakSelf.studentModels.count //减去优惠 var discountPrice = price - (weakSelf.selectCouponModel?.favorable ?? 0) var coin = model.playPaiCoin * weakSelf.studentModels.count //待支付订单 ,取最终订单金额 if weakSelf.signUpModel?.payStatus == .unPayment{ discountPrice = weakSelf.signUpModel?.payPrice ?? 0 coin = weakSelf.signUpModel?.coinPrice ?? 0 } PaymentView.show(money: (ali:discountPrice,wx:discountPrice,coin:coin,course:nil,integral:nil)) { [weak self] payType in guard let weakSelf = self else { return } @@ -240,12 +261,18 @@ switch payType { case .aliPay,.wechat: resultPayPrice = price //待支付订单单独处理 if weakSelf.signUpModel?.payStatus == .unPayment{ resultPayPrice = weakSelf.signUpModel?.payPrice ?? 0 } case .coin: resultPayPrice = Double(coin) case .courseNum,.integral:break } Services.courcePayment(conponId: weakSelf.selectCouponModel?.id, courseConfigId: model.id, id: weakSelf.detailModel!.id, price: resultPayPrice, payType: payType, stuId: weakSelf.studentModels.map({$0.id})).subscribe(onNext: { data in Services.courcePayment(conponId: weakSelf.selectCouponModel?.id, courseConfigId: model.id, id: weakSelf.detailModel!.id, price: resultPayPrice, payType: payType, stuId: weakSelf.studentModels.map({$0.id}),orderId: weakSelf.signUpModel?.coursePayId).subscribe(onNext: { data in if data.code == 200{ switch payType { case .aliPay: @@ -298,6 +325,34 @@ //计算价格 private func changePrice(_ index:Int){ //待支付订单,终止后续 if signUpModel?.payStatus == .unPayment{ label_price.isHidden = true label_originPrice.isHidden = signUpModel!.payPrice == signUpModel!.orinPrice label_vipPrice.isHidden = true label_coin.isHidden = true let originPrice = signUpModel!.orinPrice - signUpModel!.payPrice label_originPrice.attributedText = AttributedStringbuilder.build().add(string: originPrice.currency(), withFont: UIFont.systemFont(ofSize: 16, weight: .semibold), withColor: UIColor(hexStr: "#3F3F3F").withAlphaComponent(0.58)).delLine(color: UIColor(hexStr: "#3F3F3F").withAlphaComponent(0.58)).mutableAttributedString if signUpModel?.coinPrice != 0{ label_coin.isHidden = false label_coin.attributedText = AttributedStringbuilder.build() .add(string: "玩湃币:", withFont: UIFont.systemFont(ofSize: 14, weight: .semibold), withColor: UIColor(hexStr: "#3F3F3F")) .add(string: "\(signUpModel!.coinPrice)币", withFont: UIFont.systemFont(ofSize: 14, weight: .semibold), withColor: UIColor(hexStr: "#F21313")).mutableAttributedString } if signUpModel?.payPrice != 0{ label_price.isHidden = false label_price.text = (signUpModel!.payPrice).currency() } return } if let subM = detailModel?.list[index]{ var studentCount:Int = 0 @@ -316,7 +371,7 @@ label_vipPrice.isHidden = true label_coin.isHidden = false //纯玩湃币没有优惠券项 btn_hasCoupon.isHidden = true btn_coupon.isHidden = true label_coin.isHidden = false //玩湃币 label_coin.attributedText = AttributedStringbuilder.build() @@ -336,7 +391,7 @@ //玩湃币 label_coin.attributedText = AttributedStringbuilder.build() .add(string: "玩湃币:", withFont: UIFont.systemFont(ofSize: 14, weight: .semibold), withColor: UIColor(hexStr: "#3F3F3F")) .add(string: "\(subM.playPaiCoin * studentModels.count)币", withFont: UIFont.systemFont(ofSize: 14, weight: .semibold), withColor: UIColor(hexStr: "#F21313")).mutableAttributedString .add(string: "\(subM.playPaiCoin * studentCount)币", withFont: UIFont.systemFont(ofSize: 14, weight: .semibold), withColor: UIColor(hexStr: "#F21313")).mutableAttributedString //原价 let attribute = AttributedStringbuilder.build().add(string: (subM.originalPrice * Double(studentCount)).currency(), withFont: UIFont.systemFont(ofSize: 16, weight: .semibold), withColor: UIColor(hexStr: "#3F3F3F").withAlphaComponent(0.58)).delLine(color: UIColor(hexStr: "#3F3F3F").withAlphaComponent(0.58)) @@ -420,7 +475,7 @@ Services.queryAvaiableCopons(id: detailModel!.id, price: price!).subscribe(onNext: { [weak self] data in guard let weakSelf = self else { return } self?.btn_hasCoupon.isHidden = (data.data?.count ?? 0) == 0 self?.btn_coupon.isHidden = (data.data?.count ?? 0) == 0 || weakSelf.signUpModel?.payStatus == .unPayment self?.couponModels = data.data ?? [] self?.label_couponInfo.isHidden = (data.data?.count ?? 0) == 0 WanPai/Root/Course/VC/CourseDetailApplyVC.xib
@@ -16,7 +16,6 @@ <outlet property="btn_coupon" destination="XNI-Vj-heV" id="es4-Cw-MCW"/> <outlet property="btn_couponInfo" destination="uvW-sZ-v3z" id="0Up-RU-njq"/> <outlet property="btn_handleBtn" destination="Dbs-38-o1O" id="yfU-7Z-g1N"/> <outlet property="btn_hasCoupon" destination="XNI-Vj-heV" id="680-zV-BEX"/> <outlet property="collectionView" destination="ZtR-nH-Ly1" id="Snf-0R-x4b"/> <outlet property="cons_collHei" destination="wOm-8j-9fG" id="gZo-vk-a95"/> <outlet property="cons_collectHei" destination="wOm-8j-9fG" id="ycB-BH-9OQ"/> WanPai/Root/Course/VC/CourseOnlineListVC.swift
@@ -55,16 +55,27 @@ type = .video } Services.bannerList(position: type).subscribe(onNext: {[weak self] data in guard let weakSelf = self else { return } if let models = data.data{ let imgs = models.map({$0.img}) var items = [CommonBannerModel]() for (index,img) in imgs.enumerated(){ items.append(CommonBannerModel(index: index,resource: img,mediaType: .imageUrl)) } self?.searchView.bannerView.setItems(items: items,selectClouse: { m in let index = m.index jumpPage(model: models[index].model, page: models[index].page, type: models[index].type, id: models[index].turnId) }) if models.count > 0{ weakSelf.view.addSubview(weakSelf.searchView) self?.searchView.btn_search.addTarget(self, action: #selector(weakSelf.beginSearch), for: .touchUpInside) self?.searchView.tf_search.delegate = self! let insertH = JQ_ScreenW * 0.564 + 57 self?.collectionView.contentInset = UIEdgeInsets(top: insertH, left: 14, bottom: 14, right: 14) self?.collectionView.scrollIndicatorInsets = UIEdgeInsets(top: insertH, left: 0, bottom: 0, right: 0) self?.searchView.bannerView.setItems(items: items,selectClouse: { m in let index = m.index jumpPage(model: models[index].model, page: models[index].page, type: models[index].type, id: models[index].turnId) }) } } }).disposed(by: disposeBag) @@ -88,19 +99,12 @@ collectionView.delegate = self collectionView.dataSource = self collectionView.backgroundColor = .white let insertH = JQ_ScreenW * 0.564 + 57 collectionView.contentInset = UIEdgeInsets(top: insertH, left: 14, bottom: 14, right: 14) collectionView.scrollIndicatorInsets = UIEdgeInsets(top: insertH, left: 0, bottom: 0, right: 0) collectionView.contentInset = UIEdgeInsets(top: 0, left: 14, bottom: 14, right: 14) view.addSubview(collectionView) collectionView.snp.makeConstraints { make in make.edges.equalToSuperview() } view.addSubview(searchView) searchView.btn_search.addTarget(self, action: #selector(beginSearch), for: .touchUpInside) searchView.tf_search.delegate = self } override func setRx() { WanPai/Root/Course/VC/CourseVideoDetailVC.swift
@@ -48,9 +48,14 @@ required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) // app.orientation = .portrait } override func viewDidLoad() { super.viewDidLoad() // app.orientation = .allButUpsideDown if let id { try? AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: .defaultToSpeaker) @@ -58,8 +63,6 @@ if let model = data.data{ self?.detailModel = model self?.playerVC.player = AVPlayer(url: URL(string: model.courseVideo)!) self?.playerVC.exitsFullScreenWhenPlaybackEnds = true self?.playerVC.entersFullScreenWhenPlaybackBegins = true self?.playerVC.player?.play() self?.playerVC.player?.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 1), queue: DispatchQueue.main) { [weak self](time) in @@ -141,7 +144,22 @@ self.addChild(playerVC) playerVC.didMove(toParent: self) label_studyState.isHidden = true } override func setRx() { NotificationCenter.default.rx.notification(UIDevice.orientationDidChangeNotification).take(until:self.rx.deallocated).subscribe { _ in let orient = UIDevice.current.orientation if orient == .landscapeLeft || orient == .landscapeRight{ // self.playerVC.enterFullScreen(animated: true) // self.playerVC.showsPlaybackControls = true }else{ // self.playerVC.exitFullScreen(animated: true) // self.playerVC.showsPlaybackControls = true } }.disposed(by: disposeBag) } @objc private func playbackEnd(){ @@ -183,3 +201,15 @@ extension CourseVideoDetailVC:AVPlayerViewControllerDelegate{ } extension AVPlayerViewController { func enterFullScreen(animated: Bool) { print("Enter full screen") perform(NSSelectorFromString("enterFullScreenAnimated:completionHandler:"), with: animated, with: nil) } func exitFullScreen(animated: Bool) { print("Exit full screen") perform(NSSelectorFromString("exitFullScreenAnimated:completionHandler:"), with: animated, with: nil) } } WanPai/Root/Course/VC/StudentCourseDetailVC.swift
@@ -84,6 +84,22 @@ }) { error in }.disposed(by: weakSelf.disposeBag) /** Services.queryCourseInfo(id: model.courseId).subscribe(onNext: {[weak self] data in guard let weakSelf = self else { return } if let m = data.data{ Services.registeredData(coursePayId: model.coursePayId ?? 0,orderId: model.orderId).subscribe(onNext: {data in if let m1 = data.data{ let vc = CourseDetailVC(id: model.courseId, signUpCourseModel: m1) weakSelf.push(vc: vc) } }) { error in }.disposed(by: weakSelf.disposeBag) } }).disposed(by: weakSelf.disposeBag) **/ } viewModel.startTime.accept(Date()) WanPai/Root/Welfare/TCell/BillInfoTCell.swift
@@ -26,8 +26,8 @@ } } if billingModel.recordId != nil{ if billingModel.recordId == 1{ if billingModel.detailsType != nil{ if billingModel.detailsType == .positive{ label_price.text = billingModel.consumeAmount label_price.textColor = UIColor(hexStr: "#FD7302") }else{ WanPai/SceneDelegate.swift
@@ -29,7 +29,7 @@ SVProgressHUD.setContainerView(window) SVProgressHUD.setDefaultStyle(.dark) SVProgressHUD.setDefaultMaskType(.gradient) //禁止交互 SVProgressHUD.setDefaultMaskType(.custom) //禁止交互 SVProgressHUD.setMinimumDismissTimeInterval(1.5) SVProgressHUD.setMaximumDismissTimeInterval(30.0)