fix
无故事王国
2024-06-06 6f7f02d5c8880ff670b2c694fe61f5af5a6e3e36
fix
37个文件已修改
4个文件已添加
1469 ■■■■ 已修改文件
DolphinEnglishLearnStudent.xcodeproj/project.pbxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Assets.xcassets/Icon/icon_answer.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Assets.xcassets/Icon/icon_answer.imageset/icon_answer.png 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Assets.xcassets/Icon/icon_answer.imageset/icon_answer@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Config/VoicePlayer.swift 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Models/CommonModel.swift 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/HomeListenFight_lesson_1_VC.swift 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/HomeVC.swift 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_1_CCell.swift 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_1_CCell.xib 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.xib 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.swift 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.xib 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/TCell/HomeListen_item_TCell.swift 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/TCell/HomeListen_item_TCell.xib 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift 117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift 135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_5_VC.swift 148 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenMenuVC.swift 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift 153 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_3_AnswerView.swift 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_4_AnswerView.swift 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_4_AnswerView.xib 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.swift 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.xib 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/View/AwardListView.swift 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/MeVC.swift 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/TCell/GoodsItemTCell.swift 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/TCell/GoodsItemTCell.xib 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/TCell/Home_1_TCell.swift 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/VC/ExchangeRecordHistoryVC.swift 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.swift 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.xib 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Other/UIView/StudyHandleView.swift 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Services/NetworkRequest.swift 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Services/Services.swift 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/ViewModel/UserViewModel.swift 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent.xcodeproj/project.pbxproj
@@ -74,6 +74,7 @@
        13649E9C2C00304C001B04E2 /* ListenFight_lesson_1_CCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13649E9A2C00304C001B04E2 /* ListenFight_lesson_1_CCell.swift */; };
        13649E9D2C00304C001B04E2 /* ListenFight_lesson_1_CCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13649E9B2C00304C001B04E2 /* ListenFight_lesson_1_CCell.xib */; };
        137CB4292BFF505800D32862 /* HomeListenFightVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137CB4282BFF505800D32862 /* HomeListenFightVC.swift */; };
        13812B9C2C0F02B700905CCE /* VoicePlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13812B9B2C0F02B600905CCE /* VoicePlayer.swift */; };
        138964002BFDF98200AEDCD9 /* StudyVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138963FE2BFDF98200AEDCD9 /* StudyVC.swift */; };
        138964012BFDF98200AEDCD9 /* StudyVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 138963FF2BFDF98200AEDCD9 /* StudyVC.xib */; };
        13A049FF2C058B1400F1F52E /* HomeListenFight_lesson_5_VC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13A049FE2C058B1400F1F52E /* HomeListenFight_lesson_5_VC.swift */; };
@@ -182,6 +183,7 @@
        13649E9A2C00304C001B04E2 /* ListenFight_lesson_1_CCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListenFight_lesson_1_CCell.swift; sourceTree = "<group>"; };
        13649E9B2C00304C001B04E2 /* ListenFight_lesson_1_CCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ListenFight_lesson_1_CCell.xib; sourceTree = "<group>"; };
        137CB4282BFF505800D32862 /* HomeListenFightVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeListenFightVC.swift; sourceTree = "<group>"; };
        13812B9B2C0F02B600905CCE /* VoicePlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoicePlayer.swift; sourceTree = "<group>"; };
        138963FE2BFDF98200AEDCD9 /* StudyVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyVC.swift; sourceTree = "<group>"; };
        138963FF2BFDF98200AEDCD9 /* StudyVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StudyVC.xib; sourceTree = "<group>"; };
        13A049FE2C058B1400F1F52E /* HomeListenFight_lesson_5_VC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeListenFight_lesson_5_VC.swift; sourceTree = "<group>"; };
@@ -289,6 +291,7 @@
            children = (
                1302783E2BFD978900DDCE81 /* Config.swift */,
                1302783F2BFD978900DDCE81 /* Enums.swift */,
                13812B9B2C0F02B600905CCE /* VoicePlayer.swift */,
            );
            path = Config;
            sourceTree = "<group>";
@@ -785,6 +788,7 @@
                13A04A032C05BFDC00F1F52E /* HomeListenGame_2_VC.swift in Sources */,
                130278592BFD985E00DDCE81 /* BitrhdayPickerView.swift in Sources */,
                133386382C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift in Sources */,
                13812B9C2C0F02B700905CCE /* VoicePlayer.swift in Sources */,
                1302787B2BFD9ED600DDCE81 /* MarketContentVC.swift in Sources */,
                13649E9C2C00304C001B04E2 /* ListenFight_lesson_1_CCell.swift in Sources */,
                13EEB8A02BFF28A7002996FC /* HomeListenVC.swift in Sources */,
