无故事王国
2023-09-25 453b79dabc0d769a246136877b5d670802f84539
补充
14个文件已修改
388 ■■■■■ 已修改文件
Podfile 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Common/VC/CommonScanQRCodeVC.swift 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Config/Enums.swift 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Model/CommonModels.swift 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Network/NetworkRequest.swift 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Network/Services.swift 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Course/TCell/CourseSignUpTCell.swift 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Course/TCell/CourseSignUpTCell.xib 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Course/TCell/CourseTCell.swift 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Games/GamesVC.swift 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Games/TCell/GamesTCell.swift 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Games/TCell/GamesTCell.xib 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Games/VC/GamesListVC.swift 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Games/VC/GamesSubListVC.swift 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Podfile
@@ -18,6 +18,7 @@
  pod 'WechatOpenSDK-XCFramework'
  pod 'AlipaySDK-iOS'
  pod 'AMap2DMap-NO-IDFA'
    pod 'CryptoSwift'
  post_install do |installer|
WanPai/Common/VC/CommonScanQRCodeVC.swift
@@ -93,7 +93,8 @@
    public override func viewWillAppear(_ animated: Bool) {
        firstResult = true
        if let session = self.session {
            DispatchQueue.main.async {
            let queue = DispatchQueue(label: "startRun")
            queue.async {
                session.startRunning()
            }
        }
@@ -260,7 +261,7 @@
                //数组中包含的都是AVMetadataMachineReadableCodeObject 类型的对象,该对象中包含解码后的数据
            let qrObject:AVMetadataMachineReadableCodeObject = metadataObjects.last as! AVMetadataMachineReadableCodeObject;
                //拿到扫描内容在这里进行个性化处理
            let result = qrObject.stringValue;
            let result = qrObject.stringValue
            clouse?(result ?? "",firstResult)
            closeView()
        }
WanPai/Config/Enums.swift
@@ -441,3 +441,8 @@
        }
    }
}
enum ScanType:Int{
    case games = 1000 //游戏
    case course = 1001 //课程
}
WanPai/Model/CommonModels.swift
@@ -300,9 +300,9 @@
    var storeCoverDrawing = ""
    var distance:Double = 0
    var imgs = ""
    var nextName = [String]()
    var halfName = [String]()
    var ishalf = 0 // 1:是 2:否
    var nextName = [String]() //场地名
    var halfName = [String]() //半场名
    var ishalf = 0 // 是否半场  1:是 2:否
    var introduce = ""
@@ -443,6 +443,7 @@
    var userImage: String = ""
    var userName: String = ""
    var userPhone: String = ""
    var userId:Int = 0
}
struct BenefitHomeModel:HandyJSON{
@@ -744,3 +745,9 @@
    var voucher: String = ""
}
struct GameListModel:HandyJSON {
    var id = 0
    var name = ""
    var icon = ""
}
WanPai/Network/NetworkRequest.swift
@@ -132,19 +132,22 @@
        var paramsArray: [String] = []
            // 排序
        let sortedArray: [String] = Array(params.keys).sorted()
        for item in sortedArray{
                // 拼接字符串
            if params.has(key: item){
                paramsArray.append("\(item)=\(params[item]!)")
            }
        }
        let content = paramsArray.joined(separator: "&")
        params += ["sign": "\(content.jq_hmacBase64(algorithm: .SHA1, key: SHAKEY))"]
        #if DEBUG
        LogInfo("签名:\(content) ----- \(content.jq_hmacBase64(algorithm: .SHA1, key: SHAKEY))")
        #endif
            //防止自签名而错误
        if !sortedArray.contains("sign"){
            for item in sortedArray{
                    // 拼接字符串
                if params.has(key: item){
                    paramsArray.append("\(item)=\(params[item]!)")
                }
            }
            let content = paramsArray.joined(separator: "&")
            params += ["sign": "\(content.jq_hmacBase64(algorithm: .SHA1, key: SHAKEY))"]
#if DEBUG
            LogInfo("签名:\(content) ----- \(content.jq_hmacBase64(algorithm: .SHA1, key: SHAKEY))")
#endif
        }
        return self.params
    }
    
