From bc4f3139eccfce19f56674ddaa4df0d29847dd8a Mon Sep 17 00:00:00 2001 From: zeng Date: Fri, 25 Apr 2025 17:00:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=8D=E9=A6=88=E5=8A=9F=E8=83=BD=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Podfile | 30 +++++----- Podfile.lock | 10 +++- Thimra.xcodeproj/project.pbxproj | 4 ++ Thimra/Base/Networking/Base/SPURLPath.swift | 5 +- .../WebView/SPCampaignWebViewController.swift | 55 ++++++++++++++++++ Thimra/Base/WebView/SPWebView.swift | 3 + .../SPWebViewController+ScriptMessage.swift | 43 +++++++++++++- Thimra/Base/WebView/SPWebViewController.swift | 26 +-------- .../Controller/SPFeedbackViewController.swift | 28 +++++++++ .../Controller/SPMineViewController.swift | 3 +- .../SPImagePickerManager.swift | 36 ++++++++++++ .../feed_back_icon_02.imageset/Contents.json | 25 ++++++++ .../feed_back_icon_02.imageset/Vector@2x.png | Bin 0 -> 479 bytes .../feed_back_icon_02.imageset/Vector@3x.png | Bin 0 -> 617 bytes Thimra/Source/Thimra-Bridging-Header.h | 1 + 15 files changed, 223 insertions(+), 46 deletions(-) create mode 100644 Thimra/Base/WebView/SPCampaignWebViewController.swift create mode 100644 Thimra/Class/Mine/Controller/SPFeedbackViewController.swift create mode 100644 Thimra/Libs/ImagePickerManager/SPImagePickerManager.swift create mode 100644 Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Contents.json create mode 100644 Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Vector@2x.png create mode 100644 Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Vector@3x.png diff --git a/Podfile b/Podfile index 2b8ac15..7dd17c9 100644 --- a/Podfile +++ b/Podfile @@ -21,21 +21,21 @@ target 'Thimra' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! - pod 'Moya' #网络框架 - pod 'SnapKit' #布局 - pod 'SmartCodable' #数据解析 - pod 'YYKit' #工具类 - pod 'MJRefresh' #刷新控件 - pod 'Toast' #吐司提示 - pod 'ZFPlayer/AVPlayer' #播放器 - pod 'KTVHTTPCache' #视频缓存 - pod 'HWPanModal' #底部弹出控制器 - pod 'Kingfisher' #图片加载 - pod 'EmptyStateKit' #空数据页面 - pod 'ReachabilitySwift' #网络状态监控 - pod 'WMZPageController' #分页控制器 - pod 'SVProgressHUD' #HUD - + pod 'Moya' #网络框架 + pod 'SnapKit' #布局 + pod 'SmartCodable' #数据解析 + pod 'YYKit' #工具类 + pod 'MJRefresh' #刷新控件 + pod 'Toast' #吐司提示 + pod 'ZFPlayer/AVPlayer' #播放器 + pod 'KTVHTTPCache' #视频缓存 + pod 'HWPanModal' #底部弹出控制器 + pod 'Kingfisher' #图片加载 + pod 'EmptyStateKit' #空数据页面 + pod 'ReachabilitySwift' #网络状态监控 + pod 'WMZPageController' #分页控制器 + pod 'SVProgressHUD' #HUD + pod 'TZImagePickerController' #相册 end diff --git a/Podfile.lock b/Podfile.lock index e6ab7a9..13d5574 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -18,6 +18,11 @@ PODS: - SVProgressHUD/Core (= 2.3.1) - SVProgressHUD/Core (2.3.1) - Toast (4.1.1) + - TZImagePickerController (3.8.8): + - TZImagePickerController/Basic (= 3.8.8) + - TZImagePickerController/Location (= 3.8.8) + - TZImagePickerController/Basic (3.8.8) + - TZImagePickerController/Location (3.8.8) - WMZPageController (1.5.5) - YYKit (1.0.9): - YYKit/no-arc (= 1.0.9) @@ -38,6 +43,7 @@ DEPENDENCIES: - SnapKit - SVProgressHUD - Toast + - TZImagePickerController - WMZPageController - YYKit - ZFPlayer/AVPlayer @@ -57,6 +63,7 @@ SPEC REPOS: - SnapKit - SVProgressHUD - Toast + - TZImagePickerController - WMZPageController - YYKit - ZFPlayer @@ -75,10 +82,11 @@ SPEC CHECKSUMS: SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e + TZImagePickerController: d084a7b97c82d387e7669dd86dc9a9057500aacf WMZPageController: 87dd82d1e3528cd362de19b9a74fd6890d6e1906 YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7 ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13 -PODFILE CHECKSUM: a2c39b60a617ef47e0a8a03d4115500405588542 +PODFILE CHECKSUM: 5a3089e2bc6a1255307675b5887c43caad0168a6 COCOAPODS: 1.16.2 diff --git a/Thimra.xcodeproj/project.pbxproj b/Thimra.xcodeproj/project.pbxproj index f59e295..23220ff 100644 --- a/Thimra.xcodeproj/project.pbxproj +++ b/Thimra.xcodeproj/project.pbxproj @@ -231,6 +231,8 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Thimra/Source/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Thimra; + INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback."; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = ""; @@ -273,6 +275,8 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Thimra/Source/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Thimra; + INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback."; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = ""; diff --git a/Thimra/Base/Networking/Base/SPURLPath.swift b/Thimra/Base/Networking/Base/SPURLPath.swift index 57d5124..59645a4 100644 --- a/Thimra/Base/Networking/Base/SPURLPath.swift +++ b/Thimra/Base/Networking/Base/SPURLPath.swift @@ -45,6 +45,9 @@ let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention" ///反馈首页 let SPFeedBackHomeWebUrl = SPCampaignWebURL + "/pages/leave/index" - +///反馈列表 +let SPFeedBackListWebUrl = SPCampaignWebURL + "/pages/leave/list" +///反馈详情 +let SPFeedBackDetailWebUrl = SPCampaignWebURL + "/pages/leave/detail" diff --git a/Thimra/Base/WebView/SPCampaignWebViewController.swift b/Thimra/Base/WebView/SPCampaignWebViewController.swift new file mode 100644 index 0000000..40999f8 --- /dev/null +++ b/Thimra/Base/WebView/SPCampaignWebViewController.swift @@ -0,0 +1,55 @@ +// +// SPCampaignWebViewController.swift +// Thimra +// +// Created by 佳尔 on 2025/4/25. +// + +import UIKit + +class SPCampaignWebViewController: SPWebViewController { + + var id: String? + + override func viewDidLoad() { + super.viewDidLoad() + + } + + + override func webViewDidFinishLoad(_ webView: SPWebView) { + super.webViewDidFinishLoad(webView) + receiveDataFromNative() + } + +} + +extension SPCampaignWebViewController { + ///设置登录信息 + func receiveDataFromNative() { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + guard let self = self else { return } + var dic = [ + "token" : SPLoginManager.manager.token?.token ?? "", + "time_zone" : String.timeZone(), + "lang" : SPLocalizedManager.shared.currentLocalizedKey, + "type" : "ios", + "theme" : "theme_1", + ] + if let id = id { + dic["id"] = id + } + + + if let json = dic.toJsonString() { + let js = "receiveDataFromNative(\(json))" + self.webView.evaluateJavaScript(js) { _, error in + + } + } + } + + } + +} + diff --git a/Thimra/Base/WebView/SPWebView.swift b/Thimra/Base/WebView/SPWebView.swift index 86c8c36..4e17d28 100644 --- a/Thimra/Base/WebView/SPWebView.swift +++ b/Thimra/Base/WebView/SPWebView.swift @@ -14,6 +14,9 @@ class SPWebView: WKWebView { private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [ WebMessageAPP, + WebMessageOpenFeedbackList, + WebMessageOpenFeedbackDetail, + WebMessageOpenPhotoPicker, ] diff --git a/Thimra/Base/WebView/SPWebViewController+ScriptMessage.swift b/Thimra/Base/WebView/SPWebViewController+ScriptMessage.swift index ab5ede8..0de6e1d 100644 --- a/Thimra/Base/WebView/SPWebViewController+ScriptMessage.swift +++ b/Thimra/Base/WebView/SPWebViewController+ScriptMessage.swift @@ -12,6 +12,12 @@ typealias SPWebViewMessageName = String ///APP交互 let WebMessageAPP: SPWebViewMessageName = "js2app" +///打开反馈列表 +let WebMessageOpenFeedbackList: SPWebViewMessageName = "openFeedbackList" +///打开反馈详情 +let WebMessageOpenFeedbackDetail: SPWebViewMessageName = "openFeedbackDetail" +///打开相册 +let WebMessageOpenPhotoPicker: SPWebViewMessageName = "openPhotoPicker" extension SPWebViewController { @@ -20,9 +26,42 @@ extension SPWebViewController { let name = message.name let body = message.body + spLog(message: body) + + if name == WebMessageOpenFeedbackList { + let vc = SPCampaignWebViewController() + vc.urlStr = SPFeedBackListWebUrl + self.navigationController?.pushViewController(vc, animated: true) + + } else if name == WebMessageOpenFeedbackDetail { + guard let body = message.body as? [String : Any] else { return } + guard let id = body["id"] as? Int else { return } + + let vc = SPCampaignWebViewController() + vc.id = "\(id)" + vc.urlStr = SPFeedBackDetailWebUrl + self.navigationController?.pushViewController(vc, animated: true) + + } else if name == WebMessageOpenPhotoPicker { + let vc = SPImagePickerManager.createImagePicker(delegate: self) + self.present(vc, animated: true) + } -// let js = "window.returnGPSposition('{\"longitude\":\(placemark.longitude ?? 0),\"latitude\":\(placemark.latitude ?? 0)}')" -// self.webView.evaluateJavaScript(js, completionHandler: nil) } } + +//MARK: -------------- TZImagePickerControllerDelegate -------------- +extension SPWebViewController: TZImagePickerControllerDelegate { + + func imagePickerController(_ picker: TZImagePickerController!, didFinishPickingPhotos photos: [UIImage]!, sourceAssets assets: [Any]!, isSelectOriginalPhoto: Bool) { + guard let image = photos.first else { return } + guard let imageData = image.jpegData(compressionQuality: 0.8) else { return } + let imageDataStr = imageData.base64EncodedString(options: .endLineWithCarriageReturn) + + let js = "uploadConvertImage('\(imageDataStr)')" + self.webView.evaluateJavaScript(js) + + } + +} diff --git a/Thimra/Base/WebView/SPWebViewController.swift b/Thimra/Base/WebView/SPWebViewController.swift index ad397a4..34d212c 100644 --- a/Thimra/Base/WebView/SPWebViewController.swift +++ b/Thimra/Base/WebView/SPWebViewController.swift @@ -12,7 +12,7 @@ class SPWebViewController: SPViewController { var urlStr: String? - private lazy var webView: SPWebView = { + private(set) lazy var webView: SPWebView = { let controller = WKUserContentController() let config = WKWebViewConfiguration() @@ -79,9 +79,6 @@ extension SPWebViewController: SPWebViewDelegate { func webViewDidFinishLoad(_ webView: SPWebView) { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in - self?.receiveDataFromNative() - } } @@ -90,24 +87,3 @@ extension SPWebViewController: SPWebViewDelegate { } } -extension SPWebViewController { - - func receiveDataFromNative() { - let dic = [ - "token" : SPLoginManager.manager.token?.token ?? "", - "time_zone" : String.timeZone(), - "lang" : SPLocalizedManager.shared.currentLocalizedKey, - "type" : "ios", - "theme" : "theme_1", - ] - - if let json = dic.toJsonString() { - let js = "receiveDataFromNative(\(json))" - self.webView.evaluateJavaScript(js) { _, error in - - } - } - - } - -} diff --git a/Thimra/Class/Mine/Controller/SPFeedbackViewController.swift b/Thimra/Class/Mine/Controller/SPFeedbackViewController.swift new file mode 100644 index 0000000..decfa75 --- /dev/null +++ b/Thimra/Class/Mine/Controller/SPFeedbackViewController.swift @@ -0,0 +1,28 @@ +// +// SPFeedbackViewController.swift +// Thimra +// +// Created by 佳尔 on 2025/4/25. +// + +import UIKit + +class SPFeedbackViewController: SPCampaignWebViewController { + + + + override func viewDidLoad() { + self.urlStr = SPFeedBackHomeWebUrl + super.viewDidLoad() + self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "feed_back_icon_02"), style: .plain, target: self, action: #selector(handleRightButton)) + + } + + + @objc private func handleRightButton() { + let vc = SPCampaignWebViewController() + vc.urlStr = SPFeedBackListWebUrl + self.navigationController?.pushViewController(vc, animated: true) + } + +} diff --git a/Thimra/Class/Mine/Controller/SPMineViewController.swift b/Thimra/Class/Mine/Controller/SPMineViewController.swift index 400c32c..4d4a088 100644 --- a/Thimra/Class/Mine/Controller/SPMineViewController.swift +++ b/Thimra/Class/Mine/Controller/SPMineViewController.swift @@ -118,8 +118,7 @@ extension SPMineViewController: UITableViewDelegate, UITableViewDataSource { self.navigationController?.pushViewController(vc, animated: true) case .feedBack: - let vc = SPWebViewController() - vc.urlStr = SPFeedBackHomeWebUrl + let vc = SPFeedbackViewController() self.navigationController?.pushViewController(vc, animated: true) default: diff --git a/Thimra/Libs/ImagePickerManager/SPImagePickerManager.swift b/Thimra/Libs/ImagePickerManager/SPImagePickerManager.swift new file mode 100644 index 0000000..0dd1bf0 --- /dev/null +++ b/Thimra/Libs/ImagePickerManager/SPImagePickerManager.swift @@ -0,0 +1,36 @@ +// +// SPImagePickerManager.swift +// Thimra +// +// Created by 佳尔 on 2025/4/25. +// + +import UIKit + +class SPImagePickerManager: NSObject { + static func createImagePicker(maxImagesCount: Int = 1, + allowCrop: Bool = false, + delegate: TZImagePickerControllerDelegate) -> TZImagePickerController { + + let imagePickerVc = TZImagePickerController(maxImagesCount: 1, columnNumber: 4, delegate: delegate, pushPhotoPickerVc: true) + imagePickerVc?.photoWidth = 375 + imagePickerVc?.photoPreviewMaxWidth = 500 + imagePickerVc?.allowTakeVideo = false + imagePickerVc?.allowPickingVideo = false + imagePickerVc?.allowPickingImage = true + ///相机按钮 + imagePickerVc?.allowTakePicture = true + + ///原图按钮 + imagePickerVc?.allowPickingOriginalPhoto = false + imagePickerVc?.maxImagesCount = maxImagesCount + imagePickerVc?.allowCrop = allowCrop +// allowsEditing + imagePickerVc?.scaleAspectFillCrop = true + imagePickerVc?.cropRect = CGRect(x: 0, y: (kSPScreenHeight - kSPScreenWidth) / 2 , width: kSPScreenWidth, height: kSPScreenWidth) + + imagePickerVc?.modalPresentationStyle = .fullScreen + + return imagePickerVc! + } +} diff --git a/Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Contents.json b/Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Contents.json new file mode 100644 index 0000000..7445735 --- /dev/null +++ b/Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Vector@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Vector@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Vector@2x.png b/Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Vector@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..32f77e439941682132359cd4d0f9ba473e1cf2f0 GIT binary patch literal 479 zcmV<50U-W~P)4s9r|yXtjeCNlf#ovLDhM9#Q!1}ZQAmce=l)`+x{Gd#LX$~4Q->Q z{Rr%7+m`PQRTHPBz2T7I)KT_f$Mdl6cwX@Nwl&Waelt4OR!CaS6vIe3fn?eN9%yGM z$8gHZywK8q$G5%3T&|940x5Q0*MJY9{m=-4G=d-v5mcwN!8DjopR^rL3y@(XZ1elm z((z|*3nZUo68ha$7Uerz5q^?VEyQHD^-m_yI95 VpS|mWQ&a!|002ovPDHLkV1h%3%EABu literal 0 HcmV?d00001 diff --git a/Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Vector@3x.png b/Thimra/Source/Assets.xcassets/icon/feed_back_icon_02.imageset/Vector@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..01eb04431565594273b478f915e823d16ffc80da GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL1|)l2v+e>Z&H|6fVg?393lL^>oo1K-6l5$8 za(7}_cTVOdki(Mh=jjugS~f6BPw)x2 zv0!dP9)nMSq2q4G)TSlE48m7@9Lx;Ldsix%UzlOBO8?X3b%8PFyW;0h{(Q8-G22#I zyCgy+#rTi-ua80PXPIR@OaAt+5wNSAq>_65oX(rxzUv(GC$&6{wcc!yyY=i(B@27w zO=%ojLS?P%wj3$$VoG%2uL5mDBT@o*K99kmS>Z!~%*-b>P*L(W8DT)3s z3jC)nvX72xTVp8Tcc?@4Rp})D9mgh3+TqUAkgbvS;j{?zL#;QWbsuZ@GW#v`NZh>O zLuLDX%Vkcpk|i$94E__iZN-W8r{3u-eOA~tH%}z|_!k-PlVK`(@yexqu8bd&pCqrD zc|7D&hvugHS_flJ)@9B~KX)i&hIq-01@`B*SHD_+>sEjF&38MMmWOaxC@q=tO014k zZE4Vl(_+jIt&YD7=)cAL>$7EugwZ;n65Z@%M`3SfRDW#bu#S@7wBc0NX#uuVR{m#q zH=DiLn;@$Ht!tXmw0_Z|{1g59r?-cC&+q)W^JJTOXX=;Q#INBg{wXnE*B03QINP^3 z>HY-U#or8__fFK=`sQvm)8GmHO)FF0w$6Oz&v)~Y*OlD? zqVr|)zTZhOv- #import "WMPageController.h" #import +#import