反馈功能接入完成

This commit is contained in:
zeng 2025-04-25 17:00:24 +08:00
parent 21fd9c5c41
commit bc4f3139ec
15 changed files with 223 additions and 46 deletions

View File

@ -35,7 +35,7 @@ target 'Thimra' do
pod 'ReachabilitySwift' #网络状态监控
pod 'WMZPageController' #分页控制器
pod 'SVProgressHUD' #HUD
pod 'TZImagePickerController' #相册
end

View File

@ -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

View File

@ -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 = "";

View File

@ -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"

View File

@ -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
}
}
}
}
}

View File

@ -14,6 +14,9 @@ class SPWebView: WKWebView {
private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [
WebMessageAPP,
WebMessageOpenFeedbackList,
WebMessageOpenFeedbackDetail,
WebMessageOpenPhotoPicker,
]

View File

@ -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)
}
}

View File

@ -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
}
}
}
}

View File

@ -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)
}
}

View File

@ -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:

View File

@ -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!
}
}

View File

@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

View File

@ -16,3 +16,4 @@
#import <WMZPageController/WMZPageController.h>
#import "WMPageController.h"
#import <SVProgressHUD/SVProgressHUD.h>
#import <TZImagePickerController/TZImagePickerController.h>