WanPai/Network/Services.swift
@@ -13,108 +13,139 @@
#if DEBUG
let All_Url = "http://192.168.110.22:56666"
let Game_Url = "https://try.daowepark.com"
//let All_Url = "https://console-mock.apipost.cn/mock/b5b2dee0-5564-40ae-f082-a352d502a153"
//let All_Url = "http://192.168.110.165:10393/mock/b5b2dee0-5564-40ae-f082-a352d502a153"
#else
let All_Url = "http://192.168.110.80:5209"
let Game_Url = "https://port.daowepark.com"
#endif
    // MARK: -- 首页部分
class Services: NSObject {
extension Services{
    class func homeInfo()->Observable<BaseResponse<HomeStoreModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/api/appUser/queryJoinPlayPai")
            .append(key: "lat", value: locationTool.currentLocation?.coordinate.latitude.string)
            .append(key: "lon", value: locationTool.currentLocation?.coordinate.longitude.string)
        return NetworkRequest.request(params: params, method: .post, progress: false)
    }
        /// 主页配置
    class func homeStoreConfig(storeId:Int)->Observable<BaseResponse<[HomeStoreConfigModel]>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/other/base/store/queryStoreConfig")
            .append(key: "storeId", value: storeId)
        return NetworkRequest.request(params: params, method: .post, progress: false)
    }
        /// 获取banner图
        /// - Parameter position: 位置(1=首页,2=首页底部,3=线上课得积分,4=看视频得奖励,5=常见问题)
    class func bannerList(position:BannerPositionType)->Observable<BaseResponse<[BannerModel]>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/other/base/banner/queryBannerList")
            .append(key: "position", value: position.rawValue)
        return NetworkRequest.request(params: params, method: .post, progress: false)
    }
}
// MARK: -- 游戏
extension Services{
    // MARK: -- 登录部分
class Services: NSObject {
    static let pageSize: Int = 20
    class func login(phone:String,verity:String,type:LoginType)->Observable<BaseResponse<String>>{
        let params = ParamsAppender.build(url: All_Url)
        if type == .pwd{
            params.interface(url: "/account/base/appUser/loginPassword")
            params.append(key: "password", value: verity.jq_md5String().uppercased())
        }else{
            params.interface(url: "/account/base/appUser/loginSMSCode")
            params.append(key: "code", value: verity)
        }
        params.append(key: "phone", value: phone)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
        /// 本地离线游戏
    class func game_gameList(spaceId:String,sutuId:String)->Observable<BaseResponse<[GameListModel]>>{
        let params = ParamsAppender.build(url: Game_Url)
            .interface(url: "/v7/user_api/general/gameList")
            .append(key: "space_id", value: spaceId)
            .append(key: "sutu_id", value: sutuId)
            .append(key: "sign", value: "0DB011836143EEE2C2E072967C9F4E4B")
        return NetworkRequest.request(params: params, method: .post, encoding: JSONEncoding.default, progress: false)
    }
    class func getSMSCode(phone:String,type:GetSMSCodeType)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/getSMSCode")
            .append(key: "phone", value: phone)
            .append(key: "type", value: type.rawValue)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
        /// 启动本地游戏
    class func game_gameStart(gameId:Int,spaceId:String,sutuId:String,userID:Int)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: Game_Url)
            .interface(url: "/v7/user_api/general/gameStart")
            .append(key: "space_id", value: spaceId)
            .append(key: "sutu_id", value: sutuId)
            .append(key: "game_id", value: gameId)
            .append(key: "app_user_id", value: userID)
            .append(key: "sign", value: "0DB011836143EEE2C2E072967C9F4E4B")
        return NetworkRequest.request(params: params, method: .post, encoding: JSONEncoding.default, progress: false)
    }
}
    class func register(phone:String,password:String,code:String)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/addAppUser")
            .append(key: "phone", value: phone)
            .append(key: "password", value: password.jq_md5String().uppercased())
            .append(key: "code", value: code)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
    // MARK: -- 登录部分
