From 538c5a5a86d485aec75221e1b2a2d39bc807673c Mon Sep 17 00:00:00 2001 From: zeng Date: Tue, 29 Apr 2025 18:01:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=84=E7=A7=8D=E8=AE=A2=E5=8D=95=E8=AE=B0?= =?UTF-8?q?=E5=BD=95UI=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MoviaBox.xcodeproj/project.pbxproj | 2 + MoviaBox/Base/Extension/UIColor+SPAdd.swift | 8 ++ MoviaBox/Base/Extension/UIFont+SPAdd.swift | 12 ++ MoviaBox/Base/Networking/API/SPUserAPI.swift | 17 +++ MoviaBox/Class/Mine/Model/SPMineItem.swift | 2 - .../Class/Player/View/SPPlayBuyView.swift | 1 - .../View/SPPlayerDetailControlView.swift | 23 ---- .../SPCoinOrderRecordViewController.swift | 58 +++++++++ .../SPConsumptionRecordsViewController.swift | 61 ++++++++++ .../SPOrderRecordsPageViewController.swift | 106 +++++++++++++++++ .../SPRewardCoinsViewController.swift | 64 ++++++++++ .../SPVIPOrderRecordViewController.swift | 57 +++++++++ .../Controller/SPWalletViewController.swift | 14 ++- .../Wallet/View/SPCoinOrderRecordCell.swift | 83 +++++++++++++ .../View/SPConsumptionRecordsCell.swift | 87 ++++++++++++++ .../Class/Wallet/View/SPRewardCoinsCell.swift | 110 ++++++++++++++++++ .../Wallet/View/SPVIPOrderRecordCell.swift | 74 ++++++++++++ MoviaBox/MoviaBox.entitlements | 10 ++ .../icon/coin_icon_06.imageset/Contents.json | 22 ++++ .../coin_icon_06.imageset/image 20@2x.png | Bin 0 -> 2220 bytes .../coin_icon_06.imageset/image 20@3x.png | Bin 0 -> 4377 bytes .../expire_icon_01.imageset/Contents.json | 22 ++++ .../expire_icon_01.imageset/time icon@2x.png | Bin 0 -> 707 bytes .../expire_icon_01.imageset/time icon@3x.png | Bin 0 -> 976 bytes MoviaBox/Source/en.lproj/Localizable.strings | 3 + 25 files changed, 809 insertions(+), 27 deletions(-) create mode 100644 MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift create mode 100644 MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift create mode 100644 MoviaBox/Class/Wallet/Controller/SPOrderRecordsPageViewController.swift create mode 100644 MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift create mode 100644 MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift create mode 100644 MoviaBox/Class/Wallet/View/SPCoinOrderRecordCell.swift create mode 100644 MoviaBox/Class/Wallet/View/SPConsumptionRecordsCell.swift create mode 100644 MoviaBox/Class/Wallet/View/SPRewardCoinsCell.swift create mode 100644 MoviaBox/Class/Wallet/View/SPVIPOrderRecordCell.swift create mode 100644 MoviaBox/MoviaBox.entitlements create mode 100644 MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/Contents.json create mode 100644 MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/image 20@2x.png create mode 100644 MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/image 20@3x.png create mode 100644 MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/Contents.json create mode 100644 MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/time icon@2x.png create mode 100644 MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/time icon@3x.png diff --git a/MoviaBox.xcodeproj/project.pbxproj b/MoviaBox.xcodeproj/project.pbxproj index 85bcf42..99cfee1 100644 --- a/MoviaBox.xcodeproj/project.pbxproj +++ b/MoviaBox.xcodeproj/project.pbxproj @@ -220,6 +220,7 @@ ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MoviaBox/MoviaBox.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; @@ -264,6 +265,7 @@ ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MoviaBox/MoviaBox.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; diff --git a/MoviaBox/Base/Extension/UIColor+SPAdd.swift b/MoviaBox/Base/Extension/UIColor+SPAdd.swift index 8e89a61..40b98d5 100644 --- a/MoviaBox/Base/Extension/UIColor+SPAdd.swift +++ b/MoviaBox/Base/Extension/UIColor+SPAdd.swift @@ -380,5 +380,13 @@ extension UIColor { static func colorFF1F1F(alpha: CGFloat = 1) -> UIColor { return color(hex: 0xFF1F1F, alpha: alpha) } + + static func colorFF3232(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xFF3232, alpha: alpha) + } + + static func color362020(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0x362020, alpha: alpha) + } } diff --git a/MoviaBox/Base/Extension/UIFont+SPAdd.swift b/MoviaBox/Base/Extension/UIFont+SPAdd.swift index 66e896d..545485e 100644 --- a/MoviaBox/Base/Extension/UIFont+SPAdd.swift +++ b/MoviaBox/Base/Extension/UIFont+SPAdd.swift @@ -9,6 +9,18 @@ import UIKit extension UIFont { + static func regularFontName() -> String { + return ".AppleSystemUIFont" + } + + static func mediumFontName() -> String { + return ".AppleSystemUIFontMedium" + } + + static func boldFontName() -> String { + return ".AppleSystemUIFontBold" + } + static func fontRegular(ofSize: CGFloat) -> UIFont { return .systemFont(ofSize: ofSize, weight: .regular) } diff --git a/MoviaBox/Base/Networking/API/SPUserAPI.swift b/MoviaBox/Base/Networking/API/SPUserAPI.swift index 1976cc7..ed53265 100644 --- a/MoviaBox/Base/Networking/API/SPUserAPI.swift +++ b/MoviaBox/Base/Networking/API/SPUserAPI.swift @@ -20,6 +20,23 @@ class SPUserAPI: NSObject { } } + ///用户登录 + + + ///退出登录 + static func requestSignout() { + var param = SPNetworkParameters(path: "customer/signout") + param.isLoding = true + + SPNetwork.request(parameters: param) { (response: SPNetworkResponse) in + if response.code == SPNetworkCodeSucceed { +// completer?(true) + } else { +// completer?(false) + } + } + } + ///注销账户 static func requestLogoff(completer: ((_ isFinish: Bool) -> Void)?) { var param = SPNetworkParameters(path: "/customer/logoff") diff --git a/MoviaBox/Class/Mine/Model/SPMineItem.swift b/MoviaBox/Class/Mine/Model/SPMineItem.swift index 63a1d5f..17654e1 100644 --- a/MoviaBox/Class/Mine/Model/SPMineItem.swift +++ b/MoviaBox/Class/Mine/Model/SPMineItem.swift @@ -35,8 +35,6 @@ struct SPMineItem { case settings ///消费记录 case consumptionRecords - ///订单记录 - case purchaseRecords ///赠币记录 case rewardCoins ///清理缓存 diff --git a/MoviaBox/Class/Player/View/SPPlayBuyView.swift b/MoviaBox/Class/Player/View/SPPlayBuyView.swift index 575fc07..f746314 100644 --- a/MoviaBox/Class/Player/View/SPPlayBuyView.swift +++ b/MoviaBox/Class/Player/View/SPPlayBuyView.swift @@ -10,7 +10,6 @@ import UIKit class SPPlayBuyView: HWPanModalContentView { - //MARK: UI属性 private lazy var bgView: UIImageView = { let view = UIImageView(image: UIImage(named: "buy_bg_image_01")) diff --git a/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift b/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift index d32c458..55198fe 100644 --- a/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift +++ b/MoviaBox/Class/Player/View/SPPlayerDetailControlView.swift @@ -219,19 +219,8 @@ extension SPPlayerDetailControlView { toolView.addSubview(progressTimeLabel) addSubview(retreatButton) addSubview(advanceButton) -// addSubview(speedButton) -// addSubview(speedSelectedView) - -// self.progressView.snp.remakeConstraints { make in -// make.left.equalToSuperview().offset(15) -// make.centerX.equalToSuperview() -// make.height.equalTo(30) -// make.bottom.equalToSuperview().offset(-(kSPTabbarSafeBottomMargin + 10)) -// } self.progressTimeLabel.snp.makeConstraints { make in -// make.left.equalTo(self.progressView) -// make.bottom.equalTo(self.progressView).offset(-12) make.centerY.equalToSuperview() make.left.equalToSuperview().offset(16) } @@ -246,18 +235,6 @@ extension SPPlayerDetailControlView { make.left.equalTo(playImageView.snp.right).offset(kSPMainW(50)) } -// speedButton.snp.makeConstraints { make in -// make.centerY.equalTo(self.progressTimeLabel) -// make.right.equalToSuperview().offset(-15) -// make.width.equalTo(40) -// make.height.equalTo(20) -// } - -// speedSelectedView.snp.makeConstraints { make in -// make.left.right.equalToSuperview() -// make.bottom.equalTo(self.speedButton.snp.top).offset(-30) -// } - } } diff --git a/MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift b/MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift new file mode 100644 index 0000000..6dbe6cf --- /dev/null +++ b/MoviaBox/Class/Wallet/Controller/SPCoinOrderRecordViewController.swift @@ -0,0 +1,58 @@ +// +// SPCoinOrderRecordViewController.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +class SPCoinOrderRecordViewController: SPViewController { + + //MARK: UI属性 + private lazy var tableView: SPTableView = { + let tableView = SPTableView(frame: .zero, style: .plain) + tableView.delegate = self + tableView.dataSource = self + tableView.rowHeight = 70 + SPCoinOrderRecordCell.registerCell(tableView: tableView) + return tableView + }() + + + override func viewDidLoad() { + super.viewDidLoad() + setBackgroundView(isShowGradient: false, bgImage: nil, backgroundColor: .clear) + + _setupUI() + } + + + + +} + +extension SPCoinOrderRecordViewController { + private func _setupUI() { + view.addSubview(tableView) + + tableView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + } +} + +//MARK: -------------- UITableViewDelegate & UITableViewDataSource -------------- +extension SPCoinOrderRecordViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = SPCoinOrderRecordCell.dequeueReusableCell(tableView: tableView, indexPath: indexPath) + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10 + } + +} diff --git a/MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift b/MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift new file mode 100644 index 0000000..5e1e4eb --- /dev/null +++ b/MoviaBox/Class/Wallet/Controller/SPConsumptionRecordsViewController.swift @@ -0,0 +1,61 @@ +// +// SPConsumptionRecordsViewController.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +///消费记录 +class SPConsumptionRecordsViewController: SPViewController { + + //MARK: UI属性 + private lazy var tableView: SPTableView = { + let tableView = SPTableView(frame: .zero, style: .plain) + tableView.delegate = self + tableView.dataSource = self + tableView.rowHeight = 72 + tableView.separatorInset = .init(top: 0, left: 32, bottom: 0, right: 32) + SPConsumptionRecordsCell.registerCell(tableView: tableView) + return tableView + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.title = "Consumption Records".localized + self.edgesForExtendedLayout = .top + + _setupUI() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: true) + setNavigationNormalStyle(backgroundColor: .clear, isTranslucent: true) + + } +} + +extension SPConsumptionRecordsViewController { + private func _setupUI() { + view.addSubview(tableView) + + tableView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview().offset(kSPNavBarHeight) + } + } +} + +//MARK: -------------- UITableViewDelegate & UITableViewDataSource -------------- +extension SPConsumptionRecordsViewController: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = SPConsumptionRecordsCell.dequeueReusableCell(tableView: tableView, indexPath: indexPath) + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10 + } +} diff --git a/MoviaBox/Class/Wallet/Controller/SPOrderRecordsPageViewController.swift b/MoviaBox/Class/Wallet/Controller/SPOrderRecordsPageViewController.swift new file mode 100644 index 0000000..c3f0218 --- /dev/null +++ b/MoviaBox/Class/Wallet/Controller/SPOrderRecordsPageViewController.swift @@ -0,0 +1,106 @@ +// +// SPOrderRecordsPageViewController.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +class SPOrderRecordsPageViewController: SPViewController { + + private lazy var titles: [String] = ["Coin Record".localized, "VIP Record".localized] + private lazy var viewControllers: [UIViewController] = { + let vc1 = SPCoinOrderRecordViewController() + let vc2 = SPVIPOrderRecordViewController() + return [vc1, vc2] + }() + + //MARK: UI属性 + private lazy var pageView: WMPageController = { + let pageView = WMPageController() + pageView.delegate = self + pageView.dataSource = self + pageView.titleFontName = UIFont.mediumFontName() + pageView.titleSizeNormal = 16 + pageView.titleSizeSelected = 16 + pageView.titleColorNormal = .colorFFFFFF(alpha: 0.45) + pageView.titleColorSelected = .colorFF3232() + pageView.progressColor = .colorFFFFFF() + pageView.menuViewStyle = .flood + pageView.menuViewLayoutMode = .center + pageView.progressHeight = 36 + pageView.menuItemWidth = (kSPScreenWidth - 44) / 2 + return pageView + }() + + private lazy var menuBgView: UIView = { + let view = UIView() + view.backgroundColor = .color362020() + view.layer.cornerRadius = 16 + view.layer.masksToBounds = true + return view + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.title = "Order Records".localized + self.edgesForExtendedLayout = .top + + _setupUI() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: true) + setNavigationNormalStyle(backgroundColor: .clear, isTranslucent: true) + + } + +} + +extension SPOrderRecordsPageViewController { + + private func _setupUI() { + addChild(self.pageView) + + view.addSubview(menuBgView) + view.addSubview(self.pageView.view) + + self.pageView.view.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview().offset(kSPNavBarHeight) + } + + menuBgView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(16) + make.centerX.equalToSuperview() + make.top.equalToSuperview().offset(kSPNavBarHeight) + make.height.equalTo(48) + } + } + +} + +//MARK: -------------- WMPageControllerDelegate & WMPageControllerDataSource -------------- +extension SPOrderRecordsPageViewController: WMPageControllerDelegate, WMPageControllerDataSource { + func pageController(_ pageController: WMPageController, preferredFrameForContentView contentView: WMScrollView) -> CGRect { + return CGRect(x: 0, y: 48, width: kSPScreenWidth, height: kSPScreenHeight - kSPNavBarHeight - 48) + } + + func pageController(_ pageController: WMPageController, preferredFrameFor menuView: WMMenuView) -> CGRect { + return CGRect(x: 0, y: 0, width: kSPScreenWidth, height: 48) + } + + func numbersOfChildControllers(in pageController: WMPageController) -> Int { + return self.titles.count + } + + func pageController(_ pageController: WMPageController, titleAt index: Int) -> String { + return self.titles[index] + } + + func pageController(_ pageController: WMPageController, viewControllerAt index: Int) -> UIViewController { + return viewControllers[index] + } +} diff --git a/MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift b/MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift new file mode 100644 index 0000000..0c007ef --- /dev/null +++ b/MoviaBox/Class/Wallet/Controller/SPRewardCoinsViewController.swift @@ -0,0 +1,64 @@ +// +// SPRewardCoinsViewController.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +//赠币记录 +class SPRewardCoinsViewController: SPViewController { + + //MARK: UI属性 + private lazy var tableView: SPTableView = { + let tableView = SPTableView(frame: .zero, style: .plain) + tableView.delegate = self + tableView.dataSource = self + tableView.rowHeight = 96 + SPRewardCoinsCell.registerCell(tableView: tableView) + return tableView + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.title = "Reward Coins".localized + self.edgesForExtendedLayout = .top + + _setupUI() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: true) + setNavigationNormalStyle(backgroundColor: .clear, isTranslucent: true) + + } + + +} + +extension SPRewardCoinsViewController { + + private func _setupUI() { + view.addSubview(tableView) + + tableView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview().offset(kSPNavBarHeight) + } + } + +} + +//MARK: -------------- UITableViewDelegate & UITableViewDataSource -------------- +extension SPRewardCoinsViewController: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = SPRewardCoinsCell.dequeueReusableCell(tableView: tableView, indexPath: indexPath) + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10 + } +} diff --git a/MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift b/MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift new file mode 100644 index 0000000..a0ee283 --- /dev/null +++ b/MoviaBox/Class/Wallet/Controller/SPVIPOrderRecordViewController.swift @@ -0,0 +1,57 @@ +// +// SPVIPOrderRecordViewController.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +class SPVIPOrderRecordViewController: SPViewController { + + //MARK: UI属性 + private lazy var tableView: SPTableView = { + let tableView = SPTableView(frame: .zero, style: .plain) + tableView.delegate = self + tableView.dataSource = self + tableView.rowHeight = 74 + SPVIPOrderRecordCell.registerCell(tableView: tableView) + return tableView + }() + + + override func viewDidLoad() { + super.viewDidLoad() + setBackgroundView(isShowGradient: false, bgImage: nil, backgroundColor: .clear) + + _setupUI() + } + + + +} + +extension SPVIPOrderRecordViewController { + private func _setupUI() { + view.addSubview(tableView) + + tableView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + } +} + +//MARK: -------------- UITableViewDelegate & UITableViewDataSource -------------- +extension SPVIPOrderRecordViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = SPVIPOrderRecordCell.dequeueReusableCell(tableView: tableView, indexPath: indexPath) + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10 + } + +} diff --git a/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift b/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift index c460c82..7c21c69 100644 --- a/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift +++ b/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift @@ -12,7 +12,7 @@ class SPWalletViewController: SPViewController { private lazy var dataArr: [SPMineItem] = { let arr = [ SPMineItem(type: .consumptionRecords, iconImage: UIImage(named: "records_icon_01"), title: "Consumption records".localized), - SPMineItem(type: .purchaseRecords, iconImage: UIImage(named: "records_icon_02"), title: "Purchase records".localized), + SPMineItem(type: .orderRecord, iconImage: UIImage(named: "records_icon_02"), title: "Purchase records".localized), SPMineItem(type: .rewardCoins, iconImage: UIImage(named: "coin_icon_03"), title: "Reward Coins".localized), SPMineItem(type: .feedBack, iconImage: UIImage(named: "feed_back_icon_03"), title: "FeedBack".localized), ] @@ -87,6 +87,18 @@ extension SPWalletViewController: UITableViewDelegate, UITableViewDataSource { let vc = SPFeedbackViewController() self.navigationController?.pushViewController(vc, animated: true) + case .rewardCoins: + let vc = SPRewardCoinsViewController() + self.navigationController?.pushViewController(vc, animated: true) + + case .consumptionRecords: + let vc = SPConsumptionRecordsViewController() + self.navigationController?.pushViewController(vc, animated: true) + + case .orderRecord: + let vc = SPOrderRecordsPageViewController() + self.navigationController?.pushViewController(vc, animated: true) + default: break } diff --git a/MoviaBox/Class/Wallet/View/SPCoinOrderRecordCell.swift b/MoviaBox/Class/Wallet/View/SPCoinOrderRecordCell.swift new file mode 100644 index 0000000..4103b8a --- /dev/null +++ b/MoviaBox/Class/Wallet/View/SPCoinOrderRecordCell.swift @@ -0,0 +1,83 @@ +// +// SPCoinOrderRecordCell.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +class SPCoinOrderRecordCell: SPTableViewCell { + + //MARK: UI属性 + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 16) + label.textColor = .colorFF3232() + return label + }() + + private lazy var timeLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 14) + label.textColor = .colorFFFFFF() + return label + }() + + private lazy var coinLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 16) + label.textColor = .colorFF3232() + return label + }() + + private lazy var coinImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "coin_icon_06")) + return imageView + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + titleLabel.text = "Recharge Coins" + timeLabel.text = "2024-6-10 23:41:18" + coinLabel.text = "+20000" + + _setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension SPCoinOrderRecordCell { + + private func _setupUI() { + contentView.addSubview(titleLabel) + contentView.addSubview(timeLabel) + contentView.addSubview(coinLabel) + contentView.addSubview(coinImageView) + + titleLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(32) + make.top.equalToSuperview().offset(15) + } + + timeLabel.snp.makeConstraints { make in + make.left.equalTo(titleLabel) + make.bottom.equalToSuperview().offset(-15) + } + + coinImageView.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalTo(coinLabel.snp.left).offset(-4) + } + + coinLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalToSuperview().offset(-25) + } + } + +} diff --git a/MoviaBox/Class/Wallet/View/SPConsumptionRecordsCell.swift b/MoviaBox/Class/Wallet/View/SPConsumptionRecordsCell.swift new file mode 100644 index 0000000..0103a1d --- /dev/null +++ b/MoviaBox/Class/Wallet/View/SPConsumptionRecordsCell.swift @@ -0,0 +1,87 @@ +// +// SPConsumptionRecordsCell.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +class SPConsumptionRecordsCell: SPTableViewCell { + + //MARK: UI属性 + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFF3232() + return label + }() + + private lazy var timeLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFFFFFF() + return label + }() + + private lazy var desLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFFFFFF() + return label + }() + + private lazy var coinLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFF3232() + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + titleLabel.text = "Purchase Single Episode" + timeLabel.text = "2024-6-10 23:41:18" + desLabel.text = "Ep.8 Romantic Flash Marriage In Progress" + coinLabel.text = "-500 Coins" + + _setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension SPConsumptionRecordsCell { + + private func _setupUI() { + contentView.addSubview(titleLabel) + contentView.addSubview(timeLabel) + contentView.addSubview(desLabel) + contentView.addSubview(coinLabel) + + titleLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(32) + make.top.equalToSuperview().offset(16) + } + + timeLabel.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-32) + make.centerY.equalTo(titleLabel) + } + + desLabel.snp.makeConstraints { make in + make.left.equalTo(titleLabel) + make.bottom.equalToSuperview().offset(-16) + make.width.lessThanOrEqualTo(kSPScreenWidth - 190) + } + + coinLabel.snp.makeConstraints { make in + make.centerY.equalTo(desLabel) + make.right.equalTo(timeLabel) + } + } + +} diff --git a/MoviaBox/Class/Wallet/View/SPRewardCoinsCell.swift b/MoviaBox/Class/Wallet/View/SPRewardCoinsCell.swift new file mode 100644 index 0000000..6378d3e --- /dev/null +++ b/MoviaBox/Class/Wallet/View/SPRewardCoinsCell.swift @@ -0,0 +1,110 @@ +// +// SPRewardCoinsCell.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +class SPRewardCoinsCell: SPTableViewCell { + + private lazy var timeLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 14) + label.textColor = .colorFFFFFF() + return label + }() + + private lazy var nameLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 16) + label.textColor = .colorFFFFFF() + return label + }() + + private lazy var expireIconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "expire_icon_01")) + return imageView + }() + + private lazy var expireLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFF3232() + return label + }() + + private lazy var coinLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 16) + label.textColor = .colorFF3232() + return label + }() + + private lazy var remainingLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 12) + label.textColor = .colorFFFFFF() + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + timeLabel.text = "2024-6-10 23:41:18" + nameLabel.text = "Check in" + expireLabel.text = "Expires in 30 days" + coinLabel.text = "+30" + remainingLabel.text = "Remaining:30" + + _setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension SPRewardCoinsCell { + + private func _setupUI() { + contentView.addSubview(timeLabel) + contentView.addSubview(nameLabel) + contentView.addSubview(expireIconImageView) + contentView.addSubview(expireLabel) + contentView.addSubview(coinLabel) + contentView.addSubview(remainingLabel) + + timeLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(32) + make.top.equalToSuperview().offset(17) + } + + nameLabel.snp.makeConstraints { make in + make.left.equalTo(timeLabel) + make.top.equalTo(timeLabel.snp.bottom).offset(6) + } + + expireIconImageView.snp.makeConstraints { make in + make.left.equalTo(timeLabel) + make.bottom.equalToSuperview().offset(-17) + } + + expireLabel.snp.makeConstraints { make in + make.centerY.equalTo(expireIconImageView) + make.left.equalTo(expireIconImageView.snp.right).offset(4) + } + + coinLabel.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-32) + make.top.equalToSuperview().offset(28) + } + + remainingLabel.snp.makeConstraints { make in + make.right.equalTo(coinLabel) + make.bottom.equalToSuperview().offset(-17) + } + } + +} diff --git a/MoviaBox/Class/Wallet/View/SPVIPOrderRecordCell.swift b/MoviaBox/Class/Wallet/View/SPVIPOrderRecordCell.swift new file mode 100644 index 0000000..213bb6f --- /dev/null +++ b/MoviaBox/Class/Wallet/View/SPVIPOrderRecordCell.swift @@ -0,0 +1,74 @@ +// +// SPVIPOrderRecordCell.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/29. +// + +import UIKit + +class SPVIPOrderRecordCell: SPTableViewCell { + + //MARK: UI属性 + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 16) + label.textColor = .colorFF3232() + return label + }() + + private lazy var timeLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 14) + label.textColor = .colorFFFFFF() + return label + }() + + private lazy var dayLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 16) + label.textColor = .colorFF3232() + return label + }() + + + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + titleLabel.text = "Purchase VIP" + timeLabel.text = "2024-6-10 23:41:18" + dayLabel.text = "+30 days" + + _setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension SPVIPOrderRecordCell { + + private func _setupUI() { + contentView.addSubview(titleLabel) + contentView.addSubview(timeLabel) + contentView.addSubview(dayLabel) + + titleLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(32) + make.top.equalToSuperview().offset(15) + } + + timeLabel.snp.makeConstraints { make in + make.left.equalTo(titleLabel) + make.bottom.equalToSuperview().offset(-15) + } + + + dayLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalToSuperview().offset(-25) + } + } +} diff --git a/MoviaBox/MoviaBox.entitlements b/MoviaBox/MoviaBox.entitlements new file mode 100644 index 0000000..a812db5 --- /dev/null +++ b/MoviaBox/MoviaBox.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.applesignin + + Default + + + diff --git a/MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/Contents.json new file mode 100644 index 0000000..54604f5 --- /dev/null +++ b/MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "image 20@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "image 20@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/image 20@2x.png b/MoviaBox/Source/Assets.xcassets/icon/coin_icon_06.imageset/image 20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2699abaa84cccca730eb8a1bc6a04fc3a5dbb1fe GIT binary patch literal 2220 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 T1`b{Q00000NkvXXu0mjfYYlR_ literal 0 HcmV?d00001 diff --git a/MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/Contents.json new file mode 100644 index 0000000..6efec3a --- /dev/null +++ b/MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "time icon@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "time icon@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/time icon@2x.png b/MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/time icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..616856ad2cfed880ce4aeaa7b9ffcb17a243421e GIT binary patch literal 707 zcmV;!0zCbRP)+Pm(&3SGy>`A8=@E_^BRFh?%0ds5}&DAt zkUM{V{!Q*$&apVHIS2v|C;BUcJl_R*(r}su0^@5-k^DW*iItW0dZx~kCg%!|`jBO8 zo5)@+62MCIMe$QM7;{3OfLtl^CIeI;pW5PTM!KHhZm;Q+kfPwqV^}-282r$+OZqBs zSqq!_ZZQayZAo7R?iokqbCUa$SH*DHZNm-e;M>jQ%S%e#;B{x1Wmi%hZ792)xi&_F zLAwEIh2;5>?&rR_?Ih8lILV2!20fcenyX5}4OoTKDanO>n{nC#6_U1Gj5X*R^G*V+ zJ?ay;5@qBKdd1>*r6<`nI(e(w&(ZBwjXna1-XC(xx`6B)yDG{uZtqkU27^=jPr!L8 z+guPL*+QVo=rkOqi1ZS}#4@io(7!s6GbPY5PLv={XH;P9&! zm+SQ>GYqFn;%$gnr%EX?hL6t*{7wHEh;(27ler-Y0w2aPK4aPjte(hY(<5ZM?1aeL pktnWf#Me`CgK`h$`B_)h{R0PdD7|^IF|+^x002ovPDHLkV1lDYL&^XE literal 0 HcmV?d00001 diff --git a/MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/time icon@3x.png b/MoviaBox/Source/Assets.xcassets/icon/expire_icon_01.imageset/time icon@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..0049739d895d23fcf31d7365a4bebc32de71f033 GIT binary patch literal 976 zcmV;>126oEP)K~#7F)mTk- z+At6viG(#bsC$BtkVSSiCunklk`pvNLEr}A1T-gro*?cnixB7us@{N?>>$XUv1D6g zY>c7Mm+w7Z6j>U7o_|R|MT8d@9?a*LAjAoTp^sAy`yyT z9?$HT|BS{`DzhnU;IEl6Cx?`G@b=ad)9DO0B^3F|Vlj+_v(-ofpbyJsP$ZDaAu|Ke zM|qh?3jM2{=U*b1%zXZk5u%XHH!&WMU<(uw%O%AKSu;)8M$*c1d9_X>VXJjX=33_; zVYBH$tu|mmA;c7Aw_Vwi?J_>&rBX0D#^d%{GW7LfIK<%q$K9fJC_|AfBysP^Z^F^h zt-DS#!L9?NX2fLDfimzk@S$uulImDrG|>7cisURIFgA{%P?guPFQ5y6Ndqyd0V8C! z<2hR>EEVhtkqcmuI8&bGU^PS;IEC6YtL{XKBGxsXjeDK90e>T@z-O2NTkeJOCJPRNJ6bOk1=LxU^9mpI|U|0Lv^42v;o zD6Pmslorgj5Tc2W*{HN9?i3tCyTNpb22=`awTH^291x*YD_VO{64fDX6Iev<_rc)p@r33Oj&EVc|T*aBkxZPD{FmwB@1x3)h;k z$IdW$Kt+yP(j6h5o`TX&Gt-?$``a!vGR}7bf}XudwMlOHn=c|WEhS3Kxrgf z0n7pMDla7zUpA2Wr0ha|UWzXpenrCLw#5|Z24(!h%LejOt-F;j8yKDB<2SI0000