Files
real-e-party-iOS/YuMi/E-P/NewLogin/Controllers/EPLoginViewController.swift
edwinQQQ 90360448a1 fix: 统一应用名称为 "E-Party" 并更新相关描述
主要变更:
1. 在 Info.plist 中将应用名称和描述中的 "E-Parti" 替换为 "E-Party"。
2. 更新多个本地化字符串和提示信息,确保一致性。
3. 修改部分代码中的错误提示信息,使用本地化字符串替代硬编码文本。

此更新旨在提升品牌一致性,确保用户在使用过程中获得统一的体验。
2025-10-15 19:11:01 +08:00

308 lines
11 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// EPLoginViewController.swift
// YuMi
//
// Created by AI on 2025-01-27.
//
import UIKit
@objc class EPLoginViewController: UIViewController {
// MARK: - Properties
private let backgroundImageView = UIImageView()
private let logoImageView = UIImageView()
private let epartiTitleLabel = UILabel()
private let idLoginButton = EPLoginButton()
private let emailLoginButton = EPLoginButton()
private let agreeCheckbox = UIButton(type: .custom)
private let policyLabel = EPPolicyLabel()
private let feedbackButton = UIButton(type: .custom)
#if DEBUG
private let debugButton = UIButton(type: .custom)
#endif
private let policySelectedKey = EPLoginConfig.Keys.policyAgreed
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// DEBUG
#if DEBUG
print("✅ [EPLogin] DEBUG 模式已激活")
#else
print("⚠️ [EPLogin] 当前为 Release 模式")
#endif
navigationController?.setNavigationBarHidden(true, animated: false)
setupUI()
loadPolicyStatus()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
// MARK: - Setup
private func setupUI() {
setupBackground()
setupLogo()
setupLoginButtons()
setupPolicyArea()
setupNavigationBar()
}
private func setupBackground() {
view.addSubview(backgroundImageView)
backgroundImageView.image = kImage(EPLoginConfig.Images.background)
backgroundImageView.contentMode = .scaleAspectFill
backgroundImageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
private func setupLogo() {
view.addSubview(logoImageView)
logoImageView.image = kImage(EPLoginConfig.Images.loginBg)
logoImageView.snp.makeConstraints { make in
make.top.leading.trailing.equalTo(view)
make.height.equalTo(EPLoginConfig.Layout.logoHeight)
}
// E-PARTY
view.addSubview(epartiTitleLabel)
epartiTitleLabel.text = "E-PARTY"
epartiTitleLabel.font = .systemFont(ofSize: EPLoginConfig.Layout.epartiTitleFontSize, weight: .bold)
epartiTitleLabel.textColor = EPLoginConfig.Colors.textLight
epartiTitleLabel.transform = CGAffineTransform(a: 1, b: 0, c: -0.2, d: 1, tx: 0, ty: 0) //
epartiTitleLabel.snp.makeConstraints { make in
make.leading.equalToSuperview().offset(EPLoginConfig.Layout.epartiTitleLeading)
make.bottom.equalTo(logoImageView.snp.bottom).offset(EPLoginConfig.Layout.epartiTitleBottomOffset)
}
}
private func setupLoginButtons() {
//
idLoginButton.configure(
icon: EPLoginConfig.Images.iconLoginId,
title: YMLocalizedString(EPLoginConfig.LocalizedKeys.idLogin)
)
idLoginButton.delegate = self
emailLoginButton.configure(
icon: EPLoginConfig.Images.iconLoginEmail,
title: YMLocalizedString(EPLoginConfig.LocalizedKeys.emailLogin)
)
emailLoginButton.delegate = self
// StackView
let stackView = UIStackView(arrangedSubviews: [idLoginButton, emailLoginButton])
stackView.axis = .vertical
stackView.spacing = EPLoginConfig.Layout.loginButtonSpacing
stackView.distribution = .fillEqually
view.addSubview(stackView)
stackView.snp.makeConstraints { make in
make.leading.equalToSuperview().offset(EPLoginConfig.Layout.loginButtonHorizontalPadding)
make.trailing.equalToSuperview().offset(-EPLoginConfig.Layout.loginButtonHorizontalPadding)
make.top.equalTo(logoImageView.snp.bottom)
}
idLoginButton.snp.makeConstraints { make in
make.height.equalTo(EPLoginConfig.Layout.loginButtonHeight)
}
emailLoginButton.snp.makeConstraints { make in
make.height.equalTo(EPLoginConfig.Layout.loginButtonHeight)
}
}
private func setupPolicyArea() {
view.addSubview(agreeCheckbox)
view.addSubview(policyLabel)
agreeCheckbox.setImage(kImage("login_privace_select"), for: .selected)
agreeCheckbox.setImage(kImage("login_privace_unselect"), for: .normal)
agreeCheckbox.addTarget(self, action: #selector(togglePolicyCheckbox), for: .touchUpInside)
policyLabel.onUserAgreementTapped = { [weak self] in
print("[EPLogin] User agreement tapped callback triggered")
let url = self?.getUserAgreementURL() ?? ""
print("[EPLogin] User agreement URL: \(url)")
self?.openPolicyInExternalBrowser(url)
}
policyLabel.onPrivacyPolicyTapped = { [weak self] in
print("[EPLogin] Privacy policy tapped callback triggered")
let url = self?.getPrivacyPolicyURL() ?? ""
print("[EPLogin] Privacy policy URL: \(url)")
self?.openPolicyInExternalBrowser(url)
}
agreeCheckbox.snp.makeConstraints { make in
make.leading.equalToSuperview().offset(EPLoginConfig.Layout.horizontalPadding)
make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-30)
make.size.equalTo(EPLoginConfig.Layout.checkboxSize)
}
policyLabel.snp.makeConstraints { make in
make.leading.equalTo(agreeCheckbox.snp.trailing).offset(8)
make.trailing.equalToSuperview().offset(-EPLoginConfig.Layout.horizontalPadding)
make.centerY.equalTo(agreeCheckbox)
}
}
private func setupNavigationBar() {
#if DEBUG
view.addSubview(feedbackButton)
feedbackButton.setTitle(YMLocalizedString(EPLoginConfig.LocalizedKeys.feedback), for: .normal)
feedbackButton.titleLabel?.font = .systemFont(ofSize: EPLoginConfig.Layout.smallFontSize)
feedbackButton.backgroundColor = EPLoginConfig.Colors.backgroundTransparent
feedbackButton.layer.cornerRadius = EPLoginConfig.Layout.feedbackButtonCornerRadius
feedbackButton.addTarget(self, action: #selector(handleFeedback), for: .touchUpInside)
feedbackButton.snp.makeConstraints { make in
make.trailing.equalToSuperview().offset(-EPLoginConfig.Layout.compactHorizontalPadding)
make.top.equalTo(view.safeAreaLayoutGuide).offset(8)
make.height.equalTo(EPLoginConfig.Layout.feedbackButtonHeight)
}
view.addSubview(debugButton)
debugButton.setTitle("切换环境", for: .normal)
debugButton.setTitleColor(.blue, for: .normal)
debugButton.addTarget(self, action: #selector(handleDebug), for: .touchUpInside)
debugButton.snp.makeConstraints { make in
make.leading.equalToSuperview().offset(EPLoginConfig.Layout.compactHorizontalPadding)
make.top.equalTo(view.safeAreaLayoutGuide).offset(8)
}
#endif // DEBUG
}
// MARK: - Actions
private func handleIDLogin() {
let vc = EPLoginTypesViewController()
vc.displayType = .id
navigationController?.pushViewController(vc, animated: true)
}
private func handleEmailLogin() {
let vc = EPLoginTypesViewController()
vc.displayType = .email
navigationController?.pushViewController(vc, animated: true)
}
@objc private func togglePolicyCheckbox() {
agreeCheckbox.isSelected.toggle()
UserDefaults.standard.set(agreeCheckbox.isSelected, forKey: policySelectedKey)
}
@objc private func handleFeedback() {
print("[EPLogin] Feedback - 占位Phase 2 实现")
}
#if DEBUG
@objc private func handleDebug() {
print("[EPLogin] Debug - 占位Phase 2 实现")
}
#endif
private func openPolicyInExternalBrowser(_ urlString: String) {
print("[EPLogin] Original URL: \(urlString)")
// URL XPWebViewController.m 697-698
var fullUrl = urlString
if !urlString.hasPrefix("http") && !urlString.hasPrefix("https") {
let hostUrl = HttpRequestHelper.getHostUrl()
fullUrl = "\(hostUrl)/\(urlString)"
print("[EPLogin] Added host URL, full URL: \(fullUrl)")
}
print("[EPLogin] Opening URL in external browser: \(fullUrl)")
guard let url = URL(string: fullUrl) else {
print("[EPLogin] ❌ Invalid URL: \(fullUrl)")
return
}
print("[EPLogin] URL object created: \(url)")
//
if UIApplication.shared.canOpenURL(url) {
print("[EPLogin] ✅ Can open URL, attempting to open...")
UIApplication.shared.open(url, options: [:]) { success in
print("[EPLogin] Open external browser: \(success ? "✅ Success" : "❌ Failed")")
}
} else {
print("[EPLogin] ❌ Cannot open URL: \(fullUrl)")
}
}
// MARK: - Helpers
private func loadPolicyStatus() {
agreeCheckbox.isSelected = UserDefaults.standard.bool(forKey: policySelectedKey)
//
if !UserDefaults.standard.bool(forKey: EPLoginConfig.Keys.hasLaunchedBefore) {
agreeCheckbox.isSelected = true
UserDefaults.standard.set(true, forKey: policySelectedKey)
UserDefaults.standard.set(true, forKey: EPLoginConfig.Keys.hasLaunchedBefore)
}
}
/// URL
private func getUserAgreementURL() -> String {
// kUserProtocalURL 4
let url = URLWithType(URLType(rawValue: 4)!) as String
print("[EPLogin] User agreement URL from URLWithType: \(url)")
return url
}
/// URL
private func getPrivacyPolicyURL() -> String {
// kPrivacyURL 0
let url = URLWithType(URLType(rawValue: 0)!) as String
print("[EPLogin] Privacy policy URL from URLWithType: \(url)")
return url
}
private func checkPolicyAgreed() -> Bool {
if !agreeCheckbox.isSelected {
// Phase 2:
print("[EPLogin] Please agree to policy first")
return false
}
return true
}
}
// MARK: - EPLoginButtonDelegate
extension EPLoginViewController: EPLoginButtonDelegate {
func loginButtonDidTap(_ button: EPLoginButton) {
guard checkPolicyAgreed() else { return }
if button == idLoginButton {
handleIDLogin()
} else if button == emailLoginButton {
handleEmailLogin()
}
}
}