diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db19039 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Xcode 编译产物 +DerivedData/ +build/ +*.xcworkspace/ +*.xcuserstate +*.xcuserdatad/ +xcuserdata/ +UserInterfaceState.xcuserstate +*.xccheckout +*.xcscmblueprint +*.xcscmblueprint +*.xcbkptn +*.xcbkptn/ + +# 模拟器缓存 +~/Library/Developer/CoreSimulator/ +CoreSimulator/ + +# Pods / Carthage / Swift Package Manager +Pods/ +Podfile.lock +Carthage/Build/ +Package/.build/ +Package.resolved + +# 隐私配置、密钥、本地环境文件 +*.env +*.plist.local +*.entitlements.local +secret*.txt +key*.pem +*.p12 +*.mobileprovision + +# 本地缓存、日志 +*.log +*.swp +*.DS_Store +.DS_Store +Thumbs.db +node_modules/ +npm-debug.log + +# 图片临时导出、截图 +*.png.orig +*.jpg.orig +screenshot/ diff --git a/QuickLocation.xcodeproj/project.pbxproj b/QuickLocation.xcodeproj/project.pbxproj index 03cb98d..7b6037b 100644 --- a/QuickLocation.xcodeproj/project.pbxproj +++ b/QuickLocation.xcodeproj/project.pbxproj @@ -295,6 +295,8 @@ 30EFF3E22FDA9DEE00EB35D4 /* EmergencyContactVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30EFF3E12FDA9DEE00EB35D4 /* EmergencyContactVM.swift */; }; 30EFF3E52FDAA93400EB35D4 /* PrivacyPolicyVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30EFF3E42FDAA93300EB35D4 /* PrivacyPolicyVC.swift */; }; 30EFF3E72FDAA93D00EB35D4 /* PrivacyPolicyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30EFF3E62FDAA93D00EB35D4 /* PrivacyPolicyView.swift */; }; + 30EFF3E82FCA8C7000227D26 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30EFF3E92FCA8C7000227D26 /* AuthenticationServices.framework */; }; + 55BF752D2FFE53F70055DA57 /* LocationPermissionPopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */; }; D698E9C56D6F2C152772131D /* Pods_QuickLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 475D33CAFA1E1911EB1F8D9F /* Pods_QuickLocation.framework */; }; /* End PBXBuildFile section */ @@ -598,8 +600,10 @@ 30EFF3E12FDA9DEE00EB35D4 /* EmergencyContactVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmergencyContactVM.swift; sourceTree = ""; }; 30EFF3E42FDAA93300EB35D4 /* PrivacyPolicyVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyVC.swift; sourceTree = ""; }; 30EFF3E62FDAA93D00EB35D4 /* PrivacyPolicyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyView.swift; sourceTree = ""; }; + 30EFF3E92FCA8C7000227D26 /* AuthenticationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthenticationServices.framework; path = System/Library/Frameworks/AuthenticationServices.framework; sourceTree = SDKROOT; }; 3E4359082FC48D26003470A5 /* QuickLocation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QuickLocation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 475D33CAFA1E1911EB1F8D9F /* Pods_QuickLocation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QuickLocation.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPermissionPopView.swift; sourceTree = ""; }; DA16D49AA46D4F6838340B55 /* Pods-QuickLocation.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickLocation.debug.xcconfig"; path = "Target Support Files/Pods-QuickLocation/Pods-QuickLocation.debug.xcconfig"; sourceTree = ""; }; E483B9929C03809ADEDE8341 /* Pods-QuickLocation.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickLocation.release.xcconfig"; path = "Target Support Files/Pods-QuickLocation/Pods-QuickLocation.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -632,6 +636,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 30EFF3E82FCA8C7000227D26 /* AuthenticationServices.framework in Frameworks */, D698E9C56D6F2C152772131D /* Pods_QuickLocation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1007,6 +1012,7 @@ 30A7A9102FCAEE3D00105780 /* GroupListPopView.swift */, 30D87CDE2FDFF1A100E958FD /* QuickMessageView.swift */, 30D87CDC2FDFF07500E958FD /* InteractionView.swift */, + 55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */, 30A87A692FEF59E60095E7C6 /* SearchLocation */, 30A87A5C2FEE711C0095E7C6 /* Bubble */, 30CCDE4F2FE2782700F5214A /* SignIn */, @@ -1648,6 +1654,7 @@ 47CD8471BE2146A2656CF27E /* Frameworks */ = { isa = PBXGroup; children = ( + 30EFF3E92FCA8C7000227D26 /* AuthenticationServices.framework */, 475D33CAFA1E1911EB1F8D9F /* Pods_QuickLocation.framework */, ); name = Frameworks; @@ -2067,6 +2074,7 @@ 30BF30102FED0C8E00D9CB52 /* ScheduleDetailVM.swift in Sources */, 30DA36BD2FECC5AB008D5A2C /* CreateScheduleVipPopView.swift in Sources */, 305A77082FCA8C7000227D26 /* PageCollectionViewFlowLayout.swift in Sources */, + 55BF752D2FFE53F70055DA57 /* LocationPermissionPopView.swift in Sources */, 3062E8C42FCFC90F00CEF511 /* CreateGroupVipPopView.swift in Sources */, 30D74ABA2FEA37AD0050EB2C /* ScheduleModel.swift in Sources */, 30CCDE512FE2785D00F5214A /* SignInVC.swift in Sources */, @@ -2130,9 +2138,11 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = QuickLocation/QuickLocation.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = XSJJKSY9FB; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = LRDLWZ2Y83; ENABLE_USER_SCRIPT_SANDBOXING = "$(inherited)"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = QuickLocation/Info.plist; @@ -2153,9 +2163,10 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = cn.zuom8.jisuloca; + PRODUCT_BUNDLE_IDENTIFIER = cn.zuomeng.jisuloca; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = jsdw_dev; STRING_CATALOG_GENERATE_SYMBOLS = YES; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -2179,9 +2190,11 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = QuickLocation/QuickLocation.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = XSJJKSY9FB; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = LRDLWZ2Y83; ENABLE_USER_SCRIPT_SANDBOXING = "$(inherited)"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = QuickLocation/Info.plist; @@ -2202,9 +2215,10 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = cn.zuom8.jisuloca; + PRODUCT_BUNDLE_IDENTIFIER = cn.zuomeng.jisuloca; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = jsdw_dev; STRING_CATALOG_GENERATE_SYMBOLS = YES; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; diff --git a/QuickLocation/AppDelegate.swift b/QuickLocation/AppDelegate.swift index 635dc6e..53ff6bb 100644 --- a/QuickLocation/AppDelegate.swift +++ b/QuickLocation/AppDelegate.swift @@ -70,6 +70,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { print("📱 application open url: \(url.absoluteString) host: \(url.host ?? "")") + + // 微信 OAuth 回调:直接从 URL 提取 code,不依赖 SDK 异步 onResp + if let scheme = url.scheme, scheme == "wx\(AppSettings.kAppsWXApiAppId)" || scheme == AppSettings.kAppsWXApiAppId { + if let components = URLComponents(url: url, resolvingAgainstBaseURL: false), + let code = components.queryItems?.first(where: { $0.name == "code" })?.value { + handleWechatLoginCode(code) + return true + } + } + // 处理支付宝支付结果(不限制 host,适应新版 SDK) if url.scheme?.hasPrefix("Alipay") == true || url.host == "safepay" { AlipaySDK.defaultService().processOrder(withPaymentResult: url) { resultDic in @@ -81,11 +91,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } return true } - else if url.host == "pay" { +// else if url.host == "pay" { return WXApi.handleOpen(url, delegate: self) - } +// } +// +// return true + } - return true + func application(_ application: UIApplication, + continue userActivity: NSUserActivity, + restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { + print("📱 continue userActivity: \(userActivity.webpageURL?.absoluteString ?? "")") + return WXApi.handleOpenUniversalLink(userActivity, delegate: self) } func setupLocation() { @@ -140,11 +157,37 @@ extension AppDelegate { } extension AppDelegate: WXApiDelegate { + private var handledWechatLoginCode: String? { + get { objc_getAssociatedObject(self, &AssociatedKeys.handledWechatLoginCode) as? String } + set { objc_setAssociatedObject(self, &AssociatedKeys.handledWechatLoginCode, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC) } + } + + private struct AssociatedKeys { + static var handledWechatLoginCode: Void? + } + + private func handleWechatLoginCode(_ code: String) { + guard code != handledWechatLoginCode else { + return + } + handledWechatLoginCode = code + LoginSessionHandler.login(type: "weixin", data: ["code": code, "code_type": ""]) + } + func onReq(_ req: BaseReq) { print(req) } func onResp(_ resp: BaseResp) { + if let authResp = resp as? SendAuthResp, authResp.errCode == 0, let code = authResp.code { + handleWechatLoginCode(code) + return + } + + if resp.isKind(of: SendAuthResp.self) { + NotificationCenter.default.post(name: .resumePopupQueue, object: nil) + } + if resp.isKind(of: PayResp.self), let response: PayResp = resp as? PayResp { print("===================== WxPay =====================") diff --git a/QuickLocation/Assets.xcassets/Home/permission_text.imageset/Contents.json b/QuickLocation/Assets.xcassets/Home/permission_text.imageset/Contents.json new file mode 100644 index 0000000..01e5772 --- /dev/null +++ b/QuickLocation/Assets.xcassets/Home/permission_text.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "permission_text@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "permission_text@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/QuickLocation/Assets.xcassets/Home/permission_text.imageset/permission_text@2x.png b/QuickLocation/Assets.xcassets/Home/permission_text.imageset/permission_text@2x.png new file mode 100644 index 0000000..4b690b0 Binary files /dev/null and b/QuickLocation/Assets.xcassets/Home/permission_text.imageset/permission_text@2x.png differ diff --git a/QuickLocation/Assets.xcassets/Home/permission_text.imageset/permission_text@3x.png b/QuickLocation/Assets.xcassets/Home/permission_text.imageset/permission_text@3x.png new file mode 100644 index 0000000..ed99a48 Binary files /dev/null and b/QuickLocation/Assets.xcassets/Home/permission_text.imageset/permission_text@3x.png differ diff --git a/QuickLocation/Assets.xcassets/Home/shield.imageset/Contents.json b/QuickLocation/Assets.xcassets/Home/shield.imageset/Contents.json new file mode 100644 index 0000000..be41ea5 --- /dev/null +++ b/QuickLocation/Assets.xcassets/Home/shield.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Group 1919@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Group 1919@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/QuickLocation/Assets.xcassets/Home/shield.imageset/Group 1919@2x.png b/QuickLocation/Assets.xcassets/Home/shield.imageset/Group 1919@2x.png new file mode 100644 index 0000000..1df1b1b Binary files /dev/null and b/QuickLocation/Assets.xcassets/Home/shield.imageset/Group 1919@2x.png differ diff --git a/QuickLocation/Assets.xcassets/Home/shield.imageset/Group 1919@3x.png b/QuickLocation/Assets.xcassets/Home/shield.imageset/Group 1919@3x.png new file mode 100644 index 0000000..49590e7 Binary files /dev/null and b/QuickLocation/Assets.xcassets/Home/shield.imageset/Group 1919@3x.png differ diff --git a/QuickLocation/Assets.xcassets/Home/warning.imageset/Contents.json b/QuickLocation/Assets.xcassets/Home/warning.imageset/Contents.json new file mode 100644 index 0000000..3d6e33b --- /dev/null +++ b/QuickLocation/Assets.xcassets/Home/warning.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Group_2220@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Group_2220@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/QuickLocation/Assets.xcassets/Home/warning.imageset/Group_2220@2x.png b/QuickLocation/Assets.xcassets/Home/warning.imageset/Group_2220@2x.png new file mode 100644 index 0000000..ad4d680 Binary files /dev/null and b/QuickLocation/Assets.xcassets/Home/warning.imageset/Group_2220@2x.png differ diff --git a/QuickLocation/Assets.xcassets/Home/warning.imageset/Group_2220@3x.png b/QuickLocation/Assets.xcassets/Home/warning.imageset/Group_2220@3x.png new file mode 100644 index 0000000..cec4ccd Binary files /dev/null and b/QuickLocation/Assets.xcassets/Home/warning.imageset/Group_2220@3x.png differ diff --git a/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/Contents.json b/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/Contents.json new file mode 100644 index 0000000..3cbef1c --- /dev/null +++ b/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "mask_bg@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "mask_bg@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/mask_bg@2x.png b/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/mask_bg@2x.png new file mode 100644 index 0000000..471c2b8 Binary files /dev/null and b/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/mask_bg@2x.png differ diff --git a/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/mask_bg@3x.png b/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/mask_bg@3x.png new file mode 100644 index 0000000..ecae651 Binary files /dev/null and b/QuickLocation/Assets.xcassets/Mine/mask_bg.imageset/mask_bg@3x.png differ diff --git a/QuickLocation/Common/Constant.swift b/QuickLocation/Common/Constant.swift index c3e9b98..f105da7 100644 --- a/QuickLocation/Common/Constant.swift +++ b/QuickLocation/Common/Constant.swift @@ -21,6 +21,8 @@ extension DefaultsKeys { var isReLogin: DefaultsKey { .init("isReLogin", defaultValue: false) } /// 显示引导页 var isShowGuide: DefaultsKey { .init("isShowGuide", defaultValue: true) } + /// 气泡持续时间 + var bubbleKeepTimes: DefaultsKey { .init("bubbleKeepTimes") } } /// 通知常量 diff --git a/QuickLocation/Manager/Account/AppContextManager.swift b/QuickLocation/Manager/Account/AppContextManager.swift index 8f22e2d..b02120a 100644 --- a/QuickLocation/Manager/Account/AppContextManager.swift +++ b/QuickLocation/Manager/Account/AppContextManager.swift @@ -91,7 +91,21 @@ class AppContextManager: NSObject { public func saveToken(_ token: String) { Defaults[\.loginToken] = token } - + + /// 状态:0、无状态 1、SOS 2、气泡等 + public func updateAccountStatus(_ status: Int) { + guard var account = self.account else { return } + account.status = status + saveAccount(account) + } + + /// 心情:0、无状态 1、开心 2、愤怒 + public func updateAccountMood(_ mood: Int) { + guard var account = self.account else { return } + account.mood = mood + saveAccount(account) + } + public func deleteAccount() { Defaults[\.loginToken] = nil Defaults[\.userConfig] = nil diff --git a/QuickLocation/Manager/Account/UserConfigModel.swift b/QuickLocation/Manager/Account/UserConfigModel.swift index 5ef2208..9eaba19 100644 --- a/QuickLocation/Manager/Account/UserConfigModel.swift +++ b/QuickLocation/Manager/Account/UserConfigModel.swift @@ -77,6 +77,12 @@ struct SystemConfigModel: Mappable { /// 圈子里的banner var groupBannerList: [String] = [] + /// 引导页显示开关 + var guideDisplay: Bool = true + + /// 全局控制显示隐藏 弹窗和充值 + var globalDisplay: Bool = true + init?(map: Map) { } @@ -87,15 +93,17 @@ struct SystemConfigModel: Mappable { popupConfig <- map["client.popup.display", nested: false] timeConfig <- map["client.time.setting", nested: false] shareConfig <- map["client.weixin.share", nested: false] + guideDisplay <- map["client.guide_display", nested: false] + globalDisplay <- map["client.global_display", nested: false] } } struct PopupWindowConfigModel: Mappable { /// 是否弹vip弹窗 - var pay_pop: Bool = false + var pay_pop: Bool = true /// 搜索位置弹窗 - var search_phone: Bool = false + var search_phone: Bool = true init?(map: Map) { diff --git a/QuickLocation/Manager/App/ApiManager.swift b/QuickLocation/Manager/App/ApiManager.swift index 27871e1..2ff1f4c 100644 --- a/QuickLocation/Manager/App/ApiManager.swift +++ b/QuickLocation/Manager/App/ApiManager.swift @@ -10,6 +10,9 @@ import Moya import SwiftyJSON import RxSwift import CommonCrypto +#if !targetEnvironment(simulator) +import GeYanSdk +#endif class ApiManager: NSObject { @@ -158,6 +161,7 @@ extension ApiManager { private func handleTokenExpired(msg: String?) { MainAsync { NotificationCenter.default.post(name: .invalidatePopupQueue, object: nil) + GeYanSdk.deletePreResultCache() AppContextManager.shared.deleteAccount() GroupIMService.shared.logout() DLToast.showError(text: msg ?? "登录失效,请重新登录!") { diff --git a/QuickLocation/Model/GroupModel.swift b/QuickLocation/Model/GroupModel.swift index 1385102..3792588 100644 --- a/QuickLocation/Model/GroupModel.swift +++ b/QuickLocation/Model/GroupModel.swift @@ -183,6 +183,8 @@ struct GroupMemberModel: Mappable, Equatable { } return UIImage(named: "VipIcon/\(level)") ?? UIImage() } + /// 状态:0、无状态 1、SOS 2、气泡等 + var status: Int = 0 /// 是否在线 var is_online: Bool = false /// 设备电量 @@ -228,6 +230,7 @@ struct GroupMemberModel: Mappable, Equatable { last_position <- map["last_position"] is_online <- map["is_online"] last_active_time <- map["last_active_time"] + status <- map["status"] } } diff --git a/QuickLocation/QuickLocation.entitlements b/QuickLocation/QuickLocation.entitlements index 9e7e98c..778b054 100644 --- a/QuickLocation/QuickLocation.entitlements +++ b/QuickLocation/QuickLocation.entitlements @@ -2,6 +2,10 @@ + com.apple.developer.applesignin + + Default + com.apple.developer.associated-domains applinks:smartdrive.zuom8.cn diff --git a/QuickLocation/Section/Group/CreateGroup/CreateGroupView.swift b/QuickLocation/Section/Group/CreateGroup/CreateGroupView.swift index 9329716..23e4e44 100644 --- a/QuickLocation/Section/Group/CreateGroup/CreateGroupView.swift +++ b/QuickLocation/Section/Group/CreateGroup/CreateGroupView.swift @@ -398,9 +398,9 @@ class CreateGroupView: UIView { lazy var submitBtn: UIButton = { let btn = UIButton(type: .custom) btn.setTitle("创建", for: .normal) - btn.setTitleColor(UIColor(hexStr: "#0F2846"), for: .normal) + btn.setTitleColor(.white, for: .normal) btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) - btn.setBackgroundImage(UIImage(named: "Common/gradient_bg"), for: .normal) + btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) btn.cornerRadius = 25 return btn diff --git a/QuickLocation/Section/Group/CreateGroup/CreateGroupViewModel.swift b/QuickLocation/Section/Group/CreateGroup/CreateGroupViewModel.swift index b36daa7..add0fdf 100644 --- a/QuickLocation/Section/Group/CreateGroup/CreateGroupViewModel.swift +++ b/QuickLocation/Section/Group/CreateGroup/CreateGroupViewModel.swift @@ -87,6 +87,8 @@ class CreateGroupViewModel { } }, onError: { (error) in guard let code = error.underlyingError?.code else { return } + + guard let systemConfig = AppContextManager.shared.systemConfig, systemConfig.globalDisplay else { return } if code == 20009 { // "您创建的圈子个数已达上限,请升级会员等级" CreateGroupVipPopView.show() } diff --git a/QuickLocation/Section/Group/GroupChat/GroupChatVC.swift b/QuickLocation/Section/Group/GroupChat/GroupChatVC.swift index 34375cc..e523880 100644 --- a/QuickLocation/Section/Group/GroupChat/GroupChatVC.swift +++ b/QuickLocation/Section/Group/GroupChat/GroupChatVC.swift @@ -49,7 +49,10 @@ final class GroupChatVC: BaseViewController { // 并行加载:业务接口 + IM SDK 互不依赖,同时发起 requestGroupInfoByKey() - viewModel.loadMessages() + GroupIMService.shared.ensureLogin { [weak self] success in + guard let self = self, success else { return } + self.viewModel.loadMessages() + } // 处理系统配置 guard let config = AppContextManager.shared.systemConfig else { return } @@ -96,7 +99,7 @@ final class GroupChatVC: BaseViewController { // 收起表情/语音面板 self.rootView.dismissAllPanels(excludeTextField: true) UIView.animate(withDuration: duration) { - self.rootView.bottomBar.layoutChain.bottom(height + kSafeBottomMargin + 20) + self.rootView.bottomBar.layoutChain.bottom(height + 20) } self.scrollToBottom() }) @@ -151,7 +154,7 @@ final class GroupChatVC: BaseViewController { private func scrollToBottom() { let count = dataSource.sectionModels.first?.items.count ?? 0 guard count > 0 else { return } - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + DispatchQueue.main.async { self.rootView.tableView.layoutIfNeeded() let indexPath = IndexPath(row: count - 1, section: 0) self.rootView.tableView.scrollToRow(at: indexPath, at: .bottom, animated: false) @@ -292,7 +295,7 @@ final class GroupChatVC: BaseViewController { let offset: CGFloat = show ? 252 : 0 UIView.animate(withDuration: 0.25) { self.rootView.bottomBar.layoutChain.bottom(show ? offset - self.rootView.bottomBar.dl.height : kSafeBottomMargin + 20) - self.rootView.voiceRecordView.layoutChain.bottom(offset - 252 + kSafeBottomMargin) + self.rootView.voiceRecordView.layoutChain.bottom(offset - 252) } scrollToBottom() } @@ -306,7 +309,7 @@ final class GroupChatVC: BaseViewController { self.rootView.emojiPanelView.isHidden = !show let offset: CGFloat = show ? 220 : 0 UIView.animate(withDuration: 0.25) { - self.rootView.bottomBar.layoutChain.bottom(kSafeBottomMargin + 20 + offset) + self.rootView.bottomBar.layoutChain.bottom(20 + offset) } // completion: { _ in // let offset: CGFloat = self.rootView.tableView.contentSize.height diff --git a/QuickLocation/Section/Group/GroupMemberList/GroupMemberListVC.swift b/QuickLocation/Section/Group/GroupMemberList/GroupMemberListVC.swift index 35eff5c..1045d35 100644 --- a/QuickLocation/Section/Group/GroupMemberList/GroupMemberListVC.swift +++ b/QuickLocation/Section/Group/GroupMemberList/GroupMemberListVC.swift @@ -33,6 +33,8 @@ class GroupMemberListVC: BaseViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + + guard let systemConfig = AppContextManager.shared.systemConfig, systemConfig.globalDisplay else { return } rootView.unlockVipMaskView.isHidden = AppContextManager.shared.vip > 1 } diff --git a/QuickLocation/Section/Group/GroupViewController.swift b/QuickLocation/Section/Group/GroupViewController.swift index 5b7454a..0757585 100644 --- a/QuickLocation/Section/Group/GroupViewController.swift +++ b/QuickLocation/Section/Group/GroupViewController.swift @@ -220,7 +220,9 @@ final class GroupViewController: BaseViewController { GroupService.groupInfo().subscribe { response in guard let model = response.model else { return } self.viewModel.groupList = model.groups - self.loadIMData() + DispatchQueue.global(qos: .default).async { [weak self] in + self?.loadIMData() + } }.disposed(by: disposeBag) } } diff --git a/QuickLocation/Section/Group/InviteJoin/InviteJoinVC.swift b/QuickLocation/Section/Group/InviteJoin/InviteJoinVC.swift index 37b96de..9ab9394 100644 --- a/QuickLocation/Section/Group/InviteJoin/InviteJoinVC.swift +++ b/QuickLocation/Section/Group/InviteJoin/InviteJoinVC.swift @@ -9,6 +9,7 @@ import UIKit import ObjectMapper import RxSwift import RxCocoa +import Kingfisher class InviteJoinVC: BaseViewController { @@ -30,6 +31,62 @@ class InviteJoinVC: BaseViewController { rootView.shareAppBtn.rx.tap.subscribe(onNext: { _ in SharePopView.show() }).disposed(by: disposeBag) + + rootView.shareCodeBtn.rx.tap.subscribe(onNext: { [weak self] in + guard let self = self else { return } + guard let config = AppContextManager.shared.systemConfig, + let shareConfig = config.shareConfig else { return } + + DLToast.showLoading() + + let fallbackImage = UIImage(named: "Common/logo108") + let imageURL: URL? = { + if shareConfig.image.isEmpty { return nil } + return URL(string: shareConfig.image) + }() + + let sendMessage: (UIImage?) -> Void = { [weak self] thumbImage in + guard let self = self else { return } + DLToast.dismiss() + + guard let screenshot = self.rootView.inviteInfoView.takeScreenshot(), + let imageData = screenshot.pngData() else { + DLToast.showError(text: "分享失败") + return + } + + let message = WXMediaMessage() + message.title = "邀请加入圈子" + message.description = shareConfig.content + if let thumb = thumbImage { + message.setThumbImage(thumb) + } + + let imageObject = WXImageObject() + imageObject.imageData = imageData + message.mediaObject = imageObject + + let req = SendMessageToWXReq() + req.bText = false + req.message = message + req.scene = 0 + + WXApi.send(req) + } + + if let url = imageURL { + KingfisherManager.shared.retrieveImage(with: url) { result in + switch result { + case .success(let value): + sendMessage(value.image) + case .failure: + sendMessage(fallbackImage) + } + } + } else { + sendMessage(fallbackImage) + } + }).disposed(by: disposeBag) guard let model = groupInModel else { return } rootView.groupIcon.image = model.groupIcon diff --git a/QuickLocation/Section/Group/InviteJoin/InviteJoinView.swift b/QuickLocation/Section/Group/InviteJoin/InviteJoinView.swift index 364d7f5..98c3c5d 100644 --- a/QuickLocation/Section/Group/InviteJoin/InviteJoinView.swift +++ b/QuickLocation/Section/Group/InviteJoin/InviteJoinView.swift @@ -91,7 +91,7 @@ class InviteJoinView: UIView { inviteInfoView.layoutChain .topToBottomOfView(groupIcon, offset: 50) .edgesHorzontal(30) - .bottomToTopOfView(shareAppBtn, offset: -32) +// .bottomToTopOfView(shareAppBtn, offset: -32) inviteInfoTitleLab.layoutChain .top(20) @@ -265,10 +265,9 @@ class InviteJoinView: UIView { lazy var shareCodeBtn: UIButton = { let btn = UIButton(type: .custom) btn.setTitle("分享邀请码", for: .normal) + btn.setTitleColor(.white, for: .normal) btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) - btn.setTitleColor(UIColor(hexStr: "#0F2846"), for: .normal) - btn.backgroundColor = .clear - btn.setBackgroundImage(UIImage(named: "Common/gradient_bg"), for: .normal) + btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) btn.cornerRadius = 25 return btn }() diff --git a/QuickLocation/Section/Home/Bubble/CreateBubbleVC.swift b/QuickLocation/Section/Home/Bubble/CreateBubbleVC.swift index e5796fd..877a4a2 100644 --- a/QuickLocation/Section/Home/Bubble/CreateBubbleVC.swift +++ b/QuickLocation/Section/Home/Bubble/CreateBubbleVC.swift @@ -8,6 +8,7 @@ import UIKit import RxSwift import RxCocoa +import SwiftyUserDefaults class CreateBubbleVC: BaseViewController { @@ -31,6 +32,13 @@ class CreateBubbleVC: BaseViewController { doneBtn.rx.tap.subscribe(onNext: { [weak self] in guard let self = self else { return } + + guard let systemConfig = AppContextManager.shared.systemConfig, systemConfig.globalDisplay else { + let hours = self.rootView.createBubbleTiemView.selectedHour.value + requestSetBubble(enable: true, keep_time: hours) + return + } + if AppContextManager.shared.vip > 1 { let hours = self.rootView.createBubbleTiemView.selectedHour.value requestSetBubble(enable: true, keep_time: hours) @@ -49,6 +57,13 @@ class CreateBubbleVC: BaseViewController { self.requestSetBubble(enable: false, keep_time: -1) }, cancelText: "取消") }).disposed(by: disposeBag) + + guard AppContextManager.shared.status == 2, let endDate = Defaults[\.bubbleKeepTimes] else { return } + self.rootView.navTitleLabel.text = "活动气泡" + self.rootView.createBubbleDoneView.messageLab.text = self.rootView.createBubbleTipsView.messageText + self.rootView.createBubbleTipsView.isHidden = true + self.rootView.createBubbleDoneView.isHidden = false + self.rootView.createBubbleDoneView.startCountdown(endDate: endDate) } private func requestSetBubble(enable: Bool, keep_time: Int) { @@ -57,13 +72,17 @@ class CreateBubbleVC: BaseViewController { DLToast.dismiss() guard enable else { DLToast.show(text: "气泡已弹出") { + Defaults[\.bubbleKeepTimes] = nil + AppContextManager.shared.updateAccountStatus(0) AppRouter.shared.popOrDismiss() } return } + AppContextManager.shared.updateAccountStatus(2) self.rootView.navTitleLabel.text = "活动气泡" self.rootView.createBubbleDoneView.messageLab.text = self.rootView.createBubbleTipsView.messageText let endDate = Calendar.current.date(byAdding: .hour, value: keep_time, to: Date()) ?? Date() + Defaults[\.bubbleKeepTimes] = endDate self.rootView.createBubbleDoneView.startCountdown(endDate: endDate) self.rootView.createBubbleTipsView.isHidden = true self.rootView.createBubbleDoneView.isHidden = false diff --git a/QuickLocation/Section/Home/GroupMemberView.swift b/QuickLocation/Section/Home/GroupMemberView.swift index 5e679de..e8ec582 100644 --- a/QuickLocation/Section/Home/GroupMemberView.swift +++ b/QuickLocation/Section/Home/GroupMemberView.swift @@ -9,6 +9,7 @@ import UIKit import UIKit import RxSwift import RxCocoa +import Lottie class GroupMemberView: UIView { @@ -184,6 +185,13 @@ class GroupMemberCell: UITableViewCell { onlineStatusLab.text = model.lastUpdateText onlineStatusLab.textColor = UIColor(hexStr: "#999999") } + + // sos + sosLottieView.isHidden = model.status != 1 + model.status == 1 ? sosLottieView.play() : sosLottieView.stop() + + // 气泡 + shieldIconView.isHidden = model.status != 2 } private func setupSubviews() { @@ -263,7 +271,7 @@ class GroupMemberCell: UITableViewCell { tagView.layoutChain .leftToRightOfView(nameLab, offset: 4) .centerY(nameLab) - .height(20) + .height(30) ownView.layoutChain.height(15) @@ -354,10 +362,10 @@ class GroupMemberCell: UITableViewCell { }() lazy var tagView: UIStackView = { - let view = UIStackView(arrangedSubviews: [ownView, offlineView]) + let view = UIStackView(arrangedSubviews: [ownView, offlineView, sosLottieView, shieldIconView]) view.axis = .horizontal view.alignment = .center - view.spacing = 0 + view.spacing = 5 view.backgroundColor = .clear return view }() @@ -401,6 +409,28 @@ class GroupMemberCell: UITableViewCell { return view }() + // sos + lazy var sosLottieView: LottieAnimationView = { + let view = LottieAnimationView(name: "siren") + view.loopMode = .loop + view.isHidden = true + + view.layoutChain.width(26).height(26) + + return view + }() + + // 气泡(盾牌) + lazy var shieldIconView: UIImageView = { + let view = UIImageView(image: UIImage(named: "Home/shield")) + view.contentMode = .scaleAspectFill + view.isHidden = true + + view.layoutChain.width(20).height(20) + + return view + }() + // 在线 lazy var onlineView: UIView = { let view = UIView() diff --git a/QuickLocation/Section/Home/HomeView.swift b/QuickLocation/Section/Home/HomeView.swift index 678306b..4629d67 100644 --- a/QuickLocation/Section/Home/HomeView.swift +++ b/QuickLocation/Section/Home/HomeView.swift @@ -58,7 +58,7 @@ class HomeView: UIView { mv.showsScale = false mv.isRotateEnabled = false mv.isRotateCameraEnabled = false - DispatchQueue.main.async { mv.logoCenter = CGPoint(x: 15, y: mv.bounds.height / 2) } + DispatchQueue.main.async { mv.logoCenter = CGPoint(x: kScreenWidth - 50, y: kScreenHeight / 2 + 65) } return mv }() #else @@ -92,7 +92,6 @@ class HomeView: UIView { }) .disposed(by: disposeBag) - groupMemberView.tableView.rx.setDelegate(self) .disposed(by: disposeBag) @@ -100,6 +99,11 @@ class HomeView: UIView { searchLottieView.rx.tapGesture.subscribe { _ in AppRouter.push(Route.searchLocation) }.disposed(by: disposeBag) + + // 感叹号 + warningIconView.rx.tapGesture.subscribe { _ in + LocationPermissionPopView.show() + }.disposed(by: disposeBag) } private func setupUI() { @@ -118,6 +122,7 @@ class HomeView: UIView { addSubview(messageView) addSubview(messageStackView) addSubview(toolsView) + addSubview(warningIconView) addSubview(searchLottieView) addSubview(locationView) locationView.addSubview(locationIconView) @@ -183,6 +188,12 @@ class HomeView: UIView { .width(40) .centerY(self, offset: -50) + warningIconView.layoutChain + .bottomToTopOfView(toolsView, offset: -10) + .centerX(toolsView) + .width(28) + .heightToWidth(1) + searchLottieView.layoutChain .centerY(toolsView) .right() @@ -191,7 +202,7 @@ class HomeView: UIView { locationView.layoutChain .right(15) - .bottomToView(toolsView) + .bottomToView(toolsView, offset: -10) .width(40) .height(40) @@ -247,7 +258,7 @@ class HomeView: UIView { quickMessageView.isHidden = true interactionView.isHidden = true toolsView.isHidden = false - searchLottieView.isHidden = false + searchLottieView.isHidden = AppContextManager.shared.systemConfig?.globalDisplay == false onDismissPanel?() } @@ -636,7 +647,16 @@ class HomeView: UIView { view.isHidden = true return view }() - + + // MARK: - warning 惊叹号图标 + lazy var warningIconView: UIImageView = { + let view = UIImageView() + view.image = UIImage(named: "Home/warning") + view.contentMode = .scaleAspectFill + view.isHidden = true + return view + }() + // MARK: - 侧边工具栏 lazy var toolsView: UIStackView = { let view = UIStackView(arrangedSubviews: [bubbleView, signInView, sosView, scheduleView]) diff --git a/QuickLocation/Section/Home/HomeViewController.swift b/QuickLocation/Section/Home/HomeViewController.swift index 0909c91..4235173 100644 --- a/QuickLocation/Section/Home/HomeViewController.swift +++ b/QuickLocation/Section/Home/HomeViewController.swift @@ -53,7 +53,7 @@ class HomeViewController: BaseViewController { private var offlineCheckTimer: Timer? private var popupQueue: PopupQueueManager? - private var sosPlayerKey: UInt8 = 0 + private static var sosPlayerKey: UInt8 = 0 private var groupRefreshWorkItem: DispatchWorkItem? private var groupSwitchWorkItem: DispatchWorkItem? @@ -82,7 +82,14 @@ class HomeViewController: BaseViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - + + let manager = AuthorizeManager.manager(type: .locationAlways) + rootView.warningIconView.isHidden = manager?.authorizeStatus() == .authorized + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) +// sosPlayer?.stop() } // MARK: - MQTT 位置上报 @@ -199,6 +206,7 @@ class HomeViewController: BaseViewController { guard let self = self, let model = response.model else { return } Defaults[\.loginToken] = model.token AppContextManager.shared.systemConfig = model.config + rootView.searchLottieView.isHidden = model.config?.globalDisplay == false self.getUserIMToken() self.requestUserInfo { [weak self] in self?.requestGroupInfo() @@ -656,11 +664,22 @@ extension HomeViewController { } } } + case "bubble": // 气泡 + guard let userId = msg.data?.user_id else { return } + DispatchQueue.main.async { [weak self] in + self?.viewModel.updateMemberStatus(userId: userId, status: 2) + self?.removeAnnotation(userId: userId) + } + case "sos": // 求助 guard let userId = msg.data?.user_id, - userId != AppContextManager.shared.userId else { return } + userId != AppContextManager.shared.userId, + topic.contains(userId) else { return } DispatchQueue.main.async { [weak self] in - guard let self = self, !self.isSOSPlaying else { return } + guard let self = self else { return } + self.viewModel.updateMemberStatus(userId: userId, status: 1) + + guard !self.isSOSPlaying else { return } self.isSOSPlaying = true self.playSOSAlarm() self.rootView.sosPopView.isHidden = false @@ -669,8 +688,11 @@ extension HomeViewController { self.rootView.sosPopView.isHidden = true } DispatchQueue.main.asyncAfter(deadline: .now() + 15) { [weak self] in + self?.sosPlayer?.stop() + self?.sosPlayer = nil self?.rootView.sosPopView.stop() self?.rootView.sosPopView.isHidden = true + self?.isSOSPlaying = false } } case "join": // 圈子有成员加入 @@ -851,8 +873,8 @@ extension HomeViewController: MAMapViewDelegate { extension HomeViewController { private var sosPlayer: AVAudioPlayer? { - get { return objc_getAssociatedObject(self, &sosPlayerKey) as? AVAudioPlayer } - set { objc_setAssociatedObject(self, &sosPlayerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } + get { return objc_getAssociatedObject(self, &HomeViewController.sosPlayerKey) as? AVAudioPlayer } + set { objc_setAssociatedObject(self, &HomeViewController.sosPlayerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } private func playSOSAlarm() { @@ -879,11 +901,6 @@ extension HomeViewController { player.volume = 1.0 player.play() self.sosPlayer = player - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { [weak self] in - self?.sosPlayer?.stop() - self?.sosPlayer = nil - self?.isSOSPlaying = false - } } } diff --git a/QuickLocation/Section/Home/HomeViewModel.swift b/QuickLocation/Section/Home/HomeViewModel.swift index 41921bc..29f6a22 100644 --- a/QuickLocation/Section/Home/HomeViewModel.swift +++ b/QuickLocation/Section/Home/HomeViewModel.swift @@ -144,6 +144,12 @@ class HomeViewModel { setMemberList(updated) } + func updateMemberStatus(userId: String, status: Int) { + guard let index = memberList.firstIndex(where: { $0.user_id == userId }) else { return } + memberList[index].status = status + sectionedItems.onNext(memberList.mapSection()) + } + // MARK: - Init init() { output = Output( diff --git a/QuickLocation/Section/Home/LocationPermissionPopView.swift b/QuickLocation/Section/Home/LocationPermissionPopView.swift new file mode 100644 index 0000000..9e21d13 --- /dev/null +++ b/QuickLocation/Section/Home/LocationPermissionPopView.swift @@ -0,0 +1,177 @@ +// +// LocationPermissionPopView.swift +// QuickLocation +// +// Created by 八条 on 2026/7/8. +// + +import UIKit +import RxSwift +import RxCocoa + +class LocationPermissionPopView: UIView { + + private static let shared = LocationPermissionPopView(frame: CGRect(origin: .zero, size: kScreenSize)) + + var disposeBag = DisposeBag() + + static func show() { + guard let superView = kKeyWindow else { + return + } + + if LocationPermissionPopView.shared.superview != nil { + LocationPermissionPopView.shared.removeFromSuperview() + LocationPermissionPopView.shared.bgView.frame = .zero + } + + LocationPermissionPopView.shared.bgView.alpha = 1 + LocationPermissionPopView.shared.bgView.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight) + superView.addSubview(LocationPermissionPopView.shared) + superView.bringSubviewToFront(LocationPermissionPopView.shared) + + UIView.animate(withDuration: 0.25) { + LocationPermissionPopView.shared.bgView.alpha = 1 + } + } + + /// 关闭 + static func dismiss() { + guard LocationPermissionPopView.shared.superview != nil else { return } + + UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseIn]) { + LocationPermissionPopView.shared.bgView.alpha = 0 + } completion: { _ in + LocationPermissionPopView.shared.removeFromSuperview() + } + } + + private func setupRx() { + settingBtn.rx.tap.subscribe(onNext: { _ in + guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return } + LocationPermissionPopView.dismiss() + if UIApplication.shared.canOpenURL(settingsURL) { + UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil) + } + }).disposed(by: disposeBag) + + closeBtn.rx.tap.subscribe(onNext: { _ in + LocationPermissionPopView.dismiss() + }).disposed(by: disposeBag) + } + + private lazy var bgView: UIView = { + let view = UIView() + view.backgroundColor = .black.withAlphaComponent(0.5) + return view + }() + + lazy var popView: UIView = { + let view = UIView() + view.backgroundColor = .clear + return view + }() + + lazy var popBgView: UIView = { + let view = UIView() + view.backgroundColor = .white + view.cornerRadius = 30 + return view + }() + + lazy var logoImgView: UIImageView = { + let view = UIImageView(image: UIImage(named: "Popup/bell")) + return view + }() + + lazy var headerBgImg: UIImageView = { + let view = UIImageView(image: UIImage(named: "Popup/header_bg")) + view.contentMode = .scaleAspectFill + return view + }() + + lazy var textImgView: UIImageView = { + let view = UIImageView() + view.contentMode = .scaleAspectFill + view.image = UIImage(named: "Home/permission_text") + return view + }() + + lazy var settingBtn: UIButton = { + let btn = UIButton(type: .custom) + btn.setTitle("马上开启", for: .normal) + btn.setTitleColor(.white, for: .normal) + btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) + btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) + btn.cornerRadius = 25 + return btn + }() + + lazy var closeBtn: UIButton = { + let btn = UIButton(type: .custom) + btn.setTitle("取消", for: .normal) + btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal) + btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) + btn.backgroundColor = .clear + return btn + }() + + // MARK: - Init + override init(frame: CGRect) { + super.init(frame: frame) + backgroundColor = .clear + addSubview(bgView) + bgView.addSubview(popView) + popView.addSubview(popBgView) + popView.addSubview(logoImgView) + popBgView.addSubview(headerBgImg) + popBgView.addSubview(textImgView) + popBgView.addSubview(settingBtn) + popBgView.addSubview(closeBtn) + + popView.layoutChain + .centerX() + .centerY() + .width(315) + .height(362) + + popBgView.layoutChain.edges() + + logoImgView.layoutChain + .left(16) + .top(-45) + .width(109) + .height(109) + + headerBgImg.layoutChain + .edges(excludingEdge: .bottom) + .heightToWidth(100/315) + + textImgView.layoutChain + .top(70) + .centerX() + .width(275) + .height(173) + + closeBtn.layoutChain + .bottom() + .height(50) + .edgesHorzontal(20) + + settingBtn.layoutChain + .bottomToTopOfView(closeBtn) + .height(50) + .edgesHorzontal(20) + + setupRx() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + + } +} diff --git a/QuickLocation/Section/Home/SOS/SOSViewController.swift b/QuickLocation/Section/Home/SOS/SOSViewController.swift index 79d0f79..7e9e89d 100644 --- a/QuickLocation/Section/Home/SOS/SOSViewController.swift +++ b/QuickLocation/Section/Home/SOS/SOSViewController.swift @@ -23,35 +23,27 @@ class SOSViewController: BaseViewController { // Do any additional setup after loading the view. fd_interactivePopDisabled = true -// requestUserInfo() rootView.didSendSOS = { status in self.requestSOS(status) } - } - - private func requestUserInfo(completion: (() -> Void)? = nil) { - UserService.userInfo().subscribe { response in - guard let model = response.model else { return } - AppContextManager.shared.saveAccount(model) - - guard model.status == 1 else { return } - self.rootView.countDownView.alpha = 1 - self.rootView.countDownFinish = true - if let path = Bundle.main.path(forResource: "red-exclamation", ofType: "json") { - self.rootView.countDownLottieView.animation = LottieAnimation.filepath(path) - self.rootView.countDownLottieView.loopMode = .loop - self.rootView.countDownLottieView.play() - self.rootView.countDownTipsLab.text = "已将你的SOS和位置发送到你的圈子和紧急联系人。\n\n您的 SOS 将发送给5个人" - } - - }.disposed(by: disposeBag) + + guard AppContextManager.shared.status == 1 else { return } + self.rootView.countDownView.alpha = 1 + self.rootView.countDownFinish = true + if let path = Bundle.main.path(forResource: "red-exclamation", ofType: "json") { + self.rootView.countDownLottieView.animation = LottieAnimation.filepath(path) + self.rootView.countDownLottieView.loopMode = .loop + self.rootView.countDownLottieView.play() + self.rootView.countDownTipsLab.text = "已将你的SOS和位置发送到你的圈子和紧急联系人。\n\n您的 SOS 将发送给5个人" + } } private func requestSOS(_ enable: Bool) { dl.showLoading() SystemService.sos(enable: enable).subscribe(onNext: { response in self.dl.show(text: enable ? "发送成功" : "取消成功") { + AppContextManager.shared.updateAccountStatus(enable ? 1 : 0) AppRouter.shared.popOrDismiss() } }, onError: { (error) in }).disposed(by: disposeBag) diff --git a/QuickLocation/Section/Launch/LaunchViewController.swift b/QuickLocation/Section/Launch/LaunchViewController.swift index e92bb5a..eb36c7c 100644 --- a/QuickLocation/Section/Launch/LaunchViewController.swift +++ b/QuickLocation/Section/Launch/LaunchViewController.swift @@ -30,19 +30,19 @@ class LaunchViewController: BaseViewController { setupLayout() experienceBtn.rx.tap.subscribe(onNext: { _ in -// Defaults[\.guideShowVersion] = self.showVersion + Defaults[\.isShowGuide] = false AppDelegate.shared.showMainViewController() }).disposed(by: disposeBag) getUserConfig() - navigateAfterDelay() } private func navigateAfterDelay() { Observable.just(()) .delay(.milliseconds(2500), scheduler: MainScheduler.instance) .subscribe(onNext: { [weak self] in - if Defaults[\.isShowGuide] { + guard let systemConfig = AppContextManager.shared.systemConfig else { return } + if systemConfig.guideDisplay, Defaults[\.isShowGuide] { self?.collectionView.isHidden = false self?.pageControl.isHidden = false self?.experienceBtn.isHidden = false @@ -76,6 +76,7 @@ class LaunchViewController: BaseViewController { guard let data = response.data, let token = data["token"] as? String else { return } AppContextManager.shared.imToken = token GroupIMService.shared.login { _ in } + self.navigateAfterDelay() }).disposed(by: disposeBag) } diff --git a/QuickLocation/Section/Login/LoginViewController.swift b/QuickLocation/Section/Login/LoginViewController.swift index e24de4e..1b961ac 100644 --- a/QuickLocation/Section/Login/LoginViewController.swift +++ b/QuickLocation/Section/Login/LoginViewController.swift @@ -91,12 +91,20 @@ class LoginViewController: BaseViewController { rootView.wechatLoginBtn.rx.tap .subscribe(onNext: { [weak self] in + guard self?.isAgreed == true else { + DLToast.showError(text: "请先同意用户协议") + return + } self?.viewModel.performWechatLogin() }) .disposed(by: disposeBag) rootView.appleLoginBtn.rx.tap .subscribe(onNext: { [weak self] in + guard self?.isAgreed == true else { + DLToast.showError(text: "请先同意用户协议") + return + } self?.viewModel.performAppleLogin() }) .disposed(by: disposeBag) @@ -115,12 +123,21 @@ class LoginViewController: BaseViewController { DLToast.show(text: "请插入SIM卡后重试") return } + + if GeYanSdk.isPreGettedTokenValidate() { //预登录有效,启动登录授权页 + let oneTapView = OneTapLoginView(frame: UIScreen.main.bounds) + self?.viewModel.performOneTapLogin(from: self!, contentView: oneTapView) + return + } + + // 预登录 GeYanSdk.preGetToken { preDic in - guard let dict = preDic as? [String: Any], - dict["code"] as? Int == 30000, - let model = GyContentModel.current(), - !model.pn.isEmpty else { - DLToast.showError(text: "获取手机号失败,请使用验证码登录") + guard GeYanSdk.isPreGettedTokenValidate() else { + var message = "" + if let dict = preDic as? [String: Any] { + message = dict["msg"] as? String ?? "获取手机号失败,请使用验证码登录" + } + DLToast.show(text: message) return } let oneTapView = OneTapLoginView(frame: UIScreen.main.bounds) diff --git a/QuickLocation/Section/Login/LoginViewModel.swift b/QuickLocation/Section/Login/LoginViewModel.swift index e808d8c..f3b8f81 100644 --- a/QuickLocation/Section/Login/LoginViewModel.swift +++ b/QuickLocation/Section/Login/LoginViewModel.swift @@ -83,28 +83,36 @@ final class LoginViewModel: BaseViewModel { contentView.carrierLabel, contentView.loginButton, contentView.checkBox, - contentView.agreementTV + contentView.agreementLabel ] GeYanSdk.oneTapLogin(vc, viewModel: gyAuthVM, contentView: contentView, subViewList: subViews) { [weak self] result in + guard let dict = result as? [String: Any], - dict["code"] as? Int == 30000, - let token = dict["token"] as? String else { return } - - let opType: String = { - switch dict["operatorType"] as? Int { - case 1: return "CM" - case 2: return "CU" - case 3: return "CT" - default: return "" + let code = dict["code"] as? Int else { return } + print(dict) + if code == 30000, // 成功 + let gyuid = dict["gyuid"], + let token = dict["token"] { + +// let opType: String = { +// switch dict["operatorType"] as? Int { +// case 1: return "CM" +// case 2: return "CU" +// case 3: return "CT" +// default: return "" +// } +// }() + GeYanSdk.closeAuthVC(true) { + self?.loginAction(type: "onekey", data: [ + "gyuid": gyuid, + "token": token + ]) } - }() - - self?.loginAction(type: "onekey", data: [ - "auth_code": "", - "access_code": token, - "operator_type": opType - ]) + } + else { + DLToast.show(text: dict["msg"] as? String ?? "运营商返回失败") + } } } #endif diff --git a/QuickLocation/Section/Login/OneTapLoginView.swift b/QuickLocation/Section/Login/OneTapLoginView.swift index a90740f..20cfe52 100644 --- a/QuickLocation/Section/Login/OneTapLoginView.swift +++ b/QuickLocation/Section/Login/OneTapLoginView.swift @@ -16,7 +16,7 @@ class OneTapLoginView: UIView { var disposeBag = DisposeBag() var oneTapLogin = true - + private func setupRx() { backBtn.rx.tap.subscribe(onNext: { _ in #if !targetEnvironment(simulator) @@ -28,6 +28,8 @@ class OneTapLoginView: UIView { guard let self = self else { return } self.checkBox.isSelected = !self.checkBox.isSelected }).disposed(by: disposeBag) + + agreementTV.delegate = self } func setupAgreementTextWithCarrier(carrier: String) { @@ -65,8 +67,8 @@ class OneTapLoginView: UIView { addSubview(agreementView) agreementView.addSubview(checkBox) - agreementView.addSubview(agreementTV) agreementView.addSubview(agreementLabel) + agreementView.addSubview(agreementTV) bgMaskImage.layoutChain.edges() @@ -102,23 +104,26 @@ class OneTapLoginView: UIView { .height(50) agreementView.layoutChain - .leftToView(loginButton) - .rightToView(loginButton) - .bottom(55) - .height(30) - - agreementLabel.layoutChain.edges() + .edgesHorzontal(30) + .bottom(kSafeBottomMargin + 20) checkBox.layoutChain .left() - .centerY() + .top(10) .width(12) .height(12) + agreementLabel.layoutChain + .leftToRightOfView(checkBox, offset: 0) + .right() + .top() + .bottom() + agreementTV.layoutChain .leftToRightOfView(checkBox, offset: 0) .right() .top() + .bottom() } override init(frame: CGRect) { @@ -193,6 +198,12 @@ class OneTapLoginView: UIView { return btn }() + lazy var label: UILabel = { + let label = UILabel() + + return label + }() + lazy var agreementView: UIView = { let view = UIView() view.backgroundColor = .clear @@ -203,15 +214,16 @@ class OneTapLoginView: UIView { let btn = UIButton(type: .custom) btn.setImage(UIImage(named: "Login/checkbox"), for: .normal) btn.setImage(UIImage(named: "Login/selected"), for: .selected) - btn.extendEdgeInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) + btn.extendEdgeInsets = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 20) + btn.isSelected = true return btn }() lazy var agreementLabel: UILabel = { let label = UILabel() label.textColor = .clear - label.numberOfLines = 1 - label.textAlignment = .center + label.numberOfLines = 0 +// label.textAlignment = .center label.font = .systemFont(ofSize: 10) return label }() @@ -222,8 +234,34 @@ class OneTapLoginView: UIView { textView.backgroundColor = .clear textView.isEditable = false textView.isScrollEnabled = false + textView.isSelectable = true textView.linkTextAttributes = [:] return textView }() } + +#if !targetEnvironment(simulator) +extension OneTapLoginView: UITextViewDelegate { + func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { + var urlStr: String? + if URL.absoluteString == "Carrier", let model = GyContentModel.current(), let link = model.link { + urlStr = link + } + if URL.absoluteString == "UserAgreement" { + urlStr = URLManager.shared.userAgreementUrl + } + if URL.absoluteString == "PrivacyPolicy" { + urlStr = URLManager.shared.privacyPolicyUrl + } + guard let urlString = urlStr else { return true } + let vc = WebViewController(url: urlString, isShare: false, fullscreen: false, style: "default") + AppRouter.present(UINavigationController(rootViewController: vc)) + return true + } + + func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { + false + } +} +#endif diff --git a/QuickLocation/Section/Mine/Account/AccountVC.swift b/QuickLocation/Section/Mine/Account/AccountVC.swift index 154faf4..5c0e3b2 100644 --- a/QuickLocation/Section/Mine/Account/AccountVC.swift +++ b/QuickLocation/Section/Mine/Account/AccountVC.swift @@ -9,6 +9,9 @@ import UIKit import RxSwift import RxCocoa import RxDataSources +#if !targetEnvironment(simulator) +import GeYanSdk +#endif class AccountVC: BaseViewController { @@ -60,6 +63,7 @@ class AccountVC: BaseViewController { UserService.logout().subscribe(onNext: { response in DLToast.dismiss() NotificationCenter.default.post(name: .invalidatePopupQueue, object: nil) + GeYanSdk.deletePreResultCache() AppContextManager.shared.deleteAccount() GroupIMService.shared.logout() AppDelegate.shared.showMainViewController() diff --git a/QuickLocation/Section/Mine/MineView.swift b/QuickLocation/Section/Mine/MineView.swift index 69f3b19..b184689 100644 --- a/QuickLocation/Section/Mine/MineView.swift +++ b/QuickLocation/Section/Mine/MineView.swift @@ -29,7 +29,11 @@ final class MineView: UIView { private let vipBtnTextColor = UIColor(hexStr: "#00343B") func setupData(_ model: UserConfigModel) { - + guard AppContextManager.shared.systemConfig?.globalDisplay == true else { + maskBgView.isHidden = false + return + } + maskBgView.isHidden = true guard model.vip > 1 else { vipTitleLab.text = "开通会员" vipContentLab.text = "会员尊享10+VIP特权" @@ -121,11 +125,19 @@ final class MineView: UIView { return iv }() + lazy var maskBgView: UIImageView = { + let iv = UIImageView() + iv.image = UIImage(named: "Mine/mask_bg") + iv.contentMode = .scaleToFill + iv.isHidden = true + return iv + }() + lazy var vipTitleLab: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: 18, weight: .bold) label.textColor = .white - label.text = "开通会员" + label.text = " " return label }() @@ -133,7 +145,7 @@ final class MineView: UIView { let label = UILabel() label.font = .systemFont(ofSize: 12, weight: .medium) label.textColor = .white - label.text = "会员尊享10+VIP特权" + label.text = " " return label }() @@ -220,6 +232,7 @@ final class MineView: UIView { vipCardView.addSubview(vipActivateButton) vipCardView.addSubview(vipTitleLab) vipCardView.addSubview(vipContentLab) + vipCardView.addSubview(maskBgView) addSubview(profileBgImageView) addSubview(bottomFillView) @@ -282,6 +295,8 @@ final class MineView: UIView { .right(19).centerY() .width(70).height(28) + maskBgView.layoutChain.edges() + // Profile transition background (100pt, overlaps VIP card bottom half) profileBgImageView.layoutChain .topToView(vipCardView, offset: 32) diff --git a/QuickLocation/Section/PopupWindow/PopupQueueManager.swift b/QuickLocation/Section/PopupWindow/PopupQueueManager.swift index 86dfffb..8f94c63 100644 --- a/QuickLocation/Section/PopupWindow/PopupQueueManager.swift +++ b/QuickLocation/Section/PopupWindow/PopupQueueManager.swift @@ -60,6 +60,7 @@ class PopupQueueManager { } private func executeNextStep() { + guard AppContextManager.shared.systemConfig?.globalDisplay == true else { return } switch currentStep { case 0: tryStartPromotionalActivities() diff --git a/QuickLocation/Section/PopupWindow/PromotionalActivitiesVC.swift b/QuickLocation/Section/PopupWindow/PromotionalActivitiesVC.swift index e0c734e..98ba917 100644 --- a/QuickLocation/Section/PopupWindow/PromotionalActivitiesVC.swift +++ b/QuickLocation/Section/PopupWindow/PromotionalActivitiesVC.swift @@ -163,16 +163,20 @@ class PromotionalActivitiesVC: BaseViewController { guard let data = response.data else { return } if payType == "weixin" { // 微信 -// WXApi.registerApp(model.appId, universalLink: AppSettings.kAppsUniversalLink) -// -// let request: PayReq = PayReq() -// request.partnerId = model.partnerId -// request.prepayId = model.prepayId -// request.package = model.packageValue -// request.nonceStr = model.nonceStr -// request.timeStamp = UInt32(model.timeStamp) ?? 0 -// request.sign = model.sign -// WXApi.send(request) + guard let partnerId = data["partnerId"] as? String, + let prepayId = data["prepayId"] as? String, + let package = data["package"] as? String, + let nonceStr = data["nonceStr"] as? String, + let timeStamp = data["timeStamp"] as? String, + let sign = data["sign"] as? String else { return } + let request: PayReq = PayReq() + request.partnerId = partnerId + request.prepayId = prepayId + request.package = package + request.nonceStr = nonceStr + request.timeStamp = UInt32(timeStamp) ?? 0 + request.sign = sign + WXApi.send(request) } else if payType == "alipay" { // 支付宝 if let payParam = data["payParam"] as? String, let appId = data["payParam"] as? String { diff --git a/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleVC.swift b/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleVC.swift index d790f02..768a7c3 100644 --- a/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleVC.swift +++ b/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleVC.swift @@ -110,6 +110,9 @@ class CreateScheduleVC: BaseViewController, MAMapViewDelegate { } }, onError: { error in guard let code = error.underlyingError?.code else { return } + + guard let systemConfig = AppContextManager.shared.systemConfig, systemConfig.globalDisplay else { return } + if code == 20010 { // "创建的行程数达到上限" CreateScheduleVipPopView.show() } @@ -235,7 +238,7 @@ class CreateScheduleVC: BaseViewController, MAMapViewDelegate { .observe(on: MainScheduler.asyncInstance) .subscribe(onNext: { [weak self] items in guard let self = self else { return } - let h = max(CGFloat(items.count) * 122, 122) + let h = max(CGFloat(items.count) * 129, 129) self.popView.tableView.layoutChain.height(h) self.refreshMapPoints() }) @@ -360,7 +363,9 @@ class CreateScheduleVC: BaseViewController, MAMapViewDelegate { // 缩放至包含所有点 if !pointAnnotations.isEmpty { - rootView.mapView.showAnnotations(pointAnnotations, animated: true) + rootView.mapView.showAnnotations(pointAnnotations, + edgePadding: UIEdgeInsets(top: kNaviHeight + 20, left: 30, bottom: kScreenHeight / 3 + 20, right: 30), + animated: true) } #endif } diff --git a/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleView.swift b/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleView.swift index dfcc561..08b2009 100644 --- a/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleView.swift +++ b/QuickLocation/Section/Schedule/CreateSchedule/CreateScheduleView.swift @@ -217,7 +217,7 @@ class CreateScheduleView: UIView { mv.showsUserLocation = false mv.showsCompass = false mv.userTrackingMode = .none - DispatchQueue.main.async { mv.logoCenter = CGPoint(x: mv.bounds.width - 55, y: kNaviHeight) } + DispatchQueue.main.async { mv.logoCenter = CGPoint(x: kScreenWidth - 50, y: kScreenHeight / 3 * 2 - 20) } return mv }() #endif diff --git a/QuickLocation/Section/Schedule/ItineraryDetail/ItineraryDetailView.swift b/QuickLocation/Section/Schedule/ItineraryDetail/ItineraryDetailView.swift index 6c4b6cd..30da56e 100644 --- a/QuickLocation/Section/Schedule/ItineraryDetail/ItineraryDetailView.swift +++ b/QuickLocation/Section/Schedule/ItineraryDetail/ItineraryDetailView.swift @@ -85,7 +85,7 @@ class ItineraryDetailView: UIView { mv.showsUserLocation = false mv.showsCompass = false mv.userTrackingMode = .none - DispatchQueue.main.async { mv.logoCenter = CGPoint(x: mv.bounds.width - 55, y: kNaviHeight) } +// DispatchQueue.main.async { mv.logoCenter = CGPoint(x: mv.bounds.width - 55, y: kNaviHeight) } return mv }() diff --git a/QuickLocation/Section/Schedule/LocationPicker/LocationPickerView.swift b/QuickLocation/Section/Schedule/LocationPicker/LocationPickerView.swift index 4b6be7f..d6c2ef8 100644 --- a/QuickLocation/Section/Schedule/LocationPicker/LocationPickerView.swift +++ b/QuickLocation/Section/Schedule/LocationPicker/LocationPickerView.swift @@ -59,7 +59,7 @@ class LocationPickerView: UIView { bottomView.layoutChain .edgesHorzontal() .bottom() - .height(160) + .height(160 + kSafeBottomMargin) poiNameLab.layoutChain .top(16).left(16).right(16) @@ -81,7 +81,7 @@ class LocationPickerView: UIView { mv.zoomLevel = 18 mv.showsUserLocation = false mv.showsCompass = false - DispatchQueue.main.async { mv.logoCenter = CGPoint(x: mv.bounds.width - 55, y: 25) } +// DispatchQueue.main.async { mv.logoCenter = CGPoint(x: mv.bounds.width - 55, y: kNaviHeight) } return mv }() #endif diff --git a/QuickLocation/Section/Schedule/ScheduleDetail/ScheduleDetailVC.swift b/QuickLocation/Section/Schedule/ScheduleDetail/ScheduleDetailVC.swift index d05826b..cf3a002 100644 --- a/QuickLocation/Section/Schedule/ScheduleDetail/ScheduleDetailVC.swift +++ b/QuickLocation/Section/Schedule/ScheduleDetail/ScheduleDetailVC.swift @@ -36,6 +36,9 @@ class ScheduleDetailVC: BaseViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + + guard let systemConfig = AppContextManager.shared.systemConfig, systemConfig.globalDisplay else { return } + rootView.vipTipsLab.text = AppContextManager.shared.vip > 1 ? "" : "升级 VIP,可查看具体人员与节点" } diff --git a/QuickLocation/Section/VipRecharge/VipRechargeVC.swift b/QuickLocation/Section/VipRecharge/VipRechargeVC.swift index f83c9dc..53413d6 100644 --- a/QuickLocation/Section/VipRecharge/VipRechargeVC.swift +++ b/QuickLocation/Section/VipRecharge/VipRechargeVC.swift @@ -138,16 +138,20 @@ class VipRechargeVC: BaseViewController { let payType = types[self.rootView.selectedPayTypeTag] if payType == "weixin" { // 微信 -// WXApi.registerApp(model.appId, universalLink: AppSettings.kAppsUniversalLink) -// -// let request: PayReq = PayReq() -// request.partnerId = model.partnerId -// request.prepayId = model.prepayId -// request.package = model.packageValue -// request.nonceStr = model.nonceStr -// request.timeStamp = UInt32(model.timeStamp) ?? 0 -// request.sign = model.sign -// WXApi.send(request) + guard let partnerId = data["partnerId"] as? String, + let prepayId = data["prepayId"] as? String, + let package = data["package"] as? String, + let nonceStr = data["nonceStr"] as? String, + let timeStamp = data["timeStamp"] as? String, + let sign = data["sign"] as? String else { return } + let request: PayReq = PayReq() + request.partnerId = partnerId + request.prepayId = prepayId + request.package = package + request.nonceStr = nonceStr + request.timeStamp = UInt32(timeStamp) ?? 0 + request.sign = sign + WXApi.send(request) } else if payType == "alipay" { // 支付宝 if let payParam = data["payParam"] as? String, let appId = data["payParam"] as? String { diff --git a/QuickLocation/Section/Web/Controller/WebViewController.swift b/QuickLocation/Section/Web/Controller/WebViewController.swift index d68c276..14ab667 100644 --- a/QuickLocation/Section/Web/Controller/WebViewController.swift +++ b/QuickLocation/Section/Web/Controller/WebViewController.swift @@ -168,7 +168,11 @@ class FullscreenWebView: WKWebView { super.viewDidLoad() fd_interactivePopDisabled = true if style == "default" { -// setupLeftBarButtonItem(iconColor: "gray") + let btn = UIButton(type: .system) + btn.setImage(UIImage(named: "Common/back"), for: .normal) + btn.tintColor = UIColor(hexStr: "#0F2846") + btn.addTarget(self, action: #selector(leftBackClicked(_:)), for: .touchUpInside) + navigationItem.leftBarButtonItem = UIBarButtonItem(customView: btn) } // setupErrorView() setupView() @@ -312,16 +316,16 @@ class FullscreenWebView: WKWebView { // backItem.tag = 1 let backBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 19, height: 19)) - backBtn.setImage(UIImage(named: "Common/back_\(iconColor)"), for: .normal) + backBtn.setImage(UIImage(named: "Common/back"), for: .normal) backBtn.addTarget(self, action: #selector(leftBackClicked(_:)), for: .touchUpInside) - backBtn.tintColor = iconColor=="white" ? .white : .black + backBtn.tintColor = .black backBtn.tag = 1 let backItem = UIBarButtonItem(customView: backBtn) let popBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 19, height: 19)) - popBtn.setImage(UIImage(named: "Common/close_black"), for: .normal) + popBtn.setImage(UIImage(named: "Common/x_black"), for: .normal) popBtn.addTarget(self, action: #selector(leftBackClicked(_:)), for: .touchUpInside) - popBtn.tintColor = iconColor=="white" ? .white : .black + popBtn.tintColor = .black popBtn.tag = 2 let popItem = UIBarButtonItem(customView: popBtn)