无故事王国
2024-07-06 607c74dfcfb5e52e56604f635d1d6a081cddcace
fix bug
22个文件已修改
2个文件已添加
1070 ■■■■ 已修改文件
DolphinEnglishLearnStudent.xcodeproj/project.pbxproj 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Assets.xcassets/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Config/VoicePlayer.swift 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Models/CommonModel.swift 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/HomeListenFight_lesson_1_VC.swift 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift 231 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_5_VC.swift 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenMenuVC.swift 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/ChooseLevelView.swift 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_4_AnswerView.swift 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/VC/ExchangeRecordHistoryVC.swift 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/VC/ParentVerifiyView.swift 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/VC/ParentVerifiyView.xib 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/VC/VIPCenterVC.swift 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/View/ShareView.swift 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Other/UIView/VoiceHandleView.swift 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Services/NetworkRequest.swift 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Services/Services.swift 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent.xcodeproj/project.pbxproj
@@ -71,6 +71,8 @@
        133386382C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133386372C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift */; };
        13397D962C05EA9D003440F9 /* ListenFight_Game_CCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13397D942C05EA9D003440F9 /* ListenFight_Game_CCell.swift */; };
        13397D972C05EA9D003440F9 /* ListenFight_Game_CCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13397D952C05EA9D003440F9 /* ListenFight_Game_CCell.xib */; };
        134C54B02C3785910009D09C /* ParentVerifiyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134C54AF2C3785910009D09C /* ParentVerifiyView.swift */; };
        134C54B22C37859D0009D09C /* ParentVerifiyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 134C54B12C37859D0009D09C /* ParentVerifiyView.xib */; };
        1362C75F2BFF4BA900BD7F73 /* StudyHandleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1362C75E2BFF4BA900BD7F73 /* StudyHandleView.swift */; };
        1362C7612BFF4BB100BD7F73 /* StudyHandleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1362C7602BFF4BB100BD7F73 /* StudyHandleView.xib */; };
        13649E982C002534001B04E2 /* HomeListenFight_lesson_1_VC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13649E972C002534001B04E2 /* HomeListenFight_lesson_1_VC.swift */; };
@@ -188,6 +190,8 @@
        133386372C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeListenFight_lesson_2_VC.swift; sourceTree = "<group>"; };
        13397D942C05EA9D003440F9 /* ListenFight_Game_CCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListenFight_Game_CCell.swift; sourceTree = "<group>"; };
        13397D952C05EA9D003440F9 /* ListenFight_Game_CCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ListenFight_Game_CCell.xib; sourceTree = "<group>"; };
        134C54AF2C3785910009D09C /* ParentVerifiyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentVerifiyView.swift; sourceTree = "<group>"; };
        134C54B12C37859D0009D09C /* ParentVerifiyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ParentVerifiyView.xib; sourceTree = "<group>"; };
        1362C75E2BFF4BA900BD7F73 /* StudyHandleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyHandleView.swift; sourceTree = "<group>"; };
        1362C7602BFF4BB100BD7F73 /* StudyHandleView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StudyHandleView.xib; sourceTree = "<group>"; };
        13649E972C002534001B04E2 /* HomeListenFight_lesson_1_VC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HomeListenFight_lesson_1_VC.swift; path = DolphinEnglishLearnStudent/Moudle/Home/HomeListenFight_lesson_1_VC.swift; sourceTree = SOURCE_ROOT; };
@@ -436,6 +440,8 @@
                130278862BFD9F2A00DDCE81 /* AddressManageVC.swift */,
                130E97752C329E2700205207 /* VIPCenterVC.swift */,
                130E97762C329E2700205207 /* VIPCenterVC.xib */,
                134C54AF2C3785910009D09C /* ParentVerifiyView.swift */,
                134C54B12C37859D0009D09C /* ParentVerifiyView.xib */,
            );
            path = VC;
            sourceTree = "<group>";
@@ -696,6 +702,7 @@
                130E97772C329E2700205207 /* VIPCenterVC.xib in Resources */,
                1302787A2BFD9ED600DDCE81 /* ExchangeResultVC.xib in Resources */,
                130278362BFD957300DDCE81 /* Base in Resources */,
                134C54B22C37859D0009D09C /* ParentVerifiyView.xib in Resources */,
                13397D972C05EA9D003440F9 /* ListenFight_Game_CCell.xib in Resources */,
                13EFFA792C22D0FC00F072E7 /* ShareView.xib in Resources */,
                1302788E2BFD9F4200DDCE81 /* CoinRecordHistoryVC.xib in Resources */,
@@ -776,6 +783,7 @@
                13A830F12C04196400BB2F23 /* HomeListenFight_lesson_3_VC.swift in Sources */,
                13CDF44D2C056A6900E8D4FD /* ListenFight_lesson_4_CCell.swift in Sources */,
                131C030B2C0D564000EA4C25 /* MarketTagCCell.swift in Sources */,
                134C54B02C3785910009D09C /* ParentVerifiyView.swift in Sources */,
                13CD3AC72C0874B3007E1065 /* CommonModel.swift in Sources */,
                131C030D2C0D6A4800EA4C25 /* CommonBannerView.swift in Sources */,
                1319B0322C0859370052F889 /* NetworkRequest.swift in Sources */,
DolphinEnglishLearnStudent/Assets.xcassets/.DS_Store
Binary files differ
DolphinEnglishLearnStudent/Config/VoicePlayer.swift
@@ -52,7 +52,8 @@
                func playerAt(url:String?){
                                guard let u = url else {return}
                                if player?.isPlaying ?? false{
                                                player?.stop()
//                                                player?.stop()
                                                return
                                }
                                                //文件存在:直接播放缓存路径的语音
                                                let fileURL = self.voiceCacheDirectory.appendingPathComponent(URL(fileURLWithPath: u).lastPathComponent).droppedScheme()
DolphinEnglishLearnStudent/Models/CommonModel.swift
@@ -274,6 +274,7 @@
                var correctNumber = 0
                var teamIds = [Int]() //题组ids
                var topicIds = [Int]() //已回答正确的题目Id
                var schedule = 0
}
@@ -340,7 +341,7 @@
                //游戏类型2专用
                var isOpen:Bool = false
                // 自主学习3专用 (是否已回答)
                // 自主学习1,3专用 (是否已回答)
                var isAnster:Bool = false
}
@@ -434,5 +435,12 @@
                var title = ""
                var phone = ""
                var img = ""
}
struct VIPInfoModel:HandyJSON{
                var id = 0
                var info = ""
                var isVip = 0
                var time = 0
                var amount = 0
}
DolphinEnglishLearnStudent/Moudle/Home/HomeListenFight_lesson_1_VC.swift
@@ -21,11 +21,11 @@
                private var listenNewModel:ListenNewModel!
                private var randomElement:Listen1SubModel?
                private var page:Int!
                private var isListen:Bool = false
                private(set) var isListen:Bool = false
                private var isAnsterComplete:Bool = false //是否已经回答完成[小题]
                private var isAnsterDone:Bool = false //是否已经回答完成[大题]
                private var isAnsterModel = Set<Listen1SubModel>()
                private var isAnsterModel = [Listen1SubModel]()
                private var menuView:VoiceHandleView?
                private lazy var collectionView:UICollectionView = {
@@ -45,12 +45,21 @@
                var teamScheduleModel:TeamScheduleModel?{
                                didSet{
                                                if let m = teamScheduleModel{
                                                                var temp = [Listen1SubModel]()
                                                                for v in listenNewModel.subjectList[page]{
                                                                                //已回答
                                                                                if m.topicIds.contains(v.id){
                                                                                                isAnsterModel.insert(v) //记录
                                                                                                temp.append(v)
                                                                                }
                                                                }
                                                                isAnsterModel.insert(contentsOf: temp, at: 0)
                                                                //todo
//                                                                let teamId = weakSelf.listenNewModel.data?.id.components(separatedBy: ",")[weakSelf.page]
//                                                                weakSelf.rootViewModel.insertCorrectAnswer(teamId: teamId, answerId: weakSelf.listenNewModel.subjectList[weakSelf.page][index.row].id)
                                                }
                                }
                }
@@ -71,6 +80,14 @@
                                collectionView.reloadData()
                                print("加载======DidLoad")
                                //回传记录,始终保持答题进度
                                if let team = teamScheduleModel{
                                                let v = team.schedule - 1
                                                for i in 0..<v{
                                                                isAnsterModel.append(listenNewModel.subjectList[page][i])
                                                }
                                }
                                //制造随机
                                listenNewModel.subjectList[page].shuffle()
                                getNextAnswer(isFirst: true)
@@ -80,6 +97,9 @@
                                                VoicePlayer.share().playerAt(url: self.randomElement?.correct)
                                                self.menuView?.playing()
                                }
                }