extension Services{
    static let pageSize: Int = 20
    class func login(phone:String,verity:String,type:LoginType)->Observable<BaseResponse<String>>{
        let params = ParamsAppender.build(url: All_Url)
        if type == .pwd{
            params.interface(url: "/account/base/appUser/loginPassword")
            params.append(key: "password", value: verity.jq_md5String().uppercased())
        }else{
            params.interface(url: "/account/base/appUser/loginSMSCode")
            params.append(key: "code", value: verity)
        }
        params.append(key: "phone", value: phone)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
    class func updatePwd(phone:String,password:String,code:String)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/updatePassword")
            .append(key: "phone", value: phone)
            .append(key: "password", value: password.jq_md5String().uppercased())
            .append(key: "code", value: code)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
    class func getSMSCode(phone:String,type:GetSMSCodeType)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/getSMSCode")
            .append(key: "phone", value: phone)
            .append(key: "type", value: type.rawValue)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
    class func forgetPwd(phone:String,password:String,code:String)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/forgetPassword")
            .append(key: "phone", value: phone)
            .append(key: "password", value: password.jq_md5String().uppercased())
            .append(key: "code", value: code)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
    class func register(phone:String,password:String,code:String)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/addAppUser")
            .append(key: "phone", value: phone)
            .append(key: "password", value: password.jq_md5String().uppercased())
            .append(key: "code", value: code)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
        /// 用户详情
    class func userDetails()->Observable<BaseResponse<UserInfoModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/api/useBenefit/userDetails")
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
    class func updatePwd(phone:String,password:String,code:String)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/updatePassword")
            .append(key: "phone", value: phone)
            .append(key: "password", value: password.jq_md5String().uppercased())
            .append(key: "code", value: code)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
        /// 勋章
    static func studMedalList(studentId:Int)->Observable<BaseResponse<[StudentMedalModel]>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/api/startCource/stuGoog")
            .append(key: "stuId", value: studentId)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
    class func forgetPwd(phone:String,password:String,code:String)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/base/appUser/forgetPassword")
            .append(key: "phone", value: phone)
            .append(key: "password", value: password.jq_md5String().uppercased())
            .append(key: "code", value: code)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
        /// 用户详情
    class func userDetails()->Observable<BaseResponse<UserInfoModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/api/useBenefit/userDetails")
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
        /// 勋章
    static func studMedalList(studentId:Int)->Observable<BaseResponse<[StudentMedalModel]>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/api/startCource/stuGoog")
            .append(key: "stuId", value: studentId)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
}
    // MARK: -- 首页部分
extension Services{
    class func homeInfo()->Observable<BaseResponse<HomeStoreModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/api/appUser/queryJoinPlayPai")
            .append(key: "lat", value: locationTool.currentLocation?.coordinate.latitude.string)
            .append(key: "lon", value: locationTool.currentLocation?.coordinate.longitude.string)
        return NetworkRequest.request(params: params, method: .post, progress: false)
    }
        /// 主页配置
    class func homeStoreConfig(storeId:Int)->Observable<BaseResponse<[HomeStoreConfigModel]>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/other/base/store/queryStoreConfig")
            .append(key: "storeId", value: storeId)
        return NetworkRequest.request(params: params, method: .post, progress: false)
    }
        /// 获取banner图
        /// - Parameter position: 位置(1=首页,2=首页底部,3=线上课得积分,4=看视频得奖励,5=常见问题)
    class func bannerList(position:BannerPositionType)->Observable<BaseResponse<[BannerModel]>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/other/base/banner/queryBannerList")
            .append(key: "position", value: position.rawValue)
        return NetworkRequest.request(params: params, method: .post, progress: false)
    }
}
// MARK: -- 福利相关
@@ -502,7 +533,7 @@
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
        /// 未分配课时
        /// 有未分配课时
    static func weeksOfGetHours()->Observable<BaseResponse<Int>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "/account/api/startCource/weeksOfGetHours")
