杨锴
2025-06-04 ac84f81ca2311300b431c1bfb9f71253b59073f2
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift
@@ -10,6 +10,7 @@
import RxRelay
let NextLession_Noti = Notification.Name.init("NextLession_Noti")
let ResetLession_Noti = Notification.Name.init("ResetLession_Noti")
//let Reload_Noti = Notification.Name.init("Reload_Noti")
enum ListenType:Int{
@@ -54,7 +55,7 @@
            /// 当前页数
            var currentPage = BehaviorRelay<Int>(value: 0)
            var subPage = BehaviorRelay<Int>(value: 1) //小题目角标
    //    var subPage = BehaviorRelay<Int>(value: 1) //小题目角标
            var maxPage = BehaviorRelay<Int>(value: 5)
            var listenType = BehaviorRelay<ListenType>(value:.lesson1)
            var times:Int = 0
@@ -104,6 +105,7 @@
            var maxPage = 0 //最大页记录
            var teamScheduleModel:TeamScheduleModel? //上次中途退出,答题记录
    var pages = [[ListenSubCardModel]]() //分页显示
            private var notiObject:Dictionary<String,Any>?
@@ -112,13 +114,48 @@
                        label.font = .systemFont(ofSize: 14, weight: .medium)
                        label.textColor = .black.withAlphaComponent(0.81)
                        label.textAlignment = .center
                        label.text = "已完成:0/0"
        label.numberOfLines = 2
        label.text = "已完成:0/0\n正确率:--%"
                        return label
            }()
            private lazy var btn_forward:UIButton = {
                        let btn = UIButton(type: .custom)
                        btn.setTitle("上一题", for: .normal)
        btn.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        btn.setTitleColor(Config.ThemeColor, for: .normal)
        btn.jq_borderColor = Config.ThemeColor
        btn.backgroundColor = .white
        btn.jq_borderWidth = 1
        btn.jq_cornerRadius = 4
        return btn
    }()
    private lazy var collection_card:UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 2
        layout.minimumLineSpacing = 2
        layout.itemSize = CGSize(width: 24, height: 24)
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.backgroundColor = .clear
        return collectionView
    }()
    private lazy var btn_beAgain:UIButton = {
        let btn = UIButton(type: .custom)
        btn.setTitle("重新开始", for: .normal)
        btn.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        btn.setTitleColor(Config.ThemeColor, for: .normal)
        btn.jq_borderColor = Config.ThemeColor
        btn.backgroundColor = .white
        btn.jq_borderWidth = 1
        btn.jq_cornerRadius = 4
        return btn
    }()
    private lazy var btn_continue:UIButton = {
        let btn = UIButton(type: .custom)
        btn.setTitle("继续答题", for: .normal)
                        btn.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
                        btn.setTitleColor(Config.ThemeColor, for: .normal)
                        btn.jq_borderColor = Config.ThemeColor
@@ -207,6 +244,7 @@
                        btn_forward.addTarget(self, action: #selector(beforeAction), for: .touchUpInside)
                        btn_forward_mini.addTarget(self, action: #selector(beforeAction_mini), for: .touchUpInside)
                        btn_next.addTarget(self, action: #selector(nextAction), for: .touchUpInside)
        btn_beAgain.addTarget(self, action: #selector(beAgaionAction), for: .touchUpInside)
                        setPages()
                        pageVC.reloadData()
@@ -217,21 +255,45 @@
                        timer.fire()
                        RunLoop.current.add(timer, forMode: .common)
        setPages()
                        if let teamSchedule = teamScheduleModel{
                                    viewModel.correctNum = viewModel.correctNum + teamSchedule.correctNumber
                                    viewModel.errorNum = teamSchedule.answerNumber - teamSchedule.correctNumber
                                    maxPage   = teamSchedule.schedule
                                    let ids = (data as! ListenNewModel).data!.id.components(separatedBy: ",")
                                    switch viewModel.listenType.value {
                                                case .lesson1:
                if let m  = data as? ListenNewModel{
                    self.pages = Array<ListenSubCardModel>.splitArray(m.list, subArraySize: 4)
                    let c = m.list.count / 4
                    let totalW = 24 * c + 2 * (c - 1)
                    collection_card.snp.updateConstraints { make in
                        make.width.equalTo(totalW)
                    }
                }
            case .lesson2,.lesson3,.lesson4,.lesson5:
                if let m  = data as? ListenNewModel{
                    self.pages = Array<ListenSubCardModel>.splitArray(m.list, subArraySize: 1)
                    let totalW = 24 * m.list.count + 2 * (m.list.count - 1)
                    collection_card.snp.updateConstraints { make in
                        make.width.equalTo(totalW)
                    }
                }
            default:break
            }
            switch viewModel.listenType.value {
            case .lesson1:
                collection_card.reloadData()
                                                            let nextPage = floor(Double(maxPage) / 5.0)
                                                            pageVC.scroll(toPage: Int(nextPage), animation: false)
                                                            viewModel.answerCount.accept(maxPage)
                                                            setPages()
                                                case .lesson2:
                collection_card.reloadData()
                                                            let maxCount = (data as! ListenNewModel).subjectList.count
                                                            let page = min((maxPage - 1),maxCount)
                                                            if pageVC.currentPage != page{
@@ -241,6 +303,7 @@
                                                            }
                                                case .lesson4:
                collection_card.reloadData()
                                                            let maxCount = (data as! ListenNewModel).subjectList.count
                                                            let page = min((maxPage - 1),maxCount)
                                                            if pageVC.currentPage != page{
@@ -251,6 +314,7 @@
                                                case .lesson3,.lesson5:
                collection_card.reloadData()
                                                            let maxCount = (data as! ListenNewModel).subjectList.count
                                                            let page = min((maxPage - 1),maxCount)
                                                            if pageVC.currentPage != page{
@@ -267,6 +331,15 @@
            override func setUI() {
                        super.setUI()
        switch viewModel.listenType.value{
        case .lesson1,.lesson2,.lesson3,.lesson4,.lesson5:
            collection_card.delegate = self
            collection_card.dataSource = self
            collection_card.register(CardItemCCell.self, forCellWithReuseIdentifier: "_CardItemCCell")
        default:break
        }
                        craeteFootFuncView()
                        pageVC.delegate = self
@@ -275,9 +348,9 @@
                                    make.left.right.equalToSuperview()
                                    make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top)
                                    if self.viewModel.listenType.value == .lesson3 || self.viewModel.listenType.value == .lesson4{
                                                make.bottom.equalTo(self.label_pageNum.snp.top).offset(-18)
                make.bottom.equalTo(self.label_pageNum.snp.top).offset(-52)
                                    }else{
                                                make.bottom.equalTo(self.label_pageNum.snp.top).offset(-32)
                make.bottom.equalTo(self.label_pageNum.snp.top).offset(-52)
                                    }
                        }
            }
@@ -305,18 +378,31 @@
            private func craeteFootFuncView(){
        view.addSubview(collection_card)
                        btn_forward.snp.makeConstraints { make in
                                    make.height.equalTo(40)
                                    make.width.equalTo(124)
                        }
        btn_beAgain.snp.makeConstraints { make in
            make.height.equalTo(40)
            make.width.equalTo(124)
        }
        btn_continue.snp.makeConstraints { make in
            make.height.equalTo(40)
            make.width.equalTo(124)
        }
                        btn_exit.snp.makeConstraints { make in
                                    make.height.equalTo(40)
                                    make.width.equalTo(124)
                        }
                        let stackView = UIStackView(arrangedSubviews: [btn_forward,label_pageNum,btn_exit])
        let stackView = UIStackView(arrangedSubviews: [btn_beAgain,label_pageNum,btn_exit])
                        if viewModel.listenType.value == .story2{
                                    btn_next.snp.makeConstraints { make in
                                                make.height.equalTo(40)
@@ -328,9 +414,20 @@
                        stackView.spacing = 22
                        view.addSubview(stackView)
                        stackView.snp.makeConstraints { make in
                                    make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-22)
            make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-5)
                                    make.centerX.equalToSuperview()
                                    make.height.equalTo(40)
        }
        switch viewModel.listenType.value{
        case .lesson1,.lesson2,.lesson3,.lesson4,.lesson5:
            collection_card.snp.makeConstraints { make in
                make.centerX.equalToSuperview()
                make.width.equalTo(10)
                make.bottom.equalTo(stackView.snp.top).offset(-10)
                make.height.equalTo(24)
            }
        default:break
                        }
            }
@@ -396,22 +493,54 @@
            private func setPages(){
                        switch viewModel.listenType.value{
                                    case .lesson1:
                                                label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\((data as! ListenNewModel).subjectList.flatMap({$0}).count)"
//                                                maxPage = max(viewModel.answerCount.value,maxPage)
            let m = data as! ListenNewModel
            label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(m.subjectList.flatMap({$0}).count / 4)"
            let correctNum = m.list.filter({$0.status == 2}).count //正确
            //                if correctNum > 0 {
            let ratio = Double(correctNum) / Double(m.list.count) * 100.0
            let ratioStr = ratio.jq_formatFloat
            label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(m.subjectList.flatMap({$0}).count / 4)\n正确率:\(ratioStr)%"
            //                }
                                                maxPage = viewModel.answerCount.value
                                                btn_forward.isHidden = viewModel.answerCount.value == 1
                                    case .lesson2,.lesson3,.lesson5:
                                                label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\((data as! ListenNewModel).subjectList.count)"
        case .lesson3:
            let m = data as! ListenNewModel
            label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(m.subjectList.count / 6)"
                                                btn_forward.isHidden = viewModel.currentPage.value == 0
                                                let page = viewModel.currentPage.value + 1
//                                                maxPage = max(page,maxPage)
                                                maxPage = page
            let correctNum = m.list.filter({$0.status == 2}).count //正确
            let ratio = Double(correctNum) / Double(m.list.count) * 100.0
            let ratioStr = ratio.jq_formatFloat
            label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\(m.subjectList.flatMap({$0}).count)\n正确率:\(ratioStr)%"
        case .lesson2,.lesson5:
            let m = data as! ListenNewModel
            label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(m.subjectList.count)"
            btn_forward.isHidden = viewModel.currentPage.value == 0
            let page = viewModel.currentPage.value + 1
            maxPage = page
            let correctNum = m.list.filter({$0.status == 2}).count //正确
            let ratio = Double(correctNum) / Double(m.list.count) * 100.0
            let ratioStr = ratio.jq_formatFloat
            label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\(m.subjectList.flatMap({$0}).count)\n正确率:\(ratioStr)%"
                                    case .lesson4:
            let m = data as! ListenNewModel
                                                //两题为一组:需要/2
                                                label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\((data as! ListenNewModel).subjectList.count)"
            label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(m.subjectList.count)"
                                                let page = viewModel.currentPage.value + 1
//                                                maxPage = max(page,maxPage)
                                                maxPage = page
            let correctNum = m.list.filter({$0.status == 2}).count //正确
            let ratio = Double(correctNum) / Double(m.list.count) * 100.0
            let ratioStr = ratio.jq_formatFloat
            label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\(m.subjectList.flatMap({$0}).count)\n正确率:\(ratioStr)%"
                                    case .game1,.game2:
                                                btn_forward.isHidden = true
                                                label_pageNum.isHidden = true
@@ -589,6 +718,26 @@
                        }
            }
    @objc func beAgaionAction(){
        CommonAlertView.show(content: "是否重新开始答题?确认后将清空当前答题进度") {[unowned self] in
            let day = self.viewModel.day.value ?? 0
            let week = self.viewModel.week.value ?? 0
            let type = self.viewModel.listenType.value.rawValue
            Services.restart(day: day, type: type, week: week).subscribe(onNext: {[unowned self]_ in
                self.pageVC.scroll(toPage: 0, animation: true)
                if let m = (self.data as? ListenNewModel){
                    for v in m.list{
                        v.status = 1
                    }
                    self.restore()
                    self.setPages()
                    self.collection_card.reloadData()
                    NotificationCenter.default.post(name: ResetLession_Noti, object: nil)
                }
            }).disposed(by: disposeBag)
        }
    }
            @objc func nextAction(){
                        listenFightLine = .next
                        if viewModel.listenType.value == .story2{
@@ -660,6 +809,31 @@
                        btn_exit.setTitle("退出", for: .normal)
            }
    private func restore(){
        if let vc = pageVC.currentController as? HomeListenFight_lesson_1_VC{
            vc.restore()
        }
        if let vc = pageVC.currentController as? HomeListenFight_lesson_2_VC{
            vc.restore()
        }
        if let vc = pageVC.currentController as? HomeListenFight_lesson_3_VC{
            vc.restore()
        }
        if let vc = pageVC.currentController as? HomeListenFight_lesson_4_VC{
            vc.restore()
        }
        if let vc = pageVC.currentController as? HomeListenFight_lesson_5_VC{
            vc.restore()
        }
        if let vc = pageVC.currentController as? HomeListenStory_1_VC{
            vc.restore()
        }
        if let vc = pageVC.currentController as? HomeListenStory_2_VC{
            vc.restore()
        }
    }
}
extension HomeListenFightVC:FFPageViewControllerDelegate{
@@ -683,28 +857,7 @@
            func pageViewController(_ pageViewController: FFPageViewController, currentPageChanged currentPage: Int) {
                        if listenFightLine == .before{
                                    if let vc = pageViewController.currentController as? HomeListenFight_lesson_1_VC{
                                                vc.restore()
                                    }
                                    if let vc = pageViewController.currentController as? HomeListenFight_lesson_2_VC{
                                                vc.restore()
                                    }
                                    if let vc = pageViewController.currentController as? HomeListenFight_lesson_3_VC{
                                                vc.restore()
                                    }
                                    if let vc = pageViewController.currentController as? HomeListenFight_lesson_4_VC{
                                                vc.restore()
                                    }
                                    if let vc = pageViewController.currentController as? HomeListenFight_lesson_5_VC{
                                                vc.restore()
                                    }
                                    if let vc = pageViewController.currentController as? HomeListenStory_1_VC{
                                                vc.restore()
                                    }
                                    if let vc = pageViewController.currentController as? HomeListenStory_2_VC{
                                                vc.restore()
                                    }
            restore()
                        }
            }
@@ -713,6 +866,10 @@
                                    let vc = HomeListenFight_lesson_1_VC(page: page,listenNewModel:data as! ListenNewModel)
                                    vc.teamScheduleModel = teamScheduleModel
                                    vc.rootViewModel = viewModel
            vc.handleClouseAction {[unowned self] in
                self.setPages()
                self.collection_card.reloadData()
            }
                                    return vc
                        }
@@ -720,6 +877,10 @@
                                    let vc = HomeListenFight_lesson_2_VC(page: page,listenNewModel:data as! ListenNewModel)
                                    vc.teamScheduleModel = teamScheduleModel
                                    vc.rootViewModel = viewModel
            vc.handleClouseAction {[unowned self] in
                self.setPages()
                self.collection_card.reloadData()
            }
                                    return vc
                        }
@@ -727,6 +888,10 @@
                                    let vc = HomeListenFight_lesson_3_VC(page: page, listenNewModel: data as! ListenNewModel)
                                    vc.teamScheduleModel = teamScheduleModel
                                    vc.rootViewModel = viewModel
            vc.handleClouseAction {[unowned self] in
                self.setPages()
                self.collection_card.reloadData()
            }
                                    return vc
                        }
@@ -734,6 +899,10 @@
                                    let vc = HomeListenFight_lesson_4_VC(page: page, listenNewModel: data as! ListenNewModel)
                                    vc.teamScheduleModel = teamScheduleModel
                                    vc.rootViewModel = viewModel
            vc.handleClouseAction {[unowned self] in
                self.setPages()
                self.collection_card.reloadData()
            }
                                    return vc
                        }
@@ -741,6 +910,10 @@
                                    let vc = HomeListenFight_lesson_5_VC(page: page, listenNewModel: data as! ListenNewModel)
                                    vc.teamScheduleModel = teamScheduleModel
                                    vc.rootViewModel = viewModel
            vc.handleClouseAction {[unowned self] in
                self.setPages()
                self.collection_card.reloadData()
            }
                                    return vc
                        }
@@ -774,3 +947,86 @@
            }
}
extension HomeListenFightVC:UICollectionViewDelegate{
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if let m = data as? ListenNewModel{
            guard m.list[indexPath.row].status != 1 else{return}
            guard pageVC.currentPage != indexPath.row else {return}
            pageVC.scroll(toPage: indexPath.row, animation: true)
            //todo
        }
    }
}
extension HomeListenFightVC:UICollectionViewDataSource{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if let m = data as? ListenNewModel{
            if viewModel.listenType.value == .lesson1{
                return pages.count
            }
            return pages.count
        }
        return 0
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_CardItemCCell", for: indexPath) as! CardItemCCell
        if let m = data as? ListenNewModel{
            let model = pages[indexPath.row]
            cell.titleL.text = "\(indexPath.row + 1)"
            if viewModel.listenType.value == .lesson1{
                if model.filter({$0.status == 2}).count == 4{
                    cell.titleL.textColor = UIColor(hexString: "#52C41A")
                    cell.titleL.jq_borderColor = UIColor(hexString: "#52C41A")
                }else if model.filter({$0.status == 3}).count >= 1 {
                    cell.titleL.textColor = UIColor(hexString: "#FF4D4F")
                    cell.titleL.jq_borderColor = UIColor(hexString: "#52C41A")
                }else{
                    cell.titleL.textColor = .black.withAlphaComponent(0.25)
                    cell.titleL.jq_borderColor = .black.withAlphaComponent(0.25)
                }
            }else{
                //状态1灰色未答题 2绿色正确 3红色错误
                switch model.first!.status{
                case 1:
                    cell.titleL.textColor = .black.withAlphaComponent(0.25)
                    cell.titleL.jq_borderColor = .black.withAlphaComponent(0.25)
                case 2:
                    cell.titleL.textColor = UIColor(hexString: "#52C41A")
                    cell.titleL.jq_borderColor = UIColor(hexString: "#52C41A")
                case 3:
                    cell.titleL.textColor = UIColor(hexString: "#FF4D4F")
                    cell.titleL.jq_borderColor = UIColor(hexString: "#52C41A")
                default:break
                }
            }
        }
        return cell
    }
}
class CardItemCCell:UICollectionViewCell{
    var titleL:UILabel!
    override init(frame: CGRect) {
        super.init(frame: frame)
        titleL = UILabel()
        titleL.text = "1"
        titleL.backgroundColor = .white
        titleL.jq_borderColor = .black.withAlphaComponent(0.15)
        titleL.jq_borderWidth = 0.5
        titleL.font = .systemFont(ofSize: 13,weight: .semibold)
        titleL.textAlignment = .center
        contentView.addSubview(titleL)
        titleL.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}