DolphinEnglishLearnStudent/Assets.xcassets/Icon/icon_answer.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "filename" : "icon_answer.png",
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "icon_answer@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
DolphinEnglishLearnStudent/Assets.xcassets/Icon/icon_answer.imageset/icon_answer.png
DolphinEnglishLearnStudent/Assets.xcassets/Icon/icon_answer.imageset/icon_answer@2x.png
DolphinEnglishLearnStudent/Config/VoicePlayer.swift
New file
@@ -0,0 +1,98 @@
//
//  VoicePlayer.swift
//  DolphinEnglishLearnStudent
//
//  Created by 无故事王国 on 2024/6/4.
//
import Foundation
import AVFAudio
/// 音频播放器
class VoicePlayer:NSObject{
                /// 缓存地址
                private let voiceCacheDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent("voices")
                private static var _sharedInstance: VoicePlayer?
                private var player:AVAudioPlayer?
                //是否正在播放
                var isPlaying:Bool{return player?.isPlaying ?? false}
                //播放完成回调
                private var playComplete:(()->Void)?
                /// 单例
                /// - Returns: <#description#>
                class func share() -> VoicePlayer {
                                guard let instance = _sharedInstance else {
                                                _sharedInstance = VoicePlayer()
                                                try? FileManager.default.createDirectory(at: _sharedInstance!.voiceCacheDirectory, withIntermediateDirectories: true)
                                                return _sharedInstance!
                                }
                                return instance
                }
                private override init() {} // 私有化init方法
                ///销毁单例对象
                class func destroy() {
                                _sharedInstance = nil
                }
                /// 播放语音
                /// - Parameter url: Https的语音地址
                func playerAt(url:String?){
                                guard let u = url else {return}
                                if player?.isPlaying ?? false{
                                                VoicePlayer.share().playComplete?() //先通知完成播放
                                                player?.stop()
                                }
                                //文件存在:直接播放缓存路径的语音
                                let fileURL = voiceCacheDirectory.appendingPathComponent(URL(fileURLWithPath: u).lastPathComponent).droppedScheme()
                                if FileManager.default.fileExists(atPath: fileURL!.absoluteString){
                                                player = try? AVAudioPlayer(contentsOf: fileURL!)
                                                player?.delegate = self
                                                player?.play()
                                }else{
                                                //文件不存在:执行下载
                                                let downloadTask = URLSession.shared.downloadTask(with: URL(string: u)!) { tempLocalUrl, response, error in
                                                                if let tempLocalUrl = tempLocalUrl, error == nil {
                                                                                do {
                                                                                                let finalCacheUrl = self.voiceCacheDirectory.appendingPathComponent(URL(fileURLWithPath: u).lastPathComponent)
                                                                                                try FileManager.default.moveItem(at: tempLocalUrl, to: finalCacheUrl)
                                                                                                self.player = try? AVAudioPlayer(contentsOf: finalCacheUrl)
                                                                                                self.player?.delegate = self
                                                                                                self.player?.play()
                                                                                } catch {
                                                                                                print("视频缓存失败:catch")
                                                                                }
                                                                } else {
                                                                                print("视频缓存失败:\(error?.localizedDescription ?? "")")
                                                                }
                                                }
                                                downloadTask.resume()
                                }
                }
                func playerEnd(){
                                player?.stop()
                                playComplete?()
                }
                func playEnd(course:@escaping ()->Void){
                                self.playComplete = course
                }
}
extension VoicePlayer:AVAudioPlayerDelegate{
                func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
                                VoicePlayer.share().playComplete?()
                }
                func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: (any Error)?) {
                                print("播放错误")
                }
}
DolphinEnglishLearnStudent/Models/CommonModel.swift
@@ -173,14 +173,17 @@
                var expressNumber: String = ""
                var expressTime: String = ""
                var goodsId: Int = 0
                var goodsName: String = ""
                var id: Int = 0
                var insertTime: String = ""
                var integral: Int = 0
                var orderNumber: String = ""
                var state: Int = 0
                var state: Int = 0 //订单状态1待发货2已发货3已完成
                var updateBy: String = ""
                var updateTime: String = ""
                var userId: Int = 0
                var goodsType = [String]()
                var coverImg:String = ""
}
struct StudyGamesModel:HandyJSON{
@@ -191,23 +194,23 @@
struct StudyGamesRecordModel:HandyJSON{
                var accuracy: Int = 0
                var createBy: String?
                var createTime: String?
                var createBy: String = ""
                var createTime: String = ""
                var disabled: Bool = false
                var gameDifficulty: Int = 0
                var gameId: Int = 0
                var gameName: String?
                var gameName: String = ""
                var id: Int = 0
                var updateBy: String?
                var updateTime: String?
                var updateBy: String = ""
                var updateTime: String = ""
                var userId: Int = 0
                var useTime: Int = 0
}
struct StudyDataRecordModel:HandyJSON{
                var answer: Int = 0
                var createBy: String?
                var createTime: String?
                var createBy: String = ""
                var createTime: String = ""
                var day: Int = 0
                var disabled: Bool = false
                var id: Int = 0
@@ -219,8 +222,8 @@
                var surplus: Int = 0
                var todayStudy: Int = 0
                var totalStudy: Int = 0
                var updateBy: String?
                var updateTime: String?
                var updateBy: String = ""
                var updateTime: String = ""
                var userId: Int = 0
                var week: Int = 0
                var weekStudy: Int = 0
@@ -235,3 +238,65 @@
                var type = 0
                var week = 0
}
class Listen1Model:HandyJSON{
                var data:Listen1DataModel?
                var subjectList = [Listen1SubModel]()
                required init(){}
}
struct Listen1DataModel:HandyJSON{
                var createBy: String = ""
                var createTime: String = ""
                var day: Int = 0
                var disabled: Bool = false
                var id: Int = 0
                var integral: Int = 0
                var isVip: Int = 0
                var studyId: Int = 0
                var subject: String = ""
                var updateBy: String = ""
                var updateTime: String = ""
                var week: Int = 0
}
class Listen1SubModel:HandyJSON{
                required init() {}
                var correct: String = ""
                var createBy: String = ""
                var createTime: String = ""
                var disabled: Bool = false
                var english: String = ""
                var error: String = ""
                var id: Int = 0
                var img: String = ""
                var name: String = ""
                var state: Int = 0
                var type: String = ""
                var updateBy: String = ""
                var updateTime: String = ""
}
struct Listen4Model:HandyJSON{
                var data = [Listen4DataModel]()
}
struct Listen4DataModel:HandyJSON{
                var answerSubject: Int = 0
                var createBy: String = ""
                var createTime: String = ""
                var day: Int = 0
                var disabled: Bool = false
                var id: Int = 0
                var integral: Int = 0
                var isAnswer: Int = 0
                var isVip: Int = 0
                var studyId: Int = 0
                var subject: Int = 0
                var subjectList = [Listen1SubModel]()
                var updateBy: String = ""
                var updateTime: String = ""
                var week: Int = 0
}
DolphinEnglishLearnStudent/Moudle/Home/HomeListenFight_lesson_1_VC.swift
@@ -18,12 +18,12 @@
class HomeListenFight_lesson_1_VC: BaseVC {
                private var viewModel = FightAnswerViewModel()
                private var listen1Model:Listen1Model!
                private var randomElement:Listen1SubModel?
                private var page:Int!
                var rootViewModel:HomeListenFightViewModel!
                private lazy var menuView:StudyHandleView = {
                                let menu = StudyHandleView.jq_loadNibView()
                                menu.listenType = .lesson1
                                return menu
                }()
                private var menuView:StudyHandleView = StudyHandleView.jq_loadNibView()
                private lazy var collectionView:UICollectionView = {
                                let flowLayout = UICollectionViewFlowLayout()
@@ -37,9 +37,31 @@
                                return collection
                }()
                required init(page:Int,listen1Model:Listen1Model){
                                super.init(nibName: nil, bundle: nil)
                                self.page = page
                                self.listen1Model = listen1Model
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
                override func viewDidLoad() {
                                super.viewDidLoad()
                                navigationItem.titleView = UIView()
                                collectionView.reloadData()
                                menuView.listenType = .lesson1
//                                collectionView.isUserInteractionEnabled = false
                                //制造随机
                                randomElement = listen1Model.subjectList.randomElement()
                                menuView.vioceSoundUrl = randomElement?.correct
                                VoicePlayer.share().playEnd {[weak self] in
                                                self?.menuView.reset()
                                }
                }
                override func setUI() {
@@ -71,11 +93,16 @@
                                                guard let index = index else { return }
                                                //判断选中是否正确逻辑
                                                if let cell = self?.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: index) as? ListenFight_lesson_1_CCell{
                                                                var answer:Fight_lessonType = .none
                                                                answer = .success
                                                                if self?.randomElement?.id == self?.listen1Model.subjectList[index.row].id{
                                                                                answer = .success
                                                                                self?.rootViewModel.correctNum += 1
                                                                }else{
                                                                                answer = .fail
                                                                                self?.rootViewModel.errorNum += 1
                                                                }
                                                                switch answer {
                                                                                case .success:
@@ -83,7 +110,8 @@
                                                                                                self?.answerSuccess(cell)
                                                                                case .fail:
                                                                                                self?.viewModel.answerType.accept(.fail)
                                                                                                self?.answerFail()
//                                                                                                self?.collectionView.isUserInteractionEnabled = false
                                                                                                self?.answerFail(errorSound: self?.listen1Model.subjectList[index.row].error)
                                                                                default:break
                                                                }
                                                }
@@ -93,7 +121,7 @@
                //回答正确
                private func answerSuccess(_ cell:ListenFight_lesson_1_CCell){
                                menuView.snp.removeConstraints()
                                collectionView.isUserInteractionEnabled = false
//                                collectionView.isUserInteractionEnabled = false
                                let v = cell.view_topHandle.convert(cell.bounds, to: self.view)
                                UIView.animate(withDuration: 0.3) {
                                                self.menuView.snp.updateConstraints { make in
@@ -107,15 +135,17 @@
                                                self.collectionView.reloadData()
                                                DispatchQueue.main.asyncAfter(deadline: .now()+2){
                                                                NotificationCenter.default.post(name: NextLession_Noti, object: nil)
                                                                self.collectionView.isUserInteractionEnabled = true
//                                                                self.collectionView.isUserInteractionEnabled = true
                                                                self.viewModel.answerType.accept(.none)
                                                                self.viewModel.selectIndex.accept(nil)
                                                                self.rootViewModel.answerItems[self.page] = self.listen1Model
                                                }
                                }
                }
                private func answerFail(){
                private func answerFail(errorSound:String?){
                                self.collectionView.reloadData()
                                VoicePlayer.share().playerAt(url: errorSound)
                }
}
@@ -136,10 +166,11 @@
                                }else{
                                                cell.setState(state: .none)
                                }
                                cell.setListen1SubModel(listen1Model.subjectList[indexPath.row])
                                return cell
                }
                func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                                return 4
                                return min(4,listen1Model.subjectList.count)
                }
}
DolphinEnglishLearnStudent/Moudle/Home/HomeVC.swift
@@ -15,6 +15,10 @@
                                                AwardListView.show(items: data.data ?? []) {[weak self] model in
                                                                let vc = MarketContentVC(goodsId: model.id)
                                                                self?.push(vc: vc)
                                                }closeClouse: {[weak self] in
                                                                let listenMenuVC = HomeListenMenuVC()
                                                                listenMenuVC.title = "第一年学习周目选择"
                                                                self?.push(vc: listenMenuVC)
                                                }
                                }).disposed(by: disposeBag)
    }
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_1_CCell.swift
@@ -15,12 +15,15 @@
class ListenFight_lesson_1_CCell: UICollectionViewCell {
                @IBOutlet weak var label_title: UILabel!
                @IBOutlet weak var image_state: UIImageView!
                @IBOutlet weak var image_cover: UIImageView!
                @IBOutlet weak var view_topHandle: UIView!
                override func awakeFromNib() {
                                super.awakeFromNib()
                                image_state.alpha = 0
                                image_state.transform = .init(scaleX: 0.1, y: 0.1)
                                label_title.isHidden = true
                }
                func setState(state:Fight_lessonType){
@@ -37,10 +40,17 @@
                                                                UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.4, options: .layoutSubviews) {
                                                                                self.image_state.alpha = 1
                                                                                self.image_state.transform = .init(scaleX: 1, y: 1)
                                                                                UIView.animate(withDuration: 0.5, delay: 3.0) {
                                                                                                self.image_state.alpha = 0
                                                                                }
                                                                }
                                                case .none:
                                                                image_state.alpha = 0
                                                                image_state.transform = .init(scaleX: 0.1, y: 0.1)
                                }
                }
                func setListen1SubModel(_ model:Listen1SubModel){
                                image_cover.sd_setImage(with: URL(string: model.img))
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_1_CCell.xib
@@ -19,12 +19,25 @@
                <subviews>
                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JdK-rh-KJI">
                        <rect key="frame" x="5" y="5" width="435" height="40"/>
                        <subviews>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="--" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rgH-1a-mKt">
                                <rect key="frame" x="0.0" y="0.0" width="435" height="40"/>
                                <color key="backgroundColor" red="0.53725490196078429" green="0.52941176470588236" blue="0.49411764705882355" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
                                <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" red="0.83137254900000002" green="0.82352941180000006" blue="0.80392156859999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstAttribute="height" constant="40" id="1mb-ik-h6n"/>
                            <constraint firstAttribute="trailing" secondItem="rgH-1a-mKt" secondAttribute="trailing" id="Zjf-E9-9in"/>
                            <constraint firstAttribute="bottom" secondItem="rgH-1a-mKt" secondAttribute="bottom" id="aMm-rB-Ltu"/>
                            <constraint firstItem="rgH-1a-mKt" firstAttribute="leading" secondItem="JdK-rh-KJI" secondAttribute="leading" id="eZG-zI-A7g"/>
                            <constraint firstItem="rgH-1a-mKt" firstAttribute="top" secondItem="JdK-rh-KJI" secondAttribute="top" id="pG4-rt-Gkh"/>
                        </constraints>
                    </view>
                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="bdL-d4-7NQ">
                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="bdL-d4-7NQ">
                        <rect key="frame" x="5" y="45" width="435" height="329"/>
                    </imageView>
                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kkd-SI-bwq">
@@ -51,7 +64,9 @@
            </constraints>
            <size key="customSize" width="445" height="379"/>
            <connections>
                <outlet property="image_cover" destination="bdL-d4-7NQ" id="r4U-gR-Ehg"/>
                <outlet property="image_state" destination="kkd-SI-bwq" id="oOC-yo-jjk"/>
                <outlet property="label_title" destination="rgH-1a-mKt" id="8rB-l0-3TW"/>
                <outlet property="view_topHandle" destination="JdK-rh-KJI" id="3e6-NI-AsQ"/>
            </connections>
            <point key="canvasLocation" x="232.3170731707317" y="103.47457627118645"/>
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift
@@ -12,8 +12,31 @@
                @IBOutlet weak var img_cover: UIImageView!
                @IBOutlet weak var view_container: UIView!
                @IBOutlet weak var btn_play: UIButton!
                @IBOutlet weak var btn_playing: UIButton!
                private var model:Listen1SubModel!
                private var playAtClouse:((IndexPath)->Void)?
                var indexPath:IndexPath!
                override func awakeFromNib() {
        super.awakeFromNib()
                                view_container.jq_addShadows(shadowColor: .black.withAlphaComponent(0.31), corner: 8, radius: 3, offset: CGSize(width: 0, height: 1), opacity: 1)
    }
                func setModel(_ model:Listen1SubModel,isplaying:Bool){
                                self.model = model
                                self.btn_play.alpha = (isplaying ? 0:1)
                }
                func palyVoiceAt(_ clouse:@escaping(IndexPath)->Void){
                                self.playAtClouse = clouse
                }
                @IBAction func playAction(_ sender: Any) {
                                VoicePlayer.share().playerAt(url: model.correct ?? "")
                                playAtClouse?(indexPath)
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.xib
@@ -24,6 +24,9 @@
                                <rect key="frame" x="104" y="10" width="32" height="32"/>
                                <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                <state key="normal" image="icon_play"/>
                                <connections>
                                    <action selector="playAction:" destination="gTV-IL-0wX" eventType="touchUpInside" id="IWn-Zu-bCh"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9Dc-Ns-SMP">
                                <rect key="frame" x="25" y="12.5" width="27" height="27"/>
@@ -75,6 +78,8 @@
            </constraints>
            <size key="customSize" width="630" height="554"/>
            <connections>
                <outlet property="btn_play" destination="7yc-PU-RgV" id="b2b-5W-bGC"/>
                <outlet property="btn_playing" destination="9Dc-Ns-SMP" id="PsY-Nd-d5z"/>
                <outlet property="img_cover" destination="n5n-eb-5xI" id="Wk5-s2-MQj"/>
                <outlet property="view_container" destination="qxz-6s-e5b" id="Ikx-kW-UkZ"/>
            </connections>
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.swift
@@ -13,9 +13,37 @@
                @IBOutlet weak var img_cover: UIImageView!
                @IBOutlet weak var view_container: UIView!
                @IBOutlet weak var img_state: UIImageView!
                @IBOutlet weak var btn_handle: UIButton!
                @IBOutlet weak var btn_voice: UIButton!
                @IBOutlet weak var btn_play: UIButton!
                private var model:Listen1SubModel?
                var indexPath:IndexPath!
                private var playAtIndexClouse:((IndexPath)->Void)?
                override func awakeFromNib() {
                                super.awakeFromNib()
                                view_container.jq_addShadows(shadowColor: .black.withAlphaComponent(0.31), corner: 8, radius: 3, offset: CGSize(width: 0, height: 1), opacity: 1)
                }
                func setModel(_ m:Listen1SubModel){
                                model = m
                                img_cover.sd_setImage(with: URL(string: m.img))
                }
                func playAtIndex(clouse:@escaping(IndexPath)->Void){
                                self.playAtIndexClouse = clouse
                }
                @IBAction func playAction(_ sender: UIButton) {
                                if let m = model{
                                                btn_play.isHidden = true
                                                VoicePlayer.share().playerAt(url: m.correct)
                                                playAtIndexClouse?(indexPath)
                                                VoicePlayer.share().playEnd {
                                                                self.btn_play.isHidden = false
                                                }
                                }
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.xib
@@ -25,6 +25,9 @@
                                <rect key="frame" x="104" y="10" width="32" height="32"/>
                                <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                <state key="normal" image="icon_play"/>
                                <connections>
                                    <action selector="playAction:" destination="gTV-IL-0wX" eventType="touchUpInside" id="FV8-uE-yj8"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kgj-Ss-D90">
                                <rect key="frame" x="65" y="12.5" width="27" height="27"/>
@@ -89,6 +92,9 @@
            </constraints>
            <size key="customSize" width="597" height="510"/>
            <connections>
                <outlet property="btn_handle" destination="ZuK-r9-26C" id="Ztw-HE-Srj"/>
                <outlet property="btn_play" destination="LLy-9v-eQJ" id="tTl-C3-lNJ"/>
                <outlet property="btn_voice" destination="kgj-Ss-D90" id="sHd-pN-FVy"/>
                <outlet property="img_cover" destination="XW5-ds-CXG" id="yuo-h2-TG8"/>
                <outlet property="img_state" destination="eyJ-Qy-E0w" id="6YM-Di-5yt"/>
                <outlet property="view_container" destination="OJ6-0b-fVC" id="4Y2-jo-yTH"/>
DolphinEnglishLearnStudent/Moudle/Home/Listen/TCell/HomeListen_item_TCell.swift
@@ -8,6 +8,8 @@
import UIKit
class HomeListen_item_TCell: UITableViewCell {
                @IBOutlet weak var view_bg1: UIView!
                @IBOutlet weak var view_bg2: UIView!
                @IBOutlet weak var label_title: UILabel!
                
    override func awakeFromNib() {
DolphinEnglishLearnStudent/Moudle/Home/Listen/TCell/HomeListen_item_TCell.xib
@@ -140,6 +140,8 @@
            </tableViewCellContentView>
            <connections>
                <outlet property="label_title" destination="28J-ZC-IiE" id="kDk-K7-10L"/>
                <outlet property="view_bg1" destination="9XB-yf-tzC" id="u8S-3q-p3Y"/>
                <outlet property="view_bg2" destination="pk7-Y8-Mtb" id="Dyb-wb-cSg"/>
            </connections>
            <point key="canvasLocation" x="282.80487804878049" y="47.033898305084747"/>
        </tableViewCell>
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift
@@ -11,16 +11,30 @@
let NextLession_Noti = Notification.Name.init("NextLession_Noti")
enum ListenType{
                case lesson1 //自主学习-听音选图
                case lesson2 //自主学习-看图选音
                case lesson3 //自主学习-归纳排除
                case lesson4 //自主学习-有问有答
                case lesson5 //自主学习-音图相配
                case game1 //游戏类型-超级听力
                case game2 //游戏类型-超级记忆
                case story1 //故事类型-自主故事1-看图配音
                case story2 //故事类型-自主故事2-框架记忆
enum ListenType:Int{
                case lesson1 = 1 //自主学习-听音选图
                case lesson2 = 2 //自主学习-看图选音
                case lesson3 = 3 //自主学习-归纳排除
                case lesson4 = 4 //自主学习-有问有答
                case lesson5 = 5 //自主学习-音图相配
                case game1 = 6 //游戏类型-超级听力
                case game2 = 7 //游戏类型-超级记忆
                case story1 = 8 //故事类型-自主故事1-看图配音
                case story2 = 9 //故事类型-自主故事2-框架记忆
                var rawTitle:String{
                                switch self {
                                                case .lesson1:return "自主学习1-听音选图"
                                                case .lesson2:return "自主学习2-看图选音"
                                                case .lesson3:return "自主学习3-归纳排除"
                                                case .lesson4:return "自主学习4-有问有答"
                                                case .lesson5:return "自主学习5-音图相配"
                                                case .game1:return "游戏类型1-超级听力"
                                                case .game2:return "游戏类型2-超级记忆"
                                                case .story1:return "自主故事1-看图配音"
                                                case .story2:return "自主故事2-框架记忆"
                                }
                }
}
class HomeListenFightViewModel{
@@ -29,11 +43,28 @@
                var currentPage = BehaviorRelay<Int>(value: 0)
                var maxPage = BehaviorRelay<Int>(value: 5)
                var listenType = BehaviorRelay<ListenType>(value:.lesson1)
                var times:Int = 0
                //回答错误数量
                var correctNum:Int = 0{
                                didSet{
                                                print("回答正确:\(correctNum)")
                                }
                }
                var errorNum:Int = 0{
                                didSet{
                                                print("回答错误:\(correctNum)")
                                }
                }
                //所有回答的
                var answerItems = Dictionary<Int,Any>() //{page:0,data:String,currectAt:0}
}
class HomeListenFightVC: BaseVC {
                private var viewModel = HomeListenFightViewModel()
                var data:Any?
                private lazy var label_pageNum:UILabel = {
                                let label = UILabel()
@@ -81,8 +112,12 @@
                private lazy var pageVC:FFPageViewController = {
                                let vc = FFPageViewController()
                                vc.scrollview.isScrollEnabled = false
                                vc.prePages = UInt(viewModel.maxPage.value) / 2
                                vc.maxPages = UInt(viewModel.maxPage.value) + 1
                                return vc
                }()
                private var timer:Timer!
                init(listenType:ListenType) {
@@ -112,6 +147,12 @@
                                                label_pageNum.isHidden = true
                                }
                                timer = Timer(fire: .distantPast, interval: 1.0, repeats: true, block: {[weak self] _ in
                                                self?.viewModel.times += 1
                                })
                                timer.fire()
                                RunLoop.current.add(timer, forMode: .common)
    }
                override func setUI() {
@@ -172,8 +213,23 @@
                                                //完成
                                                if nextPage >= weakSelf.viewModel.maxPage.value{
                                                                let vc = HomeStudyCompleteVC()
                                                                vc.title = "自主学习1-听音选图"
                                                                var toalIntegral:Int = 0
                                                                var ids = [Int]()
                                                                for v in weakSelf.viewModel.answerItems.values{
                                                                                if let v =  v as? Listen1Model{
                                                                                                toalIntegral += v.data?.integral ?? 0
                                                                                                ids.append(v.data?.studyId ?? 0)
                                                                                }
                                                                }
                                                                Services.completeLearing(type: weakSelf.viewModel.listenType.value.rawValue, studyTime: weakSelf.viewModel.times, studyIds: ids, isComplete: false).subscribe(onNext: {data in
                                                                }).disposed(by: weakSelf.disposeBag)
                                                                weakSelf.timer.invalidate()
                                                                let vc = HomeStudyCompleteVC(correctNum: weakSelf.viewModel.correctNum, errorNum: weakSelf.viewModel.errorNum, totalCoin: toalIntegral)
                                                                vc.title = weakSelf.viewModel.listenType.value.rawTitle
                                                                                weakSelf.push(vc: vc)
                                                                return
                                                }
@@ -189,6 +245,10 @@
                                }).disposed(by: disposeBag)
                }
                deinit{
                                timer.invalidate()
                }
                @objc func quitAction(){
                                CommonAlertView.show(content: "未完成全部答题,确认退出吗?") {
                                                self.navigationController?.popViewController(animated: true)
@@ -196,7 +256,7 @@
                }
                @objc func beforeAction(){
                                let beforePage = max(1, viewModel.currentPage.value - 1)
                                let beforePage = max(0, viewModel.currentPage.value - 1)
                                pageVC.scroll(toPage: beforePage, animation: true)
                                viewModel.currentPage.accept(beforePage)
                }
@@ -214,27 +274,32 @@
                func pageViewController(_ pageViewConteoller: FFPageViewController, controllerForPage page: Int) -> UIViewController {
                                if viewModel.listenType.value == .lesson1{
                                                let vc = HomeListenFight_lesson_1_VC()
                                                let vc = HomeListenFight_lesson_1_VC(page: page,listen1Model:data as! Listen1Model)
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson2{
                                                let vc = HomeListenFight_lesson_2_VC()
                                                let vc = HomeListenFight_lesson_2_VC(page: page,listen1Model:data as! Listen1Model)
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson3{
                                                let vc = HomeListenFight_lesson_3_VC()
                                                let vc = HomeListenFight_lesson_3_VC(page: page, listen1Model: data as! Listen1Model)
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson4{
                                                let vc = HomeListenFight_lesson_4_VC()
                                                let vc = HomeListenFight_lesson_4_VC(page: page, listen4Model: data as! Listen4Model)
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
                                if viewModel.listenType.value == .lesson5{
                                                let vc = HomeListenFight_lesson_5_VC()
                                                let vc = HomeListenFight_lesson_5_VC(page: page, listen1Model: data as! Listen1Model)
                                                vc.rootViewModel = viewModel
                                                return vc
                                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift
@@ -12,6 +12,11 @@
                private var viewModel = FightAnswerViewModel()
                private var listen1Model:Listen1Model!
                private var randomElement:Listen1SubModel?
                private var page:Int!
                var rootViewModel:HomeListenFightViewModel!
                private lazy var stackView:UIStackView = {
                                let stackView = UIStackView()
                                stackView.spacing = 78
@@ -31,14 +36,27 @@
                                return collection
                }()
                required init(page:Int,listen1Model:Listen1Model){
                                super.init(nibName: nil, bundle: nil)
                                self.page = page
                                self.listen1Model = listen1Model
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
                override func viewDidLoad() {
                                super.viewDidLoad()
                                navigationItem.titleView = UIView()
                                viewModel.selectIndex.accept(IndexPath(row: 0, section: 0))
                }
                override func setUI() {
                                super.setUI()
                                viewModel.selectIndex.accept(IndexPath(row: 0, section: 0))
                                collectionView.delegate = self
                                collectionView.dataSource = self
@@ -59,18 +77,52 @@
                                                make.width.greaterThanOrEqualTo(100)
                                }
                                addStackView()
                                VoicePlayer.share().playEnd {[weak self] in
                                }
                }
                private func addStackView(){
                                stackView.removeArrangedSubviews()
                                var tempViews = [StudyHandleView]()
                                for index in 0...2{
                                                let handleView = StudyHandleView.jq_loadNibView()
                                                handleView.listenType = .lesson2
                                                handleView.btn_choose.tag = 10 + index
                                                let row = viewModel.selectIndex.value!.row
                                                let model = listen1Model.subjectList[row]
                                                if index == 0{
                                                                handleView.vioceSoundUrl = model.correct
                                                }
                                                if index == 1{
                                                                handleView.vioceSoundUrl = model.error.components(separatedBy: ",").first
                                                }
                                                if index == 2{
                                                                handleView.vioceSoundUrl = model.error.components(separatedBy: ",").last
                                                }
                                                handleView.chooseClouse {[weak self] btn in
                                                                guard let weakSelf = self else { return }
                                                                let row = weakSelf.viewModel.selectIndex.value!.row
                                                                var lessionType:Fight_lessonType = .none
                                                                lessionType = .success
                                                                if handleView.vioceSoundUrl == weakSelf.listen1Model.subjectList[row].correct{
                                                                                lessionType = .success
                                                                }else{
                                                                                lessionType = .fail
                                                                }
                                                                switch lessionType {
                                                                                case .success:
                                                                                                weakSelf.rootViewModel.correctNum += 1
                                                                                                handleView.btn_choose.isEnabled = false
                                                                                                handleView.btn_state.setImage(UIImage(named: "icon_success_small"), for: .normal)
                                                                                                UIView.animate(withDuration: 0.5) {
@@ -82,6 +134,7 @@
                                                                                                                self?.answerSuccess(cell,index: index)
                                                                                                }
                                                                                case .fail:
                                                                                                weakSelf.rootViewModel.errorNum += 1
                                                                                                handleView.btn_state.setImage(UIImage(named: "icon_waring_small"), for: .normal)
                                                                                                UIView.animate(withDuration: 0.5) {
                                                                                                                handleView.btn_state.alpha = 1
@@ -97,9 +150,11 @@
                                                                make.height.equalTo(52)
                                                                make.width.greaterThanOrEqualTo(159)
                                                }
                                                stackView.addArrangedSubview(handleView)
                                                tempViews.append(handleView)
                                }
                                tempViews.shuffle() //乱序
                                stackView.addArrangedSubviews(tempViews)
                }
                private func answerSuccess(_ cell:ListenFight_lesson_1_CCell,index:Int){
@@ -135,43 +190,40 @@
                                                self.view.layoutIfNeeded()
                                }completion: { _ in
                                                self.resetStackView()
                                }
                }
                private func resetStackView(){
                                for v in stackView.arrangedSubviews as! [StudyHandleView]{
                                                v.view_choose.alpha = 0
                                                v.btn_choose.isEnabled = true
                                                v.btn_choose.isSelected = false
                                                v.btn_state.setImage(nil, for: .normal)
                                }
                                let newRow = viewModel.selectIndex.value!.row+1
                                viewModel.selectIndex.accept(IndexPath(row: newRow, section: 0))
                                collectionView.reloadData()
                                if newRow == 4{
                                                NotificationCenter.default.post(name: NextLession_Noti, object: nil)
                                                rootViewModel.answerItems[page] = listen1Model
                                                NotificationCenter.default.post(name: NextLession_Noti, object: nil);return
                                }
                                addStackView()
                }
                override func setRx() {
                                viewModel.selectIndex.subscribe(onNext: {[weak self] index in
                                                guard let index = index else { return }
                                                //判断选中是否正确逻辑
                                                if let cell = self?.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: index) as? ListenFight_lesson_1_CCell{
                                                                var answerType:Fight_lessonType = .none
                                                                answerType = .success
                                                                switch answerType {
                                                                                case .success:
                                                                                                self?.viewModel.answerType.accept(.success)
                                                                                case .fail:
                                                                                                self?.viewModel.answerType.accept(.fail)
                                                                                default:break
                                                                }
                                                }
                                }).disposed(by: disposeBag)
//                                viewModel.selectIndex.subscribe(onNext: {[weak self] index in
//                                                guard let index = index else { return }
//                                                //判断选中是否正确逻辑
//                                                if self?.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: index) is ListenFight_lesson_1_CCell{
//                                                                var answerType:Fight_lessonType = .none
//                                                                answerType = .success
//                                                                switch answerType {
//                                                                                case .success:
//                                                                                                self?.viewModel.answerType.accept(.success)
//                                                                                                self?.rootViewModel.correctNum += 1
//                                                                                case .fail:
//                                                                                                self?.viewModel.answerType.accept(.fail)
//                                                                                                self?.rootViewModel.errorNum += 1
//                                                                                default:break
//                                                                }
//                                                }
//                                }).disposed(by: disposeBag)
                }
}
@@ -186,10 +238,17 @@
                                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: indexPath) as! ListenFight_lesson_1_CCell
                                cell.jq_addShadows(shadowColor: .black.withAlphaComponent(0.31), corner: 5, radius: 5, offset: CGSize(width: 0, height: 1), opacity: 1)
                                cell.backgroundColor = .white
                                if viewModel.selectIndex.value?.row == indexPath.row{
                                                cell.label_title.isHidden = false
                                }else{
                                                cell.label_title.isHidden = true
                                }
                                cell.setListen1SubModel(listen1Model.subjectList[indexPath.row])
                                cell.label_title.text = listen1Model.subjectList[indexPath.row].name
                                return cell
                }
                func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                                return 4
                                return min(4,listen1Model.subjectList.count)
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift
@@ -31,10 +31,37 @@
                                return sta
                }()
                private var listen1Model:Listen1Model!
                private var page:Int!
                private var answterCount:Int = 0 //回答计数,用于确定角标
                var rootViewModel:HomeListenFightViewModel!
                required init(page:Int,listen1Model:Listen1Model){
                                super.init(nibName: nil, bundle: nil)
                                self.page = page
                                self.listen1Model = listen1Model
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
                override func viewDidLoad() {
                                super.viewDidLoad()
                                navigationItem.titleView = UIView()
                                viewModel.selectIndex.accept(IndexPath(row: 0, section: 0))
//                                viewModel.selectIndex.accept(IndexPath(row: 0, section: 0))
                                setAnswerStackView()
                                VoicePlayer.share().playEnd { [weak self] in
                                                guard let weakSelf = self else { return }
                                                if weakSelf.viewModel.selectIndex.value != nil{
                                                                weakSelf.collectionView.reloadItems(at: [weakSelf.viewModel.selectIndex.value!])
                                                                weakSelf.viewModel.selectIndex.accept(nil)
                                                }
                                                weakSelf.collectionView.reloadData()
                                }
                }
                override func setUI() {
@@ -83,9 +110,14 @@
                private func setAnswerStackView(){
                                for subView in stackView.arrangedSubviews{
                                                subView.removeFromSuperview()
                                }
                                stackView.removeArrangedSubviews()
                                var tempImageArray = [String]()
                                tempImageArray.append(listen1Model.subjectList[2].img ?? "")
                                tempImageArray.append(listen1Model.subjectList[4].img ?? "")
                                tempImageArray.append(listen1Model.subjectList[5].img ?? "")
//                                tempImageArray.shuffle()
                                view.addSubview(stackView)
                                stackView.snp.makeConstraints { make in
@@ -98,8 +130,11 @@
                                                answerView.alpha = 0
                                                answerView.btn_choose.addTarget(self, action: #selector(chooseAnswerAction), for: .touchUpInside)
                                                answerView.btn_fullscreen.addTarget(self, action: #selector(fullscreenAction), for: .touchUpInside)
                                                answerView.img_cover.contentMode = .scaleToFill
                                                answerView.btn_choose.tag = 10+i
                                                answerView.btn_fullscreen.tag = 20+i
                                                answerView.imageUrl = tempImageArray[i]
                                                answerView.img_cover.sd_setImage(with: URL(string: tempImageArray[i]))
                                                answerView.snp.makeConstraints { make in
                                                                make.width.equalTo(85)
                                                                make.height.equalTo(52)
@@ -114,6 +149,9 @@
                }
                @objc private func chooseAnswerAction(btn:UIButton){
                                if viewModel.selectIndex.value == nil{alertError(msg: "请先听题");return}
                                let index = btn.tag - 10
                                var subV:Lesson_3_AnswerView?
@@ -123,36 +161,70 @@
                                }
                                var answerType:Fight_lessonType = .none
                                answerType = .success
                                var valueIndex:Int! //图片的角标
                                if viewModel.selectIndex.value?.section == 0{
                                                valueIndex = viewModel.selectIndex.value!.row
                                }
                                if viewModel.selectIndex.value?.section == 1{
                                                valueIndex = viewModel.selectIndex.value!.row + 3
                                }
                                if subV?.imageUrl == listen1Model.subjectList[valueIndex].img{
                                                answerType = .success
                                }else{
                                                answerType = .fail
                                }
                                switch answerType {
                                                case .success:
                                                                rootViewModel.correctNum += 1
                                                                viewModel.answerType.accept(.success)
                                                                let copyViewFrame = subV?.convert(subV!.bounds, to: self.view)
                                                                let copyView = subV?.copyView()
                                                                copyView?.frame = copyViewFrame!
                                                                copyView?.backgroundColor = .red
                                                                copyView?.img_cover.image = subV?.img_cover.image
                                                                copyView?.img_cover.contentMode = .scaleToFill
                                                                self.view.addSubview(copyView!)
                                                                copyView?.layoutIfNeeded()
                                                                if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_3_CCell", for: viewModel.selectIndex.value!) as? ListenFight_lesson_3_CCell{
                                                                                cell.layoutIfNeeded()
                                                                var ansterIndePath:IndexPath?
                                                                if viewModel.selectIndex.value?.section == 0{
                                                                                ansterIndePath = IndexPath(row: 2, section: 0)
                                                                }
                                                                if viewModel.selectIndex.value?.section == 1 && (viewModel.selectIndex.value?.row == 0 || viewModel.selectIndex.value?.row == 1){
                                                                                ansterIndePath = IndexPath(row: 1, section: 1)
                                                                }
                                                                if viewModel.selectIndex.value?.section == 1 && viewModel.selectIndex.value?.row == 2{
                                                                                ansterIndePath = IndexPath(row: 2, section: 1)
                                                                }
                                                                guard ansterIndePath != nil else {return}
                                                                if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_3_CCell", for: ansterIndePath!) as? ListenFight_lesson_3_CCell{
                                                                                var newFrame = cell.img_cover.convert(cell.img_cover.bounds, to: self.view)
                                                                                copyView?.img_cover.image = cell.img_cover.image
                                                                                newFrame.origin.x += 97
                                                                                newFrame.origin.y += (JQ_NavBarHeight - 15)
                                                                                newFrame.origin.x += 0
                                                                                newFrame.origin.y += 0
                                                                                UIView.animate(withDuration: 0.4) {
                                                                                                copyView?.frame = newFrame
                                                                                } completion: { _ in
                                                                                                for subView in self.stackView.arrangedSubviews{
                                                                                                                subView.removeFromSuperview()
                                                                                                self.answterCount += 1
                                                                                                if self.answterCount == 3{
                                                                                                                self.rootViewModel.answerItems[self.page] = self.listen1Model
                                                                                                                NotificationCenter.default.post(name: NextLession_Noti, object: nil);return
                                                                                                }
                                                                                                DispatchQueue.main.asyncAfter(deadline: .now()+1.5) {
                                                                                                                self.setAnswerStackView()
                                                                                                                self.viewModel.selectIndex.accept(nil)
                                                                                                }
                                                                                }
                                                                }
                                                case .fail:
                                                                rootViewModel.errorNum += 1
                                                                viewModel.answerType.accept(.fail)
                                                                UIView.animate(withDuration: 0.4) {
                                                                                subV?.img_state.alpha = 1
@@ -173,8 +245,7 @@
extension HomeListenFight_lesson_3_VC:UICollectionViewDelegate{
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                                viewModel.selectIndex.accept(indexPath)
                                setAnswerStackView()
                }
}
@@ -191,7 +262,37 @@
                func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_3_CCell", for: indexPath) as! ListenFight_lesson_3_CCell
                                cell.backgroundColor = .clear
                                cell.indexPath = indexPath
                                cell.contentView.backgroundColor = .clear
                                cell.palyVoiceAt {[weak self] index in
                                                self?.viewModel.selectIndex.accept(index)
                                                if (index.section == 0 && index.row == 2) || (index.section == 1 && index.row > 0){
                                                                self?.viewModel.selectIndex.accept(index)
                                                                self?.setAnswerStackView()
                                                }
                                                collectionView.reloadItems(at: [index])
                                }
                                if indexPath.section == 0{
                                                let model = listen1Model.subjectList[indexPath.row]
                                                if indexPath.row != 2{
                                                                cell.img_cover.sd_setImage(with: URL(string: model.img))
                                                }else{
                                                                cell.img_cover.image = nil
                                                }
                                                cell.setModel(model,isplaying: viewModel.selectIndex.value == indexPath)
                                }
                                if indexPath.section == 1{
                                                let model = listen1Model.subjectList[indexPath.row + 3]
                                                if indexPath.row == 0{
                                                                cell.img_cover.sd_setImage(with: URL(string: model.img))
                                                }else{
                                                                cell.img_cover.image = nil
                                                }
                                                cell.setModel(model,isplaying: viewModel.selectIndex.value == indexPath)
                                }
                                return cell
                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift
@@ -11,6 +11,13 @@
                private var viewModel = FightAnswerViewModel()
                private var listen4Model:Listen4Model!
                private var page:Int!
                var rootViewModel:HomeListenFightViewModel!
                private var answerIndex:IndexPath? //答案的Index
                private var answerCount:Int = 0 //回答计数
                private lazy var stackView:UIStackView = {
                                let sta = UIStackView()
                                sta.spacing = 41
@@ -32,10 +39,22 @@
                                return collection
                }()
                required init(page:Int,listen4Model:Listen4Model){
                                super.init(nibName: nil, bundle: nil)
                                self.page = page
                                self.listen4Model = listen4Model
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
    override func viewDidLoad() {
        super.viewDidLoad()
                                VoicePlayer.share().playEnd {
                                                print("播放完成")
                                }
    }
                override func setUI() {
@@ -54,12 +73,13 @@
                                }
                }
                private func setAnswerStackView(){
                                for subView in stackView.arrangedSubviews{
                                                subView.removeFromSuperview()
                                guard viewModel.selectIndex.value != nil else{
                                                alertError(msg: "请先听题");return
                                }
                                stackView.removeArrangedSubviews()
                                if !view.subviews.contains(stackView){
                                                view.addSubview(stackView)
@@ -69,9 +89,24 @@
                                                }
                                }
                                let answerId = listen4Model.data[viewModel.selectIndex.value!.section].answerSubject
                                var tempVoiceArray = [String]()
                                for v in listen4Model.data[viewModel.selectIndex.value!.section].subjectList{
                                                if v.id == answerId{
                                                                tempVoiceArray.append(v.correct)
                                                                tempVoiceArray.append(v.error.components(separatedBy: ",").first ?? "")
                                                                tempVoiceArray.append(v.error.components(separatedBy: ",").last ?? "")
                                                }
                                }
                                tempVoiceArray.shuffle()
                                for i in 0...2{
                                                let answerView = Lesson_4_AnswerView.jq_loadNibView()
                                                answerView.btn_choose.tag = 10 + i
                                                answerView.voiceUrl = tempVoiceArray[i]
                                                answerView.btn_choose.addTarget(self, action: #selector(answerAction), for: .touchUpInside)
                                                answerView.alpha = 0
                                                answerView.snp.makeConstraints { make in
@@ -97,9 +132,25 @@
                                                }
                                }
                                var answerModel:Listen1SubModel?
                                for (index,v) in (listen4Model.data[viewModel.selectIndex.value!.section].subjectList).enumerated(){
                                                if v.id == listen4Model.data[viewModel.selectIndex.value!.section].answerSubject{
                                                                answerModel = v
                                                }else{
                                                                answerIndex = IndexPath(row: index, section: viewModel.selectIndex.value!.section)
                                                }
                                }
                                var answerType:Fight_lessonType = .none
                                answerType = .success
                                if tempSubV?.voiceUrl == answerModel?.correct{
                                                answerType = .success
                                                answerCount += 1
                                                rootViewModel.correctNum += 1
                                }else{
                                                answerType = .fail
                                                rootViewModel.errorNum += 1
                                }
                                VoicePlayer.share().playerEnd()
                                switch answerType {
                                                case .success:
@@ -112,9 +163,8 @@
                                                                                                self.view.addSubview(copyView)
                                                                                                self.view.layoutIfNeeded()
                                                                                                //获取Cell的顶部试图
                                                                                                if let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_4_CCell", for: self.viewModel.selectIndex.value!) as? ListenFight_lesson_4_CCell{
                                                                                                if let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_4_CCell", for: self.answerIndex!) as? ListenFight_lesson_4_CCell{
                                                                                                                var newRect1 = cell.convert(cell.bounds, to: self.collectionView)
                                                                                                                newRect1.origin.x += 76
                                                                                                                newRect1.origin.y += 33
@@ -123,7 +173,16 @@
                                                                                                                UIView.animate(withDuration: 0.4) {
                                                                                                                                copyView.frame = CGRect(origin: newRect1.origin, size: CGSize(width: 152, height: 52))
                                                                                                                } completion: { _ in
                                                                                                                                self.setAnswerStackView()
                                                                                                                                self.viewModel.selectIndex.accept(nil)
                                                                                                                                self.stackView.removeArrangedSubviews()
                                                                                                                                self.stackView.layoutIfNeeded()
                                                                                                                                //回答完成,下一答题
                                                                                                                                if self.answerCount == 2{
                                                                                                                                                self.rootViewModel.answerItems[self.page] = self.listen4Model
                                                                                                                                                VoicePlayer.share().playerEnd()
                                                                                                                                                NotificationCenter.default.post(name: NextLession_Noti, object: nil);return
                                                                                                                                }
                                                                                                                }
                                                                                                }
                                                                                }
@@ -134,7 +193,7 @@
                                                                                tempSubV?.img_state.alpha = 1
                                                                }completion: { _ in
                                                                                DispatchQueue.main.asyncAfter(deadline: .now()+3) {
                                                                                                self.setAnswerStackView()
//                                                                                                self.setAnswerStackView()
                                                                                }
                                                                }
                                                case .none:
@@ -145,18 +204,7 @@
extension HomeListenFight_lesson_4_VC:UICollectionViewDelegate{
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                                viewModel.selectIndex.accept(indexPath)
                                UIView.animate(withDuration: 0.5) {
                                                self.collectionView.snp.remakeConstraints { make in
                                                                make.left.equalTo(76)
                                                                make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(0)
                                                                make.width.equalTo(JQ_ScreenW - 164 * 2)
                                                                make.bottom.equalToSuperview()
                                                }
                                                self.view.layoutIfNeeded()
                                }
                                self.setAnswerStackView()
//                                viewModel.selectIndex.accept(indexPath)
                }
}
@@ -171,8 +219,25 @@
                                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_4_CCell", for: indexPath) as! ListenFight_lesson_4_CCell
                                cell.backgroundColor = .clear
                                cell.contentView.backgroundColor = .clear
                                cell.indexPath = indexPath
                                cell.playAtIndex {[weak self] index in
                                                guard let weakSelf = self else { return }
                                                weakSelf.viewModel.selectIndex.accept(index)
                                                UIView.animate(withDuration: 0.5) {
                                                                weakSelf.collectionView.snp.remakeConstraints { make in
                                                                                make.left.equalTo(76)
                                                                                make.top.equalTo(weakSelf.view.safeAreaLayoutGuide.snp.top).offset(0)
                                                                                make.width.equalTo(JQ_ScreenW - 164 * 2)
                                                                                make.bottom.equalToSuperview()
                                                                }
                                                                weakSelf.view.layoutIfNeeded()
                                                }completion: { _ in
                                                                weakSelf.setAnswerStackView()
                                                }
                                }
                                if indexPath == viewModel.selectIndex.value{
                                let m = listen4Model.data[indexPath.section].subjectList[indexPath.row]
                                if indexPath == answerIndex{
                                                UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.4,options: .layoutSubviews) {
                                                                cell.img_state.alpha = 1
                                                                cell.img_state.transform = .init(scaleX: 1.0, y: 1.0)
@@ -181,6 +246,14 @@
                                                cell.img_state.alpha = 0
                                                cell.img_state.transform = .init(scaleX: 0.1, y: 0.1)
                                }
                                //问题
                                if listen4Model.data[indexPath.section].subject == m.id{
                                                cell.btn_handle.setImage(UIImage(named: "icon_question"), for: .normal)
                                                cell.view_handle.isHidden = true
                                }else{
                                                cell.view_handle.isHidden = false
                                }
                                cell.setModel(m)
                                return cell
                }
@@ -191,11 +264,11 @@
                }
                func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                                return 2
                                return listen4Model.data[section].subjectList.count
                }
                func numberOfSections(in collectionView: UICollectionView) -> Int {
                                return 2
                                return listen4Model.data.count
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_5_VC.swift
@@ -10,11 +10,17 @@
class HomeListenFight_lesson_5_VC: BaseVC {
                private var viewModel = FightAnswerViewModel()
                private var listen1Model:Listen1Model!
                private var page:Int!
                private var answterCount:Int = 0 //回答计数,用于确定角标
                private var playVoiceAt:Int? //播放声音的View
                private var playVoiceRealAt:Int? //播放声音的View -被乱序后,真实Index
                var rootViewModel:HomeListenFightViewModel!
                private lazy var collectionView:UICollectionView = {
                                let flowLayout = UICollectionViewFlowLayout()
                                let w = (JQ_ScreenW - 189 * 2 - 18) / 2.0
                                flowLayout.itemSize = CGSize(width: w, height: w * 0.75)
                                flowLayout.itemSize = CGSize(width: w, height: w * 0.70)
                                flowLayout.minimumInteritemSpacing = 15
                                flowLayout.minimumLineSpacing = 15
                                flowLayout.scrollDirection = .vertical
@@ -32,25 +38,34 @@
                                return sta
                }()
                private lazy var label_hint:UILabel = {
                                let label = UILabel()
                                label.font = .systemFont(ofSize: 18, weight: .medium)
                                label.textColor = .black
                                label.text = "语音对应内容"
                                label.textAlignment = .center
                                return label
                }()
                required init(page:Int,listen1Model:Listen1Model){
                                super.init(nibName: nil, bundle: nil)
                                self.page = page
                                self.listen1Model = listen1Model
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
                override func viewDidLoad() {
                                super.viewDidLoad()
                                collectionView.reloadData()
                }
                override func setUI() {
                                super.setUI()
                                collectionView.delegate = self
                                collectionView.dataSource = self
                                collectionView.showsVerticalScrollIndicator = false
                                collectionView.backgroundColor = .clear
                                view.addSubview(collectionView)
                                collectionView.snp.makeConstraints { make in
                                                make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(89)
                                                make.left.equalTo(189)
                                                make.width.equalTo(JQ_ScreenW - 189 * 2)
                                                make.bottom.equalToSuperview()
                                }
                                view.addSubview(stackView)
                                stackView.snp.makeConstraints { make in
@@ -59,7 +74,36 @@
                                                make.height.equalTo(52)
                                }
                                view.addSubview(label_hint)
                                label_hint.snp.makeConstraints { make in
                                                make.left.right.equalToSuperview()
                                                make.top.equalTo(stackView.snp.bottom).offset(6)
                                                make.height.equalTo(0)
                                }
                                collectionView.delegate = self
                                collectionView.dataSource = self
                                collectionView.showsVerticalScrollIndicator = false
                                collectionView.backgroundColor = .clear
                                view.addSubview(collectionView)
                                collectionView.snp.makeConstraints { make in
                                                make.top.equalTo(self.label_hint.snp.bottom).offset(11)
                                                make.left.equalTo(189)
                                                make.width.equalTo(JQ_ScreenW - 189 * 2)
                                                make.bottom.equalToSuperview()
                                }
                                showHintText(false)
                                setAnswerStackView()
                }
                override func setRx() {
//                                viewModel.selectIndex.subscribe(onNext: {indexPath in
//                                                if let index = indexPath{
//
//                                                }
//                                }).disposed(by: disposeBag)
                }
                private func setAnswerStackView(){
@@ -76,9 +120,19 @@
                                                }
                                }
                                for i in 0...3{
                                var tempArray = [StudyHandleView]()
                                for (i,value) in listen1Model.subjectList.enumerated(){
                                                let answerView = StudyHandleView.jq_loadNibView()
                                                answerView.listenType = .lesson5
                                                answerView.view_choose.isHidden = true
                                                answerView.tag = 1000+i
                                                answerView.playAt {[weak self] index in
                                                                print("--->\(index)--\(answerView.frame.origin.x / 248)")
                                                                self?.playVoiceRealAt = Int(answerView.frame.origin.x) / 248
                                                                self?.playVoiceAt = index - 1000
                                                                self?.showHintText(true)
                                                }
                                                answerView.vioceSoundUrl = value.correct
                                                answerView.snp.makeConstraints { make in
                                                                make.width.equalTo(159)
                                                                make.height.equalTo(52)
@@ -87,23 +141,62 @@
                                                UIView.animate(withDuration: 0.05 + Double(i)) {
                                                                answerView.alpha = 1
                                                }
                                                tempArray.append(answerView)
                                }
                                tempArray.shuffle()
                                stackView.addArrangedSubviews(tempArray)
                }
                                                stackView.insertArrangedSubview(answerView, at: 0)
                private func showHintText(_ state:Bool){
                                if let at = playVoiceAt{
                                                label_hint.text = listen1Model.subjectList[at].name
                                                UIView.animate(withDuration: 0.5) {
                                                                if state{
                                                                                self.label_hint.snp.remakeConstraints { make in
                                                                                                make.left.right.equalToSuperview()
                                                                                                make.top.equalTo(self.stackView.snp.bottom).offset(6)
                                                                                                make.height.equalTo(25)
                                                                                }
                                                                }else{
                                                                                self.label_hint.snp.remakeConstraints { make in
                                                                                                make.left.right.equalToSuperview()
                                                                                                make.top.equalTo(self.stackView.snp.bottom).offset(6)
                                                                                                make.height.equalTo(0)
                                                                                }
                                                                }
                                                                self.view.layoutIfNeeded()
                                                }
                                }
                }
}
extension HomeListenFight_lesson_5_VC:UICollectionViewDelegate{
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                                if playVoiceAt == nil{
                                                alertError(msg: "请先听题");return
                                }
                                viewModel.selectIndex.accept(indexPath)
                                var answerType:Fight_lessonType = .none
                                answerType = .success
                                let answer = listen1Model.subjectList[playVoiceAt!]
                                let selectAnswer = listen1Model.subjectList[indexPath.row]
                                let tempSubV = stackView.arrangedSubviews[indexPath.row] as! StudyHandleView
                                var answerType:Fight_lessonType = .none
                                if answer.id == selectAnswer.id{
                                                answerType = .success
                                }else{
                                                answerType = .fail
                                }
                                let tempSubV = stackView.arrangedSubviews[self.playVoiceRealAt!] as! StudyHandleView
                                switch answerType {
                                                case .success:
                                                                answterCount += 1
                                                                rootViewModel.correctNum += 1
                                                                viewModel.answerType.accept(.success)
                                                                DispatchQueue.main.asyncAfter(deadline: .now()+0.4) {
                                                                                let copyView = tempSubV.copyView()
                                                                                copyView.view_choose.isHidden = true
@@ -116,21 +209,30 @@
                                                                                //获取Cell的顶部试图
                                                                                let flowLayout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
                                                                                if let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: self.viewModel.selectIndex.value!) as? ListenFight_lesson_1_CCell{
                                                                                if let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: indexPath) as? ListenFight_lesson_1_CCell{
                                                                                                var newRect1 = cell.convert(cell.bounds, to: self.collectionView)
                                                                                                newRect1.origin.x += (collectionView.frame.origin.x + 5)
                                                                                                newRect1.origin.y += 94
                                                                                                newRect1.origin.y += 94 + 25
                                                                                                UIView.animateKeyframes(withDuration: 0.4, delay: 0,options: .calculationModeLinear) {
                                                                                                                copyView.frame = CGRect(origin: newRect1.origin, size: CGSize(width: flowLayout.itemSize.width - 10 , height: 40))
                                                                                                }completion: { _ in
                                                                                                                self.playVoiceRealAt = nil
                                                                                                                self.playVoiceAt = nil
                                                                                                                if self.answterCount == 4{
                                                                                                                                self.rootViewModel.answerItems[self.page] = self.listen1Model
                                                                                                                                VoicePlayer.share().playerEnd()
                                                                                                                                NotificationCenter.default.post(name: NextLession_Noti, object: nil)
                                                                                                                }
                                                                                                }
                                                                                }
                                                                }
                                                case .fail:
                                                                viewModel.answerType.accept(.fail)
                                                                rootViewModel.errorNum += 1
                                                                collectionView.reloadData()
                                                case .none:
                                                                break
@@ -146,13 +248,15 @@
extension HomeListenFight_lesson_5_VC:UICollectionViewDataSource{
                func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                                let model = listen1Model.subjectList[indexPath.row]
                                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: indexPath) as! ListenFight_lesson_1_CCell
                                cell.jq_addShadows(shadowColor: .black.withAlphaComponent(0.31), corner: 8, radius: 3, offset: CGSize(width: 0, height: 1), opacity: 1)
                                if viewModel.selectIndex.value == indexPath{
                                                cell.setState(state: .success)
                                                cell.setState(state: viewModel.answerType.value)
                                }else{
                                                cell.setState(state: .none)
                                }
                                cell.setListen1SubModel(model)
                                return cell
                }
@@ -163,7 +267,7 @@
                }
                func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                                return 4
                                return listen1Model.subjectList.count
                }
                func numberOfSections(in collectionView: UICollectionView) -> Int {
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenMenuVC.swift
@@ -26,7 +26,7 @@
                private func getData(){
                                Services.weekList(quarter: selectIndexPath.row).subscribe(onNext: {result in
                                Services.weekList(quarter: selectIndexPath.row + 1).subscribe(onNext: {result in
                                                self.dataItems[self.selectIndexPath.row] = result.data ?? []
                                                self.collectionView.reloadData()
                                }).disposed(by: disposeBag)
@@ -53,14 +53,21 @@
extension HomeListenMenuVC:UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                                let vc = HomeListenVC()
                                let model = dataItems[selectIndexPath.row][indexPath.row]
                                let quarter = selectIndexPath.row + 1 //季度
                                let week = model.week //周
                                let vc = HomeListenVC(quarter: quarter, week: week)
                                push(vc: vc)
                }
                func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_HomeListenMenuCCell", for: indexPath) as! HomeListenMenuCCell
                                cell.setTitle(week: "第一周", title: "提示基础认知能力", coin: 2000)
                                cell.contentView.backgroundColor = UIColor.qmui_random()
                                let seal = indexPath.row % 10
                                cell.contentView.backgroundColor = UIColor(hexString: repeatColors[seal])
                                let model = dataItems[selectIndexPath.row][indexPath.row]
                                cell.setTitle(week: "第\(model.week.jq_cn)周", title: model.title, coin: model.totalIntegral)
                                return cell
                }
@@ -91,6 +98,7 @@
                                                getData()
                                }
                                tableView.reloadData()
                                collectionView.reloadData()
                }
                func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
@@ -154,6 +162,12 @@
                private var label_title = UILabel()
                private var label_completeCoin = UILabel()
                var listenWeekModel:ListenWeekModel!{
                                didSet{
                                }
                }
                override init(frame: CGRect) {
                                super.init(frame: frame)
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift
@@ -10,11 +10,15 @@
class HomeListenSubVC: BaseVC {
                private var page:Int!
                private var quarter:Int!
                private var week:Int!
                private var tableView:UITableView!
                required init(page:Int) {
                                self.page = page
                required init(page:Int,quarter:Int,week:Int) {
                                super.init(nibName: nil, bundle: nil)
                                self.page = page
                                self.quarter = quarter
                                self.week = week
                }
                
                required init?(coder: NSCoder) {
@@ -45,37 +49,87 @@
extension HomeListenSubVC:UITableViewDelegate{
                func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                                if indexPath.section == 1{
                                let day = page + 1
                                if page <= 4{
                                                if indexPath.row == 0{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .lesson1))
                                                                //听音选图
                                                                Services.listenSelectPicture(day:day, quarter: quarter, week: week).subscribe(onNext: {result in
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson1)
                                                                                                fightVC.title = ListenType.lesson1.rawTitle
                                                                                                fightVC.data = data
                                                                                                JQ_currentViewController().jq_push(vc:fightVC)
                                                                                }
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 1{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .lesson2))
                                                                //看图选音
                                                                Services.pictureSelectVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {result in
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson2)
                                                                                                fightVC.title = ListenType.lesson2.rawTitle
                                                                                                fightVC.data = data
                                                                                                JQ_currentViewController().jq_push(vc:fightVC)
                                                                                }
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 2{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .lesson3))
                                                                //归纳排除
                                                                Services.induceExclude(day: day, quarter: quarter, week: week).subscribe(onNext: {result in
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson3)
                                                                                                fightVC.title = ListenType.lesson3.rawTitle
                                                                                                fightVC.data = data
                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                }
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 3{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .lesson4))
                                                                //有问有答
                                                                Services.questionsAndAnswers(day: day, quarter: quarter, week: week).subscribe(onNext: {result in
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson4)
                                                                                                fightVC.title = ListenType.lesson4.rawTitle
                                                                                                fightVC.data = data
                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                }
                                                                }).disposed(by: disposeBag)
                                                }
                                                if indexPath.row == 4{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .lesson5))
                                                                //音图相配
                                                                Services.pictureMateVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {result in
                                                                                if let data = result.data{
                                                                                                let fightVC = HomeListenFightVC(listenType: .lesson5)
                                                                                                fightVC.title = ListenType.lesson5.rawTitle
                                                                                                fightVC.data = data
                                                                                                JQ_currentViewController().jq_push(vc: fightVC)
                                                                                }
                                                                }).disposed(by: disposeBag)
                                                }
                                }
                                                if indexPath.row == 5{
                                //自主游戏
                                if page == 5{
                                                if indexPath.row == 0{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .game1))
                                                }
                                                if indexPath.row == 6{
                                                if indexPath.row == 1{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .game2))
                                                }
                                                if indexPath.row == 7{
                                }
                                //听故事
                                if page == 6{
                                                if indexPath.row == 0{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .story1))
                                                }
                                                if indexPath.row == 8{
                                                if indexPath.row == 1{
                                                                JQ_currentViewController().jq_push(vc: HomeListenFightVC(listenType: .story2))
                                                }
                                }
@@ -84,38 +138,76 @@
extension HomeListenSubVC:UITableViewDataSource{
                func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                                if section == 0{
                                                return 1
                                if page <= 4{
                                                if section == 0{return 1}
                                                return 5
                                }else{
                                                return 2
                                }
                                return 9
                }
                func numberOfSections(in tableView: UITableView) -> Int {
                                if page <= 6{
                                if page <= 4{
                                                return 2
                                }
                                return 1
                }
                func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                                if indexPath.section == 0{
                                if indexPath.section == 0 && page <= 4{
                                                let cell = tableView.dequeueReusableCell(withIdentifier: "_HomeListen_process_TCell", for: indexPath) as! HomeListen_process_TCell
                                                return cell
                                }else{
                                                let cell = tableView.dequeueReusableCell(withIdentifier: "_HomeListen_item_TCell", for: indexPath) as! HomeListen_item_TCell
                                                cell.label_title.text = "\(indexPath.row + 1)"
                                                switch indexPath.row {
                                                                case 0:cell.label_title.text = "题目类型一"
                                                                case 1:cell.label_title.text = "题目类型二"
                                                                case 2:cell.label_title.text = "题目类型三"
                                                                case 3:cell.label_title.text = "题目类型四"
                                                                case 4:cell.label_title.text = "题目类型五"
                                                                case 5:cell.label_title.text = "游戏一"
                                                                case 6:cell.label_title.text = "游戏二"
                                                                case 7:cell.label_title.text = "故事一"
                                                                case 8:cell.label_title.text = "故事二"
                                                                default:break
                                                if page <= 4{
                                                                cell.view_bg1.isHidden = true
                                                                switch indexPath.row {
                                                                                case 0:
                                                                                                cell.label_title.text = "自主学习1-听音选图"
                                                                                                cell.view_bg2.backgroundColor = UIColor(hexString: "#6EC3FF")
                                                                                case 1:
                                                                                                cell.label_title.text = "自主学习2-看图选音"
                                                                                                cell.view_bg2.backgroundColor = UIColor(hexString: "#FF9A85")
                                                                                case 2:
                                                                                                cell.label_title.text = "自主学习3-归纳排除"
                                                                                                cell.view_bg2.backgroundColor = UIColor(hexString: "#28C8C5")
                                                                                case 3:
                                                                                                cell.label_title.text = "自主学习4-有问有答"
                                                                                                cell.view_bg2.backgroundColor = UIColor(hexString: "#F8A169")
                                                                                case 4:
                                                                                                cell.label_title.text = "自主学习5-音图相配"
                                                                                                cell.view_bg2.backgroundColor = UIColor(hexString: "#92CADB")
                                                                                default:break
                                                                }
                                                }
                                                if page == 5{
                                                                cell.view_bg2.isHidden = true
                                                                switch indexPath.row {
                                                                                case 0:
                                                                                                cell.label_title.text = "自主游戏1-超级听力"
                                                                                                cell.view_bg1.backgroundColor = UIColor(hexString: "#6EC3FF")
                                                                                case 1:
                                                                                                cell.label_title.text = "自主游戏2-超级记忆"
                                                                                                cell.view_bg1.backgroundColor = UIColor(hexString: "#FF9A85")
                                                                                default:break
                                                                }
                                                }
                                                if page == 6{
                                                                cell.view_bg2.isHidden = true
                                                                switch indexPath.row {
                                                                                case 0:
                                                                                                cell.label_title.text = "自主故事1-看图配音"
                                                                                                cell.view_bg1.backgroundColor = UIColor(hexString: "#6EC3FF")
                                                                                case 1:
                                                                                                cell.label_title.text = "自主故事2-框架记忆"
                                                                                                cell.view_bg1.backgroundColor = UIColor(hexString: "#FF9A85")
                                                                                default:break
                                                                }
                                                }
                                                return cell
@@ -123,8 +215,9 @@
                }
                func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
                                if indexPath.section == 0{
                                                return 145.5
                                if page <= 5{
                                                if indexPath.section == 0{return 145.5}
                                                return 127.5
                                }else{
                                                return 127.5
                                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift
@@ -13,6 +13,8 @@
                //限制后面的点击:天数(1开始)
                private var limitDay = 7
                private var quarter:Int!
                private var week:Int!
                private lazy var menu:SPPageMenu = {
                                let menu = SPPageMenu(frame: .zero, trackerStyle: .line)
@@ -35,6 +37,16 @@
                                return vc
                }()
                required init(quarter:Int,week:Int) {
                                super.init(nibName: nil, bundle: nil)
                                self.quarter = quarter
                                self.week = week
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
@@ -98,6 +110,6 @@
                }
                func pageViewController(_ pageViewConteoller: FFPageViewController, controllerForPage page: Int) -> UIViewController {
                                return HomeListenSubVC(page: page)
                                return HomeListenSubVC(page: page,quarter: quarter,week: week)
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_3_AnswerView.swift
@@ -14,6 +14,9 @@
                @IBOutlet weak var btn_choose: UIButton!
                @IBOutlet weak var btn_fullscreen: UIButton!
                @IBOutlet weak var img_cover: UIImageView!
                var imageUrl:String = ""
                override func awakeFromNib() {
                                super.awakeFromNib()
                                img_state.alpha = 0
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_4_AnswerView.swift
@@ -14,7 +14,9 @@
                @IBOutlet weak var btn_choose: UIButton!
                @IBOutlet weak var view_state: UIView!
                @IBOutlet weak var view_handle: UIView!
                var voiceUrl:String?
                override func awakeFromNib() {
                                super.awakeFromNib()
                                img_state.alpha = 0
@@ -27,6 +29,9 @@
                                return copyV
                }
                @IBAction func playAction(_ sender: UIButton) {
                                if let url = voiceUrl{
                                                VoicePlayer.share().playerAt(url: url)
                                }
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/View/Lesson_4_AnswerView.xib
@@ -19,31 +19,42 @@
                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qsr-6I-w3R">
                            <rect key="frame" x="0.0" y="0.0" width="152" height="52"/>
                            <subviews>
                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="otl-1Z-qED">
                                    <rect key="frame" x="18" y="9.5" width="33" height="33"/>
                                <button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="otl-1Z-qED">
                                    <rect key="frame" x="18" y="15" width="28" height="22"/>
                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                    <state key="normal" image="icon_question"/>
                                    <state key="normal" image="icon_answer"/>
                                </button>
                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mba-RI-50M">
                                    <rect key="frame" x="70" y="12.5" width="27" height="27"/>
                                <button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mba-RI-50M">
                                    <rect key="frame" x="65" y="12.5" width="27" height="27"/>
                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                    <state key="normal" image="icon_play_1"/>
                                </button>
                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_fail" translatesAutoresizingMaskIntoConstraints="NO" id="mkh-g4-79e">
                                    <rect key="frame" x="108" y="10" width="32" height="32"/>
                                    <rect key="frame" x="103" y="10" width="32" height="32"/>
                                    <constraints>
                                        <constraint firstAttribute="height" constant="32" id="unt-83-tZW"/>
                                        <constraint firstAttribute="width" constant="32" id="yDR-8r-kHx"/>
                                    </constraints>
                                </imageView>
                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tfO-7L-o0T">
                                    <rect key="frame" x="0.0" y="0.0" width="152" height="52"/>
                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                    <connections>
                                        <action selector="playAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="mAa-LF-0SJ"/>
                                    </connections>
                                </button>
                            </subviews>
                            <color key="backgroundColor" red="0.25490196079999999" green="0.63529411759999999" blue="0.92156862750000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                            <constraints>
                                <constraint firstItem="mba-RI-50M" firstAttribute="leading" secondItem="otl-1Z-qED" secondAttribute="trailing" constant="19" id="0nx-t9-1zV"/>
                                <constraint firstAttribute="width" constant="152" id="3Zx-vg-H2U"/>
                                <constraint firstItem="otl-1Z-qED" firstAttribute="leading" secondItem="qsr-6I-w3R" secondAttribute="leading" constant="18" id="6CA-c8-Zr7"/>
                                <constraint firstAttribute="bottom" secondItem="tfO-7L-o0T" secondAttribute="bottom" id="8ro-2n-YNH"/>
                                <constraint firstAttribute="trailing" secondItem="tfO-7L-o0T" secondAttribute="trailing" id="A2h-po-R4k"/>
                                <constraint firstItem="mba-RI-50M" firstAttribute="centerY" secondItem="otl-1Z-qED" secondAttribute="centerY" id="FTc-eb-PWk"/>
                                <constraint firstItem="tfO-7L-o0T" firstAttribute="top" secondItem="qsr-6I-w3R" secondAttribute="top" id="HqC-Ia-1OU"/>
                                <constraint firstItem="mkh-g4-79e" firstAttribute="centerY" secondItem="otl-1Z-qED" secondAttribute="centerY" id="N6f-d4-80e"/>
                                <constraint firstItem="tfO-7L-o0T" firstAttribute="leading" secondItem="qsr-6I-w3R" secondAttribute="leading" id="QfH-1Q-LyV"/>
                                <constraint firstItem="mkh-g4-79e" firstAttribute="leading" secondItem="mba-RI-50M" secondAttribute="trailing" constant="11" id="a9o-Lq-9SP"/>
                                <constraint firstItem="otl-1Z-qED" firstAttribute="centerY" secondItem="qsr-6I-w3R" secondAttribute="centerY" id="v0P-gn-zbN"/>
                            </constraints>
@@ -94,8 +105,8 @@
    <resources>
        <image name="btn_radio" width="52" height="52"/>
        <image name="btn_radio_u" width="52" height="52"/>
        <image name="icon_answer" width="28" height="14"/>
        <image name="icon_fail" width="80" height="80"/>
        <image name="icon_play_1" width="27" height="27"/>
        <image name="icon_question" width="33" height="33"/>
    </resources>
</document>
DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.swift
@@ -8,11 +8,35 @@
import UIKit
class HomeStudyCompleteVC: BaseVC {
                @IBOutlet weak var label_coin: UILabel!
                @IBOutlet weak var label_correctNum: UILabel!
                @IBOutlet weak var label_totalNum: UILabel!
                @IBOutlet weak var label_errorNum: UILabel!
                @IBOutlet weak var label_ratioNum: UILabel!
                private var correctNum:Int = 0
                private var errorNum:Int = 0
                private var totalCoin:Int = 0
                required init(correctNum:Int,errorNum:Int,totalCoin:Int){
                                super.init(nibName: nil, bundle: nil)
                                self.correctNum = correctNum
                                self.errorNum = errorNum
                                self.totalCoin = totalCoin
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
    override func viewDidLoad() {
        super.viewDidLoad()
                                label_coin.text = "恭喜你,已完成全部答题!获得\(totalCoin)积分!"
                                label_correctNum.text = "\(correctNum)次"
                                label_errorNum.text = "\(errorNum)次"
                                label_totalNum.text = "\(correctNum + errorNum)次"
                                label_ratioNum.text = String(format: "正确率:%.0lf%%", Double(correctNum) / Double(correctNum + errorNum) * 100)
    }
                override func setUI() {
DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.xib
@@ -11,6 +11,11 @@
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="HomeStudyCompleteVC" customModule="DolphinEnglishLearnStudent" customModuleProvider="target">
            <connections>
                <outlet property="label_coin" destination="0Rg-U5-bnk" id="Ue5-07-HUP"/>
                <outlet property="label_correctNum" destination="GyL-R8-T1w" id="ljq-bs-33V"/>
                <outlet property="label_errorNum" destination="8Lo-W3-dxd" id="y0q-RX-MkE"/>
                <outlet property="label_ratioNum" destination="4uZ-XC-Xc3" id="cSZ-ND-O0D"/>
                <outlet property="label_totalNum" destination="EAE-ID-4sP" id="Xpa-MR-y2Y"/>
                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
            </connections>
        </placeholder>
DolphinEnglishLearnStudent/Moudle/Home/View/AwardListView.swift
@@ -13,6 +13,7 @@
                @IBOutlet weak var view_container: UIView!
                private var items = [RecommendModel]()
                private var clickClouse:((RecommendModel)->Void)!
                private var closeClouse:(()->Void)!
                override func awakeFromNib() {
                                super.awakeFromNib()
                                self.alpha = 0
@@ -24,13 +25,14 @@
                                layoutIfNeeded()
                }
                static func show(items:[RecommendModel],clouse:@escaping (RecommendModel)->Void){
                static func show(items:[RecommendModel],clouse:@escaping (RecommendModel)->Void,closeClouse:@escaping()->Void){
                                if items.count == 0{return}
                                let awardListView = AwardListView.jq_loadNibView()
                                awardListView.items = items
                                awardListView.clickClouse = clouse
                                awardListView.closeClouse = closeClouse
                                sceneDelegate?.window?.addSubview(awardListView)
                                awardListView.frame = sceneDelegate?.window?.frame ?? .zero
@@ -48,6 +50,7 @@
                                                self.alpha = 0
                                                self.view_container.transform = .init(scaleX: 0.1, y: 0.1)
                                } completion: { _ in
                                                self.closeClouse?()
                                                self.removeFromSuperview()
                                }
                }
@@ -57,14 +60,14 @@
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                                UIView.animate(withDuration: 0.4) {
                                                self.alpha = 0
                                                self.view_container.transform = .init(scaleX: 0.1, y: 0.1)
                                } completion: { _ in
                                                self.removeFromSuperview()
                                                let item = self.items[indexPath.row]
                                                self.clickClouse(item)
                                }
//                                UIView.animate(withDuration: 0.4) {
//                                                self.alpha = 0
//                                                self.view_container.transform = .init(scaleX: 0.1, y: 0.1)
//                                } completion: { _ in
//                                                self.removeFromSuperview()
//                                                let item = self.items[indexPath.row]
//                                                self.clickClouse(item)
//                                }
                }
}
DolphinEnglishLearnStudent/Moudle/Me/MeVC.swift
@@ -22,19 +22,27 @@
        super.viewDidLoad()
                                Services.userInfo().subscribe(onNext: {result in
                                                if let model = result.data{
                                                var items = Array<String>()
                                                if let model = result.data?.user{
                                                                self.imge_cover.sd_setImage(with: URL(string: model.headImg))
                                                                self.label_name.text = model.name
//                                                                var items = Array<String>()
//                                                                items.append("剩余积分:\(model.integral)")
//                                                                items.append("学习进度:\(model.integral)")
                                                                items.append("剩余积分:\(model.integral)")
                                                }
                                                if let model = result.data?.userStudy{
                                                                items.append("学习进度:\(model.week)")
                                                                items.append("学习总时长:\(model.totalStudy)小时")
                                                }
                                                self.label_info.text = items.joined(separator: "|")
                                }).disposed(by: disposeBag)
    }
                override func setUI() {
                                super.setUI()
                                label_info.text = ""
                                btn_address.spacingBetweenImageAndTitle = 11
                                btn_coinRecord.spacingBetweenImageAndTitle = 11
                                btn_exchangeRecord.spacingBetweenImageAndTitle = 11
DolphinEnglishLearnStudent/Moudle/Me/TCell/GoodsItemTCell.swift
@@ -17,6 +17,7 @@
                @IBOutlet weak var label_sendInfo: UILabel!
                @IBOutlet weak var btn_state: UIButton!
                @IBOutlet weak var label_coin: UILabel!
                @IBOutlet weak var img_cover: UIImageView!
                
                @IBOutlet weak var view_container: UIView!
                override func awakeFromNib() {
@@ -29,7 +30,9 @@
                func setModel(_ model:ExchangeRecordModel){
                                label_goodsNum.text = "商品数量:\(model.count)"
                                label_coin.text = "\(model.integral)积分"
                                label_goodsName.text = model.goodsName
                                label_types.text = model.goodsType.joined(separator: "|")
                                img_cover.sd_setImage(with: URL(string: model.coverImg))
                                var items_consignee = Array<String>()
                                items_consignee.append(model.consigneeName)
                                items_consignee.append(model.consigneePhone)
@@ -42,6 +45,23 @@
                                label_sendInfo.isHidden = items_express.filter({!$0.isEmpty}).count == 0
                                label_sendInfo.text = "发货信息:" + items_express.joined(separator: "|")
                                //订单状态1待发货2已发货3已完成
                                switch model.state{
                                                case 1:
                                                                label_state.text = "待发货"
                                                                btn_state.setTitle("修改地址", for: .normal)
                                                                btn_state.isHidden = false
                                                case 2:
                                                                label_state.text = "平台已发货,请耐心等待"
                                                                btn_state.setTitle("已收货", for: .normal)
                                                                btn_state.isHidden = false
                                                case 3:
                                                                label_state.text = "已完成"
                                                                btn_state.isHidden = true
                                                default:
                                                                btn_state.isHidden = true
                                }
                }
                @IBAction func handleAction(_ sender: UIButton) {
DolphinEnglishLearnStudent/Moudle/Me/TCell/GoodsItemTCell.xib
@@ -142,6 +142,7 @@
            <viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
            <connections>
                <outlet property="btn_state" destination="xwt-lH-fyW" id="YNc-qk-0gB"/>
                <outlet property="img_cover" destination="HZS-Oe-5LR" id="jhE-JJ-jDa"/>
                <outlet property="label_coin" destination="nMG-SO-H2Z" id="weP-sJ-QLG"/>
                <outlet property="label_goodsName" destination="UdI-oe-WSO" id="o9d-iH-BCJ"/>
                <outlet property="label_goodsNum" destination="PlF-D7-xZD" id="1mj-HF-LGA"/>
DolphinEnglishLearnStudent/Moudle/Me/TCell/Home_1_TCell.swift
@@ -6,6 +6,7 @@
//
import UIKit
import JQTools
class Home_1_TCell: UITableViewCell {
@@ -25,7 +26,14 @@
                var studyGamesRecordModel:StudyGamesRecordModel!{
                                didSet{
                                                label_1.text = studyGamesRecordModel.createTime
                                                label_2.text = studyGamesRecordModel.gameName
                                                let date = Date.JQ_secondToDate(interval: studyGamesRecordModel.useTime)
                                                var emuple = [String]()
                                                if date.hour > 0{emuple.append("\(date.hour)小时")}
                                                if date.minute > 0{emuple.append("\(date.minute)分钟")}
                                                label_3.text = emuple.joined(separator: "")
                                                label_4.text = "\(studyGamesRecordModel.accuracy)%"
                                }
                }
DolphinEnglishLearnStudent/Moudle/Me/VC/ExchangeRecordHistoryVC.swift
@@ -37,8 +37,8 @@
                                tableView.register(UINib(nibName: "GoodsItemTCell", bundle: nil), forCellReuseIdentifier: "_GoodsItemTCell")
                                view.addSubview(tableView)
                                tableView.snp.makeConstraints { make in
                                                make.left.equalTo(239 * Config.RatioW)
                                                make.right.equalTo(-239 * Config.RatioW)
                                                make.left.equalTo(159 * Config.RatioW)
                                                make.right.equalTo(-159 * Config.RatioW)
                                                make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(27 * Config.RatioW)
                                                make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-5)
                                }
@@ -62,7 +62,7 @@
                }
                func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
                                return 221 * Config.RatioH
                                return 241 * Config.RatioH
                }
DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.swift
@@ -6,21 +6,35 @@
//
import UIKit
import JQTools
class StudyVC: BaseVC {
                @IBOutlet weak var label_currentProcess: UILabel!
                @IBOutlet weak var label_surplusProcess: UILabel!
                @IBOutlet weak var label_studyTotalTimes: UILabel!
                @IBOutlet weak var label_studyWeekTotalTimes: UILabel!
                @IBOutlet weak var view_menu: UIView!
                @IBOutlet weak var tableView: UITableView!
                
                private var gamesRecordModel:StudyGamesModel?{
                                didSet{
                                                self.tableView.reloadData()
                                                label_currentProcess.text = "当前进度:周目\(gamesRecordModel?.record?.week.jq_cn ?? "")"
                                                label_surplusProcess.text = "剩余进度:周目\(gamesRecordModel?.record?.surplus.jq_cn ?? "")"
                                                label_studyTotalTimes.attributedText = AttributedStringbuilder.build().add(string: "学习总时长:", withFont: .systemFont(ofSize: 16), withColor: UIColor(hexString: "#2B3648")!).add(string: "\(gamesRecordModel?.record?.totalStudy ?? 0)小时", withFont: .systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexString: "#2B3648")!).add(string: "|今日学习:", withFont: .systemFont(ofSize: 16), withColor: UIColor(hexString: "#2B3648")!).add(string: "\(gamesRecordModel?.record?.todayStudy ?? 0)小时", withFont: .systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexString: "#2B3648")!).mutableAttributedString
                                                label_studyWeekTotalTimes.attributedText = AttributedStringbuilder.build().add(string: "本周学习时长:", withFont: .systemFont(ofSize: 16), withColor: UIColor(hexString: "#2B3648")!).add(string: "\(gamesRecordModel?.record?.weekStudy ?? 0)小时", withFont: .systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexString: "#2B3648")!).add(string: "|本月学习时长:", withFont: .systemFont(ofSize: 16), withColor: UIColor(hexString: "#2B3648")!).add(string: "\(gamesRecordModel?.record?.monthStudy ?? 0)小时", withFont: .systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexString: "#2B3648")!).mutableAttributedString
                                }
                }
    override func viewDidLoad() {
        super.viewDidLoad()
                                Services.studyGamesRecord().subscribe(onNext: {result in
                                                if let m = result.data{
                                                                self.gamesRecordModel = m
@@ -59,7 +73,6 @@
                                if let m = gamesRecordModel?.gameRecordList[indexPath.row]{
                                                cell.studyGamesRecordModel = m
                                }
                                return cell
                }
DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.xib
@@ -11,6 +11,10 @@
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="StudyVC" customModule="DolphinEnglishLearnStudent" customModuleProvider="target">
            <connections>
                <outlet property="label_currentProcess" destination="6E8-Ab-gRb" id="70S-Tq-iJq"/>
                <outlet property="label_studyTotalTimes" destination="crR-lR-Tnj" id="aM4-1l-jTW"/>
                <outlet property="label_studyWeekTotalTimes" destination="r1z-jS-qK4" id="844-dB-a5N"/>
                <outlet property="label_surplusProcess" destination="SYT-bU-Qar" id="z3n-Ny-Yfs"/>
                <outlet property="tableView" destination="byc-YG-6j2" id="BDN-57-WDq"/>
                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
                <outlet property="view_menu" destination="1HY-aY-obo" id="m6s-HL-ZwQ"/>
DolphinEnglishLearnStudent/Other/UIView/StudyHandleView.swift
@@ -7,6 +7,7 @@
import UIKit
import JQTools
import AVFoundation
class StudyHandleView: UIView,JQNibView{
                @IBOutlet weak var btn_choose: UIButton!
@@ -17,15 +18,28 @@
                var listenType:ListenType?
                private var clouse:((UIButton)->Void)?
                private var playComplete:(()->Void)?
                private var playAtClouse:((Int)->Void)?
                private var voicePlayer = VoicePlayer.share()
                var vioceSoundUrl:String?
                override func awakeFromNib() {
                                super.awakeFromNib()
                                btn_state.alpha = 0
                                view_choose.alpha = 0
                                voicePlayer.playEnd {[weak self] in
                                                self?.reset()
                                }
                }
                func chooseClouse(callback:@escaping (UIButton)->Void){
                                clouse = callback
                }
                func playAt(_ clouse:@escaping(Int)->Void){
                                self.playAtClouse = clouse
                }
                func copyView()->StudyHandleView{
@@ -34,9 +48,26 @@
                                return copyV
                }
                @IBAction func payAction(_ sender: UIButton) {
                func reset(){
                                switch listenType {
                                                case .lesson1:
                                                case .lesson1,.lesson5:
                                                                btn_state.setImage(UIImage(named: "icon_play"), for: .normal)
                                                                btn_voice.alpha = 1
                                                                btn_pay.alpha = 1
                                                                btn_state.alpha = 0
                                                case .lesson2:
                                                                view_choose.alpha = 1
                                                default:break
                                }
                                self.superview?.layoutIfNeeded()
                }
                @IBAction func payAction(_ sender: UIButton) {
                                guard let v = vioceSoundUrl else {return}
                                voicePlayer.playerAt(url: v)
                                playAtClouse?(self.tag)
                                switch listenType {
                                                case .lesson1,.lesson5:
                                                                btn_state.setImage(UIImage(named: "icon_playing"), for: .normal)
                                                                btn_voice.alpha = 0
                                                                btn_pay.alpha = 0
@@ -46,7 +77,7 @@
                                                default:break
                                }
                }
                @IBAction func chooseAction(_ sender: UIButton) {
                                sender.isSelected = !sender.isSelected
                                clouse?(sender)
DolphinEnglishLearnStudent/Services/NetworkRequest.swift
@@ -245,7 +245,7 @@
//
//                                                                                                                                }
//                                                                                                                                ob.onError(NetRequestError.InvaildSession)
                                                                                                                case 401:
                                                                                                                case 401,505,600:
                                                                                                                                if !ignoreAlert{
                                                                                                                                                alertError(msg: "登录失效,请重新登录");ob.onError(NetRequestError.InvaildSession)
                                                                                                                                }
DolphinEnglishLearnStudent/Services/Services.swift
@@ -26,7 +26,70 @@
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/weekList")
                                params.append(key: "quarter", value: quarter)
                                return NetworkRequest.request(params: params, method: .get, progress: false)
                                return NetworkRequest.request(params: params, method: .get, progress: true)
                }
                /// 自主学习1-听音选图
                class func listenSelectPicture(day:Int,quarter:Int,week:Int)->Observable<BaseResponse<Listen1Model>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/listenSelectPicture")
                                params.append(key: "quarter", value: quarter)
                                params.append(key: "day", value: day)
                                params.append(key: "week", value: week)
                                return NetworkRequest.request(params: params, method: .get, progress: true)
                }
                /// 自主学习2-看图选音
                class func pictureSelectVoice(day:Int,quarter:Int,week:Int)->Observable<BaseResponse<Listen1Model>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/pictureSelectVoice")
                                params.append(key: "quarter", value: quarter)
                                params.append(key: "day", value: day)
                                params.append(key: "week", value: week)
                                return NetworkRequest.request(params: params, method: .get, progress: true)
                }
                /// 自主学习3-归纳排除
                class func induceExclude(day:Int,quarter:Int,week:Int)->Observable<BaseResponse<Listen1Model>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/induceExclude")
                                params.append(key: "quarter", value: quarter)
                                params.append(key: "day", value: day)
                                params.append(key: "week", value: week)
                                return NetworkRequest.request(params: params, method: .get, progress: true)
                }
                /// 自主学习4-有问有答
                class func questionsAndAnswers(day:Int,quarter:Int,week:Int)->Observable<BaseResponse<Listen4Model>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/questionsAndAnswers")
                                params.append(key: "quarter", value: quarter)
                                params.append(key: "day", value: day)
                                params.append(key: "week", value: week)
                                return NetworkRequest.request(params: params, method: .get, progress: true)
                }
                /// 自主学习5-音图相配
                class func pictureMateVoice(day:Int,quarter:Int,week:Int)->Observable<BaseResponse<Listen1Model>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/pictureMateVoice")
                                params.append(key: "quarter", value: quarter)
                                params.append(key: "day", value: day)
                                params.append(key: "week", value: week)
                                return NetworkRequest.request(params: params, method: .get, progress: true)
                }
                /// 完成学习
                class func completeLearing(type:Int,studyTime:Int,studyIds:[Int],isComplete:Bool)->Observable<BaseResponse<SimpleModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/completeLearning")
                                                .append(key: "type", value: type)
                                                .append(key: "studyTime", value: studyTime)
                                                .append(key: "studyIds", value: studyIds.map({"\($0)"}))
                                                .append(key: "isComplete", value: isComplete)
                                return NetworkRequest.request(params: params, method: .post,encoding: JSONEncoding.default, progress: true)
                }
}
@@ -173,7 +236,7 @@
                class func studyGamesRecord()->Observable<BaseResponse<StudyGamesModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/study/base/study/record")
                                params.interface(url: "/study/base/study/studyRecord")
                                return NetworkRequest.request(params: params, method: .get, progress: true)
                }
DolphinEnglishLearnStudent/ViewModel/UserViewModel.swift
@@ -12,6 +12,12 @@
struct UserInfoModel:HandyJSON,Identifiable,Codable{
                static let idKey = \UserInfoModel.id
                var id: Int = 0
                var user:UserInfoUserModel?
                var userStudy:UserInfoStudyModel?
}
struct UserInfoUserModel:HandyJSON,Codable{
                var account: String = ""
                var birthday: String = ""
                var createBy: String = ""
@@ -31,7 +37,25 @@
                var updateTime: String = ""
                var vipEndTime: String = ""
                var vipPayTime: String = ""
}
struct UserInfoStudyModel:HandyJSON,Codable{
                var answer: Int = 0
                var day: Int = 0
                var id: Int = 0
                var induction: Int = 0
                var listen: Int = 0
                var look: Int = 0
                var monthStudy: Int = 0
                var pair: Int = 0
                var surplus: Int = 0
                var todayStudy: Int = 0
                var totalStudy: Int = 0
                var updateBy: String?
                var updateTime: String?
                var userId: Int = 0
                var week: Int = 0
                var weekStudy: Int = 0
}
class UserViewModel{