WanPai/Root/Course/TCell/CourseSignUpTCell.swift
@@ -17,6 +17,7 @@
    @IBOutlet weak var label_teachNum: UILabel!
    @IBOutlet weak var label_paymentState: UILabel!
    @IBOutlet weak var label_courseType: UILabel!
    @IBOutlet weak var stackview_courseType: UIStackView!
    
    var signUpCourseItemModel:SignUpCourseItemModel!{
        didSet{
@@ -27,7 +28,7 @@
            label_courseType.text = signUpCourseItemModel.type.strTitle
            label_paymentState.isHidden = signUpCourseItemModel.payStatus == .paymented
            stackview_courseType.isHidden = signUpCourseItemModel.type != .normal
        }
    }
WanPai/Root/Course/TCell/CourseSignUpTCell.xib
@@ -21,6 +21,7 @@
                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="placeholder_1" translatesAutoresizingMaskIntoConstraints="NO" id="skA-8v-kDR">
                        <rect key="frame" x="14" y="22" width="106" height="141"/>
                        <constraints>
                            <constraint firstAttribute="width" secondItem="skA-8v-kDR" secondAttribute="height" multiplier="1:1.33" id="CaL-vK-OKS"/>
                            <constraint firstAttribute="width" constant="105" id="gdL-1V-gDh"/>
                        </constraints>
                        <userDefinedRuntimeAttributes>
@@ -129,7 +130,6 @@
                    <constraint firstItem="9jG-tW-jzN" firstAttribute="leading" secondItem="skA-8v-kDR" secondAttribute="trailing" constant="10" id="0KL-dk-3XM"/>
                    <constraint firstItem="yS2-Ri-epi" firstAttribute="top" secondItem="skA-8v-kDR" secondAttribute="top" id="18R-VB-f8t"/>
                    <constraint firstItem="0U6-2L-7GF" firstAttribute="top" secondItem="n2V-mw-3oN" secondAttribute="bottom" constant="26" id="2rb-an-jPP"/>
                    <constraint firstItem="skA-8v-kDR" firstAttribute="width" secondItem="skA-8v-kDR" secondAttribute="height" multiplier="1:1.33" id="CaL-vK-OKS"/>
                    <constraint firstItem="skA-8v-kDR" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="22" id="Eb0-Sp-QWA"/>
                    <constraint firstItem="skA-8v-kDR" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="F8n-ro-WoI"/>
                    <constraint firstItem="082-6t-M2H" firstAttribute="leading" secondItem="skA-8v-kDR" secondAttribute="trailing" constant="11" id="GRg-Ae-2bF"/>
@@ -154,6 +154,7 @@
                <outlet property="label_paymentState" destination="yS2-Ri-epi" id="k5Y-hA-wyq"/>
                <outlet property="label_teachNum" destination="HoK-tr-Fbj" id="cD6-aK-M7H"/>
                <outlet property="label_title" destination="9jG-tW-jzN" id="pXs-zA-I2N"/>
                <outlet property="stackview_courseType" destination="qty-G5-pIz" id="e3X-T3-77e"/>
            </connections>
            <point key="canvasLocation" x="282.44274809160305" y="103.52112676056339"/>
        </tableViewCell>