@@ -106,7 +126,23 @@
                                collectionView.reloadData()
                                getNextAnswer(isFirst: true)
                }
                func tobefore(){
                                if isAnsterModel.count == 1{return}
                                isAnsterModel.removeLast()
                                rootViewModel.answerCount.accept(page + isAnsterModel.count)
                                randomElement = isAnsterModel.last
                                menuView?.playUrl = randomElement?.correct
                                VoicePlayer.share().playerAt(url: self.randomElement?.correct)
                                menuView?.playing()
                                listenNewModel.subjectList[page].shuffle()
                                collectionView.reloadData()
                }
                /// 下一题
                /// - Parameter isFirst: 是否首次进入,首次页码不+1
                private func getNextAnswer(isFirst:Bool = false){
@@ -125,12 +161,18 @@
                                                return
                                }
                                randomElement = listenNewModel.subjectList[page].randomElement()
                                randomElement = listenNewModel.subjectList[page].randomElement() //随机抽题
                                if randomElement != nil{
                                                //如果已经回答,或标记为已回答(返回上一小题时)
                                                if isAnsterModel.contains(randomElement!){
                                                                getNextAnswer();return
                                                }
                                                isAnsterModel.insert(randomElement!)
                                                //没有回答
                                                if !isAnsterModel.contains(randomElement!){
                                                                isAnsterModel.append(randomElement!)
                                                }
                                }
                                menuView?.playUrl = randomElement?.correct
@@ -211,6 +253,7 @@
                                                                var answer:Fight_lessonType = .none
                                                                if self?.randomElement?.id == weakSelf.listenNewModel.subjectList[weakSelf.page][index.row].id{
                                                                                answer = .success
                                                                                self?.randomElement?.isAnster = true
                                                                                self?.isListen = false
                                                                                if self?.isAnsterComplete == false{
                                                                                                self?.rootViewModel.correctNum += 1
@@ -251,6 +294,7 @@
                private func answerSuccess(_ cell:ListenFight_lesson_1_CCell){
                                menuView?.snp.removeConstraints()
                                menuView?.playing()
                                menuView?.jq_cornerRadius = 0
                                let v = cell.view_topHandle.convert(cell.bounds, to: self.view)
                                UIView.animate(withDuration: 0.3) {
                                                self.menuView?.snp.updateConstraints { make in
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift
@@ -24,8 +24,6 @@
                override func awakeFromNib() {
        super.awakeFromNib()
//                                img_playSuccess.alpha = 0
//                                img_playSuccess.transform = .init(scaleX: 0.1, y: 0.1)
                                view_container.jq_addShadows(shadowColor: .black.withAlphaComponent(0.31), corner: 8, radius: 3, offset: CGSize(width: 0, height: 1), opacity: 1)
                                layoutIfNeeded()
    }
@@ -43,7 +41,6 @@
                func canClick(_ state:Bool){
                                btn_play.isEnabled = state
//                                view_playHandle.alpha = state == true ? 1:0
                                view_playHandle.backgroundColor = state == true ? UIColor(hexString: "#41A2EB") : .gray
                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift
@@ -83,15 +83,16 @@
                var answerItems = Dictionary<Int,Any>() //{page:0,data:String,currectAt:0}
                var answerCount = BehaviorRelay<Int>(value: 1)
                var answerItems_1 = Dictionary<String,Set<Int>>()
                var answerItems_1 = Dictionary<String,Array<Int>>()
                //回答正确的题
                func insertCorrectAnswer(teamId:String?,answerId:Int){
                                guard teamId != nil else {return}
                                if answerItems_1[teamId!] == nil{
                                                answerItems_1[teamId!] = Set<Int>()
                                                answerItems_1[teamId!] = Array<Int>()
                                }
                                answerItems_1[teamId!]!.insert(answerId)
                                answerItems_1[teamId!]!.append(answerId)
                }
}
@@ -100,6 +101,9 @@
                var studyScheduleModel:StudyScheduleModel? //学习进度(上级传递)
                var listenFightLine:ListenFightLine = .none
                var data:Any?
                var maxPage = 0 //最大页记录
                var teamScheduleModel:TeamScheduleModel? //上次中途退出,答题记录
                private var notiObject:Dictionary<String,Any>?
@@ -119,6 +123,19 @@
                                btn.setTitleColor(Config.ThemeColor, for: .normal)
                                btn.jq_borderColor = Config.ThemeColor
                                btn.backgroundColor = .white
                                btn.jq_borderWidth = 1
                                btn.jq_cornerRadius = 4
                                return btn
                }()
                private lazy var btn_forward_mini:UIButton = {
                                let btn = UIButton(type: .custom)
                                btn.setTitle("上一小题", for: .normal)
                                btn.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
                                btn.setTitleColor(Config.ThemeColor, for: .normal)
                                btn.jq_borderColor = Config.ThemeColor
                                btn.backgroundColor = .white
                                btn.isHidden = true
                                btn.jq_borderWidth = 1
                                btn.jq_cornerRadius = 4
                                return btn
@@ -174,10 +191,13 @@
                override func viewDidDisappear(_ animated: Bool) {
                                super.viewDidDisappear(animated)
                                sceneDelegate?.suspendTimer()
                                self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
                }
                override func viewDidLoad() {
                                super.viewDidLoad()
                                self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
                                yy_popBlock = {[weak self] in
                                                self?.quitAction(isPop: true)
@@ -185,6 +205,7 @@
                                btn_exit.addTarget(self, action: #selector(quitAction), for: .touchUpInside)
                                btn_forward.addTarget(self, action: #selector(beforeAction), for: .touchUpInside)
                                btn_forward_mini.addTarget(self, action: #selector(beforeAction_mini), for: .touchUpInside)
                                btn_next.addTarget(self, action: #selector(nextAction), for: .touchUpInside)
                                setPages()
@@ -197,36 +218,70 @@
                                timer.fire()
                                RunLoop.current.add(timer, forMode: .common)
                                Services.teamSchedule(type: viewModel.listenType.value, week: viewModel.week.value!, day: viewModel.day.value!).subscribe(onNext: {[weak self] data in
                                                guard let weakSelf = self else { return }
                                                if let model = data.data{
                                                                weakSelf.viewModel.correctNum = weakSelf.viewModel.correctNum + model.correctNumber
                                                                weakSelf.viewModel.errorNum = model.answerNumber - model.correctNumber
                                                                //跳转至指定页面
                                                                let page = max(0,model.topicIds.count - 1)
                                                                if weakSelf.pageVC.currentPage != page{
                                                                                weakSelf.pageVC.scroll(toPage: page, animation: false)
                                                                }
                                if let teamSchedule = teamScheduleModel{
                                                                viewModel.correctNum = viewModel.correctNum + teamSchedule.correctNumber
                                                                viewModel.errorNum = teamSchedule.answerNumber - teamSchedule.correctNumber
                                                maxPage    = teamSchedule.schedule
                                                                let ids = (data as! ListenNewModel).data!.id.components(separatedBy: ",")
                                                                switch viewModel.listenType.value {
                                                                                case .lesson1:
                                                                                                let nextPage = floor(Double(maxPage) / 5.0)
                                                                                                pageVC.scroll(toPage: Int(nextPage), animation: false)
                                                                                                viewModel.answerCount.accept(maxPage)
                                                                                                setPages()
                                                                DispatchQueue.main.asyncAfter(wallDeadline: .now()+0.5){
                                                                                switch weakSelf.viewModel.listenType.value {
                                                                                                case .lesson1:
                                                                                                                let vc = weakSelf.pageVC.currentController as! HomeListenFight_lesson_1_VC
                                                                                                case .lesson2:
                                                                                                                let vc = weakSelf.pageVC.currentController as! HomeListenFight_lesson_2_VC
                                                                                                case .lesson3:
                                                                                                                let vc = weakSelf.pageVC.currentController as! HomeListenFight_lesson_3_VC
                                                                                                case .lesson4:
                                                                                                                let vc = weakSelf.pageVC.currentController as! HomeListenFight_lesson_4_VC
                                                                                                case .lesson5:
                                                                                                                let vc = weakSelf.pageVC.currentController as! HomeListenFight_lesson_5_VC
                                                                                                default:
                                                                                                                break
                                                                                }
//                                                                                                for (index,v) in ids.enumerated(){
//                                                                                                                if v == String(teamSchedule.teamIds.last!){
//                                                                                                                                let maxCount = (data as! ListenNewModel).subjectList.count
//                                                                                                                                //下一页页码
//                                                                                                                                let page = min(index, maxCount)
//                                                                                                                                if pageVC.currentPage != page{
//                                                                                                                                                pageVC.scroll(toPage: page, animation: false)
//                                                                                                                                                setPages()
//                                                                                                                                }
//                                                                                                                                viewModel.answerCount.accept(teamSchedule.topicIds.count + 1)
//                                                                                                                }
//                                                                                                }
                                                                                case .lesson2:
//                                                                                                let nextPage = (teamSchedule.teamIds.count) - 1
                                                                                                let maxCount = (data as! ListenNewModel).subjectList.count
                                                                                                                let page = min((maxPage - 1),maxCount)
                                                                                                if pageVC.currentPage != page{
                                                                                                                viewModel.currentPage.accept(page)
                                                                                                                pageVC.scroll(toPage: page, animation: false)
                                                                                                                setPages()
                                                                                                }
                                                                                case .lesson4:
//                                                                                                let nextPage = (teamSchedule.teamIds.count) - 1
                                                                                                let maxCount = (data as! ListenNewModel).subjectList.count
                                                                                                let page = min((maxPage - 1),maxCount)
                                                                                                if pageVC.currentPage != page{
                                                                                                                viewModel.currentPage.accept(page)
                                                                                                                pageVC.scroll(toPage: page, animation: false)
                                                                                                                setPages()
                                                                                                }
                                                                                case .lesson3,.lesson5:
//                                                                                                let nextPage = (teamSchedule.teamIds.count) - 1
                                                                                                let maxCount = (data as! ListenNewModel).subjectList.count
                                                                                                let page = min((maxPage - 1),maxCount)
                                                                                                if pageVC.currentPage != page{
                                                                                                                viewModel.currentPage.accept(page)
                                                                                                                pageVC.scroll(toPage: page, animation: false)
                                                                                                                setPages()
                                                                                                }
                                                                                default:break
                                                                }
                                                }
                                }).disposed(by: disposeBag)
                                }
                }
                override func setUI() {
@@ -269,15 +324,12 @@
                private func craeteFootFuncView(){
                                view.addSubview(label_pageNum)
                                view.addSubview(btn_forward)
                                btn_forward.snp.makeConstraints { make in
                                                make.height.equalTo(40)
                                                make.width.equalTo(124)
                                }
                                view.addSubview(btn_exit)
                                btn_exit.snp.makeConstraints { make in
                                                make.height.equalTo(40)
                                                make.width.equalTo(124)
@@ -362,13 +414,20 @@
                private func setPages(){
                                switch viewModel.listenType.value{
                                                case .lesson1,.lesson5:
                                                case .lesson1:
                                                                label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\((data as! ListenNewModel).subjectList.flatMap({$0}).count)"
                                                case .lesson2,.lesson3:
                                                                maxPage = max(viewModel.answerCount.value,maxPage)
                                                                btn_forward.isHidden = viewModel.answerCount.value == 1
                                                case .lesson2,.lesson3,.lesson5:
                                                                label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\((data as! ListenNewModel).subjectList.count)"
                                                                btn_forward.isHidden = viewModel.currentPage.value == 0
                                                                let page = viewModel.currentPage.value + 1
                                                                maxPage = max(page,maxPage)
                                                case .lesson4:
                                                                //两题为一组:需要/2
                                                                label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\((data as! ListenNewModel).subjectList.count)"
                                                                let page = viewModel.currentPage.value + 1
                                                                maxPage = max(page,maxPage)
                                                case .game1,.game2:
                                                                btn_forward.isHidden = true
                                                                label_pageNum.isHidden = true
@@ -376,17 +435,18 @@
                                                                if viewModel.listenType.value == .game1{
                                                                                showGameLevel(canLevel: studyScheduleModel?.gameDifficulty ?? 0)
                                                                }
                                                case .story1,.story2:
                                                                let count = (data as! Listen1Model).storyList.count
                                                                viewModel.maxPage.accept(count)
                                                                label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(count)"
                                                case .story1:
                                                                if viewModel.listenType.value == .story2{
                                                                                btn_next.isHidden = (viewModel.currentPage.value + 1) == viewModel.maxPage.value
                                                                                if btn_next.isHidden{
                                                                                                btn_exit.setTitle("完成", for: .normal)
                                                                                }
                                                                }
                                                                fallthrough
                                                case .story2:
                                                                let count = (data as! Listen1Model).storyList.count
                                                                viewModel.maxPage.accept(count)
                                                                label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(count)"
                                }
                }
@@ -477,10 +537,6 @@
                                                                                                                if vc.isKind(of: HomeListenVC.self){
                                                                                                                                weakSelf.navigationController?.popToViewController(vc, animated: true);break
                                                                                                                }
//                                                                                                                if vc.isKind(of: HomeListenMenuVC.self){
//                                                                                                                                weakSelf.navigationController?.popToViewController(vc, animated: true);break
//                                                                                                                }
                                                                                                }
                                                                                }
                                                                                return
@@ -503,10 +559,6 @@
                                                                                                if vc.isKind(of: HomeListenVC.self){
                                                                                                                weakSelf.navigationController?.popToViewController(vc, animated: true);break
                                                                                                }
//                                                                                                if vc.isKind(of: HomeListenMenuVC.self){
//                                                                                                                weakSelf.navigationController?.popToViewController(vc, animated: true);break
//                                                                                                }
                                                                                }
                                                                }
                                                                return
@@ -521,27 +573,37 @@
                                                CommonAlertView.show(content: "未完成全部答题,确认退出吗?") {[weak self] () in
                                                                guard let weakSelf = self else { return }
                                                                let topicIds = weakSelf.viewModel.answerItems_1.keys.sorted()
                                                                let temIds = weakSelf.viewModel.answerItems_1.values.flatMap({$0}).map({"\($0)"})
//                                                                let temIds = weakSelf.viewModel.answerItems_1.keys.sorted()
//                                                                let topicIds = weakSelf.viewModel.answerItems_1.values.flatMap({$0}).map({"\($0)"})
                                                                var schedule:Int = 0
                                                                switch weakSelf.viewModel.listenType.value{
                                                                                case .lesson1,.lesson2,.lesson5:schedule = weakSelf.viewModel.answerCount.value
                                                                                case .lesson3:schedule = weakSelf.viewModel.currentPage.value + 1
                                                                                case .lesson4:schedule = weakSelf.viewModel.currentPage.value + 1
                                                                                default:break
                                                                }
                                                                let temIds = [String]()
                                                                let topicIds = [String]()
//                                                                var schedule:Int = 0
//                                                                if let page = weakSelf.label_pageNum.text?.components(separatedBy: ":").last?.components(separatedBy: "/").first?.int{
//                                                                                schedule = max((page - 1),1)
//                                                                }
//                                                                switch weakSelf.viewModel.listenType.value{
//                                                                                case .lesson1:schedule = max(weakSelf.viewModel.answerCount.value - 1,1)
//                                                                                case .lesson2,.lesson3:schedule = max(weakSelf.viewModel.currentPage.value,1)
//                                                                                case .lesson4:schedule = max(weakSelf.viewModel.currentPage.value,1)
//                                                                                case .lesson5:schedule = max(weakSelf.viewModel.currentPage.value,1)
//                                                                                default:break
//                                                                }
                                                                switch weakSelf.viewModel.listenType.value{
                                                                                case .lesson1,.lesson2,.lesson3,.lesson4,.lesson5:
                                                                                                if temIds.count > 0 && topicIds.count > 0{
//                                                                                                if temIds.count > 0 && topicIds.count > 0{
                                                                                                                let totalNum = weakSelf.viewModel.correctNum + weakSelf.viewModel.errorNum
                                                                                                                Services.exitLearning(type:weakSelf.viewModel.listenType.value.rawValue,quarter: weakSelf.viewModel.quarter.value!,week: weakSelf.viewModel.week.value!, day: weakSelf.viewModel.day.value!, teamIds: temIds, topicIds: topicIds,answerNumber: totalNum,correctNumber:weakSelf.viewModel.correctNum,studyTime:weakSelf.viewModel.times,schedule: schedule).subscribe(onNext: { data in
                                                                                                                Services.exitLearning(type:weakSelf.viewModel.listenType.value.rawValue,quarter: weakSelf.viewModel.quarter.value!,week: weakSelf.viewModel.week.value!, day: weakSelf.viewModel.day.value!, teamIds: temIds, topicIds: topicIds,answerNumber: totalNum,correctNumber:weakSelf.viewModel.correctNum,studyTime:weakSelf.viewModel.times,schedule: weakSelf.maxPage).subscribe(onNext: { data in
                                                                                                                                NotificationCenter.default.post(name: MeUserInfoUpdate_Noti, object: nil)
                                                                                                                }).disposed(by: weakSelf.disposeBag)
                                                                                                }
//                                                                                                }
                                                                                case .game1,.game2,.story1,.story2:
                                                                                                Services.exitGameOrStory(studyTime: weakSelf.viewModel.times).subscribe(onNext: { _ in
@@ -551,10 +613,6 @@
                                                                                if vc.isKind(of: HomeListenVC.self){
                                                                                                weakSelf.navigationController?.popToViewController(vc, animated: true);break
                                                                                }
//
//                                                                                if vc.isKind(of: HomeListenMenuVC.self){
//                                                                                                weakSelf.navigationController?.popToViewController(vc, animated: true);break
//                                                                                }
                                                                }
                                                }
                                }
@@ -576,18 +634,28 @@
                                }
                }
                @objc func beforeAction(){
                                if viewModel.listenType.value == .story2{
                                                guard (pageVC.currentController as! HomeListenStory_2_VC).isPlayEnd else {
                                                                alert(msg: "请听完");return
                @objc func beforeAction_mini(){
                                if viewModel.listenType.value == .lesson1{
                                                if let vc = pageVC.currentController as? HomeListenFight_lesson_1_VC{
                                                                print("---->进入")
                                                                vc.tobefore()
                                                }
                                }
                }
                @objc func beforeAction(){
                                listenFightLine = .before
                                let beforePage = max(0, viewModel.currentPage.value - 1)
                                switch viewModel.listenType.value {
                                                case .lesson1,.lesson2:
                                                case .lesson1:
                                                                if !(pageVC.currentController as! HomeListenFight_lesson_1_VC).isListen{
                                                                                alert(msg: "请听完");return
                                                                }
                                                                let temp = viewModel.answerCount.value - 1
                                                                viewModel.answerCount.accept(max(1,temp))
                                                case .lesson2:
                                                                let temp = (beforePage * 4) + 1
                                                                viewModel.answerCount.accept(max(1,temp))
                                                default:break
@@ -596,6 +664,24 @@
                                pageVC.scroll(toPage: beforePage, animation: true)
                                viewModel.currentPage.accept(beforePage)
                                if viewModel.listenType.value == .story2{
                                                guard (pageVC.currentController as! HomeListenStory_2_VC).isPlayEnd else {
                                                                alert(msg: "请听完");return
                                                }
                                }
                                if viewModel.listenType.value == .lesson1{
                                                let currentVC = pageVC.currentController as! HomeListenFight_lesson_1_VC
//                                                if (viewModel.answerCount.value - 1 ) % 4 != 0 || viewModel.answerCount.value <= 4{
                                                                currentVC.tobefore();return
//                                                }
                                }
                                if viewModel.listenType.value == .lesson3{
                                                (pageVC.currentController as! HomeListenFight_lesson_3_VC).restore()
                                }
                                if viewModel.listenType.value == .story2{
                                                btn_next.isHidden = false
@@ -654,30 +740,35 @@
                func pageViewController(_ pageViewConteoller: FFPageViewController, controllerForPage page: Int) -> UIViewController {
                                if viewModel.listenType.value == .lesson1{
                                                let vc = HomeListenFight_lesson_1_VC(page: page,listenNewModel:data as! ListenNewModel)
                                                vc.teamScheduleModel = teamScheduleModel
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson2{
                                                let vc = HomeListenFight_lesson_2_VC(page: page,listenNewModel:data as! ListenNewModel)
                                                vc.teamScheduleModel = teamScheduleModel
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson3{
                                                let vc = HomeListenFight_lesson_3_VC(page: page, listenNewModel: data as! ListenNewModel)
                                                vc.teamScheduleModel = teamScheduleModel
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson4{
                                                let vc = HomeListenFight_lesson_4_VC(page: page, listenNewModel: data as! ListenNewModel)
                                                vc.teamScheduleModel = teamScheduleModel
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson5{
                                                let vc = HomeListenFight_lesson_5_VC(page: page, listenNewModel: data as! ListenNewModel)
                                                vc.teamScheduleModel = teamScheduleModel
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift
@@ -14,6 +14,7 @@
                private var listenNewModel:ListenNewModel!
                private var page:Int!
                var rootViewModel:HomeListenFightViewModel!
                var teamScheduleModel:TeamScheduleModel?
                private var tempViews = [StudyHandleView]()
                private var playedIndex = Set<Int>() //已经播放过的view
@@ -54,6 +55,17 @@
                override func viewDidLoad() {
                                super.viewDidLoad()
                                navigationItem.titleView = UIView()
                                //回传记录,始终保持答题进度
                                if let team = teamScheduleModel{
                                                for teamId in team.teamIds{
                                                                for v in listenNewModel.subjectList[page]{
                                                                                if team.topicIds.contains(v.id){
                                                                                                rootViewModel.insertCorrectAnswer(teamId: "\(teamId)", answerId: v.id)
                                                                                }
                                                                }
                                                }
                                }
                }
                override func viewDidAppear(_ animated: Bool) {
@@ -323,7 +335,6 @@
                                                sub.btn_pay.isEnabled = false
                                                sub.btn_choose.isEnabled = false
                                }
                }
                func playComplete() {
@@ -351,7 +362,15 @@
                                                let v = rootViewModel.answerCount.value
                                                rootViewModel.answerCount.accept(v + 1)
                                                viewModel.answerType.accept(.none)
                                                for sub in stackView.arrangedSubviews as! [StudyHandleView]{
                                                                sub.btn_pay.isEnabled = false
                                                                sub.btn_choose.isEnabled = false
                                                }
                                                DispatchQueue.main.asyncAfter(deadline: .now()+3) {
                                                                self.resetStackView()
                                                }
                                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift
@@ -37,6 +37,7 @@
                private var page:Int!
                private var answterCount:Int = 0 //回答计数,用于确定角标
                var rootViewModel:HomeListenFightViewModel!
                var teamScheduleModel:TeamScheduleModel?
                private var voicePlayer = VoicePlayer.share()
                private var playIndex = Set<IndexPath>() //顺序播放
                private var isPlayingIndex:IndexPath? //正在播放中
@@ -70,9 +71,23 @@
                                listenNewModel.subjectList[page][0].isQuestion = 1
                                listenNewModel.subjectList[page][1].isQuestion = 1
                                listenNewModel.subjectList[page][3].isQuestion = 1
                                //回传记录,始终保持答题进度
                                if let team = teamScheduleModel{
                                                for teamId in team.teamIds{
                                                                for v in listenNewModel.subjectList[page]{
                                                                                if team.topicIds.contains(v.id){
                                                                                                rootViewModel.insertCorrectAnswer(teamId: "\(teamId)", answerId: v.id)
                                                                                }
                                                                }
                                                }
                                }
                }
                func restore(){
                                playIndex.removeAll()
                                playIndex.insert(IndexPath(row: 0, section: 0))
                                answterCount = 0
                                for subView in view.subviews{
                                                if subView is Lesson_3_AnswerView{
@@ -170,10 +185,6 @@
                                if !islisten{
                                                alertError(msg: "请先听题");return
                                }
//                                if isPlayingIndex != nil {
//                                                alertError(msg: "请先听题");return
//                                }
                                if answterCount == 0 && !playIndex.contains(IndexPath(row: 2, section: 0)){
                                                alertError(msg: "请先听题");return
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift
@@ -13,6 +13,7 @@
                private var listenNewModel:ListenNewModel!
                private var page:Int!
                var rootViewModel:HomeListenFightViewModel!
                var teamScheduleModel:TeamScheduleModel?
                private var answerIndex:IndexPath? //答案的Index
                private var answerIndexs = Set<IndexPath>() //回答过的Index集合
@@ -72,6 +73,18 @@
    override func viewDidLoad() {
        super.viewDidLoad()
                                //回传记录,始终保持答题进度
                                if let team = teamScheduleModel{
                                                for teamId in team.teamIds{
                                                                for v in listenNewModel.subjectList[page]{
                                                                                if team.topicIds.contains(v.id){
                                                                                                rootViewModel.insertCorrectAnswer(teamId: "\(teamId)", answerId: v.id)
                                                                                }
                                                                }
                                                }
                                }
    }
                override func viewDidAppear(_ animated: Bool) {
@@ -258,6 +271,7 @@
                                                                                                copyView.frame = CGRect(origin: newRect.origin, size: CGSize(width: 159, height: 52))
                                                                                                copyView.view_state.isHidden = true
                                                                                                copyView.isCopy = true
                                                                                                copyView.isPlaying()
                                                                                                copyView.btn_isAnswer.setImage(self.viewModel.selectIndex.value?.row == 1 ? UIImage(named: "icon_question"):UIImage(named: "icon_answer"), for: .normal)
                                                                                                copyView.img_play.alpha = 1
                                                                                                copyView.voiceUrl = tempSubV!.voiceUrl
@@ -396,6 +410,16 @@
                func playComplete() {
                                self.view.isUserInteractionEnabled = true
                                for subV in view.subviews {
                                                if let s = subV as? Lesson_4_AnswerView{
                                                                s.playEnd()
                                                                s.img_play.isHidden = false
                                                                s.img_play.alpha = 1
                                                }
                                }
                                for subV in stackView.arrangedSubviews{
                                                if let s = subV as? Lesson_4_AnswerView{
                                                                s.playEnd()
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_5_VC.swift
@@ -16,6 +16,7 @@
                private var playVoiceAt:Int? //播放声音的View
                private var playVoiceRealAt:Int? //播放声音的View -被乱序后,真实Index
                var rootViewModel:HomeListenFightViewModel!
                var teamScheduleModel:TeamScheduleModel?
                private var voicePlayer = VoicePlayer.share()
                private var isListen:Bool = false
@@ -66,6 +67,18 @@
                                super.viewDidLoad()
                                collectionView.reloadData()
                                //回传记录,始终保持答题进度
                                if let team = teamScheduleModel{
                                                for teamId in team.teamIds{
                                                                for v in listenNewModel.subjectList[page]{
                                                                                if team.topicIds.contains(v.id){
                                                                                                rootViewModel.insertCorrectAnswer(teamId: "\(teamId)", answerId: v.id)
                                                                                }
                                                                }
                                                }
                                }
                }
@@ -334,12 +347,11 @@
                                                viewModel.answerType.accept(.none)
                                }
                                DispatchQueue.main.asyncAfter(deadline: .now()+0.4) {
                                                if self.answterCount >= 4{
//                                                                self.rootViewModel.answerItems[self.page] = self.listenNewModel.subjectList[self.page]
                                if self.answterCount >= 4{
//                                                DispatchQueue.main.asyncAfter(delay: 3.0) {
                                                                self.voicePlayer.playerEnd()
                                                                NotificationCenter.default.post(name: NextLession_Noti, object: nil)
                                                }
//                                                }
                                }
                }
                
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenMenuVC.swift
@@ -59,10 +59,10 @@
                                let model = dataItems[selectIndexPath.row][indexPath.row]
                                // 暂时关闭,上线时开启
//                                guard model.canStudy == 1 else {
//                                                CommonAlertView.show(isSinple: true, content: "请先完成上一周练习")
//                                                return
//                                }
                                guard model.canStudy == 1 else {
                                                CommonAlertView.show(isSinple: true, content: "请先完成上一周练习")
                                                return
                                }
                                Services.studySchedule(week: model.week).subscribe(onNext: {[weak self]data in
                                                guard let weakSelf = self else { return }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift
@@ -68,73 +68,93 @@
                                if page <= 4{
                                                if indexPath.row == 0{
                                                                //听音选图
                                                                Services.listenSelectPicture(day:day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in
                                                                Services.teamSchedule(type: .lesson1, week: week, day: day).subscribe(onNext: {[weak self] teamSchedule in
                                                                                guard let weakSelf = self else { return }
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson1,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                fightVC.title = ListenType.lesson1.rawTitle
                                                                                                fightVC.data = data
                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                JQ_currentViewController().jq_push(vc:fightVC)
                                                                                }
                                                                                //听音选图
                                                                                Services.listenSelectPicture(day:day, quarter: weakSelf.quarter, week: weakSelf.week).subscribe(onNext: {[weak self] result in
                                                                                                guard let weakSelf = self else { return }
                                                                                                if let data = result.data{
                                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson1,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                                fightVC.title = ListenType.lesson1.rawTitle
                                                                                                                fightVC.teamScheduleModel = teamSchedule.data
                                                                                                                fightVC.data = data
                                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                                JQ_currentViewController().jq_push(vc:fightVC)
                                                                                                }
                                                                                }).disposed(by: weakSelf.disposeBag)
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 1{
                                                                //看图选音
                                                                Services.pictureSelectVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in
                                                                Services.teamSchedule(type: .lesson2, week: week, day: day).subscribe(onNext: {[weak self] teamSchedule in
                                                                                guard let weakSelf = self else { return }
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson2,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                fightVC.title = ListenType.lesson2.rawTitle
                                                                                                fightVC.data = data
                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                JQ_currentViewController().jq_push(vc:fightVC)
                                                                                }
                                                                                Services.pictureSelectVoice(day: day, quarter: weakSelf.quarter, week: weakSelf.week).subscribe(onNext: {[weak self] result in
                                                                                                guard let weakSelf = self else { return }
                                                                                                if let data = result.data{
                                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson2,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                                fightVC.title = ListenType.lesson2.rawTitle
                                                                                                                fightVC.teamScheduleModel = teamSchedule.data
                                                                                                                fightVC.data = data
                                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                                JQ_currentViewController().jq_push(vc:fightVC)
                                                                                                }
                                                                                }).disposed(by: weakSelf.disposeBag)
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 2{
                                                                //归纳排除
                                                                Services.induceExclude(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in
                                                                Services.teamSchedule(type: .lesson3, week: week, day: day).subscribe(onNext: {[weak self] teamSchedule in
                                                                                guard let weakSelf = self else { return }
                                                                                Services.induceExclude(day: day, quarter: weakSelf.quarter, week: weakSelf.week).subscribe(onNext: {[weak self] result in
                                                                                guard let weakSelf = self else { return }
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson3,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                fightVC.title = ListenType.lesson3.rawTitle
                                                                                                fightVC.teamScheduleModel = teamSchedule.data
                                                                                                fightVC.data = data
                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                }
                                                                                }).disposed(by: weakSelf.disposeBag)
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 3{
                                                                //有问有答
                                                                Services.questionsAndAnswers(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in
                                                                Services.teamSchedule(type: .lesson4, week: week, day: day).subscribe(onNext: {[weak self] teamSchedule in
                                                                                guard let weakSelf = self else { return }
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson4,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                fightVC.title = ListenType.lesson4.rawTitle
                                                                                                fightVC.data = data
                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                }
                                                                                Services.questionsAndAnswers(day: day, quarter: weakSelf.quarter, week: weakSelf.week).subscribe(onNext: {[weak self] result in
                                                                                                guard let weakSelf = self else { return }
                                                                                                if let data = result.data{
                                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson4,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                                fightVC.title = ListenType.lesson4.rawTitle
                                                                                                                fightVC.teamScheduleModel = teamSchedule.data
                                                                                                                fightVC.data = data
                                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                                }
                                                                                }).disposed(by: weakSelf.disposeBag)
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 4{
                                                                //音图相配
                                                                Services.pictureMateVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in
                                                                Services.teamSchedule(type: .lesson5, week: week, day: day).subscribe(onNext: {[weak self] teamSchedule in
                                                                                guard let weakSelf = self else { return }
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson5,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                fightVC.title = ListenType.lesson5.rawTitle
                                                                                                fightVC.data = data
                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                }
                                                                                Services.pictureMateVoice(day: day, quarter: weakSelf.quarter, week: weakSelf.week).subscribe(onNext: {[weak self] result in
                                                                                                guard let weakSelf = self else { return }
                                                                                                if let data = result.data{
                                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson5,quarter:weakSelf.quarter,week: weakSelf.week,day:day)
                                                                                                                fightVC.title = ListenType.lesson5.rawTitle
                                                                                                                fightVC.teamScheduleModel = teamSchedule.data
                                                                                                                fightVC.data = data
                                                                                                                fightVC.studyScheduleModel = self?.studyScheduleModel
                                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                                }
                                                                                }).disposed(by: weakSelf.disposeBag)
                                                                }).disposed(by: disposeBag)
                                                }
                                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift
@@ -54,11 +54,13 @@
                                self.limitDay = studyScheduleModel.day
#if DEBUG
                                self.limitDay = 5
#endif
//#if DEBUG
//                                self.limitDay = 5
//#endif
                                if self.limitDay == 5{
                                let total = studyScheduleModel.pair + studyScheduleModel.induction + studyScheduleModel.listen + studyScheduleModel.look + studyScheduleModel.answer
                                if self.limitDay == 5 && total == 500 {
                                                self.limitDay = Int.max
                                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/ChooseLevelView.swift
@@ -20,15 +20,20 @@
                private var clouseLevel:((Int)->Void)!
                private var cancelClouse:(()->Void)!
                private var level:Int = 0
                private var limitLevel:Int = 0
                override func awakeFromNib() {
                                super.awakeFromNib()
                                alpha = 0
                                transform = .init(scaleX: 0.1, y: 0.1)
                                layoutIfNeeded()
                                btn_level1.setTitleColor(.black.withAlphaComponent(0.3), for: .normal)
                                btn_level2.setTitleColor(.black.withAlphaComponent(0.3), for: .normal)
                                btn_level3.setTitleColor(.black.withAlphaComponent(0.3), for: .normal)
                                btn_level1.alpha = 0.5
                                btn_level2.alpha = 0.5
                                btn_level3.alpha = 0.5
                            btn_level3.tag = 12
                            btn_level2.tag = 11
                            btn_level1.tag = 10
                }
@@ -42,6 +47,7 @@
                                guard needLoad else {return}
                                let levelView = ChooseLevelView.jq_loadNibView()
                                levelView.limitLevel = canLevel
                                levelView.clouseLevel = clouse
                                levelView.cancelClouse = cancelClouse
                                sceneDelegate?.window?.addSubview(levelView)
@@ -49,36 +55,45 @@
                                switch canLevel {
                                                case 2:
                                                                levelView.btn_level3.setTitleColor(.black.withAlphaComponent(0.6), for: .normal)
                                                                levelView.btn_level3.alpha = 1
                                                                fallthrough
                                                case 1:
                                                                levelView.btn_level2.setTitleColor(.black.withAlphaComponent(0.6), for: .normal)
                                                                levelView.btn_level2.alpha = 1
                                                                fallthrough
                                                case 0:
                                                                levelView.btn_level1.setTitleColor(.black.withAlphaComponent(0.6), for: .normal)
                                                                levelView.btn_level1.alpha = 1
                                                default:
                                                                levelView.btn_level1.setTitleColor(.black.withAlphaComponent(0.6), for: .normal)
                                                                levelView.btn_level1.alpha = 1
                                }
                                UIView.animate(withDuration: 0.4) {
                                                levelView.transform = .init(scaleX: 1.0, y: 1.0)
                                                levelView.alpha = 1
                                } completion: { _ in
                                                levelView.layoutIfNeeded()
                                }
                }
                @IBAction func chooseAction(_ sender: QMUIButton) {
                                guard sender.alpha == 1.0 else {
                                                sender.alpha = 0.5
                                                sender.isSelected = false
                                level = sender.tag - 10
                                guard level <= limitLevel else {
                                                DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
                                                                sender.alpha = 0.5
                                                                sender.isSelected = false
                                                }
                                                alertError(msg: "请先完成上一难度再挑战");return
                                }
                                level = sender.tag - 10
                                for subView in tackView_level.arrangedSubviews as! [QMUIButton]{
                                                subView.isSelected = sender.tag == subView.tag
                                                if subView.isSelected{
                                                                level = sender.tag - 10
                                                }
                                }
                }
@@ -98,7 +113,21 @@
                                                self.alpha = 0
                                } completion: { _ in
                                                self.removeFromSuperview()
                                                self.clouseLevel(self.level)
                                                if self.btn_level1.isSelected{
                                                                self.clouseLevel(0)
                                                }
                                                if self.btn_level2.isSelected{
                                                                self.clouseLevel(1)
                                                }
                                                if self.btn_level3.isSelected{
                                                                self.clouseLevel(2)
                                                }
                                }
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_4_AnswerView.swift
@@ -43,6 +43,12 @@
                                self.playAtClouse = clouse
                }
                func isPlaying(){
                                btn_playing.setImage(UIImage(named: "icon_playing"), for: .normal)
                                btn_isAnswer.isHidden = true
                                img_play.isHidden = true
                }
                func playEnd(){
                                btn_isAnswer.isHidden = false
                                btn_playing.setImage(UIImage(named: "icon_play_1"), for: .normal)
DolphinEnglishLearnStudent/Moudle/Me/VC/ExchangeRecordHistoryVC.swift
@@ -10,9 +10,10 @@
let Refresh_MarketExchange_Noti = Notification.Name.init("Refresh_MarketExchange_Noti")
class ExchangeRecordViewModel:RefreshModel<ExchangeRecordModel>{
                override func api() -> (Observable<BaseResponse<[ExchangeRecordModel]>>)? {
                                return Services.exchangeRecord()
class ExchangeRecordViewModel:RefreshInnerModel<ExchangeRecordModel>{
                override func api() -> (Observable<BaseResponse<BaseResponseList<ExchangeRecordModel>>>)? {
                                return Services.exchangeRecord(page: page, pageSize: 20)
                }
}
@@ -25,7 +26,7 @@
    override func viewDidLoad() {
        super.viewDidLoad()
                                viewModel.configure(tableView,needMore: false)
                                viewModel.configure(tableView)
                                viewModel.beginRefresh()
                                yy_popBlock = {[weak self] () in
@@ -68,11 +69,14 @@
extension ExchangeRecordHistoryVC:UITableViewDataSource{
                func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                                let cell = tableView.dequeueReusableCell(withIdentifier: "_GoodsItemTCell") as! GoodsItemTCell
                                cell.setModel(viewModel.dataSource.value[indexPath.row])
                                if let model = viewModel.dataSource.value?.records[indexPath.row]{
                                                cell.setModel(model)
                                }
                                return cell
                }
                func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                                return viewModel.dataSource.value.count
                                return viewModel.dataSource.value?.records.count ?? 0
                }
}
DolphinEnglishLearnStudent/Moudle/Me/VC/ParentVerifiyView.swift
New file
@@ -0,0 +1,206 @@
//
//  ParentVerifiyView.swift
//  DolphinEnglishLearnStudent
//
//  Created by 无故事王国 on 2024/7/5.
//
import UIKit
import JQTools
import RxSwift
import QMUIKit
class ParentVerifiyView: UIView,JQNibView{
                @IBOutlet weak var view_container: UIView!
                @IBOutlet weak var label_num1: UILabel!
                @IBOutlet weak var label_num2: UILabel!
                @IBOutlet weak var view_in1: UIView!
                @IBOutlet weak var label_in1: UILabel!
                @IBOutlet weak var view_in2: UIView!
                @IBOutlet weak var label_in2: UILabel!
                @IBOutlet weak var view_in3: UIView!
                @IBOutlet weak var label_in3: UILabel!
                @IBOutlet weak var tf_input: QMUITextField!
                private var num1 = 0
                private var num2 = 0
                private var total = 0
                private var closue:(()->Void)!
                private var disposeBag = DisposeBag()
                override func awakeFromNib() {
                                super.awakeFromNib()
                                view_container.transform = .init(scaleX: 0.1, y: 0.1)
                                alpha = 0
                                layoutIfNeeded()
                                next()
                                tf_input.rx.text.changed.subscribe(onNext: {[weak self]text in
                                                guard let weakSelf = self else { return }
                                                weakSelf.label_in1.text = ""
                                                weakSelf.label_in2.text = ""
                                                weakSelf.label_in3.text = ""
                                                guard !(text!.isEmpty) else {return}
                                                guard text!.jq_isDigit else {return}
                                                let array    = weakSelf.splitInteger(number: Int(text!)!)
                                                for (index,v) in array.enumerated(){
                                                                switch index {
                                                                                case 0:weakSelf.label_in1.text = "\(v)"
                                                                                case 1:weakSelf.label_in2.text = "\(v)"
                                                                                case 2:weakSelf.label_in3.text = "\(v)"
                                                                                default:
                                                                                                weakSelf.label_in1.text = ""
                                                                                                weakSelf.label_in2.text = ""
                                                                                                weakSelf.label_in3.text = ""
                                                                }
                                                }
                                }).disposed(by: disposeBag)
                                tf_input.rx.controlEvent(.editingDidEnd).subscribe(onNext: {[weak self] _ in
                                                guard let weakSelf = self else { return }
                                                weakSelf.total = Int(weakSelf.tf_input.text ?? "0") ?? 0
                                }).disposed(by: disposeBag)
                                tf_input.returnKeyType = .done
                                tf_input.delegate = self
                }
                private func next(){
                                view_in3.isHidden = true
                                view_in2.isHidden = true
                                view_in1.isHidden = true
                                num1 = Int.random(in: 1...99)
                                num2 = Int.random(in: 1...99)
                                label_num1.text = "\(num1)"
                                label_num2.text = "\(num2)"
                                let tmep = num1 + num2
                                tf_input.maximumTextLength = UInt("\(tmep)".count)
                                switch "\(tmep)".count {
                                                case 3:
                                                                view_in3.isHidden = false
                                                                fallthrough
                                                case 2:
                                                                view_in2.isHidden = false
                                                                fallthrough
                                                case 1:
                                                                view_in1.isHidden = false
                                                                fallthrough
                                                default:break
                                }
                }
                static func show(verifiy:@escaping()->Void){
                                let verifiyView = ParentVerifiyView.jq_loadNibView()
                                verifiyView.frame = sceneDelegate?.window?.frame ?? .zero
                                verifiyView.closue = verifiy
                                sceneDelegate?.window?.addSubview(verifiyView)
                                UIView.animate(withDuration: 0.5) {
                                                verifiyView.alpha = 1
                                                verifiyView.view_container.transform = .init(scaleX: 1.0, y: 1.0)
                                }completion: { complete in
                                                if complete{
                                                                verifiyView.tf_input.becomeFirstResponder()
                                                }
                                }
                }
                private func splitInteger(number: Int) -> [Int] {
                                var digits: [Int] = []
                                var num = number
                                while num > 0 {
                                                digits.append(num % 10)
                                                num /= 10
                                }
                                return digits.reversed()
                }
                private func dismiss(){
                                UIView.animate(withDuration: 0.5) {
                                                self.alpha = 0
                                                self.view_container.transform = .init(scaleX: 0.1, y: 0.1)
                                }completion: { complete in
                                                self.removeFromSuperview()
                                }
                }
                @IBAction func dissmissAction(_ sender: Any) {
                                UIView.animate(withDuration: 0.5) {
                                                self.alpha = 0
                                                self.view_container.transform = .init(scaleX: 0.1, y: 0.1)
                                }completion: { complete in
                                                self.removeFromSuperview()
                                }
                }
                @IBAction func completeAction(_ sender: Any) {
                                verifiy()
                }
                private func verifiy(){
                                if num1 + num2 == total{
                                                closue()
                                                dismiss()
                                }else{
                                                alertError(msg: "答题错误")
                                                tf_input.text = ""
                                            label_in1.text = ""
                                            label_in2.text = ""
                                            label_in3.text = ""
                                                DispatchQueue.main.asyncAfter(delay: 2) {
                                                                self.tf_input.becomeFirstResponder()
                                                }
                                                next()
                                }
                }
}
extension ParentVerifiyView:QMUITextFieldDelegate{
                func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                                 //输入是否是数值
                                if string.jq_isDigit{
                                                return true
                                }
                                return false
                }
                func textFieldShouldReturn(_ textField: UITextField) -> Bool {
                                if textField.text!.isEmpty{
                                                alert(msg: "请输入答案");return false
                                }
                                if textField.text!.jq_isDigit{
                                                textField.resignFirstResponder()
                                                total = Int(textField.text!)!
                                                return true
                                }
                                alertError(msg: "答题错误")
                                next()
                                return false
                }
}
DolphinEnglishLearnStudent/Moudle/Me/VC/ParentVerifiyView.xib
New file
@@ -0,0 +1,256 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
    <device id="ipad10_9rounded" orientation="landscape" layout="fullscreen" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="ParentVerifiyView" customModule="DolphinEnglishLearnStudent" customModuleProvider="target">
            <rect key="frame" x="0.0" y="0.0" width="1180" height="820"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="atP-IF-7BM">
                    <rect key="frame" x="0.0" y="24" width="1180" height="776"/>
                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                    <state key="normal" title="Button"/>
                    <connections>
                        <action selector="dissmissAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="TP7-r3-c3H"/>
                    </connections>
                </button>
                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="N8a-JL-j8g">
                    <rect key="frame" x="234" y="56" width="712" height="690"/>
                    <subviews>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请家长作答" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="n6P-Pq-9pQ">
                            <rect key="frame" x="310" y="30" width="92" height="21.5"/>
                            <fontDescription key="fontDescription" type="system" pointSize="18"/>
                            <nil key="textColor"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dii-aN-1yX">
                            <rect key="frame" x="51" y="114.5" width="23" height="51.5"/>
                            <fontDescription key="fontDescription" name="Impact" family="Impact" pointSize="42"/>
                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="+" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="g1B-C3-hEx">
                            <rect key="frame" x="104" y="114.5" width="22.5" height="51.5"/>
                            <fontDescription key="fontDescription" name="Impact" family="Impact" pointSize="42"/>
                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ylp-CE-kV6">
                            <rect key="frame" x="156.5" y="114.5" width="23" height="51.5"/>
                            <fontDescription key="fontDescription" name="Impact" family="Impact" pointSize="42"/>
                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="=" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QGU-Q3-X9a">
                            <rect key="frame" x="209.5" y="116" width="22.5" height="52"/>
                            <constraints>
                                <constraint firstAttribute="width" constant="22.5" id="KYa-sL-WL3"/>
                                <constraint firstAttribute="height" constant="52" id="ipg-fi-A5c"/>
                            </constraints>
                            <fontDescription key="fontDescription" name="Impact" family="Impact" pointSize="42"/>
                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="5SY-e5-Efb" customClass="QMUITextField">
                            <rect key="frame" x="262" y="106.5" width="4" height="68"/>
                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
                            <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
                            <userDefinedRuntimeAttributes>
                                <userDefinedRuntimeAttribute type="number" keyPath="maximumTextLength">
                                    <integer key="value" value="3"/>
                                </userDefinedRuntimeAttribute>
                            </userDefinedRuntimeAttributes>
                        </textField>
                        <stackView opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="S9V-cR-c3k">
                            <rect key="frame" x="262" y="106.5" width="4" height="68"/>
                            <subviews>
                                <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="epx-0B-e7a">
                                    <rect key="frame" x="0.0" y="0.0" width="68" height="68"/>
                                    <subviews>
                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LSu-k2-Vh3">
                                            <rect key="frame" x="0.0" y="0.0" width="68" height="68"/>
                                            <fontDescription key="fontDescription" name="Impact" family="Impact" pointSize="42"/>
                                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
                                            <nil key="highlightedColor"/>
                                        </label>
                                    </subviews>
                                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                                    <constraints>
                                        <constraint firstItem="LSu-k2-Vh3" firstAttribute="top" secondItem="epx-0B-e7a" secondAttribute="top" id="9cN-e6-GRa"/>
                                        <constraint firstAttribute="trailing" secondItem="LSu-k2-Vh3" secondAttribute="trailing" id="AYL-nf-JdV"/>
                                        <constraint firstAttribute="bottom" secondItem="LSu-k2-Vh3" secondAttribute="bottom" id="Mhf-8z-LJH"/>
                                        <constraint firstItem="LSu-k2-Vh3" firstAttribute="leading" secondItem="epx-0B-e7a" secondAttribute="leading" id="fVM-sH-FCf"/>
                                        <constraint firstAttribute="width" constant="68" id="pd2-ub-KI9"/>
                                    </constraints>
                                    <userDefinedRuntimeAttributes>
                                        <userDefinedRuntimeAttribute type="number" keyPath="ld_borderWidthXIB">
                                            <real key="value" value="1"/>
                                        </userDefinedRuntimeAttribute>
                                        <userDefinedRuntimeAttribute type="color" keyPath="ld_borderColorXIB">
                                            <color key="value" red="0.8666666666666667" green="0.8666666666666667" blue="0.8666666666666667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        </userDefinedRuntimeAttribute>
                                        <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/>
                                        <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB">
                                            <real key="value" value="8"/>
                                        </userDefinedRuntimeAttribute>
                                    </userDefinedRuntimeAttributes>
                                </view>
                                <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Uja-r5-Snq">
                                    <rect key="frame" x="0.0" y="0.0" width="68" height="68"/>
                                    <subviews>
                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="THW-sS-knk">
                                            <rect key="frame" x="0.0" y="0.0" width="68" height="68"/>
                                            <fontDescription key="fontDescription" name="Impact" family="Impact" pointSize="42"/>
                                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
                                            <nil key="highlightedColor"/>
                                        </label>
                                    </subviews>
                                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                                    <constraints>
                                        <constraint firstAttribute="trailing" secondItem="THW-sS-knk" secondAttribute="trailing" id="ISS-tk-Whb"/>
                                        <constraint firstItem="THW-sS-knk" firstAttribute="top" secondItem="Uja-r5-Snq" secondAttribute="top" id="OFF-Ie-DLO"/>
                                        <constraint firstAttribute="width" constant="68" id="Tnk-Kh-83M"/>
                                        <constraint firstAttribute="bottom" secondItem="THW-sS-knk" secondAttribute="bottom" id="Wom-4C-fGG"/>
                                        <constraint firstItem="THW-sS-knk" firstAttribute="leading" secondItem="Uja-r5-Snq" secondAttribute="leading" id="ylo-pq-ikD"/>
                                    </constraints>
                                    <userDefinedRuntimeAttributes>
                                        <userDefinedRuntimeAttribute type="number" keyPath="ld_borderWidthXIB">
                                            <real key="value" value="1"/>
                                        </userDefinedRuntimeAttribute>
                                        <userDefinedRuntimeAttribute type="color" keyPath="ld_borderColorXIB">
                                            <color key="value" red="0.86666666670000003" green="0.86666666670000003" blue="0.86666666670000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        </userDefinedRuntimeAttribute>
                                        <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/>
                                        <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB">
                                            <real key="value" value="8"/>
                                        </userDefinedRuntimeAttribute>
                                    </userDefinedRuntimeAttributes>
                                </view>
                                <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q7Z-mf-Snl">
                                    <rect key="frame" x="0.0" y="0.0" width="68" height="68"/>
                                    <subviews>
                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AAT-Wy-dzJ">
                                            <rect key="frame" x="0.0" y="0.0" width="68" height="68"/>
                                            <fontDescription key="fontDescription" name="Impact" family="Impact" pointSize="42"/>
                                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
                                            <nil key="highlightedColor"/>
                                        </label>
                                    </subviews>
                                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                                    <constraints>
                                        <constraint firstItem="AAT-Wy-dzJ" firstAttribute="top" secondItem="Q7Z-mf-Snl" secondAttribute="top" id="JKc-rf-neK"/>
                                        <constraint firstAttribute="trailing" secondItem="AAT-Wy-dzJ" secondAttribute="trailing" id="KDv-3L-IIv"/>
                                        <constraint firstItem="AAT-Wy-dzJ" firstAttribute="leading" secondItem="Q7Z-mf-Snl" secondAttribute="leading" id="Vpm-4v-UnV"/>
                                        <constraint firstAttribute="width" constant="68" id="nS0-FV-eUh"/>
                                        <constraint firstAttribute="bottom" secondItem="AAT-Wy-dzJ" secondAttribute="bottom" id="ozJ-9T-Ny2"/>
                                    </constraints>
                                    <userDefinedRuntimeAttributes>
                                        <userDefinedRuntimeAttribute type="number" keyPath="ld_borderWidthXIB">
                                            <real key="value" value="1"/>
                                        </userDefinedRuntimeAttribute>
                                        <userDefinedRuntimeAttribute type="color" keyPath="ld_borderColorXIB">
                                            <color key="value" red="0.86666666670000003" green="0.86666666670000003" blue="0.86666666670000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        </userDefinedRuntimeAttribute>
                                        <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/>
                                        <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB">
                                            <real key="value" value="8"/>
                                        </userDefinedRuntimeAttribute>
                                    </userDefinedRuntimeAttributes>
                                </view>
                            </subviews>
                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                            <constraints>
                                <constraint firstAttribute="height" constant="68" id="pbM-1x-2rj"/>
                            </constraints>
                        </stackView>
                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jqe-JS-xoc">
                            <rect key="frame" x="148" y="620" width="416" height="47"/>
                            <color key="backgroundColor" red="0.25490196078431371" green="0.63529411764705879" blue="0.92156862745098034" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
                            <constraints>
                                <constraint firstAttribute="height" constant="47" id="Msb-z4-Sv4"/>
                            </constraints>
                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                            <state key="normal" title="确认"/>
                            <userDefinedRuntimeAttributes>
                                <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/>
                                <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB">
                                    <real key="value" value="8"/>
                                </userDefinedRuntimeAttribute>
                            </userDefinedRuntimeAttributes>
                            <connections>
                                <action selector="completeAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Ixr-q7-ebI"/>
                            </connections>
                        </button>
                    </subviews>
                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                    <constraints>
                        <constraint firstItem="g1B-C3-hEx" firstAttribute="leading" secondItem="dii-aN-1yX" secondAttribute="trailing" constant="30" id="8hk-YL-cvQ"/>
                        <constraint firstItem="g1B-C3-hEx" firstAttribute="centerY" secondItem="dii-aN-1yX" secondAttribute="centerY" id="9bv-d4-vtN"/>
                        <constraint firstItem="Ylp-CE-kV6" firstAttribute="centerY" secondItem="dii-aN-1yX" secondAttribute="centerY" id="BTe-ev-0iD"/>
                        <constraint firstItem="S9V-cR-c3k" firstAttribute="centerY" secondItem="dii-aN-1yX" secondAttribute="centerY" id="Ceq-Wb-XGn"/>
                        <constraint firstItem="5SY-e5-Efb" firstAttribute="trailing" secondItem="S9V-cR-c3k" secondAttribute="trailing" id="Fgc-HV-KOv"/>
                        <constraint firstItem="QGU-Q3-X9a" firstAttribute="top" secondItem="N8a-JL-j8g" secondAttribute="top" constant="116" id="Hwf-bB-Wuc"/>
                        <constraint firstAttribute="trailing" secondItem="jqe-JS-xoc" secondAttribute="trailing" constant="148" id="InB-4K-SSt"/>
                        <constraint firstItem="Ylp-CE-kV6" firstAttribute="leading" secondItem="g1B-C3-hEx" secondAttribute="trailing" constant="30" id="Jof-hm-Vq6"/>
                        <constraint firstAttribute="bottom" secondItem="jqe-JS-xoc" secondAttribute="bottom" constant="23" id="LCs-bA-klZ"/>
                        <constraint firstItem="dii-aN-1yX" firstAttribute="leading" secondItem="N8a-JL-j8g" secondAttribute="leading" constant="51" id="OvF-Rq-NiU"/>
                        <constraint firstItem="5SY-e5-Efb" firstAttribute="bottom" secondItem="S9V-cR-c3k" secondAttribute="bottom" id="SGv-S0-O7e"/>
                        <constraint firstItem="jqe-JS-xoc" firstAttribute="leading" secondItem="N8a-JL-j8g" secondAttribute="leading" constant="148" id="SY0-Nn-fcN"/>
                        <constraint firstItem="5SY-e5-Efb" firstAttribute="top" secondItem="S9V-cR-c3k" secondAttribute="top" id="XGK-h0-eoY"/>
                        <constraint firstItem="n6P-Pq-9pQ" firstAttribute="centerX" secondItem="N8a-JL-j8g" secondAttribute="centerX" id="ZL1-Cv-cDr"/>
                        <constraint firstItem="5SY-e5-Efb" firstAttribute="leading" secondItem="S9V-cR-c3k" secondAttribute="leading" id="d9s-aX-OiW"/>
                        <constraint firstItem="dii-aN-1yX" firstAttribute="top" secondItem="n6P-Pq-9pQ" secondAttribute="bottom" constant="63" id="lWh-70-8WG"/>
                        <constraint firstItem="n6P-Pq-9pQ" firstAttribute="top" secondItem="N8a-JL-j8g" secondAttribute="top" constant="30" id="r2L-ma-z31"/>
                        <constraint firstItem="QGU-Q3-X9a" firstAttribute="leading" secondItem="Ylp-CE-kV6" secondAttribute="trailing" constant="30" id="u6X-PW-dwg"/>
                        <constraint firstItem="S9V-cR-c3k" firstAttribute="leading" secondItem="QGU-Q3-X9a" secondAttribute="trailing" constant="30" id="udk-Rn-50x"/>
                    </constraints>
                    <userDefinedRuntimeAttributes>
                        <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB">
                            <real key="value" value="8"/>
                        </userDefinedRuntimeAttribute>
                    </userDefinedRuntimeAttributes>
                </view>
            </subviews>
            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="sRGB"/>
            <constraints>
                <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="N8a-JL-j8g" secondAttribute="bottom" constant="54" id="4Ih-eU-D8U"/>
                <constraint firstItem="N8a-JL-j8g" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="32" id="BEn-FI-VWa"/>
                <constraint firstItem="atP-IF-7BM" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="BSl-kN-Ygp"/>
                <constraint firstItem="atP-IF-7BM" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="SEP-NA-1Ld"/>
                <constraint firstItem="N8a-JL-j8g" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="234" id="VAU-HL-rFk"/>
                <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="atP-IF-7BM" secondAttribute="trailing" id="frg-sW-hJw"/>
                <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="N8a-JL-j8g" secondAttribute="trailing" constant="234" id="ggl-6c-idW"/>
                <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="atP-IF-7BM" secondAttribute="bottom" id="uUL-BE-UHA"/>
            </constraints>
            <connections>
                <outlet property="label_in1" destination="LSu-k2-Vh3" id="ika-8d-7by"/>
                <outlet property="label_in2" destination="THW-sS-knk" id="JsI-8Y-psy"/>
                <outlet property="label_in3" destination="AAT-Wy-dzJ" id="uts-zw-ReD"/>
                <outlet property="label_num1" destination="dii-aN-1yX" id="A1d-ln-dzV"/>
                <outlet property="label_num2" destination="Ylp-CE-kV6" id="aMw-Fj-sas"/>
                <outlet property="tf_input" destination="5SY-e5-Efb" id="7i0-tm-VEL"/>
                <outlet property="view_container" destination="N8a-JL-j8g" id="TZt-EL-3n1"/>
                <outlet property="view_in1" destination="epx-0B-e7a" id="VTj-Nz-bYj"/>
                <outlet property="view_in2" destination="Uja-r5-Snq" id="cxb-KV-pE0"/>
                <outlet property="view_in3" destination="Q7Z-mf-Snl" id="HcL-1U-imo"/>
            </connections>
            <point key="canvasLocation" x="139.83050847457628" y="19.756097560975608"/>
        </view>
    </objects>
    <resources>
        <systemColor name="systemBackgroundColor">
            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
    </resources>
</document>
DolphinEnglishLearnStudent/Moudle/Me/VC/VIPCenterVC.swift
@@ -33,13 +33,16 @@
                                }
                                Services.vipInfo().subscribe(onNext: {data in
                                                if let model = data.data?.first{
                                                                self.webView.loadHTMLString(model.info.jq_wrapHtml(edge: UIEdgeInsets(top: 0, left: 10, bottom: 3, right: 0)), baseURL: nil)
                                                }
                                }).disposed(by: disposeBag)
    }
                override func setUI() {
                                webView = WKWebView(frame: .zero)
                                webView.scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 120, right: 0)
                                view.addSubview(webView)
                                webView.snp.makeConstraints { make in
                                                make.edges.equalToSuperview()
@@ -51,6 +54,7 @@
                                btn_vip.setTitleColor(.white, for: .normal)
                                btn_vip.backgroundColor = UIColor(hexStr: "#41A2EB")
                                btn_vip.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
                                btn_vip.addTarget(self, action: #selector(becomeVIPAction), for: .touchUpInside)
                                btn_vip.jq_cornerRadius = 8
                                view.addSubview(btn_vip)
                                btn_vip.snp.makeConstraints { make in
@@ -60,4 +64,10 @@
                                                make.centerX.equalToSuperview()
                                }
                }
                @objc func becomeVIPAction(){
                                ParentVerifiyView.show {
                                }
                }
}
DolphinEnglishLearnStudent/Moudle/Me/View/ShareView.swift
@@ -75,7 +75,12 @@
                                                                SDWebImageDownloader.shared.downloadImage(with: URL(string: m.img)) { iamge, data, error, state in
                                                                                hiddenHUD()
                                                                                guard error == nil else {alert(msg: "图片获取失败");return}
                                                                                WeChatTools.shareUrl("https://dollearn.com/", title:"海豚智能教育平台" , desc: m.title, thumb: iamge!, scene: scene)
                                                                                if scene == WXSceneSession{
                                                                                                WeChatTools.shareUrl("https://dollearn.com/", title:"海豚智能教育平台" , desc: m.title, thumb: iamge!, scene: scene)
                                                                                }else{
                                                                                                WeChatTools.shareUrl("https://dollearn.com/", title:m.title, desc: "", thumb: iamge!, scene: scene)
                                                                                }
                                                                }
                                                }
                                }).disposed(by: disposeBag)
DolphinEnglishLearnStudent/Other/UIView/VoiceHandleView.swift
@@ -92,6 +92,7 @@
                                img_hint.isHidden = false
                                btn_play.isHidden = false
                                img_hint_playing.isHidden = true
                                jq_cornerRadius = 8
                }
                func playing(){
DolphinEnglishLearnStudent/Services/NetworkRequest.swift
@@ -235,7 +235,7 @@
                                                                                                                case 502: //登录被冻结
                                                                                                                                CommonAlertView.show(isSinple: true, content: next.msg)
                                                                                                                case 501:
                                                                                                                                CommonAlertView.show(content: next.msg, completeTitle: "成为会员") {
                                                                                                                                CommonAlertView.show(content: "以下内容仅限会员查看,请先成为会员!", completeTitle: "成为会员") {
                                                                                                                                                 let vc = VIPCenterVC()
                                                                                                                                                vc.title = "会员中心"
                                                                                                                                                JQ_currentNavigationController().pushViewController(vc)
DolphinEnglishLearnStudent/Services/Services.swift
@@ -315,9 +315,11 @@
                                return NetworkRequest.request(params: params, method: .get, progress: false)
                }
                class func exchangeRecord()->Observable<BaseResponse<[ExchangeRecordModel]>>{
                class func exchangeRecord(page:Int,pageSize:Int = 20)->Observable<BaseResponse<BaseResponseList<ExchangeRecordModel>>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/goods/base/goods/exchangeRecord")
                                                .append(key: "pageNumber", value: page)
                                                .append(key: "pageSize", value: pageSize)
                                return NetworkRequest.request(params: params, method: .get, progress: false)
                }
@@ -389,9 +391,9 @@
                                return NetworkRequest.request(params: params, method: .get, progress: false)
                }
                class func vipInfo()->Observable<BaseResponse<SimpleModel>>{
                class func vipInfo()->Observable<BaseResponse<[VIPInfoModel]>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/user/vipInfo")
                                params.interface(url: "/study/base/user/vipInfoStudy")
                                return NetworkRequest.request(params: params, method: .post, progress: false)
                }
}