WanPai/Root/Course/TCell/CourseTCell.swift
@@ -28,7 +28,7 @@
            img_cover.sd_setImage(with: URL(string: courseItemModel.coverDrawing),placeholderImage: UIImage(named: "placeholder_1"))
            label_title.text = String(format: "%@(%@)", courseItemModel.name,courseItemModel.storeName)
            label_teachTime.text = String(format: "上课时间:%@", courseItemModel.classStartTime.joined(separator: ","))
            label_teachTime.text = String(format: "上课时间:%@", courseItemModel.classStartTime.jq_max(size: 2).joined(separator: "|"))
            label_enrollNumber.text = String(format: "已报名:%ld人", courseItemModel.applicantsNumber)
            label_distance.text = String(format: "%.2lfkm", courseItemModel.distance)
WanPai/Root/Games/GamesVC.swift
@@ -7,8 +7,20 @@
import UIKit
import JQTools
import HandyJSON
let StartGame_Noti = Notification.Name.init("StartGame_Noti")
struct QRCodeModel:HandyJSON {
//    var scan_type:ScanType? //扫码类型:1000:游戏,10001:课程
    var space_id:String? //场地ID
    var sutu_id:String? //设备ID
    var course_id:Int? //课程ID
}
class GamesVC: BaseVC {
    private var codeModel:QRCodeModel!
    override func viewDidLoad() {
        super.viewDidLoad()
@@ -20,28 +32,55 @@
    }
    private func checkUnPayGame(){
        let gamesListVC = GamesListVC()
    private func checkUnPayGame(_ model:QRCodeModel){
        let gamesListVC = GamesListVC(model: model)
        addChild(gamesListVC)
        view.addSubview(gamesListVC.view)
        gamesListVC.view.frame = CGRect(x: 0, y: UIDevice.jq_safeEdges.top + navigationController!.navigationBar.height, width: JQ_ScreenW, height: JQ_ScreenH - UIDevice.jq_safeEdges.top - navigationController!.navigationBar.height)
        gamesListVC.didMove(toParent: self)
    }
    override func setRx() {
        NotificationCenter.default.rx.notification(StartGame_Noti).take(until: self.rx.deallocated).subscribe(onNext: {[weak self] noti in
            guard let weakSelf = self else { return }
            if let gameId = noti.object as? Int{
                Services.userDetails().subscribe(onNext: {[weak self] data in
                    guard let weakSelf = self else { return }
                    if let model = data.data{
                        Services.game_gameStart(gameId: gameId, spaceId: weakSelf.codeModel.space_id!, sutuId: weakSelf.codeModel.sutu_id!, userID: model.userId).subscribe(onNext: { _ in
                            alertSuccess(msg: "启动成功")
                        }) { error in
                        }.disposed(by: weakSelf.disposeBag)
                    }
                }).disposed(by: weakSelf.disposeBag)
            }
        }).disposed(by: disposeBag)
    }
    @IBAction func scanAction(_ sender: UIButton) {
        let scan = CommonScanQRCodeVC { text, status in
            if status{
                GamesPayView.show(price: 120, coin: 99) {
                    PaymentView.show(money: (ali: 120, wx: 120, coin: 99,course:nil)) { type in
                        let vc = PaymentResultVC(result: .success, objType: .games, handleVC: self)
                        vc.modalPresentationStyle = .fullScreen
                        self.present(vc, animated: true)
                        DispatchQueue.main.asyncAfter(deadline: .now()+0.6) {
                            self.checkUnPayGame()
                        }
                    }
                if let model = QRCodeModel.deserialize(from: text){
                    self.codeModel = model
                    self.checkUnPayGame(model)
                }else{
                    alertError(msg: "识别失败")
                }
                //暂时关闭【勿删】
//                GamesPayView.show(price: 120, coin: 99) {
//                    PaymentView.show(money: (ali: 120, wx: 120, coin: 99,course:nil)) { type in
//                        let vc = PaymentResultVC(result: .success, objType: .games, handleVC: self)
//                        vc.modalPresentationStyle = .fullScreen
//                        self.present(vc, animated: true)
//
//                        DispatchQueue.main.asyncAfter(deadline: .now()+0.6) {
//                            self.checkUnPayGame()
//                        }
//                    }
//                }
            }
        }
        present(scan, animated: true)
WanPai/Root/Games/TCell/GamesTCell.swift
@@ -6,8 +6,20 @@
//
import UIKit
import RxSwift
import RxRelay
class GamesTCell: UITableViewCell {
    var disposeBag = DisposeBag()
    @IBOutlet weak var img_icon: UIImageView!
    var gameListModel:GameListModel!{
        didSet{
            img_icon.sd_setImage(with: URL(string: gameListModel.icon))
        }
    }
    override func awakeFromNib() {
        super.awakeFromNib()
@@ -20,6 +32,6 @@
    }
    @IBAction func launchGameAction(_ sender: UIButton) {
        NotificationCenter.default.post(name: StartGame_Noti, object: gameListModel.id)
    }
}
WanPai/Root/Games/TCell/GamesTCell.xib
@@ -3,7 +3,7 @@
    <device id="retina6_12" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22129"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
@@ -81,6 +81,9 @@
                </constraints>
            </tableViewCellContentView>
            <viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
            <connections>
                <outlet property="img_icon" destination="tsc-uc-uMd" id="mXE-32-ghe"/>
            </connections>
            <point key="canvasLocation" x="180.15267175572518" y="2.1126760563380285"/>
        </tableViewCell>
    </objects>
WanPai/Root/Games/VC/GamesListVC.swift
@@ -12,6 +12,7 @@
class GamesListVC: BaseVC {
    private var model:QRCodeModel!
    private(set) var pageMenu:SPPageMenu = {
        let pageMenu = SPPageMenu(frame: .zero, trackerStyle: .line)
            // 追踪线
@@ -48,6 +49,15 @@
        return pageVC
    }()
    init(model:QRCodeModel) {
        super.init(nibName: nil, bundle: nil)
        self.model = model
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidLoad() {
        super.viewDidLoad()
@@ -86,7 +96,7 @@
    }
    func pageViewController(_ pageViewConteoller: FFPageViewController, controllerForPage page: Int) -> UIViewController {
        let vc = GamesSubListVC(type: GamesSubType(rawValue: page)!)
        let vc = GamesSubListVC(type: GamesSubType(rawValue: page)!,model: model)
        return vc
    }
}
WanPai/Root/Games/VC/GamesSubListVC.swift
@@ -6,6 +6,8 @@
//
import UIKit
import RxRelay
import RxSwift
enum GamesSubType:Int{
    case all = -1
@@ -13,14 +15,27 @@
    case online = 1
}
class GamesOffLineViewModel:RefreshModel<GameListModel>{
    let spaceId = BehaviorRelay<String>(value: "")
    let sutuId = BehaviorRelay<String>(value: "")
    override func api() -> (Observable<BaseResponse<[GameListModel]>>)? {
        return Services.game_gameList(spaceId: spaceId.value, sutuId: sutuId.value)
    }
}
class GamesSubListVC: BaseVC {
    private var type:GamesSubType!
    private var model:QRCodeModel!
    private let offLineViewModel = GamesOffLineViewModel()
    private var tableView:UITableView!
    init(type:GamesSubType) {
    init(type:GamesSubType,model:QRCodeModel) {
        super.init(nibName: nil, bundle: nil)
        self.type = type
        self.model = model
    }
    
    required init?(coder: NSCoder) {
@@ -29,6 +44,13 @@
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if type == .offline{
            offLineViewModel.spaceId.accept(model.space_id!)
            offLineViewModel.sutuId.accept(model.sutu_id!)
            offLineViewModel.configure(tableView, needMore: false)
            offLineViewModel.beginRefresh()
        }
    }
@@ -50,11 +72,19 @@
extension GamesSubListVC:UITableViewDataSource{
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "_GamesTCell") as! GamesTCell
        if type == .offline{
            cell.gameListModel = offLineViewModel.dataSource.value[indexPath.row]
        }
        return cell
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 212
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
        return offLineViewModel.dataSource.value.count
    }
}